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