|
1 /* $Xorg: parse.c,v 1.6 2001/02/09 02:03:16 xorgcvs Exp $ */ |
|
2 /* |
|
3 |
|
4 Copyright (c) 1993, 1994, 1998 The Open Group |
|
5 |
|
6 Permission to use, copy, modify, distribute, and sell this software and its |
|
7 documentation for any purpose is hereby granted without fee, provided that |
|
8 the above copyright notice appear in all copies and that both that |
|
9 copyright notice and this permission notice appear in supporting |
|
10 documentation. |
|
11 |
|
12 The above copyright notice and this permission notice shall be included in |
|
13 all copies or substantial portions of the Software. |
|
14 |
|
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
|
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
21 |
|
22 Except as contained in this notice, the name of The Open Group shall not be |
|
23 used in advertising or otherwise to promote the sale, use or other dealings |
|
24 in this Software without prior written authorization from The Open Group. |
|
25 |
|
26 */ |
|
27 /* $XFree86: xc/config/makedepend/parse.c,v 1.12 2002/02/26 05:09:10 tsi Exp $ */ |
|
28 |
|
29 #include "def.h" |
|
30 |
|
31 extern char *directives[]; |
|
32 extern struct inclist inclist[ MAXFILES ], |
|
33 *inclistnext, |
|
34 maininclist; |
|
35 extern char *includedirs[ ], |
|
36 **includedirsnext; |
|
37 |
|
38 static int deftype (char *line, struct filepointer *filep, |
|
39 struct inclist *file_red, struct inclist *file, |
|
40 int parse_it); |
|
41 static int zero_value(char *filename, char *exp, struct filepointer *filep, |
|
42 struct inclist *file_red); |
|
43 static int merge2defines(struct inclist *file1, struct inclist *file2); |
|
44 |
|
45 static int |
|
46 gobble(struct filepointer *filep, struct inclist *file, |
|
47 struct inclist *file_red) |
|
48 { |
|
49 char *line; |
|
50 int type; |
|
51 |
|
52 while ((line = getnextline(filep))) { |
|
53 switch(type = deftype(line, filep, file_red, file, FALSE)) { |
|
54 case IF: |
|
55 case IFFALSE: |
|
56 case IFGUESSFALSE: |
|
57 case IFDEF: |
|
58 case IFNDEF: |
|
59 type = gobble(filep, file, file_red); |
|
60 while ((type == ELIF) || (type == ELIFFALSE) || |
|
61 (type == ELIFGUESSFALSE)) |
|
62 type = gobble(filep, file, file_red); |
|
63 if (type == ELSE) |
|
64 (void)gobble(filep, file, file_red); |
|
65 break; |
|
66 case ELSE: |
|
67 case ENDIF: |
|
68 debug(0,("%s, line %d: #%s\n", |
|
69 file->i_file, filep->f_line, |
|
70 directives[type])); |
|
71 return(type); |
|
72 case DEFINE: |
|
73 case UNDEF: |
|
74 case INCLUDE: |
|
75 case INCLUDEDOT: |
|
76 case PRAGMA: |
|
77 case ERROR: |
|
78 case IDENT: |
|
79 case SCCS: |
|
80 case EJECT: |
|
81 case WARNING: |
|
82 case INCLUDENEXT: |
|
83 case INCLUDENEXTDOT: |
|
84 break; |
|
85 case ELIF: |
|
86 case ELIFFALSE: |
|
87 case ELIFGUESSFALSE: |
|
88 return(type); |
|
89 case -1: |
|
90 warning("%s", file_red->i_file); |
|
91 if (file_red != file) |
|
92 warning1(" (reading %s)", file->i_file); |
|
93 warning1(", line %d: unknown directive == \"%s\"\n", |
|
94 filep->f_line, line); |
|
95 break; |
|
96 } |
|
97 } |
|
98 return(-1); |
|
99 } |
|
100 |
|
101 /* |
|
102 * Decide what type of # directive this line is. |
|
103 */ |
|
104 static int |
|
105 deftype (char *line, struct filepointer *filep, |
|
106 struct inclist *file_red, struct inclist *file, int parse_it) |
|
107 { |
|
108 register char *p; |
|
109 char *directive, savechar, *q; |
|
110 register int ret; |
|
111 |
|
112 /* |
|
113 * Parse the directive... |
|
114 */ |
|
115 directive=line+1; |
|
116 while (*directive == ' ' || *directive == '\t') |
|
117 directive++; |
|
118 |
|
119 p = directive; |
|
120 while ((*p == '_') || (*p >= 'a' && *p <= 'z')) |
|
121 p++; |
|
122 savechar = *p; |
|
123 *p = '\0'; |
|
124 ret = match(directive, directives); |
|
125 *p = savechar; |
|
126 |
|
127 /* If we don't recognize this compiler directive or we happen to just |
|
128 * be gobbling up text while waiting for an #endif or #elif or #else |
|
129 * in the case of an #elif we must check the zero_value and return an |
|
130 * ELIF or an ELIFFALSE. |
|
131 */ |
|
132 |
|
133 if (ret == ELIF && !parse_it) |
|
134 { |
|
135 while (*p == ' ' || *p == '\t') |
|
136 p++; |
|
137 /* |
|
138 * parse an expression. |
|
139 */ |
|
140 debug(0,("%s, line %d: #elif %s ", |
|
141 file->i_file, filep->f_line, p)); |
|
142 ret = zero_value(file->i_file, p, filep, file_red); |
|
143 if (ret != IF) |
|
144 { |
|
145 debug(0,("false...\n")); |
|
146 if (ret == IFFALSE) |
|
147 return(ELIFFALSE); |
|
148 else |
|
149 return(ELIFGUESSFALSE); |
|
150 } |
|
151 else |
|
152 { |
|
153 debug(0,("true...\n")); |
|
154 return(ELIF); |
|
155 } |
|
156 } |
|
157 |
|
158 if (ret < 0 || ! parse_it) |
|
159 return(ret); |
|
160 |
|
161 /* |
|
162 * now decide how to parse the directive, and do it. |
|
163 */ |
|
164 while (*p == ' ' || *p == '\t') |
|
165 p++; |
|
166 q = p + strlen(p); |
|
167 do { |
|
168 q--; |
|
169 } while (*q == ' ' || *q == '\t'); |
|
170 q[1] = '\0'; |
|
171 switch (ret) { |
|
172 case IF: |
|
173 /* |
|
174 * parse an expression. |
|
175 */ |
|
176 ret = zero_value(file->i_file, p, filep, file_red); |
|
177 debug(0,("%s, line %d: %s #if %s\n", |
|
178 file->i_file, filep->f_line, ret?"false":"true", p)); |
|
179 break; |
|
180 case IFDEF: |
|
181 case IFNDEF: |
|
182 debug(0,("%s, line %d: #%s %s\n", |
|
183 file->i_file, filep->f_line, directives[ret], p)); |
|
184 case UNDEF: |
|
185 /* |
|
186 * separate the name of a single symbol. |
|
187 */ |
|
188 while (isalnum(*p) || *p == '_') |
|
189 *line++ = *p++; |
|
190 *line = '\0'; |
|
191 break; |
|
192 case INCLUDE: |
|
193 case INCLUDENEXT: |
|
194 debug(2,("%s, line %d: #include%s %s\n", |
|
195 file->i_file, filep->f_line, |
|
196 (ret == INCLUDE) ? "" : "_next", p)); |
|
197 |
|
198 /* Support ANSI macro substitution */ |
|
199 while (1) { |
|
200 struct symtab **sym; |
|
201 |
|
202 if (!*p || *p == '"' || *p == '<') |
|
203 break; |
|
204 |
|
205 sym = isdefined(p, file_red, NULL); |
|
206 if (!sym) |
|
207 break; |
|
208 |
|
209 p = (*sym)->s_value; |
|
210 debug(3,("%s : #includes SYMBOL %s = %s\n", |
|
211 file->i_incstring, |
|
212 (*sym) -> s_name, |
|
213 (*sym) -> s_value)); |
|
214 /* mark file as having included a 'soft include' */ |
|
215 file->i_flags |= INCLUDED_SYM; |
|
216 } |
|
217 |
|
218 /* |
|
219 * Separate the name of the include file. |
|
220 */ |
|
221 while (*p && *p != '"' && *p != '<') |
|
222 p++; |
|
223 if (! *p) |
|
224 return(-2); |
|
225 if (*p++ == '"') { |
|
226 if (ret == INCLUDE) |
|
227 ret = INCLUDEDOT; |
|
228 else |
|
229 ret = INCLUDENEXTDOT; |
|
230 while (*p && *p != '"') |
|
231 *line++ = *p++; |
|
232 } else |
|
233 while (*p && *p != '>') |
|
234 *line++ = *p++; |
|
235 *line = '\0'; |
|
236 break; |
|
237 case DEFINE: |
|
238 /* |
|
239 * copy the definition back to the beginning of the line. |
|
240 */ |
|
241 strcpy (line, p); |
|
242 break; |
|
243 case ELSE: |
|
244 case ENDIF: |
|
245 case ELIF: |
|
246 case PRAGMA: |
|
247 case ERROR: |
|
248 case IDENT: |
|
249 case SCCS: |
|
250 case EJECT: |
|
251 case WARNING: |
|
252 debug(0,("%s, line %d: #%s\n", |
|
253 file->i_file, filep->f_line, directives[ret])); |
|
254 /* |
|
255 * nothing to do. |
|
256 */ |
|
257 break; |
|
258 } |
|
259 return(ret); |
|
260 } |
|
261 |
|
262 struct symtab ** |
|
263 fdefined(char *symbol, struct inclist *file, struct inclist **srcfile) |
|
264 { |
|
265 struct inclist **ip; |
|
266 struct symtab **val; |
|
267 int i; |
|
268 static int recurse_lvl = 0; |
|
269 |
|
270 if (file->i_flags & DEFCHECKED) |
|
271 return(NULL); |
|
272 debug(2,("Looking for %s in %s\n", symbol, file->i_file)); |
|
273 file->i_flags |= DEFCHECKED; |
|
274 if ((val = slookup(symbol, file))) |
|
275 debug(1,("%s defined in %s as %s\n", |
|
276 symbol, file->i_file, (*val)->s_value)); |
|
277 if (val == NULL && file->i_list) |
|
278 { |
|
279 for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++) |
|
280 if (file->i_merged[i]==FALSE) { |
|
281 val = fdefined(symbol, *ip, srcfile); |
|
282 file->i_merged[i]=merge2defines(file,*ip); |
|
283 if (val!=NULL) break; |
|
284 } |
|
285 } |
|
286 else if (val != NULL && srcfile != NULL) *srcfile = file; |
|
287 recurse_lvl--; |
|
288 file->i_flags &= ~DEFCHECKED; |
|
289 |
|
290 return(val); |
|
291 } |
|
292 |
|
293 struct symtab ** |
|
294 isdefined(char *symbol, struct inclist *file, struct inclist **srcfile) |
|
295 { |
|
296 struct symtab **val; |
|
297 |
|
298 if ((val = slookup(symbol, &maininclist))) { |
|
299 debug(1,("%s defined on command line\n", symbol)); |
|
300 if (srcfile != NULL) *srcfile = &maininclist; |
|
301 return(val); |
|
302 } |
|
303 if ((val = fdefined(symbol, file, srcfile))) |
|
304 return(val); |
|
305 debug(1,("%s not defined in %s\n", symbol, file->i_file)); |
|
306 return(NULL); |
|
307 } |
|
308 |
|
309 /* |
|
310 * Return type based on if the #if expression evaluates to 0 |
|
311 */ |
|
312 static int |
|
313 zero_value(char *filename, |
|
314 char *exp, |
|
315 struct filepointer *filep, |
|
316 struct inclist *file_red) |
|
317 { |
|
318 if (cppsetup(filename, exp, filep, file_red)) |
|
319 return(IFFALSE); |
|
320 else |
|
321 return(IF); |
|
322 } |
|
323 |
|
324 void |
|
325 define2(char *name, char *val, struct inclist *file) |
|
326 { |
|
327 int first, last, below; |
|
328 register struct symtab **sp = NULL, **dest; |
|
329 struct symtab *stab; |
|
330 |
|
331 /* Make space if it's needed */ |
|
332 if (file->i_defs == NULL) |
|
333 { |
|
334 file->i_defs = (struct symtab **) |
|
335 malloc(sizeof (struct symtab*) * SYMTABINC); |
|
336 file->i_ndefs = 0; |
|
337 } |
|
338 else if (!(file->i_ndefs % SYMTABINC)) |
|
339 file->i_defs = (struct symtab **) |
|
340 realloc(file->i_defs, |
|
341 sizeof(struct symtab*)*(file->i_ndefs+SYMTABINC)); |
|
342 |
|
343 if (file->i_defs == NULL) |
|
344 fatalerr("malloc()/realloc() failure in insert_defn()\n"); |
|
345 |
|
346 below = first = 0; |
|
347 last = file->i_ndefs - 1; |
|
348 while (last >= first) |
|
349 { |
|
350 /* Fast inline binary search */ |
|
351 register char *s1; |
|
352 register char *s2; |
|
353 register int middle = (first + last) / 2; |
|
354 |
|
355 /* Fast inline strchr() */ |
|
356 s1 = name; |
|
357 s2 = file->i_defs[middle]->s_name; |
|
358 while (*s1++ == *s2++) |
|
359 if (s2[-1] == '\0') break; |
|
360 |
|
361 /* If exact match, set sp and break */ |
|
362 if (*--s1 == *--s2) |
|
363 { |
|
364 sp = file->i_defs + middle; |
|
365 break; |
|
366 } |
|
367 |
|
368 /* If name > i_defs[middle] ... */ |
|
369 if (*s1 > *s2) |
|
370 { |
|
371 below = first; |
|
372 first = middle + 1; |
|
373 } |
|
374 /* else ... */ |
|
375 else |
|
376 { |
|
377 below = last = middle - 1; |
|
378 } |
|
379 } |
|
380 |
|
381 /* Search is done. If we found an exact match to the symbol name, |
|
382 just replace its s_value */ |
|
383 if (sp != NULL) |
|
384 { |
|
385 debug(1,("redefining %s from %s to %s in file %s\n", |
|
386 name, (*sp)->s_value, val, file->i_file)); |
|
387 free((*sp)->s_value); |
|
388 (*sp)->s_value = copy(val); |
|
389 return; |
|
390 } |
|
391 |
|
392 sp = file->i_defs + file->i_ndefs++; |
|
393 dest = file->i_defs + below + 1; |
|
394 while (sp > dest) |
|
395 { |
|
396 *sp = sp[-1]; |
|
397 sp--; |
|
398 } |
|
399 stab = (struct symtab *) malloc(sizeof (struct symtab)); |
|
400 if (stab == NULL) |
|
401 fatalerr("malloc()/realloc() failure in insert_defn()\n"); |
|
402 |
|
403 debug(1,("defining %s to %s in file %s\n", name, val, file->i_file)); |
|
404 stab->s_name = copy(name); |
|
405 stab->s_value = copy(val); |
|
406 *sp = stab; |
|
407 } |
|
408 |
|
409 void |
|
410 define(char *def, struct inclist *file) |
|
411 { |
|
412 char *val; |
|
413 |
|
414 /* Separate symbol name and its value */ |
|
415 val = def; |
|
416 while (isalnum(*val) || *val == '_') |
|
417 val++; |
|
418 if (*val) |
|
419 *val++ = '\0'; |
|
420 while (*val == ' ' || *val == '\t') |
|
421 val++; |
|
422 |
|
423 if (!*val) |
|
424 val = "1"; |
|
425 define2(def, val, file); |
|
426 } |
|
427 |
|
428 struct symtab ** |
|
429 slookup(char *symbol, struct inclist *file) |
|
430 { |
|
431 register int first = 0; |
|
432 register int last = file->i_ndefs - 1; |
|
433 |
|
434 if (file) while (last >= first) |
|
435 { |
|
436 /* Fast inline binary search */ |
|
437 register char *s1; |
|
438 register char *s2; |
|
439 register int middle = (first + last) / 2; |
|
440 |
|
441 /* Fast inline strchr() */ |
|
442 s1 = symbol; |
|
443 s2 = file->i_defs[middle]->s_name; |
|
444 while (*s1++ == *s2++) |
|
445 if (s2[-1] == '\0') break; |
|
446 |
|
447 /* If exact match, we're done */ |
|
448 if (*--s1 == *--s2) |
|
449 { |
|
450 return file->i_defs + middle; |
|
451 } |
|
452 |
|
453 /* If symbol > i_defs[middle] ... */ |
|
454 if (*s1 > *s2) |
|
455 { |
|
456 first = middle + 1; |
|
457 } |
|
458 /* else ... */ |
|
459 else |
|
460 { |
|
461 last = middle - 1; |
|
462 } |
|
463 } |
|
464 return(NULL); |
|
465 } |
|
466 |
|
467 static int |
|
468 merge2defines(struct inclist *file1, struct inclist *file2) |
|
469 { |
|
470 int i; |
|
471 |
|
472 if ((file1==NULL) || (file2==NULL) || |
|
473 !(file2->i_flags & FINISHED)) |
|
474 return 0; |
|
475 |
|
476 for (i=0; i < file2->i_listlen; i++) |
|
477 if (file2->i_merged[i]==FALSE) |
|
478 return 0; |
|
479 |
|
480 { |
|
481 int first1 = 0; |
|
482 int last1 = file1->i_ndefs - 1; |
|
483 |
|
484 int first2 = 0; |
|
485 int last2 = file2->i_ndefs - 1; |
|
486 |
|
487 int first=0; |
|
488 struct symtab** i_defs = NULL; |
|
489 int deflen=file1->i_ndefs+file2->i_ndefs; |
|
490 |
|
491 debug(2,("merging %s into %s\n", |
|
492 file2->i_file, file1->i_file)); |
|
493 |
|
494 if (deflen>0) |
|
495 { |
|
496 /* make sure deflen % SYMTABINC == 0 is still true */ |
|
497 deflen += (SYMTABINC - deflen % SYMTABINC) % SYMTABINC; |
|
498 i_defs=(struct symtab**) |
|
499 malloc(deflen*sizeof(struct symtab*)); |
|
500 if (i_defs==NULL) return 0; |
|
501 } |
|
502 |
|
503 while ((last1 >= first1) && (last2 >= first2)) |
|
504 { |
|
505 char *s1=file1->i_defs[first1]->s_name; |
|
506 char *s2=file2->i_defs[first2]->s_name; |
|
507 |
|
508 if (strcmp(s1,s2) < 0) |
|
509 i_defs[first++]=file1->i_defs[first1++]; |
|
510 else if (strcmp(s1,s2) > 0) |
|
511 i_defs[first++]=file2->i_defs[first2++]; |
|
512 else /* equal */ |
|
513 { |
|
514 i_defs[first++]=file2->i_defs[first2++]; |
|
515 first1++; |
|
516 } |
|
517 } |
|
518 while (last1 >= first1) |
|
519 { |
|
520 i_defs[first++]=file1->i_defs[first1++]; |
|
521 } |
|
522 while (last2 >= first2) |
|
523 { |
|
524 i_defs[first++]=file2->i_defs[first2++]; |
|
525 } |
|
526 |
|
527 if (file1->i_defs) free(file1->i_defs); |
|
528 file1->i_defs=i_defs; |
|
529 file1->i_ndefs=first; |
|
530 |
|
531 return 1; |
|
532 } |
|
533 } |
|
534 |
|
535 void |
|
536 undefine(char *symbol, struct inclist *file) |
|
537 { |
|
538 register struct symtab **ptr; |
|
539 struct inclist *srcfile; |
|
540 while ((ptr = isdefined(symbol, file, &srcfile)) != NULL) |
|
541 { |
|
542 srcfile->i_ndefs--; |
|
543 for (; ptr < srcfile->i_defs + srcfile->i_ndefs; ptr++) |
|
544 *ptr = ptr[1]; |
|
545 } |
|
546 } |
|
547 |
|
548 int |
|
549 find_includes(struct filepointer *filep, struct inclist *file, |
|
550 struct inclist *file_red, int recursion, boolean failOK) |
|
551 { |
|
552 struct inclist *inclistp; |
|
553 char **includedirsp; |
|
554 register char *line; |
|
555 register int type; |
|
556 boolean recfailOK; |
|
557 |
|
558 while ((line = getnextline(filep))) { |
|
559 switch(type = deftype(line, filep, file_red, file, TRUE)) { |
|
560 case IF: |
|
561 doif: |
|
562 type = find_includes(filep, file, |
|
563 file_red, recursion+1, failOK); |
|
564 while ((type == ELIF) || (type == ELIFFALSE) || |
|
565 (type == ELIFGUESSFALSE)) |
|
566 type = gobble(filep, file, file_red); |
|
567 if (type == ELSE) |
|
568 gobble(filep, file, file_red); |
|
569 break; |
|
570 case IFFALSE: |
|
571 case IFGUESSFALSE: |
|
572 doiffalse: |
|
573 if (type == IFGUESSFALSE || type == ELIFGUESSFALSE) |
|
574 recfailOK = TRUE; |
|
575 else |
|
576 recfailOK = failOK; |
|
577 type = gobble(filep, file, file_red); |
|
578 if (type == ELSE) |
|
579 find_includes(filep, file, |
|
580 file_red, recursion+1, recfailOK); |
|
581 else |
|
582 if (type == ELIF) |
|
583 goto doif; |
|
584 else |
|
585 if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE)) |
|
586 goto doiffalse; |
|
587 break; |
|
588 case IFDEF: |
|
589 case IFNDEF: |
|
590 if ((type == IFDEF && isdefined(line, file_red, NULL)) |
|
591 || (type == IFNDEF && !isdefined(line, file_red, NULL))) { |
|
592 debug(1,(type == IFNDEF ? |
|
593 "line %d: %s !def'd in %s via %s%s\n" : "", |
|
594 filep->f_line, line, |
|
595 file->i_file, file_red->i_file, ": doit")); |
|
596 type = find_includes(filep, file, |
|
597 file_red, recursion+1, failOK); |
|
598 while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE) |
|
599 type = gobble(filep, file, file_red); |
|
600 if (type == ELSE) |
|
601 gobble(filep, file, file_red); |
|
602 } |
|
603 else { |
|
604 debug(1,(type == IFDEF ? |
|
605 "line %d: %s !def'd in %s via %s%s\n" : "", |
|
606 filep->f_line, line, |
|
607 file->i_file, file_red->i_file, ": gobble")); |
|
608 type = gobble(filep, file, file_red); |
|
609 if (type == ELSE) |
|
610 find_includes(filep, file, |
|
611 file_red, recursion+1, failOK); |
|
612 else if (type == ELIF) |
|
613 goto doif; |
|
614 else if (type == ELIFFALSE || type == ELIFGUESSFALSE) |
|
615 goto doiffalse; |
|
616 } |
|
617 break; |
|
618 case ELSE: |
|
619 case ELIFFALSE: |
|
620 case ELIFGUESSFALSE: |
|
621 case ELIF: |
|
622 if (!recursion) |
|
623 gobble(filep, file, file_red); |
|
624 case ENDIF: |
|
625 if (recursion) |
|
626 return(type); |
|
627 case DEFINE: |
|
628 define(line, file); |
|
629 break; |
|
630 case UNDEF: |
|
631 if (!*line) { |
|
632 warning("%s", file_red->i_file); |
|
633 if (file_red != file) |
|
634 warning1(" (reading %s)", file->i_file); |
|
635 warning1(", line %d: incomplete undef == \"%s\"\n", |
|
636 filep->f_line, line); |
|
637 break; |
|
638 } |
|
639 undefine(line, file_red); |
|
640 break; |
|
641 case INCLUDE: |
|
642 case INCLUDEDOT: |
|
643 case INCLUDENEXT: |
|
644 case INCLUDENEXTDOT: |
|
645 inclistp = inclistnext; |
|
646 includedirsp = includedirsnext; |
|
647 debug(2,("%s, reading %s, includes %s\n", |
|
648 file_red->i_file, file->i_file, line)); |
|
649 add_include(filep, file, file_red, line, type, failOK); |
|
650 inclistnext = inclistp; |
|
651 includedirsnext = includedirsp; |
|
652 break; |
|
653 case ERROR: |
|
654 case WARNING: |
|
655 warning("%s", file_red->i_file); |
|
656 if (file_red != file) |
|
657 warning1(" (reading %s)", file->i_file); |
|
658 warning1(", line %d: %s\n", |
|
659 filep->f_line, line); |
|
660 break; |
|
661 |
|
662 case PRAGMA: |
|
663 case IDENT: |
|
664 case SCCS: |
|
665 case EJECT: |
|
666 break; |
|
667 case -1: |
|
668 warning("%s", file_red->i_file); |
|
669 if (file_red != file) |
|
670 warning1(" (reading %s)", file->i_file); |
|
671 warning1(", line %d: unknown directive == \"%s\"\n", |
|
672 filep->f_line, line); |
|
673 break; |
|
674 case -2: |
|
675 warning("%s", file_red->i_file); |
|
676 if (file_red != file) |
|
677 warning1(" (reading %s)", file->i_file); |
|
678 warning1(", line %d: incomplete include == \"%s\"\n", |
|
679 filep->f_line, line); |
|
680 break; |
|
681 } |
|
682 } |
|
683 file->i_flags |= FINISHED; |
|
684 debug(2,("finished with %s\n", file->i_file)); |
|
685 return(-1); |
|
686 } |