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