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.11 2001/12/17 20:52:22 dawes 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 | }
|
---|