Added package with the documentation and the examples
[lwc.git] / util.c
blob5180a687fd46bb8187cf4cd6c802f1856af80a6f
1 #include "global.h"
3 NormPtr skip_brackets (NormPtr p)
5 NormPtr perr = p;
6 int po = 1;
7 while (CODE [p] != -1 && po)
8 switch (CODE [p++]) {
9 case '[': po++;
10 ncase RESERVED_oper_array:
11 case ']': po--;
13 if (CODE [p] == -1)
14 parse_error (perr, "Unclosed '[' :[");
15 return p;
18 NormPtr skip_braces (NormPtr p)
20 NormPtr perr = p;
21 int po = 1;
22 while (CODE [p] != -1 && po)
23 switch (CODE [p++]) {
24 case '{': po++;
25 ncase '}': po--;
27 if (CODE [p] == -1)
28 parse_error (perr, "Unclosed '{' :{");
29 return p;
32 /* Start RIGHT AFTER the parenthesis. (never remember that) */
33 NormPtr skip_parenthesis (NormPtr p)
35 NormPtr perr = p;
36 int po = 1;
37 while (CODE [p] != -1 && po)
38 switch (CODE [p++]) {
39 case '(': po++;
40 ncase ')': po--;
42 if (CODE [p] == -1)
43 parse_error (perr, "Unclosed '(' :(");
44 return p;
47 NormPtr skip_buffer_parenthesis (Token *C, NormPtr p)
49 int po = 1;
50 while (C [p] != -1 && po)
51 switch (C [p++]) {
52 case '(': po++;
53 ncase ')': po--;
55 if (C [p-1] == -1)
56 parse_error_ll ("Unclosed '(' :(");
57 return p;
60 NormPtr skip_buffer_brackets (Token *C, NormPtr p)
62 int po = 1;
63 while (C [p] != -1 && po)
64 switch (C [p++]) {
65 case '[': po++;
66 ncase ']': po--;
68 if (C [p-1] == -1)
69 parse_error_ll ("Unclosed '[' :[");
70 return p;
73 NormPtr skip_buffer_braces (Token *C, NormPtr p)
75 int po = 1;
76 while (C [p] != -1 && po)
77 switch (C [p++]) {
78 case '{': po++;
79 ncase '}': po--;
81 if (C [p-1] == -1)
82 parse_error_ll ("Unclosed '{' :{");
83 return p;
86 NormPtr skip_declaration (NormPtr p)
88 bool obj_after_brace = isaggrspc (CODE [p]) || CODE [p] == RESERVED_specialize
89 || CODE [p] == RESERVED_typedef
90 && (isaggrspc (CODE [p + 1]) || CODE [p+1] == RESERVED_specialize);
92 if (CODE [p + 1] == ':'
93 && (CODE [p] == RESERVED_private || CODE [p] == RESERVED_public))
94 return p + 2;
95 for (;;) switch (CODE [p]) {
96 case ';': return p + 1;
97 case '{': p = skip_braces (p + 1);
98 if (!obj_after_brace) return p;
99 ncase '(': p = skip_parenthesis (p + 1);
100 ncase '[': p = skip_brackets (p + 1);
101 ndefault: ++p;
105 bool intchr (int *s, int t)
107 while (*s != -1)
108 if (*s++ == t) return true;
109 return false;
112 void intsubst (int *str, int t1, int t2)
114 int i;
115 for (i = 0; str [i] != -1; i++)
116 if (str [i] == t1)
117 str [i] = t2;
120 void intsubst1 (int *str, int t1, int t2)
122 int i;
123 for (i = 0; str [i] != -1; i++)
124 if (str [i] == t1) {
125 str [i] = t2;
126 break;
130 Token *intcpy (int *dest, int *src)
132 Token *r = dest;
133 do *dest++ = *src;
134 while (*src++ != -1);
135 return r;
138 void intextract (int *dest, int *src, int len)
140 while (len--)
141 *dest++ = *src++;
142 *dest = -1;
145 int intlen (int *t)
147 int i;
148 for (i = 0; *t != -1; t++, i++);
149 return i;
152 int *argtdup (typeID *src)
154 int *dest, *r;
155 int len;
157 for (len = 0; src [len] != INTERNAL_ARGEND; len++)
159 r = dest = (int*) malloc ((len + 1) * sizeof (int));
160 do *dest++ = *src;
161 while (*src++ != INTERNAL_ARGEND);
162 *(dest - 1) = -1;
163 return r;
166 int *intdup1 (int *src)
168 int *dest;
169 int len;
171 for (len = 0; src [len] != -1; len++)
173 dest = (int*) malloc ((len + 2) * sizeof (int));
174 intcpy (dest, src);
175 return dest;
178 int *intdup (int *src)
180 int *dest;
181 int len;
183 for (len = 0; src [len] != -1; len++)
185 dest = (int*) malloc ((len + 1) * sizeof (int));
186 intcpy (dest, src);
187 return dest;
190 int *intndup (int *src, int len)
192 int *dest = (int*) malloc ((len + 1) * sizeof (int));
193 intextract (dest, src, len);
194 return dest;
197 int intcmp (int *p1, int *p2)
199 while (*p1 == *p2 && *p1 != -1)
200 p1++, p2++;
201 return *p1 == *p2 ? 0 : *p1 < *p2 ? -1 : 1;
204 void intcat (int *dest, int *src)
206 while (*dest != -1) dest++;
207 intcpy (dest, src);
210 void intncat (int *dest, int *src, int len)
212 while (*dest != -1) dest++;
213 intextract (dest, src, len);
216 void intcatc (int *dest, int t)
218 while (*dest != -1) dest++;
219 *dest++ = t;
220 *dest = -1;
223 void fintprint (FILE *f, int *s)
225 while (*s != -1)
226 fprintf (f, "%s ", expand (*s++));
229 /* escape double quotes */
230 char *escape_q_string (char *str, int len)
232 int i, slen;
233 char *ret;
235 for (i = 0, slen = 4; i < len; i++, slen++)
236 if (str [i] == '"')
237 ++slen;
239 ret = (char*) malloc (slen);
241 ret [0] = '"';
242 for (i = 0, slen = 1; i < len; i++) {
243 if (str [i] == '"') ret [slen++] = '\\';
244 ret [slen++] = str [i];
246 ret [slen++] = '"';
247 ret [slen] = 0;
249 return ret;
252 /* load an entire text file into a string literal */
253 char *loadtext (char *file)
255 struct load_file L;
256 ctor_load_file_ (&L, file);
257 if (!L.success) return 0;
258 file = escape_c_string (L.data, L.len);
259 dtor_load_file_ (&L);
260 return file;
263 /* load a file with mmap */
264 /* How did this got here ??? bootstrap?? */
266 void ctor_load_file_(struct load_file *const this, char *file)
268 this->data = 0;
269 this->success = 0;
270 this->fd = -1;
271 struct stat statbuf;
273 if (stat(file, &statbuf) == -1)
274 return;
275 if ((this->len = statbuf.st_size) == -1)
276 return;
277 if ((this->fd = open(file, O_RDONLY)) == -1)
278 return;
279 #ifdef SYS_HAS_MMAP
280 this->data = (char *) mmap(0, this->len, PROT_READ, MAP_PRIVATE, this->fd, 0);
281 this->success = this->data != MAP_FAILED;
282 #else
283 this->data = (char*) malloc(this->len);
284 this->success = read(this->fd, this->data, this->len) == this->len;
285 close(this->fd);
286 #endif
289 void dtor_load_file_(struct load_file *const this)
291 #ifdef SYS_HAS_MMAP
292 if (this->success)
293 munmap(this->data, this->len);
294 if (this->fd != -1)
295 close(this->fd);
296 #else
297 free(this->data);
298 #endif
301 /* integer trees in C */
302 intnode *intfind (intnode *n, int key)
304 int cbit;
306 if (!n) return NULL;
308 for (cbit = 1;; cbit <<= 1)
309 if (n->key == key) return n;
310 else if ((cbit & key))
311 if (n->less) n = n->less;
312 else return NULL;
313 else
314 if (n->more) n = n->more;
315 else return NULL;
316 return NULL;
319 void intadd (intnode **r, int key, union ival v)
321 int cbit;
322 intnode *n, *m = (intnode*) malloc (sizeof * m);
323 m->less = m->more = NULL;
324 m->key = key;
325 m->v = v;
327 if (!(n = *r)) {
328 *r = m;
329 return;
332 for (cbit = 1;; cbit <<= 1)
333 if ((cbit & key))
334 if (n->less) n = n->less;
335 else {
336 n->less = m;
337 break;
339 else
340 if (n->more) n = n->more;
341 else {
342 n->more = m;
343 break;
347 void intremove (intnode **root, intnode *i)
349 unsigned int isroot, bt = 0;
350 unsigned int key = i->key;
351 intnode *n = *root;
353 if (!(isroot = n == i))
354 for (bt = 1; bt; bt *= 2)
355 if (key & bt) // avoid braces like hell
356 if (n->less != i) n = n->less;
357 else break;
358 else // yes but why?
359 if (n->more != i) n = n->more;
360 else break;
362 if (!i->less && !i->more)
363 if (isroot) *root = 0;
364 else
365 if (key & bt) n->less = 0;
366 else n->more = 0;
367 else {
368 intnode *r = i, *rp = 0;
369 while (r->more || r->less) {
370 rp = r;
371 r = (r->more) ? r->more : r->less;
373 if (isroot) *root = r;
374 else
375 if (key & bt) n->less = r;
376 else n->more = r;
377 if (rp->more == r) rp->more = 0;
378 else rp->less = 0;
379 r->more = i->more;
380 r->less = i->less;