1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | #include "def.h" |
28 | |
29 | static int deftype (char *line, struct filepointer *filep, |
30 | struct inclist *file_red, struct inclist *file, |
31 | int parse_it); |
32 | static int zero_value(char *filename, char *exp, struct filepointer *filep, |
33 | struct inclist *file_red); |
34 | static int merge2defines(struct inclist *file1, struct inclist *file2); |
35 | |
36 | static int |
37 | gobble(struct filepointer *filep, struct inclist *file, |
38 | struct inclist *file_red) |
39 | { |
40 | char *line; |
41 | int type; |
42 | |
43 | while ((line = getnextline(filep))) { |
44 | switch(type = deftype(line, filep, file_red, file, FALSE0)) { |
45 | case IF0: |
46 | case IFFALSE17: |
47 | case IFGUESSFALSE20: |
48 | case IFDEF1: |
49 | case IFNDEF2: |
50 | type = gobble(filep, file, file_red); |
51 | while ((type == ELIF13) || (type == ELIFFALSE18) || |
52 | (type == ELIFGUESSFALSE21)) |
53 | type = gobble(filep, file, file_red); |
54 | if (type == ELSE3) |
55 | (void)gobble(filep, file, file_red); |
56 | break; |
57 | case ELSE3: |
58 | case ENDIF4: |
59 | debug(0,("%s, line %d: #%s\n",do { } while (0) |
60 | file->i_file, filep->f_line,do { } while (0) |
61 | directives[type]))do { } while (0); |
62 | return(type); |
63 | case DEFINE5: |
64 | case UNDEF6: |
65 | case INCLUDE7: |
66 | case INCLUDEDOT19: |
67 | case PRAGMA9: |
68 | case ERROR10: |
69 | case IDENT11: |
70 | case SCCS12: |
71 | case EJECT14: |
72 | case WARNING15: |
73 | case INCLUDENEXT16: |
74 | case INCLUDENEXTDOT22: |
75 | break; |
76 | case ELIF13: |
77 | case ELIFFALSE18: |
78 | case ELIFGUESSFALSE21: |
79 | return(type); |
80 | case -1: |
81 | warning("%s", file_red->i_file); |
82 | if (file_red != file) |
83 | warning1(" (reading %s)", file->i_file); |
84 | warning1(", line %ld: unknown directive == \"%s\"\n", |
85 | filep->f_line, line); |
86 | break; |
87 | } |
88 | } |
89 | return(-1); |
90 | } |
91 | |
92 | |
93 | |
94 | |
95 | static int |
96 | deftype (char *line, struct filepointer *filep, |
97 | struct inclist *file_red, struct inclist *file, int parse_it) |
98 | { |
99 | register char *p; |
100 | char *directive, savechar, *q; |
101 | register int ret; |
102 | |
103 | |
104 | |
105 | |
106 | directive=line+1; |
107 | while (*directive == ' ' || *directive == '\t') |
108 | directive++; |
109 | |
110 | p = directive; |
111 | while ((*p == '_') || (*p >= 'a' && *p <= 'z')) |
112 | p++; |
113 | savechar = *p; |
114 | *p = '\0'; |
115 | ret = match(directive, directives); |
116 | *p = savechar; |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | if (ret == ELIF13 && !parse_it) |
125 | { |
126 | while (*p == ' ' || *p == '\t') |
127 | p++; |
128 | |
129 | |
130 | |
131 | debug(0,("%s, line %d: #elif %s ",do { } while (0) |
132 | file->i_file, filep->f_line, p))do { } while (0); |
133 | ret = zero_value(file->i_file, p, filep, file_red); |
134 | if (ret != IF0) |
135 | { |
136 | debug(0,("false...\n"))do { } while (0); |
137 | if (ret == IFFALSE17) |
138 | return(ELIFFALSE18); |
139 | else |
140 | return(ELIFGUESSFALSE21); |
141 | } |
142 | else |
143 | { |
144 | debug(0,("true...\n"))do { } while (0); |
145 | return(ELIF13); |
146 | } |
147 | } |
148 | |
149 | if (ret < 0 || ! parse_it) |
150 | return(ret); |
151 | |
152 | |
153 | |
154 | |
155 | while (*p == ' ' || *p == '\t') |
156 | p++; |
157 | q = p + strlen(p); |
158 | do { |
159 | q--; |
160 | } while (*q == ' ' || *q == '\t'); |
161 | q[1] = '\0'; |
162 | switch (ret) { |
163 | case IF0: |
164 | |
165 | |
166 | |
167 | ret = zero_value(file->i_file, p, filep, file_red); |
168 | debug(0,("%s, line %d: %s #if %s\n",do { } while (0) |
169 | file->i_file, filep->f_line, ret?"false":"true", p))do { } while (0); |
170 | break; |
171 | case IFDEF1: |
172 | case IFNDEF2: |
173 | debug(0,("%s, line %d: #%s %s\n",do { } while (0) |
174 | file->i_file, filep->f_line, directives[ret], p))do { } while (0); |
175 | case UNDEF6: |
176 | |
177 | |
178 | |
179 | while (isalnum(*p) || *p == '_') |
180 | *line++ = *p++; |
181 | *line = '\0'; |
182 | break; |
183 | case INCLUDE7: |
184 | case INCLUDENEXT16: |
185 | debug(2,("%s, line %d: #include%s %s\n",do { } while (0) |
186 | file->i_file, filep->f_line,do { } while (0) |
187 | (ret == INCLUDE) ? "" : "_next", p))do { } while (0); |
188 | |
189 | |
190 | while (1) { |
191 | struct symtab **sym; |
192 | |
193 | if (!*p || *p == '"' || *p == '<') |
194 | break; |
195 | |
196 | sym = isdefined(p, file_red, NULL((void *)0)); |
197 | if (!sym) |
198 | break; |
199 | |
200 | p = (*sym)->s_value; |
201 | debug(3,("%s : #includes SYMBOL %s = %s\n",do { } while (0) |
202 | file->i_incstring,do { } while (0) |
203 | (*sym) -> s_name,do { } while (0) |
204 | (*sym) -> s_value))do { } while (0); |
205 | |
206 | file->i_flags |= INCLUDED_SYM(1<<5); |
207 | } |
208 | |
209 | |
210 | |
211 | |
212 | while (*p && *p != '"' && *p != '<') |
213 | p++; |
214 | if (! *p) |
215 | return(-2); |
216 | if (*p++ == '"') { |
217 | if (ret == INCLUDE7) |
218 | ret = INCLUDEDOT19; |
219 | else |
220 | ret = INCLUDENEXTDOT22; |
221 | while (*p && *p != '"') |
222 | *line++ = *p++; |
223 | } else |
224 | while (*p && *p != '>') |
225 | *line++ = *p++; |
226 | *line = '\0'; |
227 | break; |
228 | case DEFINE5: |
229 | |
230 | |
231 | |
232 | memmove (line, p, strlen(p) + 1)__builtin___memmove_chk (line, p, strlen(p) + 1, __builtin_object_size (line, 0)); |
233 | break; |
234 | case ELSE3: |
235 | case ENDIF4: |
236 | case ELIF13: |
237 | case PRAGMA9: |
238 | case ERROR10: |
239 | case IDENT11: |
240 | case SCCS12: |
241 | case EJECT14: |
242 | case WARNING15: |
243 | debug(0,("%s, line %d: #%s\n",do { } while (0) |
244 | file->i_file, filep->f_line, directives[ret]))do { } while (0); |
245 | |
246 | |
247 | |
248 | break; |
249 | } |
250 | return(ret); |
251 | } |
252 | |
253 | struct symtab ** |
254 | fdefined(const char *symbol, struct inclist *file, struct inclist **srcfile) |
255 | { |
256 | struct inclist **ip; |
257 | struct symtab **val; |
258 | int i; |
259 | static int recurse_lvl = 0; |
260 | |
261 | if (file->i_flags & DEFCHECKED(1<<0)) |
| |
262 | return(NULL((void *)0)); |
263 | debug(2,("Looking for %s in %s\n", symbol, file->i_file))do { } while (0); |
264 | file->i_flags |= DEFCHECKED(1<<0); |
265 | if ((val = slookup(symbol, file))) |
| |
266 | debug(1,("%s defined in %s as %s\n",do { } while (0) |
267 | symbol, file->i_file, (*val)->s_value))do { } while (0); |
268 | if (val == NULL((void *)0) && file->i_list) |
| |
269 | { |
270 | for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++) |
| 17 | | Loop condition is true. Entering loop body | |
|
| 19 | | Loop condition is true. Entering loop body | |
|
| 21 | | Loop condition is true. Entering loop body | |
|
| 23 | | Loop condition is true. Entering loop body | |
|
271 | if (file->i_merged[i]==FALSE0) { |
| |
| |
| |
| |
272 | val = fdefined(symbol, *ip, srcfile); |
273 | file->i_merged[i]=merge2defines(file,*ip); |
| 25 | | Calling 'merge2defines' | |
|
274 | if (val!=NULL((void *)0)) break; |
275 | } |
276 | } |
277 | else if (val != NULL((void *)0) && srcfile != NULL((void *)0)) *srcfile = file; |
278 | recurse_lvl--; |
279 | file->i_flags &= ~DEFCHECKED(1<<0); |
280 | |
281 | return(val); |
282 | } |
283 | |
284 | struct symtab ** |
285 | isdefined(const char *symbol, struct inclist *file, struct inclist **srcfile) |
286 | { |
287 | struct symtab **val; |
288 | |
289 | if ((val = slookup(symbol, &maininclist))) { |
| |
290 | debug(1,("%s defined on command line\n", symbol))do { } while (0); |
291 | if (srcfile != NULL((void *)0)) *srcfile = &maininclist; |
292 | return(val); |
293 | } |
294 | if ((val = fdefined(symbol, file, srcfile))) |
| |
295 | return(val); |
296 | debug(1,("%s not defined in %s\n", symbol, file->i_file))do { } while (0); |
297 | return(NULL((void *)0)); |
298 | } |
299 | |
300 | |
301 | |
302 | |
303 | static int |
304 | zero_value(char *filename, |
305 | char *exp, |
306 | struct filepointer *filep, |
307 | struct inclist *file_red) |
308 | { |
309 | if (cppsetup(filename, exp, filep, file_red)) |
310 | return(IFFALSE17); |
311 | else |
312 | return(IF0); |
313 | } |
314 | |
315 | void |
316 | define2(const char *name, const char *val, struct inclist *file) |
317 | { |
318 | int first, last, below; |
319 | register struct symtab **sp = NULL((void *)0), **dest; |
320 | struct symtab *stab; |
321 | |
322 | |
323 | if (file->i_defs == NULL((void *)0)) |
324 | { |
325 | file->i_defs = malloc(sizeof (struct symtab*) * SYMTABINC10); |
326 | file->i_ndefs = 0; |
327 | } |
328 | else if (!(file->i_ndefs % SYMTABINC10)) |
329 | file->i_defs = realloc(file->i_defs, |
330 | sizeof(struct symtab*)*(file->i_ndefs+SYMTABINC10)); |
331 | |
332 | if (file->i_defs == NULL((void *)0)) |
333 | fatalerr("malloc()/realloc() failure in insert_defn()\n"); |
334 | |
335 | below = first = 0; |
336 | last = file->i_ndefs - 1; |
337 | while (last >= first) |
338 | { |
339 | |
340 | register const char *s1; |
341 | register const char *s2; |
342 | register int middle = (first + last) / 2; |
343 | |
344 | |
345 | s1 = name; |
346 | s2 = file->i_defs[middle]->s_name; |
347 | while (*s1++ == *s2++) |
348 | if (s2[-1] == '\0') break; |
349 | |
350 | |
351 | if (*--s1 == *--s2) |
352 | { |
353 | sp = file->i_defs + middle; |
354 | break; |
355 | } |
356 | |
357 | |
358 | if (*s1 > *s2) |
359 | { |
360 | below = first; |
361 | first = middle + 1; |
362 | } |
363 | |
364 | else |
365 | { |
366 | below = last = middle - 1; |
367 | } |
368 | } |
369 | |
370 | |
371 | |
372 | if (sp != NULL((void *)0)) |
373 | { |
374 | debug(1,("redefining %s from %s to %s in file %s\n",do { } while (0) |
375 | name, (*sp)->s_value, val, file->i_file))do { } while (0); |
376 | free((*sp)->s_value); |
377 | (*sp)->s_value = strdup(val); |
378 | return; |
379 | } |
380 | |
381 | sp = file->i_defs + file->i_ndefs++; |
382 | dest = file->i_defs + below + 1; |
383 | while (sp > dest) |
384 | { |
385 | *sp = sp[-1]; |
386 | sp--; |
387 | } |
388 | stab = malloc(sizeof (struct symtab)); |
389 | if (stab == NULL((void *)0)) |
390 | fatalerr("malloc()/realloc() failure in insert_defn()\n"); |
391 | |
392 | debug(1,("defining %s to %s in file %s\n", name, val, file->i_file))do { } while (0); |
393 | stab->s_name = strdup(name); |
394 | stab->s_value = strdup(val); |
395 | *sp = stab; |
396 | } |
397 | |
398 | void |
399 | define(char *def, struct inclist *file) |
400 | { |
401 | char *val; |
402 | |
403 | |
404 | val = def; |
405 | while (isalnum(*val) || *val == '_') |
406 | val++; |
407 | if (*val) |
408 | *val++ = '\0'; |
409 | while (*val == ' ' || *val == '\t') |
410 | val++; |
411 | |
412 | if (!*val) |
413 | define2(def, "1", file); |
414 | else |
415 | define2(def, val, file); |
416 | } |
417 | |
418 | struct symtab ** |
419 | slookup(const char *symbol, struct inclist *file) |
420 | { |
421 | register int first = 0; |
422 | register int last; |
423 | |
424 | if (file == NULL((void *)0)) |
425 | return NULL((void *)0); |
426 | |
427 | last = file->i_ndefs - 1; |
428 | |
429 | while (last >= first) |
430 | { |
431 | |
432 | register const char *s1; |
433 | register const char *s2; |
434 | register int middle = (first + last) / 2; |
435 | |
436 | |
437 | s1 = symbol; |
438 | s2 = file->i_defs[middle]->s_name; |
439 | while (*s1++ == *s2++) |
440 | if (s2[-1] == '\0') break; |
441 | |
442 | |
443 | if (*--s1 == *--s2) |
444 | { |
445 | return file->i_defs + middle; |
446 | } |
447 | |
448 | |
449 | if (*s1 > *s2) |
450 | { |
451 | first = middle + 1; |
452 | } |
453 | |
454 | else |
455 | { |
456 | last = middle - 1; |
457 | } |
458 | } |
459 | return(NULL((void *)0)); |
460 | } |
461 | |
462 | static int |
463 | merge2defines(struct inclist *file1, struct inclist *file2) |
464 | { |
465 | int i; |
466 | |
467 | if ((file1==NULL((void *)0)) || (file2==NULL((void *)0)) || |
| 26 | | Assuming 'file2' is not equal to null | |
|
| |
468 | !(file2->i_flags & FINISHED(1<<4))) |
469 | return 0; |
470 | |
471 | for (i=0; i < file2->i_listlen; i++) |
| 28 | | Loop condition is false. Execution continues on line 476 | |
|
472 | if (file2->i_merged[i]==FALSE0) |
473 | return 0; |
474 | |
475 | { |
476 | int first1 = 0; |
477 | int last1 = file1->i_ndefs - 1; |
478 | |
479 | int first2 = 0; |
480 | int last2 = file2->i_ndefs - 1; |
481 | |
482 | int first=0; |
483 | struct symtab** i_defs = NULL((void *)0); |
| 29 | | 'i_defs' initialized to a null pointer value | |
|
484 | int deflen=file1->i_ndefs+file2->i_ndefs; |
485 | |
486 | debug(2,("merging %s into %s\n",do { } while (0) |
487 | file2->i_file, file1->i_file))do { } while (0); |
488 | |
489 | if (deflen>0) |
| 30 | | Assuming 'deflen' is <= 0 | |
|
| |
490 | { |
491 | |
492 | deflen += (SYMTABINC10 - deflen % SYMTABINC10) % SYMTABINC10; |
493 | i_defs = malloc(deflen*sizeof(struct symtab*)); |
494 | if (i_defs==NULL((void *)0)) return 0; |
495 | } |
496 | |
497 | while ((last1 >= first1) && (last2 >= first2)) |
498 | { |
499 | const char *s1 = file1->i_defs[first1]->s_name; |
500 | const char *s2 = file2->i_defs[first2]->s_name; |
501 | |
502 | if (strcmp(s1,s2) < 0) |
503 | i_defs[first++]=file1->i_defs[first1++]; |
504 | else if (strcmp(s1,s2) > 0) |
505 | i_defs[first++]=file2->i_defs[first2++]; |
506 | else |
507 | { |
508 | i_defs[first++]=file2->i_defs[first2++]; |
509 | first1++; |
510 | } |
511 | } |
512 | while (last1 >= first1) |
| 32 | | Loop condition is false. Execution continues on line 516 | |
|
513 | { |
514 | i_defs[first++]=file1->i_defs[first1++]; |
515 | } |
516 | while (last2 >= first2) |
| 33 | | Assuming 'last2' is >= 'first2' | |
|
| 34 | | Loop condition is true. Entering loop body | |
|
517 | { |
518 | i_defs[first++]=file2->i_defs[first2++]; |
| 35 | | Array access (from variable 'i_defs') results in a null pointer dereference |
|
519 | } |
520 | |
521 | if (file1->i_defs) free(file1->i_defs); |
522 | file1->i_defs=i_defs; |
523 | file1->i_ndefs=first; |
524 | |
525 | return 1; |
526 | } |
527 | } |
528 | |
529 | void |
530 | undefine(const char *symbol, struct inclist *file) |
531 | { |
532 | register struct symtab **ptr; |
533 | struct inclist *srcfile; |
534 | while ((ptr = isdefined(symbol, file, &srcfile)) != NULL((void *)0)) |
| |
535 | { |
536 | srcfile->i_ndefs--; |
537 | for (; ptr < srcfile->i_defs + srcfile->i_ndefs; ptr++) |
538 | *ptr = ptr[1]; |
539 | } |
540 | } |
541 | |
542 | int |
543 | find_includes(struct filepointer *filep, struct inclist *file, |
544 | struct inclist *file_red, int recursion, boolean failOK) |
545 | { |
546 | struct inclist *inclistp; |
547 | const char **includedirsp; |
548 | register char *line; |
549 | register int type; |
550 | boolean recfailOK; |
551 | |
552 | while ((line = getnextline(filep))) { |
| 1 | Loop condition is true. Entering loop body | |
|
| 3 | | Loop condition is true. Entering loop body | |
|
| 5 | | Loop condition is true. Entering loop body | |
|
| 7 | | Loop condition is true. Entering loop body | |
|
553 | switch(type = deftype(line, filep, file_red, file, TRUE1)) { |
| 2 | | 'Default' branch taken. Execution continues on line 552 | |
|
| 4 | | 'Default' branch taken. Execution continues on line 552 | |
|
| 6 | | 'Default' branch taken. Execution continues on line 552 | |
|
| 8 | | Control jumps to 'case 6:' at line 624 | |
|
554 | case IF0: |
555 | doif: |
556 | type = find_includes(filep, file, |
557 | file_red, recursion+1, failOK); |
558 | while ((type == ELIF13) || (type == ELIFFALSE18) || |
559 | (type == ELIFGUESSFALSE21)) |
560 | type = gobble(filep, file, file_red); |
561 | if (type == ELSE3) |
562 | gobble(filep, file, file_red); |
563 | break; |
564 | case IFFALSE17: |
565 | case IFGUESSFALSE20: |
566 | doiffalse: |
567 | if (type == IFGUESSFALSE20 || type == ELIFGUESSFALSE21) |
568 | recfailOK = TRUE1; |
569 | else |
570 | recfailOK = failOK; |
571 | type = gobble(filep, file, file_red); |
572 | if (type == ELSE3) |
573 | find_includes(filep, file, |
574 | file_red, recursion+1, recfailOK); |
575 | else |
576 | if (type == ELIF13) |
577 | goto doif; |
578 | else |
579 | if ((type == ELIFFALSE18) || (type == ELIFGUESSFALSE21)) |
580 | goto doiffalse; |
581 | break; |
582 | case IFDEF1: |
583 | case IFNDEF2: |
584 | if ((type == IFDEF1 && isdefined(line, file_red, NULL((void *)0))) |
585 | || (type == IFNDEF2 && !isdefined(line, file_red, NULL((void *)0)))) { |
586 | debug(1,(type == IFNDEF ?do { } while (0) |
587 | "line %d: %s !def'd in %s via %s%s\n" : "",do { } while (0) |
588 | filep->f_line, line,do { } while (0) |
589 | file->i_file, file_red->i_file, ": doit"))do { } while (0); |
590 | type = find_includes(filep, file, |
591 | file_red, recursion+1, failOK); |
592 | while (type == ELIF13 || type == ELIFFALSE18 || type == ELIFGUESSFALSE21) |
593 | type = gobble(filep, file, file_red); |
594 | if (type == ELSE3) |
595 | gobble(filep, file, file_red); |
596 | } |
597 | else { |
598 | debug(1,(type == IFDEF ?do { } while (0) |
599 | "line %d: %s !def'd in %s via %s%s\n" : "",do { } while (0) |
600 | filep->f_line, line,do { } while (0) |
601 | file->i_file, file_red->i_file, ": gobble"))do { } while (0); |
602 | type = gobble(filep, file, file_red); |
603 | if (type == ELSE3) |
604 | find_includes(filep, file, |
605 | file_red, recursion+1, failOK); |
606 | else if (type == ELIF13) |
607 | goto doif; |
608 | else if (type == ELIFFALSE18 || type == ELIFGUESSFALSE21) |
609 | goto doiffalse; |
610 | } |
611 | break; |
612 | case ELSE3: |
613 | case ELIFFALSE18: |
614 | case ELIFGUESSFALSE21: |
615 | case ELIF13: |
616 | if (!recursion) |
617 | gobble(filep, file, file_red); |
618 | case ENDIF4: |
619 | if (recursion) |
620 | return(type); |
621 | case DEFINE5: |
622 | define(line, file); |
623 | break; |
624 | case UNDEF6: |
625 | if (!*line) { |
| |
626 | warning("%s", file_red->i_file); |
627 | if (file_red != file) |
628 | warning1(" (reading %s)", file->i_file); |
629 | warning1(", line %ld: incomplete undef == \"%s\"\n", |
630 | filep->f_line, line); |
631 | break; |
632 | } |
633 | undefine(line, file_red); |
| |
634 | break; |
635 | case INCLUDE7: |
636 | case INCLUDEDOT19: |
637 | case INCLUDENEXT16: |
638 | case INCLUDENEXTDOT22: |
639 | inclistp = inclistnext; |
640 | includedirsp = includedirsnext; |
641 | debug(2,("%s, reading %s, includes %s\n",do { } while (0) |
642 | file_red->i_file, file->i_file, line))do { } while (0); |
643 | add_include(filep, file, file_red, line, type, failOK); |
644 | inclistnext = inclistp; |
645 | includedirsnext = includedirsp; |
646 | break; |
647 | case ERROR10: |
648 | case WARNING15: |
649 | warning("%s", file_red->i_file); |
650 | if (file_red != file) |
651 | warning1(" (reading %s)", file->i_file); |
652 | warning1(", line %ld: %s\n", |
653 | filep->f_line, line); |
654 | break; |
655 | |
656 | case PRAGMA9: |
657 | case IDENT11: |
658 | case SCCS12: |
659 | case EJECT14: |
660 | break; |
661 | case -1: |
662 | warning("%s", file_red->i_file); |
663 | if (file_red != file) |
664 | warning1(" (reading %s)", file->i_file); |
665 | warning1(", line %ld: unknown directive == \"%s\"\n", |
666 | filep->f_line, line); |
667 | break; |
668 | case -2: |
669 | warning("%s", file_red->i_file); |
670 | if (file_red != file) |
671 | warning1(" (reading %s)", file->i_file); |
672 | warning1(", line %ld: incomplete include == \"%s\"\n", |
673 | filep->f_line, line); |
674 | break; |
675 | } |
676 | } |
677 | file->i_flags |= FINISHED(1<<4); |
678 | debug(2,("finished with %s\n", file->i_file))do { } while (0); |
679 | return(-1); |
680 | } |