1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* $XConsortium: parse.c,v 1.30 94/04/17 20:10:38 gildea Exp $ */
5 Copyright (c) 1993, 1994 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
33 static char *hash_lookup( char *symbol
, struct symhash
*symbols
);
34 static int gobble( struct filepointer
*filep
, struct inclist
*file
,
35 struct inclist
*file_red
, struct symhash
*symbols
);
36 static int deftype ( char *line
, struct filepointer
*filep
, struct inclist
*file
,
37 int parse_it
, struct symhash
*symbols
);
38 static int zero_value(char const *exp
, struct symhash
*symbols
);
40 extern struct symhash
*maininclist
;
42 int find_includes(struct filepointer
*filep
, struct inclist
*file
, struct inclist
*file_red
, int recursion
, boolean failOK
, struct IncludesCollection
* incCollection
, struct symhash
*symbols
)
47 while ((line
= get_line(filep
))) {
48 type
= deftype(line
, filep
, file
, TRUE
, symbols
);
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
);
60 type
= gobble(filep
, file
, file_red
, symbols
);
63 else if ((type
== ELIFFALSE
) || (type
== ELIFGUESSFALSE
))
70 gobble(filep
, file
, file_red
, symbols
);
73 define(line
, &symbols
);
76 warning("%s: %d: %s\n", file_red
->i_file
,
81 warning("%s", file_red
->i_file
);
83 warning1(" (reading %s)", file
->i_file
);
84 warning1(", line %d: unknown directive == \"%s\"\n",
88 warning("%s", file_red
->i_file
);
90 warning1(" (reading %s)", file
->i_file
);
91 warning1(", line %d: incomplete include == \"%s\"\n",
96 // coverity[leaked_storage] - on purpose
100 int gobble(struct filepointer
*filep
,
101 struct inclist
*file
,
102 struct inclist
*file_red
,
103 struct symhash
*symbols
)
108 while ((line
= get_line(filep
))) {
109 type
= deftype(line
, filep
, file
, FALSE
, symbols
);
113 type
= gobble(filep
, file
, file_red
, symbols
);
114 while ((type
== ELIF
) || (type
== ELIFFALSE
) ||
115 (type
== ELIFGUESSFALSE
))
116 type
= gobble(filep
, file
, file_red
, symbols
);
125 warning("%s, line %d: unknown directive == \"%s\"\n",
126 file_red
->i_file
, filep
->f_line
, line
);
134 * Decide what type of # directive this line is.
136 int deftype (char *line
, struct filepointer
*filep
, struct inclist
* file
,
137 int parse_it
, struct symhash
*symbols
)
140 char *directive
, savechar
;
142 (void)file
; // used in DEBUG mode
145 * Parse the directive...
148 while (*directive
== ' ' || *directive
== '\t')
152 while (*p
>= 'a' && *p
<= 'z')
156 ret
= match(directive
, directives
);
159 /* If we don't recognize this compiler directive or we happen to just
160 * be gobbling up text while waiting for an #endif or #elif or #else
161 * in the case of an #elif we must check the zero_value and return an
162 * ELIF or an ELIFFALSE.
165 if (ret
== ELIF
&& !parse_it
)
167 while (*p
== ' ' || *p
== '\t')
170 * parse an expression.
172 debug(0,("%s, line %d: #elif %s ",
173 file
->i_file
, filep
->f_line
, p
));
174 ret
= zero_value(p
, symbols
);
177 debug(0,("false...\n"));
181 return ELIFGUESSFALSE
;
185 debug(0,("true...\n"));
190 if (ret
< 0 || ! parse_it
)
194 * now decide how to parse the directive, and do it.
196 while (*p
== ' ' || *p
== '\t')
201 * parse an expression.
203 ret
= zero_value(p
, symbols
);
204 debug(0,("%s, line %d: %s #if %s\n",
205 file
->i_file
, filep
->f_line
, ret
?"false":"true", p
));
209 debug(0,("%s, line %d: #%s\n",
210 file
->i_file
, filep
->f_line
, directives
[ret
]));
220 * HACK! - so that we do not have to introduce 'symbols' in each cppsetup.c
221 * function... It's safe, functions from cppsetup.c don't return here.
223 static struct symhash
*global_symbols
= NULL
;
225 char * isdefined( char *symbol
)
227 return hash_lookup( symbol
, global_symbols
);
231 * Return type based on if the #if expression evaluates to 0
233 int zero_value(char const *exp
, struct symhash
*symbols
)
235 global_symbols
= symbols
; /* HACK! see above */
242 void define( char *def
, struct symhash
**symbols
)
246 /* Separate symbol name and its value */
248 while (isalnum((unsigned char)*val
) || *val
== '_')
252 while (*val
== ' ' || *val
== '\t')
257 hash_define( def
, val
, symbols
);
260 static int hash( char *str
)
262 /* Hash (Kernighan and Ritchie) */
263 unsigned int hashval
= 0;
265 for ( ; *str
; str
++ )
267 hashval
= ( hashval
* SYMHASHSEED
) + ( *str
);
270 return hashval
& ( SYMHASHMEMBERS
- 1 );
273 struct symhash
*hash_copy( struct symhash
*symbols
)
276 struct symhash
*newsym
;
280 newsym
= (struct symhash
*) malloc( sizeof( struct symhash
) );
282 for ( i
= 0; i
< SYMHASHMEMBERS
; ++i
)
284 if ( !symbols
->s_pairs
[ i
] )
285 newsym
->s_pairs
[ i
] = NULL
;
288 struct pair
*it
= symbols
->s_pairs
[ i
];
289 struct pair
*nw
= newsym
->s_pairs
[ i
] = (struct pair
*) malloc( sizeof( struct pair
) );
290 nw
->p_name
= it
->p_name
;
291 nw
->p_value
= it
->p_value
;
296 nw
->p_next
= (struct pair
*) malloc( sizeof( struct pair
) );
299 nw
->p_name
= it
->p_name
;
300 nw
->p_value
= it
->p_value
;
308 void hash_free( struct symhash
*symbols
)
315 for ( i
= 0; i
< SYMHASHMEMBERS
; ++i
)
317 struct pair
*it
= symbols
->s_pairs
[ i
];
326 free( symbols
->s_pairs
);
329 void hash_define( char *name
, char const *val
, struct symhash
**symbols
)
337 /* Make space if it's needed */
338 if ( *symbols
== NULL
)
342 *symbols
= (struct symhash
*) malloc( sizeof( struct symhash
) );
343 if ( *symbols
== NULL
)
344 fatalerr( "malloc()/realloc() failure in insert_defn()\n" );
346 for ( i
= 0; i
< SYMHASHMEMBERS
; ++i
)
347 (*symbols
)->s_pairs
[i
] = NULL
;
350 hashval
= hash( name
);
351 it
= (*symbols
)->s_pairs
[ hashval
];
353 /* Replace/insert the symbol */
356 it
= (*symbols
)->s_pairs
[ hashval
] = (struct pair
*) malloc( sizeof( struct pair
) );
357 it
->p_name
= copy( name
);
358 it
->p_value
= copy( val
);
361 else if ( strcmp( it
->p_name
, name
) == 0 )
363 it
->p_value
= copy( val
);
367 while ( it
->p_next
&& ( strcmp( it
->p_next
->p_name
, name
) != 0 ) )
372 it
->p_next
->p_name
= copy( name
);
375 it
->p_next
= (struct pair
*) malloc( sizeof( struct pair
) );
376 it
->p_next
->p_name
= copy( name
);
377 it
->p_next
->p_value
= copy( val
);
378 it
->p_next
->p_next
= NULL
;
383 char *hash_lookup( char *symbol
, struct symhash
*symbols
)
390 it
= symbols
->s_pairs
[ hash( symbol
) ];
392 while ( it
&& ( strcmp( it
->p_name
, symbol
) != 0 ) )
402 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */