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