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", |
60 | file->i_file, filep->f_line, |
61 | directives[type])); |
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 ", |
132 | file->i_file, filep->f_line, p)); |
133 | ret = zero_value(file->i_file, p, filep, file_red); |
134 | if (ret != IF0) |
135 | { |
136 | debug(0,("false...\n")); |
137 | if (ret == IFFALSE17) |
138 | return(ELIFFALSE18); |
139 | else |
140 | return(ELIFGUESSFALSE21); |
141 | } |
142 | else |
143 | { |
144 | debug(0,("true...\n")); |
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", |
169 | file->i_file, filep->f_line, ret?"false":"true", p)); |
170 | break; |
171 | case IFDEF1: |
172 | case IFNDEF2: |
173 | debug(0,("%s, line %d: #%s %s\n", |
174 | file->i_file, filep->f_line, directives[ret], p)); |
175 | case UNDEF6: |
176 | |
177 | |
178 | |
179 | while (isalnum(*p)((*__ctype_b_loc ())[(int) ((*p))] & (unsigned short int) _ISalnum) || *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", |
186 | file->i_file, filep->f_line, |
187 | (ret == INCLUDE) ? "" : "_next", p)); |
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", |
202 | file->i_incstring, |
203 | (*sym) -> s_name, |
204 | (*sym) -> s_value)); |
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 | strcpy (line, p); |
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", |
244 | file->i_file, filep->f_line, directives[ret])); |
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)); |
264 | file->i_flags |= DEFCHECKED(1<<0); |
265 | if ((val = slookup(symbol, file))) |
266 | debug(1,("%s defined in %s as %s\n", |
267 | symbol, file->i_file, (*val)->s_value)); |
268 | if (val == NULL((void*)0) && file->i_list) |
269 | { |
270 | for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++) |
271 | if (file->i_merged[i]==FALSE0) { |
272 | val = fdefined(symbol, *ip, srcfile); |
273 | file->i_merged[i]=merge2defines(file,*ip); |
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)); |
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)); |
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 = (struct symtab **) |
326 | malloc(sizeof (struct symtab*) * SYMTABINC10); |
327 | file->i_ndefs = 0; |
328 | } |
329 | else if (!(file->i_ndefs % SYMTABINC10)) |
330 | file->i_defs = (struct symtab **) |
331 | realloc(file->i_defs, |
332 | sizeof(struct symtab*)*(file->i_ndefs+SYMTABINC10)); |
333 | |
334 | if (file->i_defs == NULL((void*)0)) |
335 | fatalerr("malloc()/realloc() failure in insert_defn()\n"); |
336 | |
337 | below = first = 0; |
338 | last = file->i_ndefs - 1; |
339 | while (last >= first) |
340 | { |
341 | |
342 | register const char *s1; |
343 | register const char *s2; |
344 | register int middle = (first + last) / 2; |
345 | |
346 | |
347 | s1 = name; |
348 | s2 = file->i_defs[middle]->s_name; |
349 | while (*s1++ == *s2++) |
350 | if (s2[-1] == '\0') break; |
351 | |
352 | |
353 | if (*--s1 == *--s2) |
354 | { |
355 | sp = file->i_defs + middle; |
356 | break; |
357 | } |
358 | |
359 | |
360 | if (*s1 > *s2) |
361 | { |
362 | below = first; |
363 | first = middle + 1; |
364 | } |
365 | |
366 | else |
367 | { |
368 | below = last = middle - 1; |
369 | } |
370 | } |
371 | |
372 | |
373 | |
374 | if (sp != NULL((void*)0)) |
375 | { |
376 | debug(1,("redefining %s from %s to %s in file %s\n", |
377 | name, (*sp)->s_value, val, file->i_file)); |
378 | free((*sp)->s_value); |
379 | (*sp)->s_value = strdup(val); |
380 | return; |
381 | } |
382 | |
383 | sp = file->i_defs + file->i_ndefs++; |
384 | dest = file->i_defs + below + 1; |
385 | while (sp > dest) |
386 | { |
387 | *sp = sp[-1]; |
388 | sp--; |
389 | } |
390 | stab = (struct symtab *) malloc(sizeof (struct symtab)); |
391 | if (stab == NULL((void*)0)) |
392 | fatalerr("malloc()/realloc() failure in insert_defn()\n"); |
393 | |
394 | debug(1,("defining %s to %s in file %s\n", name, val, file->i_file)); |
395 | stab->s_name = strdup(name); |
396 | stab->s_value = strdup(val); |
397 | *sp = stab; |
398 | } |
399 | |
400 | void |
401 | define(char *def, struct inclist *file) |
402 | { |
403 | char *val; |
404 | |
405 | |
406 | val = def; |
407 | while (isalnum(*val)((*__ctype_b_loc ())[(int) ((*val))] & (unsigned short int ) _ISalnum) || *val == '_') |
408 | val++; |
409 | if (*val) |
410 | *val++ = '\0'; |
411 | while (*val == ' ' || *val == '\t') |
412 | val++; |
413 | |
414 | if (!*val) |
415 | define2(def, "1", file); |
416 | else |
417 | define2(def, val, file); |
418 | } |
419 | |
420 | struct symtab ** |
421 | slookup(const char *symbol, struct inclist *file) |
422 | { |
423 | register int first = 0; |
424 | register int last; |
425 | |
426 | if (file == NULL((void*)0)) |
427 | return NULL((void*)0); |
428 | |
429 | last = file->i_ndefs - 1; |
430 | |
431 | while (last >= first) |
432 | { |
433 | |
434 | register const char *s1; |
435 | register const char *s2; |
436 | register int middle = (first + last) / 2; |
437 | |
438 | |
439 | s1 = symbol; |
440 | s2 = file->i_defs[middle]->s_name; |
441 | while (*s1++ == *s2++) |
442 | if (s2[-1] == '\0') break; |
443 | |
444 | |
445 | if (*--s1 == *--s2) |
446 | { |
447 | return file->i_defs + middle; |
448 | } |
449 | |
450 | |
451 | if (*s1 > *s2) |
452 | { |
453 | first = middle + 1; |
454 | } |
455 | |
456 | else |
457 | { |
458 | last = middle - 1; |
459 | } |
460 | } |
461 | return(NULL((void*)0)); |
462 | } |
463 | |
464 | static int |
465 | merge2defines(struct inclist *file1, struct inclist *file2) |
466 | { |
467 | int i; |
468 | |
469 | if ((file1==NULL((void*)0)) || (file2==NULL((void*)0)) || |
| 1 | Assuming 'file1' is not equal to null |
|
| 2 | Assuming 'file2' is not equal to null |
|
| |
470 | !(file2->i_flags & FINISHED(1<<4))) |
471 | return 0; |
472 | |
473 | for (i=0; i < file2->i_listlen; i++) |
| 4 | Loop condition is false. Execution continues on line 478 |
|
474 | if (file2->i_merged[i]==FALSE0) |
475 | return 0; |
476 | |
477 | { |
478 | int first1 = 0; |
479 | int last1 = file1->i_ndefs - 1; |
480 | |
481 | int first2 = 0; |
482 | int last2 = file2->i_ndefs - 1; |
483 | |
484 | int first=0; |
485 | struct symtab** i_defs = NULL((void*)0); |
486 | int deflen=file1->i_ndefs+file2->i_ndefs; |
487 | |
488 | debug(2,("merging %s into %s\n", |
489 | file2->i_file, file1->i_file)); |
490 | |
491 | if (deflen>0) |
| 5 | Assuming 'deflen' is <= 0 |
|
| |
492 | { |
493 | |
494 | deflen += (SYMTABINC10 - deflen % SYMTABINC10) % SYMTABINC10; |
495 | i_defs=(struct symtab**) |
496 | malloc(deflen*sizeof(struct symtab*)); |
497 | if (i_defs==NULL((void*)0)) return 0; |
498 | } |
499 | |
500 | while ((last1 >= first1) && (last2 >= first2)) |
| 7 | Assuming 'last1' is >= 'first1' |
|
| 8 | Assuming 'last2' is >= 'first2' |
|
| 9 | Loop condition is true. Entering loop body |
|
501 | { |
502 | char *s1=file1->i_defs[first1]->s_name; |
503 | char *s2=file2->i_defs[first2]->s_name; |
504 | |
505 | if (strcmp(s1,s2) < 0) |
| |
506 | i_defs[first++]=file1->i_defs[first1++]; |
| 11 | Array access (from variable 'i_defs') results in a null pointer dereference |
|
507 | else if (strcmp(s1,s2) > 0) |
508 | i_defs[first++]=file2->i_defs[first2++]; |
509 | else |
510 | { |
511 | i_defs[first++]=file2->i_defs[first2++]; |
512 | first1++; |
513 | } |
514 | } |
515 | while (last1 >= first1) |
516 | { |
517 | i_defs[first++]=file1->i_defs[first1++]; |
518 | } |
519 | while (last2 >= first2) |
520 | { |
521 | i_defs[first++]=file2->i_defs[first2++]; |
522 | } |
523 | |
524 | if (file1->i_defs) free(file1->i_defs); |
525 | file1->i_defs=i_defs; |
526 | file1->i_ndefs=first; |
527 | |
528 | return 1; |
529 | } |
530 | } |
531 | |
532 | void |
533 | undefine(const char *symbol, struct inclist *file) |
534 | { |
535 | register struct symtab **ptr; |
536 | struct inclist *srcfile; |
537 | while ((ptr = isdefined(symbol, file, &srcfile)) != NULL((void*)0)) |
538 | { |
539 | srcfile->i_ndefs--; |
540 | for (; ptr < srcfile->i_defs + srcfile->i_ndefs; ptr++) |
541 | *ptr = ptr[1]; |
542 | } |
543 | } |
544 | |
545 | int |
546 | find_includes(struct filepointer *filep, struct inclist *file, |
547 | struct inclist *file_red, int recursion, boolean failOK) |
548 | { |
549 | struct inclist *inclistp; |
550 | const char **includedirsp; |
551 | register char *line; |
552 | register int type; |
553 | boolean recfailOK; |
554 | |
555 | while ((line = getnextline(filep))) { |
556 | switch(type = deftype(line, filep, file_red, file, TRUE1)) { |
557 | case IF0: |
558 | doif: |
559 | type = find_includes(filep, file, |
560 | file_red, recursion+1, failOK); |
561 | while ((type == ELIF13) || (type == ELIFFALSE18) || |
562 | (type == ELIFGUESSFALSE21)) |
563 | type = gobble(filep, file, file_red); |
564 | if (type == ELSE3) |
565 | gobble(filep, file, file_red); |
566 | break; |
567 | case IFFALSE17: |
568 | case IFGUESSFALSE20: |
569 | doiffalse: |
570 | if (type == IFGUESSFALSE20 || type == ELIFGUESSFALSE21) |
571 | recfailOK = TRUE1; |
572 | else |
573 | recfailOK = failOK; |
574 | type = gobble(filep, file, file_red); |
575 | if (type == ELSE3) |
576 | find_includes(filep, file, |
577 | file_red, recursion+1, recfailOK); |
578 | else |
579 | if (type == ELIF13) |
580 | goto doif; |
581 | else |
582 | if ((type == ELIFFALSE18) || (type == ELIFGUESSFALSE21)) |
583 | goto doiffalse; |
584 | break; |
585 | case IFDEF1: |
586 | case IFNDEF2: |
587 | if ((type == IFDEF1 && isdefined(line, file_red, NULL((void*)0))) |
588 | || (type == IFNDEF2 && !isdefined(line, file_red, NULL((void*)0)))) { |
589 | debug(1,(type == IFNDEF ? |
590 | "line %d: %s !def'd in %s via %s%s\n" : "", |
591 | filep->f_line, line, |
592 | file->i_file, file_red->i_file, ": doit")); |
593 | type = find_includes(filep, file, |
594 | file_red, recursion+1, failOK); |
595 | while (type == ELIF13 || type == ELIFFALSE18 || type == ELIFGUESSFALSE21) |
596 | type = gobble(filep, file, file_red); |
597 | if (type == ELSE3) |
598 | gobble(filep, file, file_red); |
599 | } |
600 | else { |
601 | debug(1,(type == IFDEF ? |
602 | "line %d: %s !def'd in %s via %s%s\n" : "", |
603 | filep->f_line, line, |
604 | file->i_file, file_red->i_file, ": gobble")); |
605 | type = gobble(filep, file, file_red); |
606 | if (type == ELSE3) |
607 | find_includes(filep, file, |
608 | file_red, recursion+1, failOK); |
609 | else if (type == ELIF13) |
610 | goto doif; |
611 | else if (type == ELIFFALSE18 || type == ELIFGUESSFALSE21) |
612 | goto doiffalse; |
613 | } |
614 | break; |
615 | case ELSE3: |
616 | case ELIFFALSE18: |
617 | case ELIFGUESSFALSE21: |
618 | case ELIF13: |
619 | if (!recursion) |
620 | gobble(filep, file, file_red); |
621 | case ENDIF4: |
622 | if (recursion) |
623 | return(type); |
624 | case DEFINE5: |
625 | define(line, file); |
626 | break; |
627 | case UNDEF6: |
628 | if (!*line) { |
629 | warning("%s", file_red->i_file); |
630 | if (file_red != file) |
631 | warning1(" (reading %s)", file->i_file); |
632 | warning1(", line %ld: incomplete undef == \"%s\"\n", |
633 | filep->f_line, line); |
634 | break; |
635 | } |
636 | undefine(line, file_red); |
637 | break; |
638 | case INCLUDE7: |
639 | case INCLUDEDOT19: |
640 | case INCLUDENEXT16: |
641 | case INCLUDENEXTDOT22: |
642 | inclistp = inclistnext; |
643 | includedirsp = includedirsnext; |
644 | debug(2,("%s, reading %s, includes %s\n", |
645 | file_red->i_file, file->i_file, line)); |
646 | add_include(filep, file, file_red, line, type, failOK); |
647 | inclistnext = inclistp; |
648 | includedirsnext = includedirsp; |
649 | break; |
650 | case ERROR10: |
651 | case WARNING15: |
652 | warning("%s", file_red->i_file); |
653 | if (file_red != file) |
654 | warning1(" (reading %s)", file->i_file); |
655 | warning1(", line %ld: %s\n", |
656 | filep->f_line, line); |
657 | break; |
658 | |
659 | case PRAGMA9: |
660 | case IDENT11: |
661 | case SCCS12: |
662 | case EJECT14: |
663 | break; |
664 | case -1: |
665 | warning("%s", file_red->i_file); |
666 | if (file_red != file) |
667 | warning1(" (reading %s)", file->i_file); |
668 | warning1(", line %ld: unknown directive == \"%s\"\n", |
669 | filep->f_line, line); |
670 | break; |
671 | case -2: |
672 | warning("%s", file_red->i_file); |
673 | if (file_red != file) |
674 | warning1(" (reading %s)", file->i_file); |
675 | warning1(", line %ld: incomplete include == \"%s\"\n", |
676 | filep->f_line, line); |
677 | break; |
678 | } |
679 | } |
680 | file->i_flags |= FINISHED(1<<4); |
681 | debug(2,("finished with %s\n", file->i_file)); |
682 | return(-1); |
683 | } |