xref: /aoo4110/main/soltools/mkdepend/ifparser.c (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /*
2*b1cdbd2cSJim Jagielski  * $XConsortium: ifparser.c,v 1.8 95/06/03 00:01:41 gildea Exp $
3*b1cdbd2cSJim Jagielski  *
4*b1cdbd2cSJim Jagielski  * Copyright 1992 Network Computing Devices, Inc.
5*b1cdbd2cSJim Jagielski  *
6*b1cdbd2cSJim Jagielski  * Permission to use, copy, modify, and distribute this software and its
7*b1cdbd2cSJim Jagielski  * documentation for any purpose and without fee is hereby granted, provided
8*b1cdbd2cSJim Jagielski  * that the above copyright notice appear in all copies and that both that
9*b1cdbd2cSJim Jagielski  * copyright notice and this permission notice appear in supporting
10*b1cdbd2cSJim Jagielski  * documentation, and that the name of Network Computing Devices may not be
11*b1cdbd2cSJim Jagielski  * used in advertising or publicity pertaining to distribution of the software
12*b1cdbd2cSJim Jagielski  * without specific, written prior permission.  Network Computing Devices makes
13*b1cdbd2cSJim Jagielski  * no representations about the suitability of this software for any purpose.
14*b1cdbd2cSJim Jagielski  * It is provided ``as is'' without express or implied warranty.
15*b1cdbd2cSJim Jagielski  *
16*b1cdbd2cSJim Jagielski  * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17*b1cdbd2cSJim Jagielski  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
18*b1cdbd2cSJim Jagielski  * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
19*b1cdbd2cSJim Jagielski  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
20*b1cdbd2cSJim Jagielski  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
21*b1cdbd2cSJim Jagielski  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22*b1cdbd2cSJim Jagielski  * PERFORMANCE OF THIS SOFTWARE.
23*b1cdbd2cSJim Jagielski  *
24*b1cdbd2cSJim Jagielski  * Author:  Jim Fulton
25*b1cdbd2cSJim Jagielski  *          Network Computing Devices, Inc.
26*b1cdbd2cSJim Jagielski  *
27*b1cdbd2cSJim Jagielski  * Simple if statement processor
28*b1cdbd2cSJim Jagielski  *
29*b1cdbd2cSJim Jagielski  * This module can be used to evaluate string representations of C language
30*b1cdbd2cSJim Jagielski  * if constructs.  It accepts the following grammar:
31*b1cdbd2cSJim Jagielski  *
32*b1cdbd2cSJim Jagielski  *     EXPRESSION	:=	VALUE
33*b1cdbd2cSJim Jagielski  * 			 |	VALUE  BINOP	EXPRESSION
34*b1cdbd2cSJim Jagielski  *
35*b1cdbd2cSJim Jagielski  *     VALUE		:=	'('  EXPRESSION  ')'
36*b1cdbd2cSJim Jagielski  * 			 |	'!'  VALUE
37*b1cdbd2cSJim Jagielski  * 			 |	'-'  VALUE
38*b1cdbd2cSJim Jagielski  * 			 |	'defined'  '('  variable  ')'
39*b1cdbd2cSJim Jagielski  * 			 |	'defined'  variable
40*b1cdbd2cSJim Jagielski  *			 |	# variable '(' variable-list ')'
41*b1cdbd2cSJim Jagielski  * 			 |	variable
42*b1cdbd2cSJim Jagielski  * 			 |	number
43*b1cdbd2cSJim Jagielski  *
44*b1cdbd2cSJim Jagielski  *     BINOP		:=	'*'	|  '/'	|  '%'
45*b1cdbd2cSJim Jagielski  * 			 |	'+'	|  '-'
46*b1cdbd2cSJim Jagielski  * 			 |	'<<'	|  '>>'
47*b1cdbd2cSJim Jagielski  * 			 |	'<'	|  '>'	|  '<='  |  '>='
48*b1cdbd2cSJim Jagielski  * 			 |	'=='	|  '!='
49*b1cdbd2cSJim Jagielski  * 			 |	'&'	|  '|'
50*b1cdbd2cSJim Jagielski  * 			 |	'&&'	|  '||'
51*b1cdbd2cSJim Jagielski  *
52*b1cdbd2cSJim Jagielski  * The normal C order of precidence is supported.
53*b1cdbd2cSJim Jagielski  *
54*b1cdbd2cSJim Jagielski  *
55*b1cdbd2cSJim Jagielski  * External Entry Points:
56*b1cdbd2cSJim Jagielski  *
57*b1cdbd2cSJim Jagielski  *     ParseIfExpression		parse a string for #if
58*b1cdbd2cSJim Jagielski  */
59*b1cdbd2cSJim Jagielski 
60*b1cdbd2cSJim Jagielski #include "ifparser.h"
61*b1cdbd2cSJim Jagielski #include <ctype.h>
62*b1cdbd2cSJim Jagielski #include <stdlib.h>
63*b1cdbd2cSJim Jagielski #include <string.h>
64*b1cdbd2cSJim Jagielski 
65*b1cdbd2cSJim Jagielski /****************************************************************************
66*b1cdbd2cSJim Jagielski 		   Internal Macros and Utilities for Parser
67*b1cdbd2cSJim Jagielski  ****************************************************************************/
68*b1cdbd2cSJim Jagielski 
69*b1cdbd2cSJim Jagielski #define DO(val) if (!(val)) return NULL
70*b1cdbd2cSJim Jagielski #define CALLFUNC(ggg,fff) (*((ggg)->funcs.fff))
71*b1cdbd2cSJim Jagielski #define SKIPSPACE(ccc) while (isspace(*ccc)) ccc++
72*b1cdbd2cSJim Jagielski #define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_')
73*b1cdbd2cSJim Jagielski 
74*b1cdbd2cSJim Jagielski 
75*b1cdbd2cSJim Jagielski static const char *
parse_variable(g,cp,varp)76*b1cdbd2cSJim Jagielski parse_variable (g, cp, varp)
77*b1cdbd2cSJim Jagielski     IfParser *g;
78*b1cdbd2cSJim Jagielski     const char *cp;
79*b1cdbd2cSJim Jagielski     const char **varp;
80*b1cdbd2cSJim Jagielski {
81*b1cdbd2cSJim Jagielski     SKIPSPACE (cp);
82*b1cdbd2cSJim Jagielski 
83*b1cdbd2cSJim Jagielski     if (!isvarfirstletter (*cp))
84*b1cdbd2cSJim Jagielski 	return CALLFUNC(g, handle_error) (g, cp, "variable name");
85*b1cdbd2cSJim Jagielski 
86*b1cdbd2cSJim Jagielski     *varp = cp;
87*b1cdbd2cSJim Jagielski     /* EMPTY */
88*b1cdbd2cSJim Jagielski     for (cp++; isalnum(*cp) || *cp == '_'; cp++) ;
89*b1cdbd2cSJim Jagielski     return cp;
90*b1cdbd2cSJim Jagielski }
91*b1cdbd2cSJim Jagielski 
92*b1cdbd2cSJim Jagielski 
93*b1cdbd2cSJim Jagielski static const char *
parse_number(g,cp,valp)94*b1cdbd2cSJim Jagielski parse_number (g, cp, valp)
95*b1cdbd2cSJim Jagielski     IfParser *g;
96*b1cdbd2cSJim Jagielski     const char *cp;
97*b1cdbd2cSJim Jagielski     int *valp;
98*b1cdbd2cSJim Jagielski {
99*b1cdbd2cSJim Jagielski     SKIPSPACE (cp);
100*b1cdbd2cSJim Jagielski 
101*b1cdbd2cSJim Jagielski     if (!isdigit(*cp))
102*b1cdbd2cSJim Jagielski 	return CALLFUNC(g, handle_error) (g, cp, "number");
103*b1cdbd2cSJim Jagielski 
104*b1cdbd2cSJim Jagielski #ifdef WIN32
105*b1cdbd2cSJim Jagielski     *valp = strtol(cp, &cp, 0);
106*b1cdbd2cSJim Jagielski #else
107*b1cdbd2cSJim Jagielski     *valp = atoi (cp);
108*b1cdbd2cSJim Jagielski     /* EMPTY */
109*b1cdbd2cSJim Jagielski     for (cp++; isdigit(*cp); cp++) ;
110*b1cdbd2cSJim Jagielski #endif
111*b1cdbd2cSJim Jagielski     return cp;
112*b1cdbd2cSJim Jagielski }
113*b1cdbd2cSJim Jagielski 
114*b1cdbd2cSJim Jagielski 
115*b1cdbd2cSJim Jagielski static const char *
parse_value(g,cp,valp)116*b1cdbd2cSJim Jagielski parse_value (g, cp, valp)
117*b1cdbd2cSJim Jagielski     IfParser *g;
118*b1cdbd2cSJim Jagielski     const char *cp;
119*b1cdbd2cSJim Jagielski     int *valp;
120*b1cdbd2cSJim Jagielski {
121*b1cdbd2cSJim Jagielski     const char *var;
122*b1cdbd2cSJim Jagielski 
123*b1cdbd2cSJim Jagielski     *valp = 0;
124*b1cdbd2cSJim Jagielski 
125*b1cdbd2cSJim Jagielski     SKIPSPACE (cp);
126*b1cdbd2cSJim Jagielski     if (!*cp)
127*b1cdbd2cSJim Jagielski 	return cp;
128*b1cdbd2cSJim Jagielski 
129*b1cdbd2cSJim Jagielski     switch (*cp) {
130*b1cdbd2cSJim Jagielski       case '(':
131*b1cdbd2cSJim Jagielski 	DO (cp = ParseIfExpression (g, cp + 1, valp));
132*b1cdbd2cSJim Jagielski 	SKIPSPACE (cp);
133*b1cdbd2cSJim Jagielski 	if (*cp != ')')
134*b1cdbd2cSJim Jagielski 	    return CALLFUNC(g, handle_error) (g, cp, ")");
135*b1cdbd2cSJim Jagielski 
136*b1cdbd2cSJim Jagielski 	return cp + 1;			/* skip the right paren */
137*b1cdbd2cSJim Jagielski 
138*b1cdbd2cSJim Jagielski       case '!':
139*b1cdbd2cSJim Jagielski 	DO (cp = parse_value (g, cp + 1, valp));
140*b1cdbd2cSJim Jagielski 	*valp = !(*valp);
141*b1cdbd2cSJim Jagielski 	return cp;
142*b1cdbd2cSJim Jagielski 
143*b1cdbd2cSJim Jagielski       case '-':
144*b1cdbd2cSJim Jagielski 	DO (cp = parse_value (g, cp + 1, valp));
145*b1cdbd2cSJim Jagielski 	*valp = -(*valp);
146*b1cdbd2cSJim Jagielski 	return cp;
147*b1cdbd2cSJim Jagielski 
148*b1cdbd2cSJim Jagielski       case '#':
149*b1cdbd2cSJim Jagielski 	DO (cp = parse_variable (g, cp + 1, &var));
150*b1cdbd2cSJim Jagielski 	SKIPSPACE (cp);
151*b1cdbd2cSJim Jagielski 	if (*cp != '(')
152*b1cdbd2cSJim Jagielski 	    return CALLFUNC(g, handle_error) (g, cp, "(");
153*b1cdbd2cSJim Jagielski 	do {
154*b1cdbd2cSJim Jagielski 	    DO (cp = parse_variable (g, cp + 1, &var));
155*b1cdbd2cSJim Jagielski 	    SKIPSPACE (cp);
156*b1cdbd2cSJim Jagielski 	} while (*cp && *cp != ')');
157*b1cdbd2cSJim Jagielski 	if (*cp != ')')
158*b1cdbd2cSJim Jagielski 	    return CALLFUNC(g, handle_error) (g, cp, ")");
159*b1cdbd2cSJim Jagielski 	*valp = 1; /* XXX */
160*b1cdbd2cSJim Jagielski 	return cp + 1;
161*b1cdbd2cSJim Jagielski 
162*b1cdbd2cSJim Jagielski       case 'd':
163*b1cdbd2cSJim Jagielski 	if (strncmp (cp, "defined", 7) == 0 && !isalnum(cp[7])) {
164*b1cdbd2cSJim Jagielski 	    int paren = 0;
165*b1cdbd2cSJim Jagielski 	    int len;
166*b1cdbd2cSJim Jagielski 
167*b1cdbd2cSJim Jagielski 	    cp += 7;
168*b1cdbd2cSJim Jagielski 	    SKIPSPACE (cp);
169*b1cdbd2cSJim Jagielski 	    if (*cp == '(') {
170*b1cdbd2cSJim Jagielski 		paren = 1;
171*b1cdbd2cSJim Jagielski 		cp++;
172*b1cdbd2cSJim Jagielski 	    }
173*b1cdbd2cSJim Jagielski 	    DO (cp = parse_variable (g, cp, &var));
174*b1cdbd2cSJim Jagielski 	    len = cp - var;
175*b1cdbd2cSJim Jagielski 	    SKIPSPACE (cp);
176*b1cdbd2cSJim Jagielski 	    if (paren && *cp != ')')
177*b1cdbd2cSJim Jagielski 		return CALLFUNC(g, handle_error) (g, cp, ")");
178*b1cdbd2cSJim Jagielski 	    *valp = (*(g->funcs.eval_defined)) (g, var, len);
179*b1cdbd2cSJim Jagielski 	    return cp + paren;		/* skip the right paren */
180*b1cdbd2cSJim Jagielski 	}
181*b1cdbd2cSJim Jagielski 	/* fall out */
182*b1cdbd2cSJim Jagielski     }
183*b1cdbd2cSJim Jagielski 
184*b1cdbd2cSJim Jagielski     if (isdigit(*cp)) {
185*b1cdbd2cSJim Jagielski 	DO (cp = parse_number (g, cp, valp));
186*b1cdbd2cSJim Jagielski     } else if (!isvarfirstletter(*cp))
187*b1cdbd2cSJim Jagielski 	return CALLFUNC(g, handle_error) (g, cp, "variable or number");
188*b1cdbd2cSJim Jagielski     else {
189*b1cdbd2cSJim Jagielski 	DO (cp = parse_variable (g, cp, &var));
190*b1cdbd2cSJim Jagielski 	*valp = (*(g->funcs.eval_variable)) (g, var, cp - var);
191*b1cdbd2cSJim Jagielski     }
192*b1cdbd2cSJim Jagielski 
193*b1cdbd2cSJim Jagielski     return cp;
194*b1cdbd2cSJim Jagielski }
195*b1cdbd2cSJim Jagielski 
196*b1cdbd2cSJim Jagielski 
197*b1cdbd2cSJim Jagielski 
198*b1cdbd2cSJim Jagielski static const char *
parse_product(g,cp,valp)199*b1cdbd2cSJim Jagielski parse_product (g, cp, valp)
200*b1cdbd2cSJim Jagielski     IfParser *g;
201*b1cdbd2cSJim Jagielski     const char *cp;
202*b1cdbd2cSJim Jagielski     int *valp;
203*b1cdbd2cSJim Jagielski {
204*b1cdbd2cSJim Jagielski     int rightval;
205*b1cdbd2cSJim Jagielski 
206*b1cdbd2cSJim Jagielski     DO (cp = parse_value (g, cp, valp));
207*b1cdbd2cSJim Jagielski     SKIPSPACE (cp);
208*b1cdbd2cSJim Jagielski 
209*b1cdbd2cSJim Jagielski     switch (*cp) {
210*b1cdbd2cSJim Jagielski       case '*':
211*b1cdbd2cSJim Jagielski 	DO (cp = parse_product (g, cp + 1, &rightval));
212*b1cdbd2cSJim Jagielski 	*valp = (*valp * rightval);
213*b1cdbd2cSJim Jagielski 	break;
214*b1cdbd2cSJim Jagielski 
215*b1cdbd2cSJim Jagielski       case '/':
216*b1cdbd2cSJim Jagielski 	DO (cp = parse_product (g, cp + 1, &rightval));
217*b1cdbd2cSJim Jagielski 
218*b1cdbd2cSJim Jagielski 	/* Do nothing in the divide-by-zero case. */
219*b1cdbd2cSJim Jagielski 	if (rightval) {
220*b1cdbd2cSJim Jagielski 		*valp = (*valp / rightval);
221*b1cdbd2cSJim Jagielski 	}
222*b1cdbd2cSJim Jagielski 	break;
223*b1cdbd2cSJim Jagielski 
224*b1cdbd2cSJim Jagielski       case '%':
225*b1cdbd2cSJim Jagielski 	DO (cp = parse_product (g, cp + 1, &rightval));
226*b1cdbd2cSJim Jagielski 	*valp = (*valp % rightval);
227*b1cdbd2cSJim Jagielski 	break;
228*b1cdbd2cSJim Jagielski     }
229*b1cdbd2cSJim Jagielski     return cp;
230*b1cdbd2cSJim Jagielski }
231*b1cdbd2cSJim Jagielski 
232*b1cdbd2cSJim Jagielski 
233*b1cdbd2cSJim Jagielski static const char *
parse_sum(g,cp,valp)234*b1cdbd2cSJim Jagielski parse_sum (g, cp, valp)
235*b1cdbd2cSJim Jagielski     IfParser *g;
236*b1cdbd2cSJim Jagielski     const char *cp;
237*b1cdbd2cSJim Jagielski     int *valp;
238*b1cdbd2cSJim Jagielski {
239*b1cdbd2cSJim Jagielski     int rightval;
240*b1cdbd2cSJim Jagielski 
241*b1cdbd2cSJim Jagielski     DO (cp = parse_product (g, cp, valp));
242*b1cdbd2cSJim Jagielski     SKIPSPACE (cp);
243*b1cdbd2cSJim Jagielski 
244*b1cdbd2cSJim Jagielski     switch (*cp) {
245*b1cdbd2cSJim Jagielski       case '+':
246*b1cdbd2cSJim Jagielski 	DO (cp = parse_sum (g, cp + 1, &rightval));
247*b1cdbd2cSJim Jagielski 	*valp = (*valp + rightval);
248*b1cdbd2cSJim Jagielski 	break;
249*b1cdbd2cSJim Jagielski 
250*b1cdbd2cSJim Jagielski       case '-':
251*b1cdbd2cSJim Jagielski 	DO (cp = parse_sum (g, cp + 1, &rightval));
252*b1cdbd2cSJim Jagielski 	*valp = (*valp - rightval);
253*b1cdbd2cSJim Jagielski 	break;
254*b1cdbd2cSJim Jagielski     }
255*b1cdbd2cSJim Jagielski     return cp;
256*b1cdbd2cSJim Jagielski }
257*b1cdbd2cSJim Jagielski 
258*b1cdbd2cSJim Jagielski 
259*b1cdbd2cSJim Jagielski static const char *
parse_shift(g,cp,valp)260*b1cdbd2cSJim Jagielski parse_shift (g, cp, valp)
261*b1cdbd2cSJim Jagielski     IfParser *g;
262*b1cdbd2cSJim Jagielski     const char *cp;
263*b1cdbd2cSJim Jagielski     int *valp;
264*b1cdbd2cSJim Jagielski {
265*b1cdbd2cSJim Jagielski     int rightval;
266*b1cdbd2cSJim Jagielski 
267*b1cdbd2cSJim Jagielski     DO (cp = parse_sum (g, cp, valp));
268*b1cdbd2cSJim Jagielski     SKIPSPACE (cp);
269*b1cdbd2cSJim Jagielski 
270*b1cdbd2cSJim Jagielski     switch (*cp) {
271*b1cdbd2cSJim Jagielski       case '<':
272*b1cdbd2cSJim Jagielski 	if (cp[1] == '<') {
273*b1cdbd2cSJim Jagielski 	    DO (cp = parse_shift (g, cp + 2, &rightval));
274*b1cdbd2cSJim Jagielski 	    *valp = (*valp << rightval);
275*b1cdbd2cSJim Jagielski 	}
276*b1cdbd2cSJim Jagielski 	break;
277*b1cdbd2cSJim Jagielski 
278*b1cdbd2cSJim Jagielski       case '>':
279*b1cdbd2cSJim Jagielski 	if (cp[1] == '>') {
280*b1cdbd2cSJim Jagielski 	    DO (cp = parse_shift (g, cp + 2, &rightval));
281*b1cdbd2cSJim Jagielski 	    *valp = (*valp >> rightval);
282*b1cdbd2cSJim Jagielski 	}
283*b1cdbd2cSJim Jagielski 	break;
284*b1cdbd2cSJim Jagielski     }
285*b1cdbd2cSJim Jagielski     return cp;
286*b1cdbd2cSJim Jagielski }
287*b1cdbd2cSJim Jagielski 
288*b1cdbd2cSJim Jagielski 
289*b1cdbd2cSJim Jagielski static const char *
parse_inequality(g,cp,valp)290*b1cdbd2cSJim Jagielski parse_inequality (g, cp, valp)
291*b1cdbd2cSJim Jagielski     IfParser *g;
292*b1cdbd2cSJim Jagielski     const char *cp;
293*b1cdbd2cSJim Jagielski     int *valp;
294*b1cdbd2cSJim Jagielski {
295*b1cdbd2cSJim Jagielski     int rightval;
296*b1cdbd2cSJim Jagielski 
297*b1cdbd2cSJim Jagielski     DO (cp = parse_shift (g, cp, valp));
298*b1cdbd2cSJim Jagielski     SKIPSPACE (cp);
299*b1cdbd2cSJim Jagielski 
300*b1cdbd2cSJim Jagielski     switch (*cp) {
301*b1cdbd2cSJim Jagielski       case '<':
302*b1cdbd2cSJim Jagielski 	if (cp[1] == '=') {
303*b1cdbd2cSJim Jagielski 	    DO (cp = parse_inequality (g, cp + 2, &rightval));
304*b1cdbd2cSJim Jagielski 	    *valp = (*valp <= rightval);
305*b1cdbd2cSJim Jagielski 	} else {
306*b1cdbd2cSJim Jagielski 	    DO (cp = parse_inequality (g, cp + 1, &rightval));
307*b1cdbd2cSJim Jagielski 	    *valp = (*valp < rightval);
308*b1cdbd2cSJim Jagielski 	}
309*b1cdbd2cSJim Jagielski 	break;
310*b1cdbd2cSJim Jagielski 
311*b1cdbd2cSJim Jagielski       case '>':
312*b1cdbd2cSJim Jagielski 	if (cp[1] == '=') {
313*b1cdbd2cSJim Jagielski 	    DO (cp = parse_inequality (g, cp + 2, &rightval));
314*b1cdbd2cSJim Jagielski 	    *valp = (*valp >= rightval);
315*b1cdbd2cSJim Jagielski 	} else {
316*b1cdbd2cSJim Jagielski 	    DO (cp = parse_inequality (g, cp + 1, &rightval));
317*b1cdbd2cSJim Jagielski 	    *valp = (*valp > rightval);
318*b1cdbd2cSJim Jagielski 	}
319*b1cdbd2cSJim Jagielski 	break;
320*b1cdbd2cSJim Jagielski     }
321*b1cdbd2cSJim Jagielski     return cp;
322*b1cdbd2cSJim Jagielski }
323*b1cdbd2cSJim Jagielski 
324*b1cdbd2cSJim Jagielski 
325*b1cdbd2cSJim Jagielski static const char *
parse_equality(g,cp,valp)326*b1cdbd2cSJim Jagielski parse_equality (g, cp, valp)
327*b1cdbd2cSJim Jagielski     IfParser *g;
328*b1cdbd2cSJim Jagielski     const char *cp;
329*b1cdbd2cSJim Jagielski     int *valp;
330*b1cdbd2cSJim Jagielski {
331*b1cdbd2cSJim Jagielski     int rightval;
332*b1cdbd2cSJim Jagielski 
333*b1cdbd2cSJim Jagielski     DO (cp = parse_inequality (g, cp, valp));
334*b1cdbd2cSJim Jagielski     SKIPSPACE (cp);
335*b1cdbd2cSJim Jagielski 
336*b1cdbd2cSJim Jagielski     switch (*cp) {
337*b1cdbd2cSJim Jagielski       case '=':
338*b1cdbd2cSJim Jagielski 	if (cp[1] == '=')
339*b1cdbd2cSJim Jagielski 	    cp++;
340*b1cdbd2cSJim Jagielski 	DO (cp = parse_equality (g, cp + 1, &rightval));
341*b1cdbd2cSJim Jagielski 	*valp = (*valp == rightval);
342*b1cdbd2cSJim Jagielski 	break;
343*b1cdbd2cSJim Jagielski 
344*b1cdbd2cSJim Jagielski       case '!':
345*b1cdbd2cSJim Jagielski 	if (cp[1] != '=')
346*b1cdbd2cSJim Jagielski 	    break;
347*b1cdbd2cSJim Jagielski 	DO (cp = parse_equality (g, cp + 2, &rightval));
348*b1cdbd2cSJim Jagielski 	*valp = (*valp != rightval);
349*b1cdbd2cSJim Jagielski 	break;
350*b1cdbd2cSJim Jagielski     }
351*b1cdbd2cSJim Jagielski     return cp;
352*b1cdbd2cSJim Jagielski }
353*b1cdbd2cSJim Jagielski 
354*b1cdbd2cSJim Jagielski 
355*b1cdbd2cSJim Jagielski static const char *
parse_band(g,cp,valp)356*b1cdbd2cSJim Jagielski parse_band (g, cp, valp)
357*b1cdbd2cSJim Jagielski     IfParser *g;
358*b1cdbd2cSJim Jagielski     const char *cp;
359*b1cdbd2cSJim Jagielski     int *valp;
360*b1cdbd2cSJim Jagielski {
361*b1cdbd2cSJim Jagielski     int rightval;
362*b1cdbd2cSJim Jagielski 
363*b1cdbd2cSJim Jagielski     DO (cp = parse_equality (g, cp, valp));
364*b1cdbd2cSJim Jagielski     SKIPSPACE (cp);
365*b1cdbd2cSJim Jagielski 
366*b1cdbd2cSJim Jagielski     switch (*cp) {
367*b1cdbd2cSJim Jagielski       case '&':
368*b1cdbd2cSJim Jagielski 	if (cp[1] != '&') {
369*b1cdbd2cSJim Jagielski 	    DO (cp = parse_band (g, cp + 1, &rightval));
370*b1cdbd2cSJim Jagielski 	    *valp = (*valp & rightval);
371*b1cdbd2cSJim Jagielski 	}
372*b1cdbd2cSJim Jagielski 	break;
373*b1cdbd2cSJim Jagielski     }
374*b1cdbd2cSJim Jagielski     return cp;
375*b1cdbd2cSJim Jagielski }
376*b1cdbd2cSJim Jagielski 
377*b1cdbd2cSJim Jagielski 
378*b1cdbd2cSJim Jagielski static const char *
parse_bor(g,cp,valp)379*b1cdbd2cSJim Jagielski parse_bor (g, cp, valp)
380*b1cdbd2cSJim Jagielski     IfParser *g;
381*b1cdbd2cSJim Jagielski     const char *cp;
382*b1cdbd2cSJim Jagielski     int *valp;
383*b1cdbd2cSJim Jagielski {
384*b1cdbd2cSJim Jagielski     int rightval;
385*b1cdbd2cSJim Jagielski 
386*b1cdbd2cSJim Jagielski     DO (cp = parse_band (g, cp, valp));
387*b1cdbd2cSJim Jagielski     SKIPSPACE (cp);
388*b1cdbd2cSJim Jagielski 
389*b1cdbd2cSJim Jagielski     switch (*cp) {
390*b1cdbd2cSJim Jagielski       case '|':
391*b1cdbd2cSJim Jagielski 	if (cp[1] != '|') {
392*b1cdbd2cSJim Jagielski 	    DO (cp = parse_bor (g, cp + 1, &rightval));
393*b1cdbd2cSJim Jagielski 	    *valp = (*valp | rightval);
394*b1cdbd2cSJim Jagielski 	}
395*b1cdbd2cSJim Jagielski 	break;
396*b1cdbd2cSJim Jagielski     }
397*b1cdbd2cSJim Jagielski     return cp;
398*b1cdbd2cSJim Jagielski }
399*b1cdbd2cSJim Jagielski 
400*b1cdbd2cSJim Jagielski 
401*b1cdbd2cSJim Jagielski static const char *
parse_land(g,cp,valp)402*b1cdbd2cSJim Jagielski parse_land (g, cp, valp)
403*b1cdbd2cSJim Jagielski     IfParser *g;
404*b1cdbd2cSJim Jagielski     const char *cp;
405*b1cdbd2cSJim Jagielski     int *valp;
406*b1cdbd2cSJim Jagielski {
407*b1cdbd2cSJim Jagielski     int rightval;
408*b1cdbd2cSJim Jagielski 
409*b1cdbd2cSJim Jagielski     DO (cp = parse_bor (g, cp, valp));
410*b1cdbd2cSJim Jagielski     SKIPSPACE (cp);
411*b1cdbd2cSJim Jagielski 
412*b1cdbd2cSJim Jagielski     switch (*cp) {
413*b1cdbd2cSJim Jagielski       case '&':
414*b1cdbd2cSJim Jagielski 	if (cp[1] != '&')
415*b1cdbd2cSJim Jagielski 	    return CALLFUNC(g, handle_error) (g, cp, "&&");
416*b1cdbd2cSJim Jagielski 	DO (cp = parse_land (g, cp + 2, &rightval));
417*b1cdbd2cSJim Jagielski 	*valp = (*valp && rightval);
418*b1cdbd2cSJim Jagielski 	break;
419*b1cdbd2cSJim Jagielski     }
420*b1cdbd2cSJim Jagielski     return cp;
421*b1cdbd2cSJim Jagielski }
422*b1cdbd2cSJim Jagielski 
423*b1cdbd2cSJim Jagielski 
424*b1cdbd2cSJim Jagielski static const char *
parse_lor(g,cp,valp)425*b1cdbd2cSJim Jagielski parse_lor (g, cp, valp)
426*b1cdbd2cSJim Jagielski     IfParser *g;
427*b1cdbd2cSJim Jagielski     const char *cp;
428*b1cdbd2cSJim Jagielski     int *valp;
429*b1cdbd2cSJim Jagielski {
430*b1cdbd2cSJim Jagielski     int rightval;
431*b1cdbd2cSJim Jagielski 
432*b1cdbd2cSJim Jagielski     DO (cp = parse_land (g, cp, valp));
433*b1cdbd2cSJim Jagielski     SKIPSPACE (cp);
434*b1cdbd2cSJim Jagielski 
435*b1cdbd2cSJim Jagielski     switch (*cp) {
436*b1cdbd2cSJim Jagielski       case '|':
437*b1cdbd2cSJim Jagielski 	if (cp[1] != '|')
438*b1cdbd2cSJim Jagielski 	    return CALLFUNC(g, handle_error) (g, cp, "||");
439*b1cdbd2cSJim Jagielski 	DO (cp = parse_lor (g, cp + 2, &rightval));
440*b1cdbd2cSJim Jagielski 	*valp = (*valp || rightval);
441*b1cdbd2cSJim Jagielski 	break;
442*b1cdbd2cSJim Jagielski     }
443*b1cdbd2cSJim Jagielski     return cp;
444*b1cdbd2cSJim Jagielski }
445*b1cdbd2cSJim Jagielski 
446*b1cdbd2cSJim Jagielski 
447*b1cdbd2cSJim Jagielski /****************************************************************************
448*b1cdbd2cSJim Jagielski 			     External Entry Points
449*b1cdbd2cSJim Jagielski  ****************************************************************************/
450*b1cdbd2cSJim Jagielski 
451*b1cdbd2cSJim Jagielski const char *
ParseIfExpression(g,cp,valp)452*b1cdbd2cSJim Jagielski ParseIfExpression (g, cp, valp)
453*b1cdbd2cSJim Jagielski     IfParser *g;
454*b1cdbd2cSJim Jagielski     const char *cp;
455*b1cdbd2cSJim Jagielski     int *valp;
456*b1cdbd2cSJim Jagielski {
457*b1cdbd2cSJim Jagielski     return parse_lor (g, cp, valp);
458*b1cdbd2cSJim Jagielski }
459*b1cdbd2cSJim Jagielski 
460*b1cdbd2cSJim Jagielski 
461