1 #include "cpp.h" 2 3 #include <stdlib.h> 4 #include <string.h> 5 6 #define NSTAK 32 7 #define SGN 0 8 #define UNS 1 9 #define UND 2 10 11 #define UNSMARK 0x1000 12 13 struct value 14 { 15 long val; 16 int type; 17 }; 18 19 /* conversion types */ 20 #define RELAT 1 21 #define ARITH 2 22 #define LOGIC 3 23 #define SPCL 4 24 #define SHIFT 5 25 #define UNARY 6 26 27 /* operator priority, arity, and conversion type, indexed by tokentype */ 28 struct pri 29 { 30 char pri; 31 char arity; 32 char ctype; 33 } priority[] = 34 35 { 36 { 37 0, 0, 0 38 }, /* END */ 39 { 40 0, 0, 0 41 }, /* UNCLASS */ 42 { 43 0, 0, 0 44 }, /* NAME */ 45 { 46 0, 0, 0 47 }, /* NUMBER */ 48 { 49 0, 0, 0 50 }, /* STRING */ 51 { 52 0, 0, 0 53 }, /* CCON */ 54 { 55 0, 0, 0 56 }, /* NL */ 57 { 58 0, 0, 0 59 }, /* WS */ 60 { 61 0, 0, 0 62 }, /* DSHARP */ 63 { 64 11, 2, RELAT 65 }, /* EQ */ 66 { 67 11, 2, RELAT 68 }, /* NEQ */ 69 { 70 12, 2, RELAT 71 }, /* LEQ */ 72 { 73 12, 2, RELAT 74 }, /* GEQ */ 75 { 76 13, 2, SHIFT 77 }, /* LSH */ 78 { 79 13, 2, SHIFT 80 }, /* RSH */ 81 { 82 7, 2, LOGIC 83 }, /* LAND */ 84 { 85 6, 2, LOGIC 86 }, /* LOR */ 87 { 88 0, 0, 0 89 }, /* PPLUS */ 90 { 91 0, 0, 0 92 }, /* MMINUS */ 93 { 94 0, 0, 0 95 }, /* ARROW */ 96 { 97 0, 0, 0 98 }, /* SBRA */ 99 { 100 0, 0, 0 101 }, /* SKET */ 102 { 103 3, 0, 0 104 }, /* LP */ 105 { 106 3, 0, 0 107 }, /* RP */ 108 { 109 0, 0, 0 110 }, /* DOT */ 111 { 112 10, 2, ARITH 113 }, /* AND */ 114 { 115 15, 2, ARITH 116 }, /* STAR */ 117 { 118 14, 2, ARITH 119 }, /* PLUS */ 120 { 121 14, 2, ARITH 122 }, /* MINUS */ 123 { 124 16, 1, UNARY 125 }, /* TILDE */ 126 { 127 16, 1, UNARY 128 }, /* NOT */ 129 { 130 15, 2, ARITH 131 }, /* SLASH */ 132 { 133 15, 2, ARITH 134 }, /* PCT */ 135 { 136 12, 2, RELAT 137 }, /* LT */ 138 { 139 12, 2, RELAT 140 }, /* GT */ 141 { 142 9, 2, ARITH 143 }, /* CIRC */ 144 { 145 8, 2, ARITH 146 }, /* OR */ 147 { 148 5, 2, SPCL 149 }, /* QUEST */ 150 { 151 5, 2, SPCL 152 }, /* COLON */ 153 { 154 0, 0, 0 155 }, /* ASGN */ 156 { 157 4, 2, 0 158 }, /* COMMA */ 159 { 160 0, 0, 0 161 }, /* SHARP */ 162 { 163 0, 0, 0 164 }, /* SEMIC */ 165 { 166 0, 0, 0 167 }, /* CBRA */ 168 { 169 0, 0, 0 170 }, /* CKET */ 171 { 172 0, 0, 0 173 }, /* ASPLUS */ 174 { 175 0, 0, 0 176 }, /* ASMINUS */ 177 { 178 0, 0, 0 179 }, /* ASSTAR */ 180 { 181 0, 0, 0 182 }, /* ASSLASH */ 183 { 184 0, 0, 0 185 }, /* ASPCT */ 186 { 187 0, 0, 0 188 }, /* ASCIRC */ 189 { 190 0, 0, 0 191 }, /* ASLSH */ 192 { 193 0, 0, 0 194 }, /* ASRSH */ 195 { 196 0, 0, 0 197 }, /* ASOR */ 198 { 199 0, 0, 0 200 }, /* ASAND */ 201 { 202 0, 0, 0 203 }, /* ELLIPS */ 204 { 205 0, 0, 0 206 }, /* DSHARP1 */ 207 { 208 0, 0, 0 209 }, /* NAME1 */ 210 { 211 0, 0, 0 212 }, /* NAME2 */ 213 { 214 16, 1, UNARY 215 }, /* DEFINED */ 216 { 217 16, 0, UNARY 218 }, /* UMINUS */ 219 { 220 16, 1, UNARY 221 }, /* ARCHITECTURE */ 222 }; 223 224 int evalop(struct pri); 225 struct value tokval(Token *); 226 struct value vals[NSTAK], *vp; 227 enum toktype ops[NSTAK], *op; 228 229 /* 230 * Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword. 231 */ 232 long 233 eval(Tokenrow * trp, int kw) 234 { 235 Token *tp; 236 Nlist *np; 237 int ntok, rnd; 238 239 trp->tp++; 240 if (kw == KIFDEF || kw == KIFNDEF) 241 { 242 if (trp->lp - trp->bp != 4 || trp->tp->type != NAME) 243 { 244 error(ERROR, "Syntax error in #ifdef/#ifndef"); 245 return 0; 246 } 247 np = lookup(trp->tp, 0); 248 return (kw == KIFDEF) == (np && np->flag & (ISDEFINED | ISMAC)); 249 } 250 ntok = trp->tp - trp->bp; 251 kwdefined->val = KDEFINED; /* activate special meaning of 252 * defined */ 253 expandrow(trp, "<if>"); 254 kwdefined->val = NAME; 255 vp = vals; 256 op = ops; 257 *op++ = END; 258 for (rnd = 0, tp = trp->bp + ntok; tp < trp->lp; tp++) 259 { 260 switch (tp->type) 261 { 262 case WS: 263 case NL: 264 continue; 265 266 /* nilary */ 267 case NAME: 268 case NAME1: 269 case NAME2: 270 case NUMBER: 271 case CCON: 272 case STRING: 273 if (rnd) 274 goto syntax; 275 *vp++ = tokval(tp); 276 rnd = 1; 277 continue; 278 279 /* unary */ 280 case DEFINED: 281 case TILDE: 282 case NOT: 283 if (rnd) 284 goto syntax; 285 *op++ = tp->type; 286 continue; 287 288 /* unary-binary */ 289 case PLUS: 290 case MINUS: 291 case STAR: 292 case AND: 293 if (rnd == 0) 294 { 295 if (tp->type == MINUS) 296 *op++ = UMINUS; 297 if (tp->type == STAR || tp->type == AND) 298 { 299 error(ERROR, "Illegal operator * or & in #if/#elsif"); 300 return 0; 301 } 302 continue; 303 } 304 /* flow through */ 305 306 /* plain binary */ 307 case EQ: 308 case NEQ: 309 case LEQ: 310 case GEQ: 311 case LSH: 312 case RSH: 313 case LAND: 314 case LOR: 315 case SLASH: 316 case PCT: 317 case LT: 318 case GT: 319 case CIRC: 320 case OR: 321 case QUEST: 322 case COLON: 323 case COMMA: 324 if (rnd == 0) 325 goto syntax; 326 if (evalop(priority[tp->type]) != 0) 327 return 0; 328 *op++ = tp->type; 329 rnd = 0; 330 continue; 331 332 case LP: 333 if (rnd) 334 goto syntax; 335 *op++ = LP; 336 continue; 337 338 case RP: 339 if (!rnd) 340 goto syntax; 341 if (evalop(priority[RP]) != 0) 342 return 0; 343 if (op <= ops || op[-1] != LP) 344 { 345 goto syntax; 346 } 347 op--; 348 continue; 349 350 case SHARP: 351 if ((tp + 1) < trp->lp) 352 { 353 np = lookup(tp + 1, 0); 354 if (np && (np->val == KMACHINE)) 355 { 356 tp++; 357 if (rnd) 358 goto syntax; 359 *op++ = ARCHITECTURE; 360 continue; 361 } 362 } 363 /* fall through */ 364 365 default: 366 error(ERROR, "Bad operator (%t) in #if/#elsif", tp); 367 return 0; 368 } 369 } 370 if (rnd == 0) 371 goto syntax; 372 if (evalop(priority[END]) != 0) 373 return 0; 374 if (op != &ops[1] || vp != &vals[1]) 375 { 376 error(ERROR, "Botch in #if/#elsif"); 377 return 0; 378 } 379 if (vals[0].type == UND) 380 error(ERROR, "Undefined expression value"); 381 return vals[0].val; 382 syntax: 383 error(ERROR, "Syntax error in #if/#elsif"); 384 return 0; 385 } 386 387 int 388 evalop(struct pri pri) 389 { 390 struct value v1; 391 struct value v2 = { 0, UND }; 392 long rv1, rv2; 393 int rtype, oper; 394 395 rv2 = 0; 396 rtype = 0; 397 while (pri.pri < priority[op[-1]].pri) 398 { 399 oper = *--op; 400 if (priority[oper].arity == 2) 401 { 402 v2 = *--vp; 403 rv2 = v2.val; 404 } 405 v1 = *--vp; 406 rv1 = v1.val; 407 /*lint -e574 -e644 */ 408 switch (priority[oper].ctype) 409 { 410 case 0: 411 default: 412 error(WARNING, "Syntax error in #if/#endif"); 413 return 1; 414 case ARITH: 415 case RELAT: 416 if (v1.type == UNS || v2.type == UNS) 417 rtype = UNS; 418 else 419 rtype = SGN; 420 if (v1.type == UND || v2.type == UND) 421 rtype = UND; 422 if (priority[oper].ctype == RELAT && rtype == UNS) 423 { 424 oper |= UNSMARK; 425 rtype = SGN; 426 } 427 break; 428 case SHIFT: 429 if (v1.type == UND || v2.type == UND) 430 rtype = UND; 431 else 432 rtype = v1.type; 433 if (rtype == UNS) 434 oper |= UNSMARK; 435 break; 436 case UNARY: 437 rtype = v1.type; 438 break; 439 case LOGIC: 440 case SPCL: 441 break; 442 } 443 switch (oper) 444 { 445 case EQ: 446 case EQ | UNSMARK: 447 rv1 = rv1 == rv2; 448 break; 449 case NEQ: 450 case NEQ | UNSMARK: 451 rv1 = rv1 != rv2; 452 break; 453 case LEQ: 454 rv1 = rv1 <= rv2; 455 break; 456 case GEQ: 457 rv1 = rv1 >= rv2; 458 break; 459 case LT: 460 rv1 = rv1 < rv2; 461 break; 462 case GT: 463 rv1 = rv1 > rv2; 464 break; 465 case LEQ | UNSMARK: 466 rv1 = (unsigned long)rv1 <= (unsigned long)rv2; 467 break; 468 case GEQ | UNSMARK: 469 rv1 = (unsigned long)rv1 >= (unsigned long)rv2; 470 break; 471 case LT | UNSMARK: 472 rv1 = (unsigned long)rv1 < (unsigned long)rv2; 473 break; 474 case GT | UNSMARK: 475 rv1 = (unsigned long)rv1 > (unsigned long)rv2; 476 break; 477 case LSH: 478 rv1 <<= rv2; 479 break; 480 case LSH | UNSMARK: 481 rv1 = (unsigned long) rv1 << rv2; 482 break; 483 case RSH: 484 rv1 >>= rv2; 485 break; 486 case RSH | UNSMARK: 487 rv1 = (unsigned long) rv1 >> rv2; 488 break; 489 case LAND: 490 rtype = UND; 491 if (v1.type == UND) 492 break; 493 if (rv1 != 0) 494 { 495 if (v2.type == UND) 496 break; 497 rv1 = rv2 != 0; 498 } 499 else 500 rv1 = 0; 501 rtype = SGN; 502 break; 503 case LOR: 504 rtype = UND; 505 if (v1.type == UND) 506 break; 507 if (rv1 == 0) 508 { 509 if (v2.type == UND) 510 break; 511 rv1 = rv2 != 0; 512 } 513 else 514 rv1 = 1; 515 rtype = SGN; 516 break; 517 case AND: 518 rv1 &= rv2; 519 break; 520 case STAR: 521 rv1 *= rv2; 522 break; 523 case PLUS: 524 rv1 += rv2; 525 break; 526 case MINUS: 527 rv1 -= rv2; 528 break; 529 case UMINUS: 530 if (v1.type == UND) 531 rtype = UND; 532 rv1 = -rv1; 533 break; 534 case OR: 535 rv1 |= rv2; 536 break; 537 case CIRC: 538 rv1 ^= rv2; 539 break; 540 case TILDE: 541 rv1 = ~rv1; 542 break; 543 case NOT: 544 rv1 = !rv1; 545 if (rtype != UND) 546 rtype = SGN; 547 break; 548 case SLASH: 549 if (rv2 == 0) 550 { 551 rtype = UND; 552 break; 553 } 554 if (rtype == UNS) 555 rv1 /= (unsigned long) rv2; 556 else 557 rv1 /= rv2; 558 break; 559 case PCT: 560 if (rv2 == 0) 561 { 562 rtype = UND; 563 break; 564 } 565 if (rtype == UNS) 566 rv1 %= (unsigned long) rv2; 567 else 568 rv1 %= rv2; 569 break; 570 case COLON: 571 if (op[-1] != QUEST) 572 error(ERROR, "Bad ?: in #if/endif"); 573 else 574 { 575 op--; 576 if ((--vp)->val == 0) 577 v1 = v2; 578 rtype = v1.type; 579 rv1 = v1.val; 580 } 581 break; 582 583 case DEFINED: 584 case ARCHITECTURE: 585 break; 586 587 default: 588 error(ERROR, "Eval botch (unknown operator)"); 589 return 1; 590 } 591 /*lint +e574 +e644 */ 592 v1.val = rv1; 593 v1.type = rtype; 594 *vp++ = v1; 595 } 596 return 0; 597 } 598 599 struct value 600 tokval(Token * tp) 601 { 602 struct value v; 603 Nlist *np; 604 int i, base; 605 unsigned long n; 606 uchar *p, c; 607 608 v.type = SGN; 609 v.val = 0; 610 switch (tp->type) 611 { 612 613 case NAME: 614 v.val = 0; 615 break; 616 617 case NAME1: 618 if ((np = lookup(tp, 0)) != NULL && np->flag & (ISDEFINED | ISMAC)) 619 v.val = 1; 620 break; 621 622 case NAME2: 623 if ((np = lookup(tp, 0)) != NULL && np->flag & (ISARCHITECTURE)) 624 v.val = 1; 625 break; 626 627 case NUMBER: 628 n = 0; 629 base = 10; 630 p = tp->t; 631 c = p[tp->len]; 632 p[tp->len] = '\0'; 633 if (*p == '0') 634 { 635 base = 8; 636 if (p[1] == 'x' || p[1] == 'X') 637 { 638 base = 16; 639 p++; 640 } 641 p++; 642 } 643 for (;; p++) 644 { 645 if ((i = digit(*p)) < 0) 646 break; 647 if (i >= base) 648 error(WARNING, 649 "Bad digit in number %t", tp); 650 n *= base; 651 n += i; 652 } 653 if (n >= 0x80000000 && base != 10) 654 v.type = UNS; 655 for (; *p; p++) 656 { 657 if (*p == 'u' || *p == 'U') 658 v.type = UNS; 659 else 660 if (*p == 'l' || *p == 'L') 661 ; 662 else 663 { 664 error(ERROR, 665 "Bad number %t in #if/#elsif", tp); 666 break; 667 } 668 } 669 v.val = n; 670 tp->t[tp->len] = c; 671 break; 672 673 case CCON: 674 n = 0; 675 p = tp->t; 676 if (*p == 'L') 677 { 678 p += 1; 679 error(WARNING, "Wide char constant value undefined"); 680 } 681 p += 1; 682 if (*p == '\\') 683 { 684 p += 1; 685 if ((i = digit(*p)) >= 0 && i <= 7) 686 { 687 n = i; 688 p += 1; 689 if ((i = digit(*p)) >= 0 && i <= 7) 690 { 691 p += 1; 692 n <<= 3; 693 n += i; 694 if ((i = digit(*p)) >= 0 && i <= 7) 695 { 696 p += 1; 697 n <<= 3; 698 n += i; 699 } 700 } 701 } 702 else 703 if (*p == 'x') 704 { 705 p += 1; 706 while ((i = digit(*p)) >= 0 && i <= 15) 707 { 708 p += 1; 709 n <<= 4; 710 n += i; 711 } 712 } 713 else 714 { 715 static char cvcon[] = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\"; 716 static size_t cvlen = sizeof(cvcon) - 1; 717 718 size_t j; 719 for (j = 0; j < cvlen; j += 2) 720 { 721 if (*p == cvcon[j]) 722 { 723 n = cvcon[j + 1]; 724 break; 725 } 726 } 727 p += 1; 728 if (j >= cvlen) 729 error(WARNING, 730 "Undefined escape in character constant"); 731 } 732 } 733 else 734 if (*p == '\'') 735 error(ERROR, "Empty character constant"); 736 else 737 n = *p++; 738 if (*p != '\'') 739 error(WARNING, "Multibyte character constant undefined"); 740 else 741 if (n > 127) 742 error(WARNING, "Character constant taken as not signed"); 743 v.val = n; 744 break; 745 746 case STRING: 747 error(ERROR, "String in #if/#elsif"); 748 break; 749 } 750 return v; 751 } 752 753 int 754 digit(int i) 755 { 756 if ('0' <= i && i <= '9') 757 i -= '0'; 758 else 759 if ('a' <= i && i <= 'f') 760 i -= 'a' - 10; 761 else 762 if ('A' <= i && i <= 'F') 763 i -= 'A' - 10; 764 else 765 i = -1; 766 return i; 767 } 768