1 #include <u.h> 2 #include <libc.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 const 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); 116 } 117 /* replace 'defined name', 'defined(name)' to prevent evaluation */ 118 for (tp=trp->tp, ntok=tp-trp->bp; tp < trp->lp; tp++) { 119 if (tp->type!=NAME) 120 continue; 121 if ((np=lookup(tp, 0))!=NULL && np->val==KDEFINED) { 122 tp->type = DEFINED; 123 if ((tp+1)<trp->lp && (tp+1)->type==NAME) 124 (tp+1)->type = NAME1; 125 else if ((tp+3)<trp->lp && (tp+1)->type==LP 126 && (tp+2)->type==NAME && (tp+3)->type==RP) 127 (tp+2)->type = NAME1; 128 else 129 error(ERROR, "Incorrect syntax for `defined'"); 130 } 131 } 132 expandrow(trp, "<if>"); 133 vp = vals; 134 op = ops; 135 *op++ = END; 136 for (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) { 137 switch(tp->type) { 138 case WS: 139 case NL: 140 continue; 141 142 /* nilary */ 143 case NAME: 144 case NAME1: 145 case NUMBER: 146 case CCON: 147 case STRING: 148 if (rand) 149 goto syntax; 150 *vp++ = tokval(tp); 151 rand = 1; 152 continue; 153 154 /* unary */ 155 case DEFINED: 156 case TILDE: 157 case NOT: 158 if (rand) 159 goto syntax; 160 *op++ = tp->type; 161 continue; 162 163 /* unary-binary */ 164 case PLUS: case MINUS: case STAR: case AND: 165 if (rand==0) { 166 if (tp->type==MINUS) 167 *op++ = UMINUS; 168 if (tp->type==STAR || tp->type==AND) { 169 error(ERROR, "Illegal operator * or & in #if/#elsif"); 170 return 0; 171 } 172 continue; 173 } 174 /* flow through */ 175 176 /* plain binary */ 177 case EQ: case NEQ: case LEQ: case GEQ: case LSH: case RSH: 178 case LAND: case LOR: case SLASH: case PCT: 179 case LT: case GT: case CIRC: case OR: case QUEST: 180 case COLON: case COMMA: 181 if (rand==0) 182 goto syntax; 183 if (evalop(priority[tp->type])!=0) 184 return 0; 185 *op++ = tp->type; 186 rand = 0; 187 continue; 188 189 case LP: 190 if (rand) 191 goto syntax; 192 *op++ = LP; 193 continue; 194 195 case RP: 196 if (!rand) 197 goto syntax; 198 if (evalop(priority[RP])!=0) 199 return 0; 200 if (op<=ops || op[-1]!=LP) { 201 goto syntax; 202 } 203 op--; 204 continue; 205 206 default: 207 error(ERROR,"Bad operator (%t) in #if/#elsif", tp); 208 return 0; 209 } 210 } 211 if (rand==0) 212 goto syntax; 213 if (evalop(priority[END])!=0) 214 return 0; 215 if (op!=&ops[1] || vp!=&vals[1]) { 216 error(ERROR, "Botch in #if/#elsif"); 217 return 0; 218 } 219 if (vals[0].type==UND) 220 error(ERROR, "Undefined expression value"); 221 return vals[0].val; 222 syntax: 223 error(ERROR, "Syntax error in #if/#elsif"); 224 return 0; 225 } 226 227 int 228 evalop(struct pri pri) 229 { 230 struct value v1, v2; 231 long rv1, rv2; 232 int rtype, oper; 233 234 rv2=0; 235 rtype=0; 236 while (pri.pri < priority[op[-1]].pri) { 237 oper = *--op; 238 if (priority[oper].arity==2) { 239 v2 = *--vp; 240 rv2 = v2.val; 241 } 242 v1 = *--vp; 243 rv1 = v1.val; 244 switch (priority[oper].ctype) { 245 case 0: 246 default: 247 error(WARNING, "Syntax error in #if/#endif"); 248 return 1; 249 case ARITH: 250 case RELAT: 251 if (v1.type==UNS || v2.type==UNS) 252 rtype = UNS; 253 else 254 rtype = SGN; 255 if (v1.type==UND || v2.type==UND) 256 rtype = UND; 257 if (priority[oper].ctype==RELAT && rtype==UNS) { 258 oper |= UNSMARK; 259 rtype = SGN; 260 } 261 break; 262 case SHIFT: 263 if (v1.type==UND || v2.type==UND) 264 rtype = UND; 265 else 266 rtype = v1.type; 267 if (rtype==UNS) 268 oper |= UNSMARK; 269 break; 270 case UNARY: 271 rtype = v1.type; 272 break; 273 case LOGIC: 274 case SPCL: 275 break; 276 } 277 switch (oper) { 278 case EQ: case EQ|UNSMARK: 279 rv1 = rv1==rv2; break; 280 case NEQ: case NEQ|UNSMARK: 281 rv1 = rv1!=rv2; break; 282 case LEQ: 283 rv1 = rv1<=rv2; break; 284 case GEQ: 285 rv1 = rv1>=rv2; break; 286 case LT: 287 rv1 = rv1<rv2; break; 288 case GT: 289 rv1 = rv1>rv2; break; 290 case LEQ|UNSMARK: 291 rv1 = (unsigned long)rv1<=rv2; break; 292 case GEQ|UNSMARK: 293 rv1 = (unsigned long)rv1>=rv2; break; 294 case LT|UNSMARK: 295 rv1 = (unsigned long)rv1<rv2; break; 296 case GT|UNSMARK: 297 rv1 = (unsigned long)rv1>rv2; break; 298 case LSH: 299 rv1 <<= rv2; break; 300 case LSH|UNSMARK: 301 rv1 = (unsigned long)rv1<<rv2; break; 302 case RSH: 303 rv1 >>= rv2; break; 304 case RSH|UNSMARK: 305 rv1 = (unsigned long)rv1>>rv2; break; 306 case LAND: 307 rtype = UND; 308 if (v1.type==UND) 309 break; 310 if (rv1!=0) { 311 if (v2.type==UND) 312 break; 313 rv1 = rv2!=0; 314 } else 315 rv1 = 0; 316 rtype = SGN; 317 break; 318 case LOR: 319 rtype = UND; 320 if (v1.type==UND) 321 break; 322 if (rv1==0) { 323 if (v2.type==UND) 324 break; 325 rv1 = rv2!=0; 326 } else 327 rv1 = 1; 328 rtype = SGN; 329 break; 330 case AND: 331 rv1 &= rv2; break; 332 case STAR: 333 rv1 *= rv2; break; 334 case PLUS: 335 rv1 += rv2; break; 336 case MINUS: 337 rv1 -= rv2; break; 338 case UMINUS: 339 if (v1.type==UND) 340 rtype = UND; 341 rv1 = -rv1; break; 342 case OR: 343 rv1 |= rv2; break; 344 case CIRC: 345 rv1 ^= rv2; break; 346 case TILDE: 347 rv1 = ~rv1; break; 348 case NOT: 349 rv1 = !rv1; if (rtype!=UND) rtype = SGN; break; 350 case SLASH: 351 if (rv2==0) { 352 rtype = UND; 353 break; 354 } 355 if (rtype==UNS) 356 rv1 /= (unsigned long)rv2; 357 else 358 rv1 /= rv2; 359 break; 360 case PCT: 361 if (rv2==0) { 362 rtype = UND; 363 break; 364 } 365 if (rtype==UNS) 366 rv1 %= (unsigned long)rv2; 367 else 368 rv1 %= rv2; 369 break; 370 case COLON: 371 if (op[-1] != QUEST) 372 error(ERROR, "Bad ?: in #if/endif"); 373 else { 374 op--; 375 if ((--vp)->val==0) 376 v1 = v2; 377 rtype = v1.type; 378 rv1 = v1.val; 379 } 380 break; 381 case DEFINED: 382 break; 383 default: 384 error(ERROR, "Eval botch (unknown operator)"); 385 return 1; 386 } 387 v1.val = rv1; 388 v1.type = rtype; 389 *vp++ = v1; 390 } 391 return 0; 392 } 393 394 struct value 395 tokval(Token *tp) 396 { 397 struct value v; 398 Nlist *np; 399 int i, base, c, longcc; 400 unsigned long n; 401 Rune r; 402 uchar *p; 403 404 v.type = SGN; 405 v.val = 0; 406 switch (tp->type) { 407 408 case NAME: 409 v.val = 0; 410 break; 411 412 case NAME1: 413 if ((np = lookup(tp, 0)) && np->flag&ISDEFINED) 414 v.val = 1; 415 break; 416 417 case NUMBER: 418 n = 0; 419 base = 10; 420 p = tp->t; 421 c = p[tp->len]; 422 p[tp->len] = '\0'; 423 if (*p=='0') { 424 base = 8; 425 if (p[1]=='x' || p[1]=='X') { 426 base = 16; 427 p++; 428 } 429 p++; 430 } 431 for (;; p++) { 432 if ((i = digit(*p)) < 0) 433 break; 434 if (i>=base) 435 error(WARNING, 436 "Bad digit in number %t", tp); 437 n *= base; 438 n += i; 439 } 440 if (n>=0x80000000 && base!=10) 441 v.type = UNS; 442 for (; *p; p++) { 443 if (*p=='u' || *p=='U') 444 v.type = UNS; 445 else if (*p=='l' || *p=='L') 446 ; 447 else { 448 error(ERROR, 449 "Bad number %t in #if/#elsif", tp); 450 break; 451 } 452 } 453 v.val = n; 454 tp->t[tp->len] = c; 455 break; 456 457 case CCON: 458 n = 0; 459 p = tp->t; 460 longcc = 0; 461 if (*p=='L') { 462 p += 1; 463 longcc = 1; 464 } 465 p += 1; 466 if (*p=='\\') { 467 p += 1; 468 if ((i = digit(*p))>=0 && i<=7) { 469 n = i; 470 p += 1; 471 if ((i = digit(*p))>=0 && i<=7) { 472 p += 1; 473 n <<= 3; 474 n += i; 475 if ((i = digit(*p))>=0 && i<=7) { 476 p += 1; 477 n <<= 3; 478 n += i; 479 } 480 } 481 } else if (*p=='x') { 482 p += 1; 483 while ((i = digit(*p))>=0 && i<=15) { 484 p += 1; 485 n <<= 4; 486 n += i; 487 } 488 } else { 489 static char cvcon[] 490 = "a\ab\bf\fn\nr\rt\tv\v''\"\"??\\\\"; 491 for (i=0; i<sizeof(cvcon); i+=2) { 492 if (*p == cvcon[i]) { 493 n = cvcon[i+1]; 494 break; 495 } 496 } 497 p += 1; 498 if (i>=sizeof(cvcon)) 499 error(WARNING, 500 "Undefined escape in character constant"); 501 } 502 } else if (*p=='\'') 503 error(ERROR, "Empty character constant"); 504 else { 505 i = chartorune(&r, (char*)p); 506 n = r; 507 p += i; 508 if (i>1 && longcc==0) 509 error(WARNING, "Undefined character constant"); 510 } 511 if (*p!='\'') 512 error(WARNING, "Multibyte character constant undefined"); 513 else if (n>127 && longcc==0) 514 error(WARNING, "Character constant taken as not signed"); 515 v.val = n; 516 break; 517 518 case STRING: 519 error(ERROR, "String in #if/#elsif"); 520 break; 521 } 522 return v; 523 } 524 525 int 526 digit(int i) 527 { 528 if ('0'<=i && i<='9') 529 i -= '0'; 530 else if ('a'<=i && i<='f') 531 i -= 'a'-10; 532 else if ('A'<=i && i<='F') 533 i -= 'A'-10; 534 else 535 i = -1; 536 return i; 537 } 538