1 /* $XConsortium: parse.c,v 1.30 94/04/17 20:10:38 gildea Exp $ */
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.
30 char *hash_lookup( char *symbol
, struct symhash
*symbols
);
31 void hash_undefine( char *symbol
, struct symhash
*symbols
);
32 int gobble( register struct filepointer
*filep
, struct inclist
*file
,
33 struct inclist
*file_red
, struct symhash
*symbols
);
34 int deftype ( register char *line
, register struct filepointer
*filep
,
35 register struct inclist
*file_red
, register struct inclist
*file
,
36 int parse_it
, struct symhash
*symbols
);
37 int zero_value(register char *exp
, register struct filepointer
*filep
,
38 register struct inclist
*file_red
, register struct symhash
*symbols
);
40 extern char *directives
[];
41 extern struct symhash
*maininclist
;
43 int find_includes(filep
, file
, file_red
, recursion
, failOK
, incCollection
, symbols
)
44 struct filepointer
*filep
;
45 struct inclist
*file
, *file_red
;
48 struct IncludesCollection
* incCollection
;
49 struct symhash
*symbols
;
55 while ((line
= get_line(filep
))) {
56 switch(type
= deftype(line
, filep
, file_red
, file
, TRUE
, symbols
)) {
59 type
= find_includes(filep
, file
,
60 file_red
, recursion
+1, failOK
, incCollection
, symbols
);
61 while ((type
== ELIF
) || (type
== ELIFFALSE
) ||
62 (type
== ELIFGUESSFALSE
))
63 type
= gobble(filep
, file
, file_red
, symbols
);
65 gobble(filep
, file
, file_red
, symbols
);
70 if (type
== IFGUESSFALSE
|| type
== ELIFGUESSFALSE
)
74 type
= gobble(filep
, file
, file_red
, symbols
);
76 find_includes(filep
, file
,
77 file_red
, recursion
+1, recfailOK
, incCollection
, symbols
);
82 if ((type
== ELIFFALSE
) || (type
== ELIFGUESSFALSE
))
87 if ((type
== IFDEF
&& hash_lookup(line
, symbols
))
88 || (type
== IFNDEF
&& !hash_lookup(line
, symbols
))) {
89 debug(1,(type
== IFNDEF
?
90 "line %d: %s !def'd in %s via %s%s\n" : "",
92 file
->i_file
, file_red
->i_file
, ": doit"));
93 type
= find_includes(filep
, file
,
94 file_red
, recursion
+1, failOK
, incCollection
, symbols
);
95 while (type
== ELIF
|| type
== ELIFFALSE
|| type
== ELIFGUESSFALSE
)
96 type
= gobble(filep
, file
, file_red
, symbols
);
98 gobble(filep
, file
, file_red
, symbols
);
101 debug(1,(type
== IFDEF
?
102 "line %d: %s !def'd in %s via %s%s\n" : "",
104 file
->i_file
, file_red
->i_file
, ": gobble"));
105 type
= gobble(filep
, file
, file_red
, symbols
);
107 find_includes(filep
, file
,
108 file_red
, recursion
+ 1, failOK
, incCollection
, symbols
);
109 else if (type
== ELIF
)
111 else if (type
== ELIFFALSE
|| type
== ELIFGUESSFALSE
)
120 gobble(filep
, file
, file_red
, symbols
);
125 define(line
, &symbols
);
129 warning("%s, line %d: incomplete undef == \"%s\"\n",
130 file_red
->i_file
, filep
->f_line
, line
);
133 hash_undefine(line
, symbols
);
136 add_include(filep
, file
, file_red
, line
, FALSE
, failOK
, incCollection
, symbols
);
139 add_include(filep
, file
, file_red
, line
, TRUE
, failOK
, incCollection
, symbols
);
142 warning("%s: %d: %s\n", file_red
->i_file
,
143 filep
->f_line
, line
);
152 warning("%s", file_red
->i_file
);
153 if (file_red
!= file
)
154 warning1(" (reading %s)", file
->i_file
);
155 warning1(", line %d: unknown directive == \"%s\"\n",
156 filep
->f_line
, line
);
159 warning("%s", file_red
->i_file
);
160 if (file_red
!= file
)
161 warning1(" (reading %s)", file
->i_file
);
162 warning1(", line %d: incomplete include == \"%s\"\n",
163 filep
->f_line
, line
);
170 int gobble(filep
, file
, file_red
, symbols
)
171 register struct filepointer
*filep
;
172 struct inclist
*file
, *file_red
;
173 struct symhash
*symbols
;
178 while ((line
= get_line(filep
))) {
179 switch(type
= deftype(line
, filep
, file_red
, file
, FALSE
, symbols
)) {
185 type
= gobble(filep
, file
, file_red
, symbols
);
186 while ((type
== ELIF
) || (type
== ELIFFALSE
) ||
187 (type
== ELIFGUESSFALSE
))
188 type
= gobble(filep
, file
, file_red
, symbols
);
190 (void)gobble(filep
, file
, file_red
, symbols
);
194 debug(0,("%s, line %d: #%s\n",
195 file
->i_file
, filep
->f_line
,
213 warning("%s, line %d: unknown directive == \"%s\"\n",
214 file_red
->i_file
, filep
->f_line
, line
);
222 * Decide what type of # directive this line is.
224 int deftype (line
, filep
, file_red
, file
, parse_it
, symbols
)
226 register struct filepointer
*filep
;
227 register struct inclist
*file_red
, *file
;
229 struct symhash
*symbols
;
232 char *directive
, savechar
;
236 * Parse the directive...
239 while (*directive
== ' ' || *directive
== '\t')
243 while (*p
>= 'a' && *p
<= 'z')
247 ret
= match(directive
, directives
);
250 /* If we don't recognize this compiler directive or we happen to just
251 * be gobbling up text while waiting for an #endif or #elif or #else
252 * in the case of an #elif we must check the zero_value and return an
253 * ELIF or an ELIFFALSE.
256 if (ret
== ELIF
&& !parse_it
)
258 while (*p
== ' ' || *p
== '\t')
261 * parse an expression.
263 debug(0,("%s, line %d: #elif %s ",
264 file
->i_file
, filep
->f_line
, p
));
265 ret
= zero_value(p
, filep
, file_red
, symbols
);
268 debug(0,("false...\n"));
272 return(ELIFGUESSFALSE
);
276 debug(0,("true...\n"));
281 if (ret
< 0 || ! parse_it
)
285 * now decide how to parse the directive, and do it.
287 while (*p
== ' ' || *p
== '\t')
292 * parse an expression.
294 ret
= zero_value(p
, filep
, file_red
, symbols
);
295 debug(0,("%s, line %d: %s #if %s\n",
296 file
->i_file
, filep
->f_line
, ret
?"false":"true", p
));
300 debug(0,("%s, line %d: #%s %s\n",
301 file
->i_file
, filep
->f_line
, directives
[ret
], p
));
304 * separate the name of a single symbol.
306 while (isalnum(*p
) || *p
== '_')
311 debug(2,("%s, line %d: #include %s\n",
312 file
->i_file
, filep
->f_line
, p
));
314 /* Support ANSI macro substitution */
316 char *sym
= hash_lookup(p
, symbols
);
320 debug(3,("%s : #includes SYMBOL %s\n",
323 /* mark file as having included a 'soft include' */
324 file
->i_included_sym
= TRUE
;
325 sym
= hash_lookup(p
, symbols
);
330 * Separate the name of the include file.
332 while (*p
&& *p
!= '"' && *p
!= '<')
338 while (*p
&& *p
!= '"')
341 while (*p
&& *p
!= '>')
347 * copy the definition back to the beginning of the line.
359 debug(0,("%s, line %d: #%s\n",
360 file
->i_file
, filep
->f_line
, directives
[ret
]));
370 * HACK! - so that we do not have to introduce 'symbols' in each cppsetup.c
371 * function... It's safe, functions from cppsetup.c don't return here.
373 struct symhash
*global_symbols
= NULL
;
375 char * isdefined( symbol
)
376 register char *symbol
;
378 return hash_lookup( symbol
, global_symbols
);
382 * Return type based on if the #if expression evaluates to 0
384 int zero_value(exp
, filep
, file_red
, symbols
)
386 register struct filepointer
*filep
;
387 register struct inclist
*file_red
;
388 register struct symhash
*symbols
;
390 global_symbols
= symbols
; /* HACK! see above */
391 if (cppsetup(exp
, filep
, file_red
))
397 void define( def
, symbols
)
399 struct symhash
**symbols
;
403 /* Separate symbol name and its value */
405 while (isalnum(*val
) || *val
== '_')
409 while (*val
== ' ' || *val
== '\t')
414 hash_define( def
, val
, symbols
);
417 static int hash( str
)
420 /* Hash (Kernighan and Ritchie) */
421 register unsigned int hashval
= 0;
424 for ( ; *str
; str
++ )
426 hashval
= ( hashval
* SYMHASHSEED
) + ( *str
);
429 //fprintf( stderr, "hash: %s, %d\n", s, hashval & ( SYMHASHMEMBERS - 1 ) );
430 return hashval
& ( SYMHASHMEMBERS
- 1 );
433 struct symhash
*hash_copy( symbols
)
434 struct symhash
*symbols
;
437 struct symhash
*newsym
;
441 newsym
= (struct symhash
*) malloc( sizeof( struct symhash
) );
443 for ( i
= 0; i
< SYMHASHMEMBERS
; ++i
)
445 if ( !symbols
->s_pairs
[ i
] )
446 newsym
->s_pairs
[ i
] = NULL
;
449 struct pair
*it
= symbols
->s_pairs
[ i
];
450 struct pair
*nw
= newsym
->s_pairs
[ i
] = (struct pair
*) malloc( sizeof( struct pair
) );
451 nw
->p_name
= it
->p_name
;
452 nw
->p_value
= it
->p_value
;
457 nw
->p_next
= (struct pair
*) malloc( sizeof( struct pair
) );
460 nw
->p_name
= it
->p_name
;
461 nw
->p_value
= it
->p_value
;
469 void hash_free( symbols
)
470 struct symhash
*symbols
;
477 for ( i
= 0; i
< SYMHASHMEMBERS
; ++i
)
479 struct pair
*it
= symbols
->s_pairs
[ i
];
488 free( symbols
->s_pairs
);
491 void hash_define( name
, val
, symbols
)
493 struct symhash
**symbols
;
501 /* Make space if it's needed */
502 if ( *symbols
== NULL
)
506 *symbols
= (struct symhash
*) malloc( sizeof( struct symhash
) );
507 if ( *symbols
== NULL
)
508 fatalerr( "malloc()/realloc() failure in insert_defn()\n" );
510 for ( i
= 0; i
< SYMHASHMEMBERS
; ++i
)
511 (*symbols
)->s_pairs
[i
] = NULL
;
514 hashval
= hash( name
);
515 it
= (*symbols
)->s_pairs
[ hashval
];
517 /* Replace/insert the symbol */
520 it
= (*symbols
)->s_pairs
[ hashval
] = (struct pair
*) malloc( sizeof( struct pair
) );
521 it
->p_name
= copy( name
);
522 it
->p_value
= copy( val
);
525 else if ( strcmp( it
->p_name
, name
) == 0 )
527 it
->p_value
= copy( val
);
531 while ( it
->p_next
&& ( strcmp( it
->p_next
->p_name
, name
) != 0 ) )
536 it
->p_next
->p_name
= copy( name
);
539 it
->p_next
= (struct pair
*) malloc( sizeof( struct pair
) );
540 it
->p_next
->p_name
= copy( name
);
541 it
->p_next
->p_value
= copy( val
);
542 it
->p_next
->p_next
= NULL
;
547 char *hash_lookup( symbol
, symbols
)
549 struct symhash
*symbols
;
556 it
= symbols
->s_pairs
[ hash( symbol
) ];
558 while ( it
&& ( strcmp( it
->p_name
, symbol
) != 0 ) )
568 void hash_undefine( symbol
, symbols
)
570 struct symhash
*symbols
;
578 hashval
= hash( symbol
);
579 it
= symbols
->s_pairs
[ hashval
];
581 /* Replace/insert the symbol */
584 else if ( strcmp( it
->p_name
, symbol
) == 0 )
589 it
->p_name
= it
->p_next
->p_name
;
590 it
->p_value
= it
->p_next
->p_value
;
591 tmp
= it
->p_next
->p_next
;
598 symbols
->s_pairs
[ hashval
] = NULL
;
603 while ( it
->p_next
&& ( strcmp( it
->p_next
->p_name
, symbol
) != 0 ) )
609 struct pair
*tmp
= it
->p_next
;
610 it
->p_next
= it
->p_next
->p_next
;