]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/byacc/mstring.c
Optionally bind ktls threads to NUMA domains
[FreeBSD/FreeBSD.git] / contrib / byacc / mstring.c
1 /* $Id: mstring.c,v 1.9 2019/11/19 23:54:53 tom Exp $ */
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <stdarg.h>
6 #include <ctype.h>
7 #include <string.h>
8 #include "defs.h"
9
10 /* parameters about string length.  HEAD is the starting size and
11 ** HEAD+TAIL should be a power of two */
12 #define HEAD    24
13 #define TAIL    8
14
15 static char *buf_ptr;
16 static size_t buf_len;
17
18 void
19 msprintf(struct mstring *s, const char *fmt, ...)
20 {
21     va_list args;
22     size_t len;
23 #ifdef HAVE_VSNPRINTF
24     int changed;
25 #endif
26
27     if (!s || !s->base)
28         return;
29
30     if (buf_len == 0)
31     {
32         buf_ptr = malloc(buf_len = 4096);
33     }
34     if (buf_ptr == 0)
35     {
36         return;
37     }
38
39 #ifdef HAVE_VSNPRINTF
40     do
41     {
42         va_start(args, fmt);
43         len = (size_t) vsnprintf(buf_ptr, buf_len, fmt, args);
44         va_end(args);
45         if ((changed = (len > buf_len)) != 0)
46         {
47             char *new_ptr = realloc(buf_ptr, (buf_len * 3) / 2);
48             if (new_ptr == 0)
49             {
50                 free(buf_ptr);
51                 buf_ptr = 0;
52                 return;
53             }
54             buf_ptr = new_ptr;
55         }
56     }
57     while (changed);
58 #else
59     va_start(args, fmt);
60     len = (size_t) vsprintf(buf_ptr, fmt, args);
61     va_end(args);
62     if (len >= buf_len)
63         return;
64 #endif
65
66     if (len > (size_t) (s->end - s->ptr))
67     {
68         char *new_base;
69         size_t cp = (size_t) (s->ptr - s->base);
70         size_t cl = (size_t) (s->end - s->base);
71         size_t nl = cl;
72         while (len > (nl - cp))
73             nl = nl + nl + TAIL;
74         if ((new_base = realloc(s->base, nl)))
75         {
76             s->base = new_base;
77             s->ptr = s->base + cp;
78             s->end = s->base + nl;
79         }
80         else
81         {
82             free(s->base);
83             s->base = 0;
84             s->ptr = 0;
85             s->end = 0;
86             return;
87         }
88     }
89     memcpy(s->ptr, buf_ptr, len);
90     s->ptr += len;
91 }
92
93 int
94 mputchar(struct mstring *s, int ch)
95 {
96     if (!s || !s->base)
97         return ch;
98     if (s->ptr == s->end)
99     {
100         size_t len = (size_t) (s->end - s->base);
101         if ((s->base = realloc(s->base, len + len + TAIL)))
102         {
103             s->ptr = s->base + len;
104             s->end = s->base + len + len + TAIL;
105         }
106         else
107         {
108             s->ptr = s->end = 0;
109             return ch;
110         }
111     }
112     *s->ptr++ = (char)ch;
113     return ch;
114 }
115
116 struct mstring *
117 msnew(void)
118 {
119     struct mstring *n = TMALLOC(struct mstring, 1);
120
121     if (n)
122     {
123         if ((n->base = n->ptr = MALLOC(HEAD)) != 0)
124         {
125             n->end = n->base + HEAD;
126         }
127         else
128         {
129             free(n);
130             n = 0;
131         }
132     }
133     return n;
134 }
135
136 struct mstring *
137 msrenew(char *value)
138 {
139     struct mstring *r = 0;
140     if (value != 0)
141     {
142         r = msnew();
143         r->base = value;
144         r->end = value + strlen(value);
145         r->ptr = r->end;
146     }
147     return r;
148 }
149
150 char *
151 msdone(struct mstring *s)
152 {
153     char *r = 0;
154     if (s)
155     {
156         mputc(s, 0);
157         r = s->base;
158         free(s);
159     }
160     return r;
161 }
162
163 #if defined(YYBTYACC)
164 /* compare two strings, ignoring whitespace, except between two letters or
165 ** digits (and treat all of these as equal) */
166 int
167 strnscmp(const char *a, const char *b)
168 {
169     while (1)
170     {
171         while (isspace(UCH(*a)))
172             a++;
173         while (isspace(UCH(*b)))
174             b++;
175         while (*a && *a == *b)
176             a++, b++;
177         if (isspace(UCH(*a)))
178         {
179             if (isalnum(UCH(a[-1])) && isalnum(UCH(*b)))
180                 break;
181         }
182         else if (isspace(UCH(*b)))
183         {
184             if (isalnum(UCH(b[-1])) && isalnum(UCH(*a)))
185                 break;
186         }
187         else
188             break;
189     }
190     return *a - *b;
191 }
192
193 unsigned int
194 strnshash(const char *s)
195 {
196     unsigned int h = 0;
197
198     while (*s)
199     {
200         if (!isspace(UCH(*s)))
201             h = (h << 5) - h + (unsigned char)*s;
202         s++;
203     }
204     return h;
205 }
206 #endif
207
208 #ifdef NO_LEAKS
209 void
210 mstring_leaks(void)
211 {
212     free(buf_ptr);
213     buf_ptr = 0;
214     buf_len = 0;
215 }
216 #endif