1 #include <stdlib.h>
2 #include <string.h>
3 #include "cpp.h"
4 
5 #define	NSTAK	32
6 #define	SGN	0
7 #define	UNS	1
8 #define	UND	2
9 
10 #define	UNSMARK	0x1000
11 
12 struct value {
13 	long	val;
14 	int	type;
15 };
16 
17 /* conversion types */
18 #define	RELAT	1
19 #define	ARITH	2
20 #define	LOGIC	3
21 #define	SPCL	4
22 #define	SHIFT	5
23 #define	UNARY	6
24 
25 /* operator priority, arity, and conversion type, indexed by tokentype */
26 struct pri {
27 	char	pri;
28 	char	arity;
29 	char	ctype;
30 } priority[] = {
31 	{ 0, 0, 0 },		/* END */
32 	{ 0, 0, 0 },		/* UNCLASS */
33 	{ 0, 0, 0 },		/* NAME */
34 	{ 0, 0, 0 },		/* NUMBER */
35 	{ 0, 0, 0 },		/* STRING */
36 	{ 0, 0, 0 },		/* CCON */
37 	{ 0, 0, 0 },		/* NL */
38 	{ 0, 0, 0 },		/* WS */
39 	{ 0, 0, 0 },		/* DSHARP */
40 	{ 11, 2, RELAT },	/* EQ */
41 	{ 11, 2, RELAT },	/* NEQ */
42 	{ 12, 2, RELAT },	/* LEQ */
43 	{ 12, 2, RELAT },	/* GEQ */
44 	{ 13, 2, SHIFT },	/* LSH */
45 	{ 13, 2, SHIFT },	/* RSH */
46 	{ 7, 2, LOGIC },	/* LAND */
47 	{ 6, 2, LOGIC },	/* LOR */
48 	{ 0, 0, 0 },		/* PPLUS */
49 	{ 0, 0, 0 },		/* MMINUS */
50 	{ 0, 0, 0 },		/* ARROW */
51 	{ 0, 0, 0 },		/* SBRA */
52 	{ 0, 0, 0 },		/* SKET */
53 	{ 3, 0, 0 },		/* LP */
54 	{ 3, 0, 0 },		/* RP */
55 	{ 0, 0, 0 },		/* DOT */
56 	{ 10, 2, ARITH },	/* AND */
57 	{ 15, 2, ARITH },	/* STAR */
58 	{ 14, 2, ARITH },	/* PLUS */
59 	{ 14, 2, ARITH },	/* MINUS */
60 	{ 16, 1, UNARY },	/* TILDE */
61 	{ 16, 1, UNARY },	/* NOT */
62 	{ 15, 2, ARITH },	/* SLASH */
63 	{ 15, 2, ARITH },	/* PCT */
64 	{ 12, 2, RELAT },	/* LT */
65 	{ 12, 2, RELAT },	/* GT */
66 	{ 9, 2, ARITH },	/* CIRC */
67 	{ 8, 2, ARITH },	/* OR */
68 	{ 5, 2, SPCL },		/* QUEST */
69 	{ 5, 2, SPCL },		/* COLON */
70 	{ 0, 0, 0 },		/* ASGN */
71 	{ 4, 2, 0 },		/* COMMA */
72 	{ 0, 0, 0 },		/* SHARP */
73 	{ 0, 0, 0 },		/* SEMIC */
74 	{ 0, 0, 0 },		/* CBRA */
75 	{ 0, 0, 0 },		/* CKET */
76 	{ 0, 0, 0 },		/* ASPLUS */
77  	{ 0, 0, 0 },		/* ASMINUS */
78  	{ 0, 0, 0 },		/* ASSTAR */
79  	{ 0, 0, 0 },		/* ASSLASH */
80  	{ 0, 0, 0 },		/* ASPCT */
81  	{ 0, 0, 0 },		/* ASCIRC */
82  	{ 0, 0, 0 },		/* ASLSH */
83 	{ 0, 0, 0 },		/* ASRSH */
84  	{ 0, 0, 0 },		/* ASOR */
85  	{ 0, 0, 0 },		/* ASAND */
86 	{ 0, 0, 0 },		/* ELLIPS */
87 	{ 0, 0, 0 },		/* DSHARP1 */
88 	{ 0, 0, 0 },		/* NAME1 */
89 	{ 16, 1, UNARY },	/* DEFINED */
90 	{ 16, 0, UNARY },	/* UMINUS */
91 };
92 
93 int	evalop(struct pri);
94 struct	value tokval(Token *);
95 struct value vals[NSTAK], *vp;
96 enum toktype ops[NSTAK], *op;
97 
98 /*
99  * Evaluate an #if #elif #ifdef #ifndef line.  trp->tp points to the keyword.
100  */
101 long
eval(Tokenrow * trp,int kw)102 eval(Tokenrow *trp, int kw)
103 {
104 	Token *tp;
105 	Nlist *np;
106 	int ntok, rand;
107 
108 	trp->tp++;
109 	if (kw==KIFDEF || kw==KIFNDEF) {
110 		if (trp->lp - trp->bp != 4 || trp->tp->type!=NAME) {
111 			error(ERROR, "Syntax error in #ifdef/#ifndef");
112 			return 0;
113 		}
114 		np = lookup(trp->tp, 0);
115 		return (kw==KIFDEF) == (np && np->flag&(ISDEFINED|ISMAC));
116 	}
117 	ntok = trp->tp - trp->bp;
118 	kwdefined->val = KDEFINED;	/* activate special meaning of defined */
119 	expandrow(trp, "<if>");
120 	kwdefined->val = NAME;
121 	vp = vals;
122 	op = ops;
123 	*op++ = END;
124 	for (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) {
125 		switch(tp->type) {
126 		case WS:
127 		case NL:
128 			continue;
129 
130 		/* nilary */
131 		case NAME:
132 		case NAME1:
133 		case NUMBER:
134 		case CCON:
135 		case STRING:
136 			if (rand)
137 				goto syntax;
138 			*vp++ = tokval(tp);
139 			rand = 1;
140 			continue;
141 
142 		/* unary */
143 		case DEFINED:
144 		case TILDE:
145 		case NOT:
146 			if (rand)
147 				goto syntax;
148 			*op++ = tp->type;
149 			continue;
150 
151 		/* unary-binary */
152 		case PLUS: case MINUS: case STAR: case AND:
153 			if (rand==0) {
154 				if (tp->type==MINUS)
155 					*op++ = UMINUS;
156 				if (tp->type==STAR || tp->type==AND) {
157 					error(ERROR, "Illegal operator * or & in #if/#elsif");
158 					return 0;
159 				}
160 				continue;
161 			}
162 			/* flow through */
163 
164 		/* plain binary */
165 		case EQ: case NEQ: case LEQ: case GEQ: case LSH: case RSH:
166 		case LAND: case LOR: case SLASH: case PCT:
167 		case LT: case GT: case CIRC: case OR: case QUEST:
168 		case COLON: case COMMA:
169 			if (rand==0)
170 				goto syntax;
171 			if (evalop(priority[tp->type])!=0)
172 				return 0;
173 			*op++ = tp->type;
174 			rand = 0;
175 			continue;
176 
177 		case LP:
178 			if (rand)
179 				goto syntax;
180 			*op++ = LP;
181 			continue;
182 
183 		case RP:
184 			if (!rand)
185 				goto syntax;
186 			if (evalop(priority[RP])!=0)
187 				return 0;
188 			if (op<=ops || op[-1]!=LP) {
189 				goto syntax;
190 			}
191 			op--;
192 			continue;
193 
194 		default:
195 			error(ERROR,"Bad operator (%t) in #if/#elsif", tp);
196 			return 0;
197 		}
198 	}
199 	if (rand==0)
200 		goto syntax;
201 	if (evalop(priority[END])!=0)
202 		return 0;
203 	if (op!=&ops[1] || vp!=&vals[1]) {
204 		error(ERROR, "Botch in #if/#elsif");
205 		return 0;
206 	}
207 	if (vals[0].type==UND)
208 		error(ERROR, "Undefined expression value");
209 	return vals[0].val;
210 syntax:
211 	error(ERROR, "Syntax error in #if/#elsif");
212 	return 0;
213 }
214 
215 int
evalop(struct pri pri)216 evalop(struct pri pri)
217 {
218 	struct value v1, v2;
219 	long rv1, rv2;
220 	int rtype, oper;
221 
222 	/* prevent compiler whining. */
223 	v1.val = v2.val = 0;
224 	v1.type = v2.type = 0;
225 
226 	rv2=0;
227 	rtype=0;
228 	while (pri.pri < priority[op[-1]].pri) {
229 		oper = *--op;
230 		if (priority[oper].arity==2) {
231 			v2 = *--vp;
232 			rv2 = v2.val;
233 		}
234 		v1 = *--vp;
235 		rv1 = v1.val;
236 /*lint -e574 -e644 */
237 		switch (priority[oper].ctype) {
238 		case 0:
239 		default:
240 			error(WARNING, "Syntax error in #if/#endif");
241 			return 1;
242 		case ARITH:
243 		case RELAT:
244 			if (v1.type==UNS || v2.type==UNS)
245 				rtype = UNS;
246 			else
247 				rtype = SGN;
248 			if (v1.type==UND || v2.type==UND)
249 				rtype = UND;
250 			if (priority[oper].ctype==RELAT && rtype==UNS) {
251 				oper |= UNSMARK;
252 				rtype = SGN;
253 			}
254 			break;
255 		case SHIFT:
256 			if (v1.type==UND || v2.type==UND)
257 				rtype = UND;
258 			else
259 				rtype = v1.type;
260 			if (rtype==UNS)
261 				oper |= UNSMARK;
262 			break;
263 		case UNARY:
264 			rtype = v1.type;
265 			break;
266 		case LOGIC:
267 		case SPCL:
268 			break;
269 		}
270 		switch (oper) {
271 		case EQ: case EQ|UNSMARK:
272 			rv1 = rv1==rv2; break;
273 		case NEQ: case NEQ|UNSMARK:
274 			rv1 = rv1!=rv2; break;
275 		case LEQ:
276 			rv1 = rv1<=rv2; break;
277 		case GEQ:
278 			rv1 = rv1>=rv2; break;
279 		case LT:
280 			rv1 = rv1<rv2; break;
281 		case GT:
282 			rv1 = rv1>rv2; break;
283 		case LEQ|UNSMARK:
284 			rv1 = (unsigned long)rv1<=rv2; break;
285 		case GEQ|UNSMARK:
286 			rv1 = (unsigned long)rv1>=rv2; break;
287 		case LT|UNSMARK:
288 			rv1 = (unsigned long)rv1<rv2; break;
289 		case GT|UNSMARK:
290 			rv1 = (unsigned long)rv1>rv2; break;
291 		case LSH:
292 			rv1 <<= rv2; break;
293 		case LSH|UNSMARK:
294 			rv1 = (unsigned long)rv1<<rv2; break;
295 		case RSH:
296 			rv1 >>= rv2; break;
297 		case RSH|UNSMARK:
298 			rv1 = (unsigned long)rv1>>rv2; break;
299 		case LAND:
300 			rtype = UND;
301 			if (v1.type==UND)
302 				break;
303 			if (rv1!=0) {
304 				if (v2.type==UND)
305 					break;
306 				rv1 = rv2!=0;
307 			} else
308 				rv1 = 0;
309 			rtype = SGN;
310 			break;
311 		case LOR:
312 			rtype = UND;
313 			if (v1.type==UND)
314 				break;
315 			if (rv1==0) {
316 				if (v2.type==UND)
317 					break;
318 				rv1 = rv2!=0;
319 			} else
320 				rv1 = 1;
321 			rtype = SGN;
322 			break;
323 		case AND:
324 			rv1 &= rv2; break;
325 		case STAR:
326 			rv1 *= rv2; break;
327 		case PLUS:
328 			rv1 += rv2; break;
329 		case MINUS:
330 			rv1 -= rv2; break;
331 		case UMINUS:
332 			if (v1.type==UND)
333 				rtype = UND;
334 			rv1 = -rv1; break;
335 		case OR:
336 			rv1 |= rv2; break;
337 		case CIRC:
338 			rv1 ^= rv2; break;
339 		case TILDE:
340 			rv1 = ~rv1; break;
341 		case NOT:
342 			rv1 = !rv1; if (rtype!=UND) rtype = SGN; break;
343 		case SLASH:
344 			if (rv2==0) {
345 				rtype = UND;
346 				break;
347 			}
348 			if (rtype==UNS)
349 				rv1 /= (unsigned long)rv2;
350 			else
351 				rv1 /= rv2;
352 			break;
353 		case PCT:
354 			if (rv2==0) {
355 				rtype = UND;
356 				break;
357 			}
358 			if (rtype==UNS)
359 				rv1 %= (unsigned long)rv2;
360 			else
361 				rv1 %= rv2;
362 			break;
363 		case COLON:
364 			if (op[-1] != QUEST)
365 				error(ERROR, "Bad ?: in #if/endif");
366 			else {
367 				op--;
368 				if ((--vp)->val==0)
369 					v1 = v2;
370 				rtype = v1.type;
371 				rv1 = v1.val;
372 			}
373 			break;
374 		case DEFINED:
375 			break;
376 		default:
377 			error(ERROR, "Eval botch (unknown operator)");
378 			return 1;
379 		}
380 /*lint +e574 +e644 */
381 		v1.val = rv1;
382 		v1.type = rtype;
383 		*vp++ = v1;
384 	}
385 	return 0;
386 }
387 
388 struct value
tokval(Token * tp)389 tokval(Token *tp)
390 {
391 	struct value v;
392 	Nlist *np;
393 	int i, base, c;
394 	unsigned long n;
395 	uchar *p;
396 
397 	v.type = SGN;
398 	v.val = 0;
399 	switch (tp->type) {
400 
401 	case NAME:
402 		v.val = 0;
403 		break;
404 
405 	case NAME1:
406 		if ((np = lookup(tp, 0)) != NULL && np->flag&(ISDEFINED|ISMAC))
407 			v.val = 1;
408 		break;
409 
410 	case NUMBER:
411 		n = 0;
412 		base = 10;
413 		p = tp->t;
414 		c = p[tp->len];
415 		p[tp->len] = '\0';
416 		if (*p=='0') {
417 			base = 8;
418 			if (p[1]=='x' || p[1]=='X') {
419 				base = 16;
420 				p++;
421 			}
422 			p++;
423 		}
424 		for (;; p++) {
425 			if ((i = digit(*p)) < 0)
426 				break;
427 			if (i>=base)
428 				error(WARNING,
429 				  "Bad digit in number %t", tp);
430 			n *= base;
431 			n += i;
432 		}
433 		if (n>=0x80000000 && base!=10)
434 			v.type = UNS;
435 		for (; *p; p++) {
436 			if (*p=='u' || *p=='U')
437 				v.type = UNS;
438 			else if (*p=='l' || *p=='L')
439 				;
440 			else {
441 				error(ERROR,
442 				  "Bad number %t in #if/#elsif", tp);
443 				break;
444 			}
445 		}
446 		v.val = n;
447 		tp->t[tp->len] = c;
448 		break;
449 
450 	case CCON:
451 		n = 0;
452 		p = tp->t;
453 		if (*p=='L') {
454 			p += 1;
455 			error(WARNING, "Wide char constant value undefined");
456 		}
457 		p += 1;
458 		if (*p=='\\') {
459 			p += 1;
460 			if ((i = digit(*p))>=0 && i<=7) {
461 				n = i;
462 				p += 1;
463 				if ((i = digit(*p))>=0 && i<=7) {
464 					p += 1;
465 					n <<= 3;
466 					n += i;
467 					if ((i = digit(*p))>=0 && i<=7) {
468 						p += 1;
469 						n <<= 3;
470 						n += i;
471 					}
472 				}
473 			} else if (*p=='x') {
474 				p += 1;
475 				while ((i = digit(*p))>=0 && i<=15) {
476 					p += 1;
477 					n <<= 4;
478 					n += i;
479 				}
480 			} else {
481 				static char cvcon[]
482 				  = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\";
483 				for (i=0; i<sizeof(cvcon); i+=2) {
484 					if (*p == cvcon[i]) {
485 						n = cvcon[i+1];
486 						break;
487 					}
488 				}
489 				p += 1;
490 				if (i>=sizeof(cvcon))
491 					error(WARNING,
492 					 "Undefined escape in character constant");
493 			}
494 		} else if (*p=='\'')
495 			error(ERROR, "Empty character constant");
496 		else
497 			n = *p++;
498 		if (*p!='\'')
499 			error(WARNING, "Multibyte character constant undefined");
500 		else if (n>127)
501 			error(WARNING, "Character constant taken as not signed");
502 		v.val = n;
503 		break;
504 
505 	case STRING:
506 		error(ERROR, "String in #if/#elsif");
507 		break;
508 	}
509 	return v;
510 }
511 
512 int
digit(int i)513 digit(int i)
514 {
515 	if ('0'<=i && i<='9')
516 		i -= '0';
517 	else if ('a'<=i && i<='f')
518 		i -= 'a'-10;
519 	else if ('A'<=i && i<='F')
520 		i -= 'A'-10;
521 	else
522 		i = -1;
523 	return i;
524 }
525