1 /*
2 Copyright 2002-2006 John Plevyak, All Rights Reserved
3 */
4
5 #include "d.h"
6
7 uint d_prime2[] = {1, 3, 7, 13, 31, 61, 127, 251, 509, 1021,
8 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139, 524287, 1048573,
9 2097143, 4194301, 8388593, 16777213, 33554393, 67108859, 134217689, 268435399, 536870909};
10
11 int d_verbose_level = 0;
12 int d_debug_level = 0;
13 int test_level = 0;
14 int d_rdebug_grammar_level = 0;
15
d_dup_pathname_str(const char * s)16 char *d_dup_pathname_str(const char *s) {
17 const char *e = s;
18 if (!s) return dup_str("", 0);
19 if (*e == '"') {
20 e++;
21 while (*e && *e != '"') e++;
22 return dup_str(s + 1, e);
23 } else
24 return dup_str(s, s + strlen(s));
25 }
26
dup_str(const char * s,const char * e)27 char *dup_str(const char *s, const char *e) {
28 int l = e ? e - s : strlen(s);
29 char *ss = (char *)MALLOC(l + 1);
30 memcpy(ss, s, l);
31 ss[l] = 0;
32 return ss;
33 }
34
strhashl(const char * s,int l)35 uint strhashl(const char *s, int l) {
36 uint h = 0, g;
37 int i = 0;
38
39 for (; i < l; i++, s++) {
40 h = (h << 4) + *s;
41 if ((g = h & 0xf0000000)) h = (h ^ (g >> 24)) ^ g;
42 }
43 return h;
44 }
45
buf_read(const char * pathname,char ** buf,int * len)46 int buf_read(const char *pathname, char **buf, int *len) {
47 struct stat sb;
48 int fd;
49 size_t real_size;
50
51 *buf = 0;
52 *len = 0;
53 fd = open(pathname, O_RDONLY);
54 if (fd <= 0) return -1;
55 memset(&sb, 0, sizeof(sb));
56 fstat(fd, &sb);
57 *len = sb.st_size;
58 *buf = (char *)MALLOC(*len + 2);
59 /* MINGW likes to convert cr lf => lf which messes with the size */
60 real_size = read(fd, *buf, *len);
61 (*buf)[real_size] = 0;
62 (*buf)[real_size + 1] = 0;
63 *len = real_size;
64 close(fd);
65 return *len;
66 }
67
sbuf_read(const char * pathname)68 char *sbuf_read(const char *pathname) {
69 char *buf;
70 int len;
71
72 if (buf_read(pathname, &buf, &len) < 0) return NULL;
73 return buf;
74 }
75
d_fail(const char * str,...)76 void d_fail(const char *str, ...) {
77 char nstr[256];
78 va_list ap;
79 va_start(ap, str);
80 snprintf(nstr, 255, "fail: %s\n", str);
81 vfprintf(stderr, nstr, ap);
82 va_end(ap);
83 exit(1);
84 }
85
d_warn(const char * str,...)86 void d_warn(const char *str, ...) {
87 char nstr[256];
88 va_list ap;
89 va_start(ap, str);
90 snprintf(nstr, 255, "warning: %s\n", str);
91 vfprintf(stderr, nstr, ap);
92 va_end(ap);
93 }
94
vec_add_internal(void * v,void * elem)95 void vec_add_internal(void *v, void *elem) {
96 AbstractVec *av = (AbstractVec *)v;
97 if (!av->n) {
98 av->v = av->e;
99 } else if (av->v == av->e) {
100 av->v = (void **)MALLOC(INITIAL_VEC_SIZE * sizeof(void *));
101 memcpy(av->v, av->e, av->n * sizeof(void *));
102 } else {
103 if ((av->n & (INITIAL_VEC_SIZE - 1)) == 0) {
104 int l = av->n, nl = (1 + INITIAL_VEC_SHIFT);
105 l = l >> INITIAL_VEC_SHIFT;
106 while (!(l & 1)) {
107 l = l >> 1;
108 nl++;
109 }
110 l = l >> 1;
111 if (!av->n || !l) {
112 nl = 1 << nl;
113 av->v = (void **)REALLOC(av->v, nl * sizeof(void *));
114 }
115 }
116 }
117 av->v[av->n] = elem;
118 av->n++;
119 }
120
vec_eq(void * v,void * vv)121 int vec_eq(void *v, void *vv) {
122 AbstractVec *av = (AbstractVec *)v;
123 AbstractVec *avv = (AbstractVec *)vv;
124 uint i;
125
126 if (av->n != avv->n) return 0;
127 for (i = 0; i < av->n; i++)
128 if (av->v[i] != avv->v[i]) return 0;
129 return 1;
130 }
131
stack_push_internal(AbstractStack * s,void * elem)132 void *stack_push_internal(AbstractStack *s, void *elem) {
133 int n = s->cur - s->start;
134 if (s->start == s->initial) {
135 s->cur = (void **)MALLOC(n * 2 * sizeof(void *));
136 memcpy(s->cur, s->start, n * sizeof(void *));
137 } else
138 s->cur = (void **)REALLOC(s->start, n * 2 * sizeof(void *));
139 s->end = s->start = s->cur;
140 s->cur += n;
141 s->end += n * 2;
142 *s->cur++ = elem;
143 return elem;
144 }
145
set_find(void * av,void * t)146 int set_find(void *av, void *t) {
147 AbstractVec *v = (AbstractVec *)av;
148 int j, n = v->n;
149 uint i;
150 if (n) {
151 uint h = ((uintptr_t)t);
152 h = h % n;
153 for (i = h, j = 0; i < v->n && j < SET_MAX_SEQUENTIAL; i = ((i + 1) % n), j++) {
154 if (!v->v[i]) {
155 return 0;
156 } else if (v->v[i] == t)
157 return 1;
158 }
159 }
160 return 0;
161 }
162
set_add(void * av,void * t)163 int set_add(void *av, void *t) {
164 AbstractVec *v = (AbstractVec *)av, vv;
165 int j, n = v->n;
166 uint i;
167 if (n) {
168 uint h = ((uintptr_t)t);
169 h = h % n;
170 for (i = h, j = 0; i < v->n && j < SET_MAX_SEQUENTIAL; i = ((i + 1) % n), j++) {
171 if (!v->v[i]) {
172 v->v[i] = t;
173 return 1;
174 } else if (v->v[i] == t)
175 return 0;
176 }
177 }
178 if (!n) {
179 vv.v = NULL;
180 v->i = INITIAL_SET_SIZE_INDEX;
181 } else {
182 vv.v = v->v;
183 vv.n = v->n;
184 v->i = v->i + 1;
185 }
186 v->n = d_prime2[v->i];
187 v->v = (void **)MALLOC(v->n * sizeof(void *));
188 memset(v->v, 0, v->n * sizeof(void *));
189 if (vv.v) {
190 set_union(av, &vv);
191 FREE(vv.v);
192 }
193 return set_add(v, t);
194 }
195
set_add_fn(void * av,void * t,hash_fns_t * fns)196 void *set_add_fn(void *av, void *t, hash_fns_t *fns) {
197 AbstractVec *v = (AbstractVec *)av, vv;
198 uint32 tt = fns->hash_fn(t, fns);
199 int j, n = v->n;
200 uint i;
201 if (n) {
202 uint h = tt % n;
203 for (i = h, j = 0; i < v->n && j < SET_MAX_SEQUENTIAL; i = ((i + 1) % n), j++) {
204 if (!v->v[i]) {
205 v->v[i] = t;
206 return t;
207 } else {
208 if (!fns->cmp_fn(v->v[i], t, fns)) return v->v[i];
209 }
210 }
211 }
212 if (!n) {
213 vv.v = NULL;
214 v->i = INITIAL_SET_SIZE_INDEX;
215 } else {
216 vv.v = v->v;
217 vv.n = v->n;
218 v->i = v->i + 1;
219 }
220 v->n = d_prime2[v->i];
221 v->v = (void **)MALLOC(v->n * sizeof(void *));
222 memset(v->v, 0, v->n * sizeof(void *));
223 if (vv.v) {
224 set_union_fn(av, &vv, fns);
225 FREE(vv.v);
226 }
227 return set_add_fn(v, t, fns);
228 }
229
set_union(void * av,void * avv)230 int set_union(void *av, void *avv) {
231 AbstractVec *vv = (AbstractVec *)avv;
232 uint i, changed = 0;
233
234 for (i = 0; i < vv->n; i++)
235 if (vv->v[i]) changed = set_add(av, vv->v[i]) || changed;
236 return changed;
237 }
238
set_union_fn(void * av,void * avv,hash_fns_t * fns)239 void set_union_fn(void *av, void *avv, hash_fns_t *fns) {
240 AbstractVec *vv = (AbstractVec *)avv;
241 uint i;
242
243 for (i = 0; i < vv->n; i++)
244 if (vv->v[i]) set_add_fn(av, vv->v[i], fns);
245 }
246
set_to_vec(void * av)247 void set_to_vec(void *av) {
248 AbstractVec *v = (AbstractVec *)av, vv;
249 uint i;
250
251 vv.n = v->n;
252 vv.v = v->v;
253 if (v->v == v->e) {
254 memcpy(vv.e, v->e, sizeof(v->e));
255 vv.v = vv.e;
256 }
257 v->n = 0;
258 v->v = 0;
259 for (i = 0; i < vv.n; i++)
260 if (vv.v[i]) vec_add_internal(v, vv.v[i]);
261 FREE(vv.v);
262 }
263
int_list_diff(int * a,int * b,int * c)264 void int_list_diff(int *a, int *b, int *c) {
265 while (1) {
266 if (*b < 0) break;
267 Lagainc:
268 if (*c < 0) {
269 while (*b >= 0) *a++ = *b++;
270 break;
271 }
272 Lagainb:
273 if (*b == *c) {
274 b++;
275 c++;
276 continue;
277 }
278 if (*b < *c) {
279 *a++ = *b++;
280 if (*b < 0) break;
281 goto Lagainb;
282 }
283 if (*c < *b) {
284 c++;
285 goto Lagainc;
286 }
287 }
288 *a++ = -1;
289 }
290
int_list_intersect(int * a,int * b,int * c)291 void int_list_intersect(int *a, int *b, int *c) {
292 while (1) {
293 if (*b < 0) break;
294 Lagainc:
295 if (*c < 0) break;
296 Lagainb:
297 if (*b == *c) {
298 *a++ = *b++;
299 c++;
300 continue;
301 }
302 if (*b < *c) {
303 b++;
304 if (*b < 0) break;
305 goto Lagainb;
306 }
307 if (*c < *b) {
308 c++;
309 goto Lagainc;
310 }
311 }
312 *a++ = -1;
313 }
314
int_list_dup(int * aa)315 int *int_list_dup(int *aa) {
316 int *a = aa, *b, *bb;
317 while (*a != -1) {
318 a++;
319 }
320 bb = b = (int *)MALLOC((a - aa + 1) * sizeof(int));
321 a = aa;
322 while (*a != -1) {
323 *b++ = *a++;
324 }
325 *b++ = -1;
326 return bb;
327 }
328
329 #define ESC(_c) \
330 *ss++ = '\\'; \
331 *ss++ = _c; \
332 break;
333
escape_string_internal(char * s,int single_quote)334 static char *escape_string_internal(char *s, int single_quote) {
335 char *ss = (char *)MALLOC((strlen(s) + 1) * 4), *sss = ss;
336 for (; *s; s++) {
337 switch (*s) {
338 case '\b':
339 ESC('b');
340 case '\f':
341 ESC('f');
342 case '\n':
343 ESC('n');
344 case '\r':
345 ESC('r');
346 case '\t':
347 ESC('t');
348 case '\v':
349 ESC('v');
350 case '\a':
351 ESC('a');
352 case '\\':
353 ESC('\\');
354 case '\"':
355 if (!single_quote) {
356 ESC(*s);
357 }
358 *ss++ = *s;
359 break;
360 case '\'':
361 if (single_quote) {
362 ESC(*s);
363 }
364 *ss++ = *s;
365 break;
366 default:
367 if (isprint_(*s))
368 *ss++ = *s;
369 else {
370 *ss++ = '\\';
371 *ss++ = 'x';
372 *ss++ = tohex2((unsigned char)*s);
373 *ss++ = tohex1((unsigned char)*s);
374 }
375 break;
376 }
377 }
378 *ss = 0;
379 return sss;
380 }
381
escape_string(char * s)382 char *escape_string(char *s) { return escape_string_internal(s, 0); }
escape_string_single_quote(char * s)383 char *escape_string_single_quote(char *s) { return escape_string_internal(s, 1); }
384
d_free(void * x)385 void d_free(void *x) { FREE(x); }
386