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