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