merge the formfield patch from ooo-build
[ooovba.git] / soltools / mkdepend / parse.c
blob64812c09f4752cdac95cedfb9b076dd5ee4e0f57
1 /* $XConsortium: parse.c,v 1.30 94/04/17 20:10:38 gildea Exp $ */
2 /*
4 Copyright (c) 1993, 1994 X Consortium
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 Except as contained in this notice, the name of the X Consortium shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from the X Consortium.
29 #include "def.h"
30 char *hash_lookup( char *symbol, struct symhash *symbols );
31 void hash_undefine( char *symbol, struct symhash *symbols );
33 extern char *directives[];
34 extern struct symhash *maininclist;
36 int find_includes(filep, file, file_red, recursion, failOK, incCollection, symbols)
37 struct filepointer *filep;
38 struct inclist *file, *file_red;
39 int recursion;
40 boolean failOK;
41 struct IncludesCollection* incCollection;
42 struct symhash *symbols;
44 register char *line;
45 register int type;
46 boolean recfailOK;
48 while ((line = get_line(filep))) {
49 switch(type = deftype(line, filep, file_red, file, TRUE, symbols)) {
50 case IF:
51 doif:
52 type = find_includes(filep, file,
53 file_red, recursion+1, failOK, incCollection, symbols);
54 while ((type == ELIF) || (type == ELIFFALSE) ||
55 (type == ELIFGUESSFALSE))
56 type = gobble(filep, file, file_red, symbols);
57 if (type == ELSE)
58 gobble(filep, file, file_red, symbols);
59 break;
60 case IFFALSE:
61 case IFGUESSFALSE:
62 doiffalse:
63 if (type == IFGUESSFALSE || type == ELIFGUESSFALSE)
64 recfailOK = TRUE;
65 else
66 recfailOK = failOK;
67 type = gobble(filep, file, file_red, symbols);
68 if (type == ELSE)
69 find_includes(filep, file,
70 file_red, recursion+1, recfailOK, incCollection, symbols);
71 else
72 if (type == ELIF)
73 goto doif;
74 else
75 if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE))
76 goto doiffalse;
77 break;
78 case IFDEF:
79 case IFNDEF:
80 if ((type == IFDEF && hash_lookup(line, symbols))
81 || (type == IFNDEF && !hash_lookup(line, symbols))) {
82 debug(1,(type == IFNDEF ?
83 "line %d: %s !def'd in %s via %s%s\n" : "",
84 filep->f_line, line,
85 file->i_file, file_red->i_file, ": doit"));
86 type = find_includes(filep, file,
87 file_red, recursion+1, failOK, incCollection, symbols);
88 while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE)
89 type = gobble(filep, file, file_red, symbols);
90 if (type == ELSE)
91 gobble(filep, file, file_red, symbols);
93 else {
94 debug(1,(type == IFDEF ?
95 "line %d: %s !def'd in %s via %s%s\n" : "",
96 filep->f_line, line,
97 file->i_file, file_red->i_file, ": gobble"));
98 type = gobble(filep, file, file_red, symbols);
99 if (type == ELSE)
100 find_includes(filep, file,
101 file_red, recursion + 1, failOK, incCollection, symbols);
102 else if (type == ELIF)
103 goto doif;
104 else if (type == ELIFFALSE || type == ELIFGUESSFALSE)
105 goto doiffalse;
107 break;
108 case ELSE:
109 case ELIFFALSE:
110 case ELIFGUESSFALSE:
111 case ELIF:
112 if (!recursion)
113 gobble(filep, file, file_red, symbols);
114 case ENDIF:
115 if (recursion)
116 return(type);
117 case DEFINE:
118 define(line, &symbols);
119 break;
120 case UNDEF:
121 if (!*line) {
122 warning("%s, line %d: incomplete undef == \"%s\"\n",
123 file_red->i_file, filep->f_line, line);
124 break;
126 hash_undefine(line, symbols);
127 break;
128 case INCLUDE:
129 add_include(filep, file, file_red, line, FALSE, failOK, incCollection, symbols);
130 break;
131 case INCLUDEDOT:
132 add_include(filep, file, file_red, line, TRUE, failOK, incCollection, symbols);
133 break;
134 case ERROR:
135 warning("%s: %d: %s\n", file_red->i_file,
136 filep->f_line, line);
137 break;
139 case PRAGMA:
140 case IDENT:
141 case SCCS:
142 case EJECT:
143 break;
144 case -1:
145 warning("%s", file_red->i_file);
146 if (file_red != file)
147 warning1(" (reading %s)", file->i_file);
148 warning1(", line %d: unknown directive == \"%s\"\n",
149 filep->f_line, line);
150 break;
151 case -2:
152 warning("%s", file_red->i_file);
153 if (file_red != file)
154 warning1(" (reading %s)", file->i_file);
155 warning1(", line %d: incomplete include == \"%s\"\n",
156 filep->f_line, line);
157 break;
160 return(-1);
163 int gobble(filep, file, file_red, symbols)
164 register struct filepointer *filep;
165 struct inclist *file, *file_red;
166 struct symhash *symbols;
168 register char *line;
169 register int type;
171 while ((line = get_line(filep))) {
172 switch(type = deftype(line, filep, file_red, file, FALSE, symbols)) {
173 case IF:
174 case IFFALSE:
175 case IFGUESSFALSE:
176 case IFDEF:
177 case IFNDEF:
178 type = gobble(filep, file, file_red, symbols);
179 while ((type == ELIF) || (type == ELIFFALSE) ||
180 (type == ELIFGUESSFALSE))
181 type = gobble(filep, file, file_red, symbols);
182 if (type == ELSE)
183 (void)gobble(filep, file, file_red, symbols);
184 break;
185 case ELSE:
186 case ENDIF:
187 debug(0,("%s, line %d: #%s\n",
188 file->i_file, filep->f_line,
189 directives[type]));
190 return(type);
191 case DEFINE:
192 case UNDEF:
193 case INCLUDE:
194 case INCLUDEDOT:
195 case PRAGMA:
196 case ERROR:
197 case IDENT:
198 case SCCS:
199 case EJECT:
200 break;
201 case ELIF:
202 case ELIFFALSE:
203 case ELIFGUESSFALSE:
204 return(type);
205 case -1:
206 warning("%s, line %d: unknown directive == \"%s\"\n",
207 file_red->i_file, filep->f_line, line);
208 break;
211 return(-1);
215 * Decide what type of # directive this line is.
217 int deftype (line, filep, file_red, file, parse_it, symbols)
218 register char *line;
219 register struct filepointer *filep;
220 register struct inclist *file_red, *file;
221 int parse_it;
222 struct symhash *symbols;
224 register char *p;
225 char *directive, savechar;
226 register int ret;
229 * Parse the directive...
231 directive=line+1;
232 while (*directive == ' ' || *directive == '\t')
233 directive++;
235 p = directive;
236 while (*p >= 'a' && *p <= 'z')
237 p++;
238 savechar = *p;
239 *p = '\0';
240 ret = match(directive, directives);
241 *p = savechar;
243 /* If we don't recognize this compiler directive or we happen to just
244 * be gobbling up text while waiting for an #endif or #elif or #else
245 * in the case of an #elif we must check the zero_value and return an
246 * ELIF or an ELIFFALSE.
249 if (ret == ELIF && !parse_it)
251 while (*p == ' ' || *p == '\t')
252 p++;
254 * parse an expression.
256 debug(0,("%s, line %d: #elif %s ",
257 file->i_file, filep->f_line, p));
258 ret = zero_value(p, filep, file_red, symbols);
259 if (ret != IF)
261 debug(0,("false...\n"));
262 if (ret == IFFALSE)
263 return(ELIFFALSE);
264 else
265 return(ELIFGUESSFALSE);
267 else
269 debug(0,("true...\n"));
270 return(ELIF);
274 if (ret < 0 || ! parse_it)
275 return(ret);
278 * now decide how to parse the directive, and do it.
280 while (*p == ' ' || *p == '\t')
281 p++;
282 switch (ret) {
283 case IF:
285 * parse an expression.
287 ret = zero_value(p, filep, file_red, symbols);
288 debug(0,("%s, line %d: %s #if %s\n",
289 file->i_file, filep->f_line, ret?"false":"true", p));
290 break;
291 case IFDEF:
292 case IFNDEF:
293 debug(0,("%s, line %d: #%s %s\n",
294 file->i_file, filep->f_line, directives[ret], p));
295 case UNDEF:
297 * separate the name of a single symbol.
299 while (isalnum(*p) || *p == '_')
300 *line++ = *p++;
301 *line = '\0';
302 break;
303 case INCLUDE:
304 debug(2,("%s, line %d: #include %s\n",
305 file->i_file, filep->f_line, p));
307 /* Support ANSI macro substitution */
309 char *sym = hash_lookup(p, symbols);
310 while (sym)
312 p = sym;
313 debug(3,("%s : #includes SYMBOL %s\n",
314 file->i_incstring,
315 sym));
316 /* mark file as having included a 'soft include' */
317 file->i_included_sym = TRUE;
318 sym = hash_lookup(p, symbols);
323 * Separate the name of the include file.
325 while (*p && *p != '"' && *p != '<')
326 p++;
327 if (! *p)
328 return(-2);
329 if (*p++ == '"') {
330 ret = INCLUDEDOT;
331 while (*p && *p != '"')
332 *line++ = *p++;
333 } else
334 while (*p && *p != '>')
335 *line++ = *p++;
336 *line = '\0';
337 break;
338 case DEFINE:
340 * copy the definition back to the beginning of the line.
342 strcpy (line, p);
343 break;
344 case ELSE:
345 case ENDIF:
346 case ELIF:
347 case PRAGMA:
348 case ERROR:
349 case IDENT:
350 case SCCS:
351 case EJECT:
352 debug(0,("%s, line %d: #%s\n",
353 file->i_file, filep->f_line, directives[ret]));
355 * nothing to do.
357 break;
359 return(ret);
363 * HACK! - so that we do not have to introduce 'symbols' in each cppsetup.c
364 * function... It's safe, functions from cppsetup.c don't return here.
366 struct symhash *global_symbols = NULL;
368 char * isdefined( symbol )
369 register char *symbol;
371 return hash_lookup( symbol, global_symbols );
375 * Return type based on if the #if expression evaluates to 0
377 int zero_value(exp, filep, file_red, symbols)
378 register char *exp;
379 register struct filepointer *filep;
380 register struct inclist *file_red;
381 register struct symhash *symbols;
383 global_symbols = symbols; /* HACK! see above */
384 if (cppsetup(exp, filep, file_red))
385 return(IFFALSE);
386 else
387 return(IF);
390 void define( def, symbols )
391 char *def;
392 struct symhash **symbols;
394 char *val;
396 /* Separate symbol name and its value */
397 val = def;
398 while (isalnum(*val) || *val == '_')
399 val++;
400 if (*val)
401 *val++ = '\0';
402 while (*val == ' ' || *val == '\t')
403 val++;
405 if (!*val)
406 val = "1";
407 hash_define( def, val, symbols );
410 static int hash( str )
411 register char *str;
413 /* Hash (Kernighan and Ritchie) */
414 register unsigned int hashval = 0;
415 register unsigned int i = 0;
416 char *s = str;
418 for ( ; *str; str++ )
420 hashval = ( hashval * SYMHASHSEED ) + ( *str );
423 //fprintf( stderr, "hash: %s, %d\n", s, hashval & ( SYMHASHMEMBERS - 1 ) );
424 return hashval & ( SYMHASHMEMBERS - 1 );
427 struct symhash *hash_copy( symbols )
428 struct symhash *symbols;
430 int i;
431 struct symhash *newsym;
432 if ( !symbols )
433 return NULL;
435 newsym = (struct symhash *) malloc( sizeof( struct symhash ) );
437 for ( i = 0; i < SYMHASHMEMBERS; ++i )
439 if ( !symbols->s_pairs[ i ] )
440 newsym->s_pairs[ i ] = NULL;
441 else
443 struct pair *it = symbols->s_pairs[ i ];
444 struct pair *nw = newsym->s_pairs[ i ] = (struct pair*) malloc( sizeof( struct pair ) );
445 nw->p_name = it->p_name;
446 nw->p_value = it->p_value;
447 nw->p_next = NULL;
449 while ( it->p_next )
451 nw->p_next = (struct pair*) malloc( sizeof( struct pair ) );
452 it = it->p_next;
453 nw = nw->p_next;
454 nw->p_name = it->p_name;
455 nw->p_value = it->p_value;
456 nw->p_next = NULL;
460 return newsym;
463 void hash_free( symbols )
464 struct symhash *symbols;
466 int i;
468 if ( !symbols )
469 return;
471 for ( i = 0; i < SYMHASHMEMBERS; ++i )
473 struct pair *it = symbols->s_pairs[ i ];
474 struct pair *next;
475 while ( it )
477 next = it->p_next;
478 free( it );
479 it = next;
482 free( symbols->s_pairs );
485 void hash_define( name, val, symbols )
486 char *name, *val;
487 struct symhash **symbols;
489 int hashval;
490 struct pair *it;
492 if ( !symbols )
493 return;
495 /* Make space if it's needed */
496 if ( *symbols == NULL )
498 int i;
500 *symbols = (struct symhash *) malloc( sizeof( struct symhash ) );
501 if ( *symbols == NULL )
502 fatalerr( "malloc()/realloc() failure in insert_defn()\n" );
504 for ( i = 0; i < SYMHASHMEMBERS; ++i )
505 (*symbols)->s_pairs[i] = NULL;
508 hashval = hash( name );
509 it = (*symbols)->s_pairs[ hashval ];
511 /* Replace/insert the symbol */
512 if ( it == NULL )
514 it = (*symbols)->s_pairs[ hashval ] = (struct pair*) malloc( sizeof( struct pair ) );
515 it->p_name = copy( name );
516 it->p_value = copy( val );
517 it->p_next = NULL;
519 else if ( strcmp( it->p_name, name ) == 0 )
521 it->p_value = copy( val );
523 else
525 while ( it->p_next && ( strcmp( it->p_next->p_name, name ) != 0 ) )
527 it = it->p_next;
529 if ( it->p_next )
530 it->p_next->p_name = copy( name );
531 else
533 it->p_next = (struct pair*) malloc( sizeof( struct pair ) );
534 it->p_next->p_name = copy( name );
535 it->p_next->p_value = copy( val );
536 it->p_next->p_next = NULL;
541 char *hash_lookup( symbol, symbols )
542 char *symbol;
543 struct symhash *symbols;
545 struct pair *it;
547 if ( !symbols )
548 return NULL;
550 it = symbols->s_pairs[ hash( symbol ) ];
552 while ( it && ( strcmp( it->p_name, symbol ) != 0 ) )
554 it = it->p_next;
556 if ( it )
557 return it->p_value;
559 return NULL;
562 void hash_undefine( symbol, symbols )
563 char *symbol;
564 struct symhash *symbols;
566 int hashval;
567 struct pair *it;
569 if ( !symbols )
570 return;
572 hashval = hash( symbol );
573 it = symbols->s_pairs[ hashval ];
575 /* Replace/insert the symbol */
576 if ( it == NULL )
577 return;
578 else if ( strcmp( it->p_name, symbol ) == 0 )
580 if ( it->p_next )
582 struct pair *tmp;
583 it->p_name = it->p_next->p_name;
584 it->p_value = it->p_next->p_value;
585 tmp = it->p_next->p_next;
586 free( it->p_next );
587 it->p_next = tmp;
589 else
591 free( it );
592 symbols->s_pairs[ hashval ] = NULL;
595 else
597 while ( it->p_next && ( strcmp( it->p_next->p_name, symbol ) != 0 ) )
599 it = it->p_next;
601 if ( it->p_next )
603 struct pair *tmp = it->p_next;
604 it->p_next = it->p_next->p_next;
605 free( tmp );