1 /* $Id: mstring.c,v 1.9 2019/11/19 23:54:53 tom Exp $ */
10 /* parameters about string length. HEAD is the starting size and
11 ** HEAD+TAIL should be a power of two */
16 static size_t buf_len;
19 msprintf(struct mstring *s, const char *fmt, ...)
32 buf_ptr = malloc(buf_len = 4096);
43 len = (size_t) vsnprintf(buf_ptr, buf_len, fmt, args);
45 if ((changed = (len > buf_len)) != 0)
47 char *new_ptr = realloc(buf_ptr, (buf_len * 3) / 2);
60 len = (size_t) vsprintf(buf_ptr, fmt, args);
66 if (len > (size_t) (s->end - s->ptr))
69 size_t cp = (size_t) (s->ptr - s->base);
70 size_t cl = (size_t) (s->end - s->base);
72 while (len > (nl - cp))
74 if ((new_base = realloc(s->base, nl)))
77 s->ptr = s->base + cp;
78 s->end = s->base + nl;
89 memcpy(s->ptr, buf_ptr, len);
94 mputchar(struct mstring *s, int ch)
100 size_t len = (size_t) (s->end - s->base);
101 if ((s->base = realloc(s->base, len + len + TAIL)))
103 s->ptr = s->base + len;
104 s->end = s->base + len + len + TAIL;
112 *s->ptr++ = (char)ch;
119 struct mstring *n = TMALLOC(struct mstring, 1);
123 if ((n->base = n->ptr = MALLOC(HEAD)) != 0)
125 n->end = n->base + HEAD;
139 struct mstring *r = 0;
144 r->end = value + strlen(value);
151 msdone(struct mstring *s)
163 #if defined(YYBTYACC)
164 /* compare two strings, ignoring whitespace, except between two letters or
165 ** digits (and treat all of these as equal) */
167 strnscmp(const char *a, const char *b)
171 while (isspace(UCH(*a)))
173 while (isspace(UCH(*b)))
175 while (*a && *a == *b)
177 if (isspace(UCH(*a)))
179 if (isalnum(UCH(a[-1])) && isalnum(UCH(*b)))
182 else if (isspace(UCH(*b)))
184 if (isalnum(UCH(b[-1])) && isalnum(UCH(*a)))
194 strnshash(const char *s)
200 if (!isspace(UCH(*s)))
201 h = (h << 5) - h + (unsigned char)*s;