eval.c (9815B)
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 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 216 evalop(struct pri pri) 217 { 218 struct value v1, v2; 219 long rv1, rv2; 220 int rtype, oper; 221 222 rv2=0; 223 rtype=0; 224 while (pri.pri < priority[op[-1]].pri) { 225 oper = *--op; 226 if (priority[oper].arity==2) { 227 v2 = *--vp; 228 rv2 = v2.val; 229 } 230 v1 = *--vp; 231 rv1 = v1.val; 232 /*lint -e574 -e644 */ 233 switch (priority[oper].ctype) { 234 case 0: 235 default: 236 error(WARNING, "Syntax error in #if/#endif"); 237 return 1; 238 case ARITH: 239 case RELAT: 240 if (v1.type==UNS || v2.type==UNS) 241 rtype = UNS; 242 else 243 rtype = SGN; 244 if (v1.type==UND || v2.type==UND) 245 rtype = UND; 246 if (priority[oper].ctype==RELAT && rtype==UNS) { 247 oper |= UNSMARK; 248 rtype = SGN; 249 } 250 break; 251 case SHIFT: 252 if (v1.type==UND || v2.type==UND) 253 rtype = UND; 254 else 255 rtype = v1.type; 256 if (rtype==UNS) 257 oper |= UNSMARK; 258 break; 259 case UNARY: 260 rtype = v1.type; 261 break; 262 case LOGIC: 263 case SPCL: 264 break; 265 } 266 switch (oper) { 267 case EQ: case EQ|UNSMARK: 268 rv1 = rv1==rv2; break; 269 case NEQ: case NEQ|UNSMARK: 270 rv1 = rv1!=rv2; break; 271 case LEQ: 272 rv1 = rv1<=rv2; break; 273 case GEQ: 274 rv1 = rv1>=rv2; break; 275 case LT: 276 rv1 = rv1<rv2; break; 277 case GT: 278 rv1 = rv1>rv2; break; 279 case LEQ|UNSMARK: 280 rv1 = (unsigned long)rv1<=rv2; break; 281 case GEQ|UNSMARK: 282 rv1 = (unsigned long)rv1>=rv2; break; 283 case LT|UNSMARK: 284 rv1 = (unsigned long)rv1<rv2; break; 285 case GT|UNSMARK: 286 rv1 = (unsigned long)rv1>rv2; break; 287 case LSH: 288 rv1 <<= rv2; break; 289 case LSH|UNSMARK: 290 rv1 = (unsigned long)rv1<<rv2; break; 291 case RSH: 292 rv1 >>= rv2; break; 293 case RSH|UNSMARK: 294 rv1 = (unsigned long)rv1>>rv2; break; 295 case LAND: 296 rtype = UND; 297 if (v1.type==UND) 298 break; 299 if (rv1!=0) { 300 if (v2.type==UND) 301 break; 302 rv1 = rv2!=0; 303 } else 304 rv1 = 0; 305 rtype = SGN; 306 break; 307 case LOR: 308 rtype = UND; 309 if (v1.type==UND) 310 break; 311 if (rv1==0) { 312 if (v2.type==UND) 313 break; 314 rv1 = rv2!=0; 315 } else 316 rv1 = 1; 317 rtype = SGN; 318 break; 319 case AND: 320 rv1 &= rv2; break; 321 case STAR: 322 rv1 *= rv2; break; 323 case PLUS: 324 rv1 += rv2; break; 325 case MINUS: 326 rv1 -= rv2; break; 327 case UMINUS: 328 if (v1.type==UND) 329 rtype = UND; 330 rv1 = -rv1; break; 331 case OR: 332 rv1 |= rv2; break; 333 case CIRC: 334 rv1 ^= rv2; break; 335 case TILDE: 336 rv1 = ~rv1; break; 337 case NOT: 338 rv1 = !rv1; if (rtype!=UND) rtype = SGN; break; 339 case SLASH: 340 if (rv2==0) { 341 rtype = UND; 342 break; 343 } 344 if (rtype==UNS) 345 rv1 /= (unsigned long)rv2; 346 else 347 rv1 /= rv2; 348 break; 349 case PCT: 350 if (rv2==0) { 351 rtype = UND; 352 break; 353 } 354 if (rtype==UNS) 355 rv1 %= (unsigned long)rv2; 356 else 357 rv1 %= rv2; 358 break; 359 case COLON: 360 if (op[-1] != QUEST) 361 error(ERROR, "Bad ?: in #if/endif"); 362 else { 363 op--; 364 if ((--vp)->val==0) 365 v1 = v2; 366 rtype = v1.type; 367 rv1 = v1.val; 368 } 369 break; 370 case DEFINED: 371 break; 372 default: 373 error(ERROR, "Eval botch (unknown operator)"); 374 return 1; 375 } 376 /*lint +e574 +e644 */ 377 v1.val = rv1; 378 v1.type = rtype; 379 *vp++ = v1; 380 } 381 return 0; 382 } 383 384 struct value 385 tokval(Token *tp) 386 { 387 struct value v; 388 Nlist *np; 389 int i, base, c; 390 unsigned long n; 391 uchar *p; 392 393 v.type = SGN; 394 v.val = 0; 395 switch (tp->type) { 396 397 case NAME: 398 v.val = 0; 399 break; 400 401 case NAME1: 402 if ((np = lookup(tp, 0)) != NULL && np->flag&(ISDEFINED|ISMAC)) 403 v.val = 1; 404 break; 405 406 case NUMBER: 407 n = 0; 408 base = 10; 409 p = tp->t; 410 c = p[tp->len]; 411 p[tp->len] = '\0'; 412 if (*p=='0') { 413 base = 8; 414 if (p[1]=='x' || p[1]=='X') { 415 base = 16; 416 p++; 417 } 418 p++; 419 } 420 for (;; p++) { 421 if ((i = digit(*p)) < 0) 422 break; 423 if (i>=base) 424 error(WARNING, 425 "Bad digit in number %t", tp); 426 n *= base; 427 n += i; 428 } 429 if (n>=0x80000000 && base!=10) 430 v.type = UNS; 431 for (; *p; p++) { 432 if (*p=='u' || *p=='U') 433 v.type = UNS; 434 else if (*p=='l' || *p=='L') 435 ; 436 else { 437 error(ERROR, 438 "Bad number %t in #if/#elsif", tp); 439 break; 440 } 441 } 442 v.val = n; 443 tp->t[tp->len] = c; 444 break; 445 446 case CCON: 447 n = 0; 448 p = tp->t; 449 if (*p=='L') { 450 p += 1; 451 error(WARNING, "Wide char constant value undefined"); 452 } 453 p += 1; 454 if (*p=='\\') { 455 p += 1; 456 if ((i = digit(*p))>=0 && i<=7) { 457 n = i; 458 p += 1; 459 if ((i = digit(*p))>=0 && i<=7) { 460 p += 1; 461 n <<= 3; 462 n += i; 463 if ((i = digit(*p))>=0 && i<=7) { 464 p += 1; 465 n <<= 3; 466 n += i; 467 } 468 } 469 } else if (*p=='x') { 470 p += 1; 471 while ((i = digit(*p))>=0 && i<=15) { 472 p += 1; 473 n <<= 4; 474 n += i; 475 } 476 } else { 477 static char cvcon[] 478 = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\"; 479 for (i=0; i<sizeof(cvcon); i+=2) { 480 if (*p == cvcon[i]) { 481 n = cvcon[i+1]; 482 break; 483 } 484 } 485 p += 1; 486 if (i>=sizeof(cvcon)) 487 error(WARNING, 488 "Undefined escape in character constant"); 489 } 490 } else if (*p=='\'') 491 error(ERROR, "Empty character constant"); 492 else 493 n = *p++; 494 if (*p!='\'') 495 error(WARNING, "Multibyte character constant undefined"); 496 else if (n>127) 497 error(WARNING, "Character constant taken as not signed"); 498 v.val = n; 499 break; 500 501 case STRING: 502 error(ERROR, "String in #if/#elsif"); 503 break; 504 } 505 return v; 506 } 507 508 int 509 digit(int i) 510 { 511 if ('0'<=i && i<='9') 512 i -= '0'; 513 else if ('a'<=i && i<='f') 514 i -= 'a'-10; 515 else if ('A'<=i && i<='F') 516 i -= 'A'-10; 517 else 518 i = -1; 519 return i; 520 }