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