]> andersk Git - moira.git/blame - util/makedepend/parse.c
sync'ing files for RCS->CVS migration
[moira.git] / util / makedepend / parse.c
CommitLineData
d1b2a10e 1/*
2 * $XConsortium: parse.c,v 1.8 88/09/22 13:52:51 jim Exp $
3 */
4#include "def.h"
5#include <sys/signal.h>
6
7extern char *directives[];
8extern struct symtab deflist[];
9
10find_includes(filep, file, file_red, recursion)
11 struct filepointer *filep;
12 struct inclist *file, *file_red;
13 int recursion;
14{
15 register char *line;
16 register int type;
17
18 while (line = getline(filep)) {
19 switch(type = deftype(line, filep, file_red, file, TRUE)) {
20 case IF:
21 doif:
22 type = find_includes(filep, file,
23 file_red, recursion+1);
24 while ((type == ELIF) || (type == ELIFFALSE))
25 type = gobble(filep, file, file_red);
26 if (type == ELSE)
27 gobble(filep, file, file_red);
28 break;
29 case IFFALSE:
30 doiffalse:
31 type = gobble(filep, file, file_red);
32 if (type == ELSE)
33 find_includes(filep, file,
34 file_red, recursion+1);
35 else
36 if (type == ELIF)
37 goto doif;
38 else
39 if (type == ELIFFALSE)
40 goto doiffalse;
41 break;
42 case IFDEF:
43 case IFNDEF:
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" : "",
48 filep->f_line, line,
49 file->i_file, file_red->i_file, ": doit");
50 type = find_includes(filep, file,
51 file_red, recursion+1);
52 if (type == ELSE)
53 gobble(filep, file, file_red);
54 }
55 else {
56 debug1(type == IFDEF ?
57 "line %d: %s !def'd in %s via %s%s\n" : "",
58 filep->f_line, line,
59 file->i_file, file_red->i_file, ": gobble");
60 type = gobble(filep, file, file_red);
61 if (type == ELSE)
62 find_includes(filep, file,
63 file_red, recursion+1);
64 }
65 break;
66 case ELSE:
67 case ELIFFALSE:
68 case ELIF:
69 if (!recursion)
70 gobble(filep, file, file_red);
71 case ENDIF:
72 if (recursion)
73 return(type);
74 case DEFINE:
75 define(line, file);
76 break;
77 case UNDEF:
78 /*
79 * undefine all occurances of line by killing s_name
80 */
81 if (!*line) {
82 log("%s, line %d: incomplete undef == \"%s\"\n",
83 file_red->i_file, filep->f_line, line);
84 break;
85 }
86 {
87 struct symtab *val;
88 for(val = defined(line, file_red);
89 (val && val->s_name);
90 val = defined(line, file_red))
91
92 *(val->s_name) = '\0';
93 }
94 break;
95 case INCLUDE:
96 add_include(file, file_red, line, FALSE);
97 break;
98 case INCLUDEDOT:
99 add_include(file, file_red, line, TRUE);
100 break;
101 case PRAGMA:
102 case EJECT:
103 break;
104 case -1:
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);
110 break;
111 case -2:
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);
117 break;
118 }
119 }
120 return(-1);
121}
122
123gobble(filep, file, file_red)
124 register struct filepointer *filep;
125 struct inclist *file, *file_red;
126{
127 register char *line;
128 register int type;
129
130 while (line = getline(filep)) {
131 switch(type = deftype(line, filep, file_red, file, FALSE)) {
132 case IF:
133 case IFFALSE:
134 case IFDEF:
135 case IFNDEF:
136 type = gobble(filep, file, file_red);
137 while ((type == ELIF) || (type == ELIFFALSE))
138 type = gobble(filep, file, file_red);
139 if (type == ELSE)
140 type = gobble(filep, file, file_red);
141 break;
142 case ELSE:
143 case ENDIF:
144 debug0("%s, line %d: #%s\n",
145 file->i_file, filep->f_line,
146 directives[type]);
147 return(type);
148 case DEFINE:
149 case UNDEF:
150 case INCLUDE:
151 case INCLUDEDOT:
152 case PRAGMA:
153 case EJECT:
154 break;
155 case ELIF:
156 case ELIFFALSE:
157 return(type);
158 case -1:
159 log("%s, line %d: unknown directive == \"%s\"\n",
160 file_red->i_file, filep->f_line, line);
161 break;
162 }
163 }
164 return(-1);
165}
166
167/*
168 * Decide what type of # directive this line is.
169 */
170deftype(line, filep, file_red, file, parse_it)
171 register char *line;
172 register struct filepointer *filep;
173 register struct inclist *file_red, *file;
174 int parse_it;
175{
176 register char *p;
177 char *directive, savechar;
178 register int ret;
179
180 /*
181 * Parse the directive...
182 */
183 directive=line+1;
184 while (*directive == ' ' || *directive == '\t')
185 directive++;
186
187 p = directive;
188 while (*p >= 'a' && *p <= 'z')
189 p++;
190 savechar = *p;
191 *p = '\0';
192 ret = match(directive, directives);
193 *p = savechar;
194
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.
199 */
200
201 if (ret == ELIF && !parse_it)
202 {
203 while (*p == ' ' || *p == '\t')
204 p++;
205 /*
206 * parse an expression.
207 */
208 debug0("%s, line %d: #elif %s ",
209 file->i_file, filep->f_line, p);
210 if (zero_value(p, filep, file_red))
211 {
212 debug0("false...\n");
213 return(ELIFFALSE);
214 }
215 else
216 {
217 debug0("true...\n");
218 return(ret);
219 }
220 }
221
222 if (ret < 0 || ! parse_it)
223 return(ret);
224
225 /*
226 * now decide how to parse the directive, and do it.
227 */
228 while (*p == ' ' || *p == '\t')
229 p++;
230 switch (ret) {
231 case IF:
232 /*
233 * parse an expression.
234 */
235 debug0("%s, line %d: #if %s\n",
236 file->i_file, filep->f_line, p);
237 if (zero_value(p, filep, file_red))
238 ret = IFFALSE;
239 break;
240 case IFDEF:
241 case IFNDEF:
242 debug0("%s, line %d: #%s %s\n",
243 file->i_file, filep->f_line, directives[ret], p);
244 case UNDEF:
245 /*
246 * separate the name of a single symbol.
247 */
248 while (isalnum(*p) || *p == '_')
249 *line++ = *p++;
250 *line = '\0';
251 break;
252 case INCLUDE:
253 debug2("%s, line %d: #include %s\n",
254 file->i_file, filep->f_line, p);
255
256 /* Support ANSI macro substitution */
257 {
258 struct symtab *sym = defined(p, file_red);
259 while (sym) {
260 p = sym->s_value;
261 debug3("%s : #includes SYMBOL %s = %s\n",
262 file->i_incstring,
263 sym -> s_name,
264 sym -> s_value);
265 /* mark file as having included a 'soft include' */
266 file->i_included_sym = TRUE;
267 sym = defined(p, file_red);
268 }
269 }
270
271 /*
272 * Separate the name of the include file.
273 */
274 while (*p && *p != '"' && *p != '<')
275 p++;
276 if (! *p)
277 return(-2);
278 if (*p++ == '"') {
279 ret = INCLUDEDOT;
280 while (*p && *p != '"')
281 *line++ = *p++;
282 } else
283 while (*p && *p != '>')
284 *line++ = *p++;
285 *line = '\0';
286 break;
287 case DEFINE:
288 /*
289 * copy the definition back to the beginning of the line.
290 */
291 strcpy (line, p);
292 break;
293 case ELSE:
294 case ENDIF:
295 case ELIF:
296 case PRAGMA:
297 case EJECT:
298 debug0("%s, line %d: #%s\n",
299 file->i_file, filep->f_line, directives[ret]);
300 /*
301 * nothing to do.
302 */
303 break;
304 }
305 return(ret);
306}
307
308struct symtab *defined(symbol, file)
309 register char *symbol;
310 struct inclist *file;
311{
312 register struct symtab *val;
313
314 if (val = slookup(symbol, deflist)) {
315 debug1("%s defined on command line\n", symbol);
316 return(val);
317 }
318 if (val = fdefined(symbol, file))
319 return(val);
320 debug1("%s not defined in %s\n", symbol, file->i_file);
321 return(NULL);
322}
323
324struct symtab *fdefined(symbol, file)
325 register char *symbol;
326 struct inclist *file;
327{
328 register struct inclist **ip;
329 register struct symtab *val;
330 register int i;
331 static int recurse_lvl = 0;
332
333 if (file->i_defchecked)
334 return(NULL);
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);
343 break;
344 }
345 recurse_lvl--;
346 file->i_defchecked = FALSE;
347
348 return(val);
349}
350
351struct symtab *slookup(symbol, stab)
352 register char *symbol;
353 register struct symtab *stab;
354{
355 if (stab)
356 for (; stab->s_name; stab++)
357 if (strcmp(symbol, stab->s_name) == 0)
358 return(stab);
359 return(NULL);
360}
361
362/*
363 * Return true if the #if expression evaluates to 0
364 */
365zero_value(exp, filep, file_red)
366 register char *exp;
367 register struct filepointer *filep;
368 register struct inclist *file_red;
369{
370#ifdef CPP
371 return (cppsetup(exp, filep, file_red) == 0);
372#else CPP
373 return(TRUE);
374#endif CPP
375}
376
377define(def, file)
378 register char *def;
379 register struct inclist *file;
380{
381 register char *p;
382 struct symtab *sp = file->i_lastdef++;
383 register int i;
384
385 /*
386 * If we are out of space, allocate some more.
387 */
388 if (file->i_defs == NULL
389 || file->i_lastdef == file->i_defs + file->i_deflen) {
390 if (file->i_defs)
391 file->i_defs = (struct symtab *) realloc(file->i_defs,
392 sizeof(struct symtab)*(file->i_deflen+SYMTABINC));
393 else
394 file->i_defs = (struct symtab *)
395 malloc(sizeof (struct symtab) * SYMTABINC);
396 i=file->i_deflen;
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 */
402 file->i_lastdef--;
403 sp = file->i_lastdef++;
404 }
405 else if (file->i_lastdef > file->i_defs + file->i_deflen)
406 log_fatal("define() botch\n");
407
408 /*
409 * copy the symbol being defined.
410 */
411 p = def;
412 while (isalnum(*p) || *p == '_')
413 p++;
414 if (*p)
415 *p++ = '\0';
416 sp->s_name = copy(def);
417
418 /*
419 * And copy its value.
420 */
421 while (*p == ' ' && *p == '\t')
422 p++;
423 sp->s_value = copy(p);
424}
This page took 0.336529 seconds and 5 git commands to generate.