2 * $XConsortium: parse.c,v 1.8 88/09/22 13:52:51 jim Exp $
5 #include <sys/signal.h>
7 extern char *directives[];
8 extern struct symtab deflist[];
10 find_includes(filep, file, file_red, recursion)
11 struct filepointer *filep;
12 struct inclist *file, *file_red;
18 while (line = getline(filep)) {
19 switch(type = deftype(line, filep, file_red, file, TRUE)) {
22 type = find_includes(filep, file,
23 file_red, recursion+1);
24 while ((type == ELIF) || (type == ELIFFALSE))
25 type = gobble(filep, file, file_red);
27 gobble(filep, file, file_red);
31 type = gobble(filep, file, file_red);
33 find_includes(filep, file,
34 file_red, recursion+1);
39 if (type == ELIFFALSE)
44 if ((type == IFDEF && defined(line, file_red))
45 || (type == IFNDEF && !defined(line, file_red))) {
46 debug1(type == IFNDEF ?
47 "line %d: %s !def'd in %s via %s%s\n" : "",
49 file->i_file, file_red->i_file, ": doit");
50 type = find_includes(filep, file,
51 file_red, recursion+1);
53 gobble(filep, file, file_red);
56 debug1(type == IFDEF ?
57 "line %d: %s !def'd in %s via %s%s\n" : "",
59 file->i_file, file_red->i_file, ": gobble");
60 type = gobble(filep, file, file_red);
62 find_includes(filep, file,
63 file_red, recursion+1);
70 gobble(filep, file, file_red);
79 * undefine all occurances of line by killing s_name
82 log("%s, line %d: incomplete undef == \"%s\"\n",
83 file_red->i_file, filep->f_line, line);
88 for(val = defined(line, file_red);
90 val = defined(line, file_red))
92 *(val->s_name) = '\0';
96 add_include(file, file_red, line, FALSE);
99 add_include(file, file_red, line, TRUE);
105 log("%s", file_red->i_file);
106 if (file_red != file)
107 log(" (reading %s)", file->i_file);
108 log(", line %d: unknown directive == \"%s\"\n",
109 filep->f_line, line);
112 log("%s", file_red->i_file);
113 if (file_red != file)
114 log(" (reading %s)", file->i_file);
115 log(", line %d: incomplete include == \"%s\"\n",
116 filep->f_line, line);
123 gobble(filep, file, file_red)
124 register struct filepointer *filep;
125 struct inclist *file, *file_red;
130 while (line = getline(filep)) {
131 switch(type = deftype(line, filep, file_red, file, FALSE)) {
136 type = gobble(filep, file, file_red);
137 while ((type == ELIF) || (type == ELIFFALSE))
138 type = gobble(filep, file, file_red);
140 type = gobble(filep, file, file_red);
144 debug0("%s, line %d: #%s\n",
145 file->i_file, filep->f_line,
159 log("%s, line %d: unknown directive == \"%s\"\n",
160 file_red->i_file, filep->f_line, line);
168 * Decide what type of # directive this line is.
170 deftype(line, filep, file_red, file, parse_it)
172 register struct filepointer *filep;
173 register struct inclist *file_red, *file;
177 char *directive, savechar;
181 * Parse the directive...
184 while (*directive == ' ' || *directive == '\t')
188 while (*p >= 'a' && *p <= 'z')
192 ret = match(directive, directives);
195 /* If we don't recognize this compiler directive or we happen to just
196 * be gobbling up text while waiting for an #endif or #elif or #else
197 * in the case of an #elif we must check the zero_value and return an
198 * ELIF or an ELIFFALSE.
201 if (ret == ELIF && !parse_it)
203 while (*p == ' ' || *p == '\t')
206 * parse an expression.
208 debug0("%s, line %d: #elif %s ",
209 file->i_file, filep->f_line, p);
210 if (zero_value(p, filep, file_red))
212 debug0("false...\n");
222 if (ret < 0 || ! parse_it)
226 * now decide how to parse the directive, and do it.
228 while (*p == ' ' || *p == '\t')
233 * parse an expression.
235 debug0("%s, line %d: #if %s\n",
236 file->i_file, filep->f_line, p);
237 if (zero_value(p, filep, file_red))
242 debug0("%s, line %d: #%s %s\n",
243 file->i_file, filep->f_line, directives[ret], p);
246 * separate the name of a single symbol.
248 while (isalnum(*p) || *p == '_')
253 debug2("%s, line %d: #include %s\n",
254 file->i_file, filep->f_line, p);
256 /* Support ANSI macro substitution */
258 struct symtab *sym = defined(p, file_red);
261 debug3("%s : #includes SYMBOL %s = %s\n",
265 /* mark file as having included a 'soft include' */
266 file->i_included_sym = TRUE;
267 sym = defined(p, file_red);
272 * Separate the name of the include file.
274 while (*p && *p != '"' && *p != '<')
280 while (*p && *p != '"')
283 while (*p && *p != '>')
289 * copy the definition back to the beginning of the line.
298 debug0("%s, line %d: #%s\n",
299 file->i_file, filep->f_line, directives[ret]);
308 struct symtab *defined(symbol, file)
309 register char *symbol;
310 struct inclist *file;
312 register struct symtab *val;
314 if (val = slookup(symbol, deflist)) {
315 debug1("%s defined on command line\n", symbol);
318 if (val = fdefined(symbol, file))
320 debug1("%s not defined in %s\n", symbol, file->i_file);
324 struct symtab *fdefined(symbol, file)
325 register char *symbol;
326 struct inclist *file;
328 register struct inclist **ip;
329 register struct symtab *val;
331 static int recurse_lvl = 0;
333 if (file->i_defchecked)
335 file->i_defchecked = TRUE;
336 if (val = slookup(symbol, file->i_defs))
337 debug1("%s defined in %s\n", symbol, file->i_file);
338 if (val == NULL && file->i_list)
339 for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++)
340 if (val = fdefined(symbol, *ip)) {
341 debug1("%s defined in %s\n",
342 symbol, (*ip)->i_file);
346 file->i_defchecked = FALSE;
351 struct symtab *slookup(symbol, stab)
352 register char *symbol;
353 register struct symtab *stab;
356 for (; stab->s_name; stab++)
357 if (strcmp(symbol, stab->s_name) == 0)
363 * Return true if the #if expression evaluates to 0
365 zero_value(exp, filep, file_red)
367 register struct filepointer *filep;
368 register struct inclist *file_red;
371 return (cppsetup(exp, filep, file_red) == 0);
379 register struct inclist *file;
382 struct symtab *sp = file->i_lastdef++;
386 * If we are out of space, allocate some more.
388 if (file->i_defs == NULL
389 || file->i_lastdef == file->i_defs + file->i_deflen) {
391 file->i_defs = (struct symtab *) realloc(file->i_defs,
392 sizeof(struct symtab)*(file->i_deflen+SYMTABINC));
394 file->i_defs = (struct symtab *)
395 malloc(sizeof (struct symtab) * SYMTABINC);
397 file->i_deflen += SYMTABINC;
398 while (i < file->i_deflen)
399 file->i_defs[ i++ ].s_name = NULL;
400 file->i_lastdef = file->i_defs + file->i_deflen - SYMTABINC;
401 if (sp) /* be sure we use last cell in previous group */
403 sp = file->i_lastdef++;
405 else if (file->i_lastdef > file->i_defs + file->i_deflen)
406 log_fatal("define() botch\n");
409 * copy the symbol being defined.
412 while (isalnum(*p) || *p == '_')
416 sp->s_name = copy(def);
419 * And copy its value.
421 while (*p == ' ' && *p == '\t')
423 sp->s_value = copy(p);