1 #include "cc.h" 2 #include "y.tab.h" 3 4 /* 5 * known debug flags 6 * -o file output file 7 * -D name define 8 * -I path include 9 * -a acid declaration output 10 * -M constant multiplication 11 * -B non ANSI 12 * -A !B 13 * -d print declarations 14 * -t print type trees 15 * -L print every NAME symbol 16 * -i print initialization 17 * -r print registerization 18 * -v verbose printing 19 * -X abort on error 20 * -w print warnings 21 * -m print add/sub/mul trees 22 * -s print structure offsets (with -a or -aa) 23 */ 24 25 void 26 main(int argc, char *argv[]) 27 { 28 char ofile[100], incfile[20], *p; 29 int nproc, nout, status, i, c; 30 31 memset(debug, 0, sizeof(debug)); 32 cinit(); 33 ginit(); 34 35 outfile = 0; 36 include[ninclude++] = "."; 37 ARGBEGIN { 38 default: 39 c = ARGC(); 40 if(c >= 0 && c < sizeof(debug)) 41 debug[c]++; 42 break; 43 44 case 'o': 45 outfile = ARGF(); 46 break; 47 48 case 'D': 49 p = ARGF(); 50 if(p) 51 dodefine(p); 52 break; 53 54 case 'I': 55 p = ARGF(); 56 if(p) 57 include[ninclude++] = p; 58 break; 59 } ARGEND 60 if(argc < 1 && outfile == 0) { 61 print("usage: %cc [-options] files\n", thechar); 62 errorexit(); 63 } 64 nproc = 1; 65 if(p = getenv("NPROC")) 66 nproc = atol(p); /* */ 67 if(argc > 1) { 68 c = 0; 69 nout = 0; 70 for(;;) { 71 while(nout < nproc && argc > 0) { 72 i = fork(); 73 if(i < 0) { 74 i = mywait(&status); 75 if(i < 0) { 76 print("cannot create a process\n"); 77 errorexit(); 78 } 79 if(status) 80 c++; 81 nout--; 82 continue; 83 } 84 if(i == 0) { 85 print("%s:\n", *argv); 86 goto child; 87 } 88 nout++; 89 argc--; 90 argv++; 91 } 92 i = mywait(&status); 93 if(i < 0) { 94 if(c) 95 errorexit(); 96 exits(0); 97 } 98 if(status) 99 c++; 100 nout--; 101 } 102 } 103 104 child: 105 if(argc < 1) 106 strcpy(ofile, "stdin"); 107 else 108 strcpy(ofile, *argv); 109 if(p = utfrrune(ofile, '/')) { 110 include[0] = ofile; 111 *p++ = 0; 112 } else 113 p = ofile; 114 if(outfile == 0) { 115 outfile = p; 116 if(p = utfrrune(outfile, '.')) 117 if(p[1] == 'c' && p[2] == 0) 118 p[0] = 0; 119 p = utfrune(outfile, 0); 120 p[0] = '.'; 121 p[1] = thechar; 122 p[2] = 0; 123 } 124 if(unix()) { 125 strcpy(incfile, "/usr/%include"); 126 p = utfrrune(incfile, '%'); 127 if(p) 128 *p = thechar; 129 } else { 130 strcpy(incfile, "/"); 131 strcat(incfile, thestring); 132 strcat(incfile, "/include"); 133 } 134 if(p = getenv("INCLUDE")) { 135 include[ninclude++] = p; 136 } else { 137 include[ninclude++] = incfile; 138 include[ninclude++] = "/sys/include"; 139 } 140 if(debug['a']) { 141 outfile = 0; 142 Binit(&outbuf, 1, OWRITE); 143 } else { 144 c = mycreat(outfile, 0664); 145 if(c < 0) { 146 diag(Z, "cannot open %s", outfile); 147 outfile = 0; 148 errorexit(); 149 } 150 Binit(&outbuf, c, OWRITE); 151 } 152 newio(); 153 if(argc < 1) 154 newfile("stdin", 0); 155 else 156 newfile(*argv, -1); 157 yyparse(); 158 if(!debug['a']) 159 gclean(); 160 Bterm(&outbuf); 161 if(nerrors) 162 errorexit(); 163 exits(0); 164 } 165 166 void 167 errorexit(void) 168 { 169 if(outfile) 170 remove(outfile); 171 exits("error"); 172 } 173 174 void 175 pushio(void) 176 { 177 Io *i; 178 179 i = iostack; 180 if(i == I) { 181 yyerror("botch in pushio"); 182 errorexit(); 183 } 184 i->p = fi.p; 185 i->c = fi.c; 186 } 187 188 void 189 newio(void) 190 { 191 Io *i; 192 static pushdepth = 0; 193 194 i = iofree; 195 if(i == I) { 196 pushdepth++; 197 if(pushdepth > 1000) { 198 yyerror("macro/io expansion too deep"); 199 errorexit(); 200 } 201 ALLOC(i, Io); 202 } else 203 iofree = i->link; 204 i->c = 0; 205 i->f = -1; 206 ionext = i; 207 } 208 209 void 210 newfile(char *s, int f) 211 { 212 Io *i; 213 214 i = ionext; 215 i->link = iostack; 216 iostack = i; 217 i->f = f; 218 if(f < 0) 219 i->f = open(s, 0); 220 if(i->f < 0) { 221 yyerror("%cc: %s: %s", thechar, myerrstr(i->f), s); 222 errorexit(); 223 } 224 fi.c = 0; 225 linehist(s, 0); 226 } 227 228 Sym* 229 slookup(char *s) 230 { 231 232 strcpy(symb, s); 233 return lookup(); 234 } 235 236 Sym* 237 lookup(void) 238 { 239 Sym *s; 240 ulong h; 241 char *p; 242 int c, n; 243 244 h = 0; 245 for(p=symb; *p;) { 246 h = h * 3; 247 h += *p++; 248 } 249 n = (p - symb) + 1; 250 if((long)h < 0) 251 h = ~h; 252 h %= NHASH; 253 c = symb[0]; 254 for(s = hash[h]; s != S; s = s->link) { 255 if(s->name[0] != c) 256 continue; 257 if(strcmp(s->name, symb) == 0) 258 return s; 259 } 260 ALLOC(s, Sym); 261 262 while(n & 3) 263 n++; 264 while(nhunk < n) 265 gethunk(); 266 s->name = hunk; 267 hunk += n; 268 nhunk -= n; 269 memmove(s->name, symb, n); 270 271 strcpy(s->name, symb); 272 s->link = hash[h]; 273 hash[h] = s; 274 syminit(s); 275 276 return s; 277 } 278 279 void 280 syminit(Sym *s) 281 { 282 283 s->lexical = LNAME; 284 s->block = 0; 285 s->offset = 0; 286 s->type = T; 287 s->suetag = T; 288 s->class = CXXX; 289 s->aused = 0; 290 } 291 292 #define EOF (-1) 293 #define IGN (-2) 294 #define ESC (1<<20) 295 #define GETC() ((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff)) 296 297 enum 298 { 299 Numdec = 1<<0, 300 Numlong = 1<<1, 301 Numuns = 1<<2, 302 Numvlong = 1<<3, 303 Numflt = 1<<4, 304 }; 305 306 long 307 yylex(void) 308 { 309 vlong vv; 310 long c, c1; 311 char *cp; 312 Rune rune; 313 Sym *s; 314 315 if(peekc != IGN) { 316 c = peekc; 317 peekc = IGN; 318 goto l1; 319 } 320 l0: 321 c = GETC(); 322 323 l1: 324 if(c >= Runeself) { 325 /* 326 * extension -- 327 * all multibyte runes are alpha 328 */ 329 cp = symb; 330 goto talph; 331 } 332 if(isspace(c)) { 333 if(c == '\n') 334 lineno++; 335 goto l0; 336 } 337 if(isalpha(c)) { 338 cp = symb; 339 if(c != 'L') 340 goto talph; 341 *cp++ = c; 342 c = GETC(); 343 if(c == '\'') { 344 /* L'x' */ 345 c = escchar('\'', 1, 0); 346 if(c == EOF) 347 c = '\''; 348 c1 = escchar('\'', 1, 0); 349 if(c1 != EOF) { 350 yyerror("missing '"); 351 peekc = c1; 352 } 353 yylval.vval = convvtox(c, TUSHORT); 354 return LUCONST; 355 } 356 if(c == '"') { 357 cp = hunk; 358 c1 = 0; 359 strcpy(symb, "\"<string>\""); 360 goto caselq; 361 } 362 goto talph; 363 } 364 if(isdigit(c)) 365 goto tnum; 366 switch(c) 367 { 368 369 case EOF: 370 peekc = EOF; 371 return -1; 372 373 case '_': 374 cp = symb; 375 goto talph; 376 377 case '#': 378 domacro(); 379 goto l0; 380 381 case '.': 382 c1 = GETC(); 383 if(isdigit(c1)) { 384 cp = symb; 385 *cp++ = c; 386 c = c1; 387 c1 = 0; 388 goto casedot; 389 } 390 break; 391 392 case '"': 393 strcpy(symb, "\"L<string>\""); 394 cp = hunk; 395 c1 = 0; 396 397 caseq: 398 /* "..." */ 399 for(;;) { 400 c = escchar('"', 0, 1); 401 if(c == EOF) 402 break; 403 if(c & ESC) { 404 ALLOCN(cp, c1, 1); 405 cp[c1] = c; 406 c1++; 407 } else { 408 rune = c; 409 c = runelen(rune); 410 ALLOCN(cp, c1, c); 411 runetochar(cp+c1, &rune); 412 c1 += c; 413 } 414 } 415 for(;;) { 416 /* it takes 2 peekc's to skip comments */ 417 c = getc(); 418 if(isspace(c)) 419 continue; 420 if(c == '"') 421 goto caseq; 422 unget(c); 423 break; 424 } 425 lnstring = c1+1; 426 do { 427 ALLOCN(cp, c1, 1); 428 cp[c1++] = 0; 429 } while(c1 & 3); 430 yylval.sval = cp; 431 return LSTRING; 432 433 caselq: 434 /* L"..." */ 435 for(;;) { 436 c = escchar('"', 1, 0); 437 if(c == EOF) 438 break; 439 ALLOCN(cp, c1, sizeof(ushort)); 440 *(ushort*)(cp + c1) = c; 441 c1 += sizeof(ushort); 442 } 443 for(;;) { 444 /* it takes 2 peekc's to skip comments */ 445 c = getc(); 446 if(isspace(c)) 447 continue; 448 if(c == '"') 449 goto caselq; 450 unget(c); 451 break; 452 } 453 lnstring = c1+sizeof(ushort); 454 do { 455 ALLOCN(cp, c1, sizeof(ushort)); 456 *(ushort*)(cp + c1) = 0; 457 c1 += sizeof(ushort); 458 } while(c1 & 3); 459 yylval.rval = (ushort*)cp; 460 return LLSTRING; 461 462 case '\'': 463 /* '.' */ 464 c = escchar('\'', 0, 0); 465 if(c == EOF) 466 c = '\''; 467 c1 = escchar('\'', 0, 0); 468 if(c1 != EOF) { 469 yyerror("missing '"); 470 peekc = c1; 471 } 472 vv = c; 473 yylval.vval = convvtox(vv, TUCHAR); 474 if(yylval.vval != vv) 475 yyerror("overflow in character constant: 0x%x", c); 476 yylval.vval = convvtox(vv, TCHAR); 477 return LCONST; 478 479 case '/': 480 c1 = GETC(); 481 if(c1 == '*') { 482 for(;;) { 483 c = getr(); 484 while(c == '*') { 485 c = getr(); 486 if(c == '/') 487 goto l0; 488 } 489 if(c == EOF) { 490 yyerror("eof in comment"); 491 errorexit(); 492 } 493 } 494 } 495 if(c1 == '/') { 496 for(;;) { 497 c = getr(); 498 if(c == '\n') 499 goto l0; 500 if(c == EOF) { 501 yyerror("eof in comment"); 502 errorexit(); 503 } 504 } 505 } 506 if(c1 == '=') 507 return LDVE; 508 break; 509 510 case '*': 511 c1 = GETC(); 512 if(c1 == '=') 513 return LMLE; 514 break; 515 516 case '%': 517 c1 = GETC(); 518 if(c1 == '=') 519 return LMDE; 520 break; 521 522 case '+': 523 c1 = GETC(); 524 if(c1 == '+') 525 return LPP; 526 if(c1 == '=') 527 return LPE; 528 break; 529 530 case '-': 531 c1 = GETC(); 532 if(c1 == '-') 533 return LMM; 534 if(c1 == '=') 535 return LME; 536 if(c1 == '>') 537 return LMG; 538 break; 539 540 case '>': 541 c1 = GETC(); 542 if(c1 == '>') { 543 c = LRSH; 544 c1 = GETC(); 545 if(c1 == '=') 546 return LRSHE; 547 break; 548 } 549 if(c1 == '=') 550 return LGE; 551 break; 552 553 case '<': 554 c1 = GETC(); 555 if(c1 == '<') { 556 c = LLSH; 557 c1 = GETC(); 558 if(c1 == '=') 559 return LLSHE; 560 break; 561 } 562 if(c1 == '=') 563 return LLE; 564 break; 565 566 case '=': 567 c1 = GETC(); 568 if(c1 == '=') 569 return LEQ; 570 break; 571 572 case '!': 573 c1 = GETC(); 574 if(c1 == '=') 575 return LNE; 576 break; 577 578 case '&': 579 c1 = GETC(); 580 if(c1 == '&') 581 return LANDAND; 582 if(c1 == '=') 583 return LANDE; 584 break; 585 586 case '|': 587 c1 = GETC(); 588 if(c1 == '|') 589 return LOROR; 590 if(c1 == '=') 591 return LORE; 592 break; 593 594 case '^': 595 c1 = GETC(); 596 if(c1 == '=') 597 return LXORE; 598 break; 599 600 default: 601 return c; 602 } 603 peekc = c1; 604 return c; 605 606 talph: 607 /* 608 * cp is set to symb and some 609 * prefix has been stored 610 */ 611 for(;;) { 612 if(c >= Runeself) { 613 for(c1=0;;) { 614 cp[c1++] = c; 615 if(fullrune(cp, c1)) 616 break; 617 c = GETC(); 618 } 619 cp += c1; 620 c = GETC(); 621 continue; 622 } 623 if(!isalnum(c) && c != '_') 624 break; 625 *cp++ = c; 626 c = GETC(); 627 } 628 *cp = 0; 629 if(debug['L']) 630 print("%L: %s\n", lineno, symb); 631 peekc = c; 632 s = lookup(); 633 if(s->macro) { 634 newio(); 635 cp = ionext->b; 636 macexpand(s, cp); 637 pushio(); 638 ionext->link = iostack; 639 iostack = ionext; 640 fi.p = cp; 641 fi.c = strlen(cp); 642 if(peekc != IGN) { 643 cp[fi.c++] = peekc; 644 cp[fi.c] = 0; 645 peekc = IGN; 646 } 647 goto l0; 648 } 649 yylval.sym = s; 650 if(s->class == CTYPEDEF) { 651 if(s->type && typesu[s->type->etype]) 652 return LCTYPE; 653 return LSTYPE; 654 } 655 if(s->lexical == LNAME) 656 return LNAME; 657 return s->lexical; 658 659 tnum: 660 c1 = 0; 661 cp = symb; 662 if(c != '0') { 663 c1 |= Numdec; 664 for(;;) { 665 *cp++ = c; 666 c = GETC(); 667 if(isdigit(c)) 668 continue; 669 goto dc; 670 } 671 } 672 *cp++ = c; 673 c = GETC(); 674 if(c == 'x' || c == 'X') 675 for(;;) { 676 *cp++ = c; 677 c = GETC(); 678 if(isdigit(c)) 679 continue; 680 if(c >= 'a' && c <= 'f') 681 continue; 682 if(c >= 'A' && c <= 'F') 683 continue; 684 if(cp == symb+2) 685 yyerror("malformed hex constant"); 686 goto ncu; 687 } 688 if(c < '0' || c > '7') 689 goto dc; 690 for(;;) { 691 if(c >= '0' && c <= '7') { 692 *cp++ = c; 693 c = GETC(); 694 continue; 695 } 696 goto ncu; 697 } 698 699 dc: 700 if(c == '.') 701 goto casedot; 702 if(c == 'e' || c == 'E') 703 goto casee; 704 705 ncu: 706 *cp = 0; 707 if(c == 'U' || c == 'u') { 708 c = GETC(); 709 c1 |= Numuns; 710 if(c == 'L' || c == 'l') { 711 c = GETC(); 712 c1 |= Numlong; 713 } 714 } else 715 if(c == 'L' || c == 'l') { 716 c = GETC(); 717 c1 |= Numlong; 718 if(c == 'U' || c == 'u') { 719 c = GETC(); 720 c1 |= Numuns; 721 } else 722 if(c == 'L' || c == 'l') { 723 c = GETC(); 724 c1 |= Numvlong; 725 } 726 } 727 peekc = c; 728 if(mpatov(symb, &yylval.vval)) 729 yyerror("overflow in constant"); 730 731 vv = yylval.vval; 732 if(c1 & Numvlong) { 733 if(c1 & Numuns) { 734 c = LUVLCONST; 735 goto nret; 736 } 737 yylval.vval = convvtox(yylval.vval, TVLONG); 738 if(yylval.vval < 0) { 739 c = LUVLCONST; 740 goto nret; 741 } 742 c = LVLCONST; 743 goto nret; 744 } 745 if(c1 & Numlong) { 746 if(c1 & Numuns) { 747 c = LULCONST; 748 goto nret; 749 } 750 yylval.vval = convvtox(yylval.vval, TLONG); 751 if(yylval.vval < 0) { 752 c = LULCONST; 753 goto nret; 754 } 755 c = LLCONST; 756 goto nret; 757 } 758 if(c1 & Numuns) { 759 c = LUCONST; 760 goto nret; 761 } 762 yylval.vval = convvtox(yylval.vval, tint->etype); 763 if(yylval.vval < 0) { 764 c = LUCONST; 765 goto nret; 766 } 767 c = LCONST; 768 goto nret; 769 770 nret: 771 return c; 772 773 casedot: 774 for(;;) { 775 *cp++ = c; 776 c = GETC(); 777 if(!isdigit(c)) 778 break; 779 } 780 if(c != 'e' && c != 'E') 781 goto caseout; 782 783 casee: 784 *cp++ = 'e'; 785 c = GETC(); 786 if(c == '+' || c == '-') { 787 *cp++ = c; 788 c = GETC(); 789 } 790 if(!isdigit(c)) 791 yyerror("malformed fp constant exponent"); 792 while(isdigit(c)) { 793 *cp++ = c; 794 c = GETC(); 795 } 796 797 caseout: 798 if(c == 'L' || c == 'l') { 799 c = GETC(); 800 c1 |= Numlong; 801 } else 802 if(c == 'F' || c == 'f') { 803 c = GETC(); 804 c1 |= Numflt; 805 } 806 *cp = 0; 807 peekc = c; 808 if(mpatof(symb, &yylval.dval)) { 809 yyerror("overflow in float constant"); 810 yylval.dval = 0; 811 } 812 if(c1 & Numflt) 813 return LFCONST; 814 return LDCONST; 815 } 816 817 int 818 getc(void) 819 { 820 int c; 821 822 if(peekc != IGN) { 823 c = peekc; 824 peekc = IGN; 825 } else 826 c = GETC(); 827 if(c == '\n') 828 lineno++; 829 if(c == EOF) { 830 yyerror("End of file"); 831 errorexit(); 832 } 833 return c; 834 } 835 836 long 837 getr(void) 838 { 839 int c, i; 840 char str[UTFmax+1]; 841 Rune rune; 842 843 844 c = getc(); 845 if(c < Runeself) 846 return c; 847 i = 0; 848 str[i++] = c; 849 850 loop: 851 c = getc(); 852 str[i++] = c; 853 if(!fullrune(str, i)) 854 goto loop; 855 c = chartorune(&rune, str); 856 if(rune == Runeerror && c == 1) { 857 nearln = lineno; 858 diag(Z, "illegal rune in string"); 859 for(c=0; c<i; c++) 860 print(" %.2x", *(uchar*)(str+c)); 861 print("\n"); 862 } 863 return rune; 864 } 865 866 int 867 getnsc(void) 868 { 869 int c; 870 871 if(peekc != IGN) { 872 c = peekc; 873 peekc = IGN; 874 } else 875 c = GETC(); 876 for(;;) { 877 if(!isspace(c)) 878 return c; 879 if(c == '\n') { 880 lineno++; 881 return c; 882 } 883 c = GETC(); 884 } 885 return 0; 886 } 887 888 void 889 unget(int c) 890 { 891 892 peekc = c; 893 if(c == '\n') 894 lineno--; 895 } 896 897 long 898 escchar(long e, int longflg, int escflg) 899 { 900 long c, l; 901 int i; 902 903 loop: 904 c = getr(); 905 if(c == '\n') { 906 yyerror("newline in string"); 907 return EOF; 908 } 909 if(c != '\\') { 910 if(c == e) 911 c = EOF; 912 return c; 913 } 914 c = getr(); 915 if(c == 'x') { 916 /* 917 * note this is not ansi, 918 * supposed to only accept 2 hex 919 */ 920 i = 2; 921 if(longflg) 922 i = 4; 923 l = 0; 924 for(; i>0; i--) { 925 c = getc(); 926 if(c >= '0' && c <= '9') { 927 l = l*16 + c-'0'; 928 continue; 929 } 930 if(c >= 'a' && c <= 'f') { 931 l = l*16 + c-'a' + 10; 932 continue; 933 } 934 if(c >= 'A' && c <= 'F') { 935 l = l*16 + c-'A' + 10; 936 continue; 937 } 938 unget(c); 939 break; 940 } 941 if(escflg) 942 l |= ESC; 943 return l; 944 } 945 if(c >= '0' && c <= '7') { 946 /* 947 * note this is not ansi, 948 * supposed to only accept 3 oct 949 */ 950 i = 2; 951 if(longflg) 952 i = 5; 953 l = c - '0'; 954 for(; i>0; i--) { 955 c = getc(); 956 if(c >= '0' && c <= '7') { 957 l = l*8 + c-'0'; 958 continue; 959 } 960 unget(c); 961 } 962 if(escflg) 963 l |= ESC; 964 return l; 965 } 966 switch(c) 967 { 968 case '\n': goto loop; 969 case 'n': return '\n'; 970 case 't': return '\t'; 971 case 'b': return '\b'; 972 case 'r': return '\r'; 973 case 'f': return '\f'; 974 case 'a': return '\a'; 975 case 'v': return '\v'; 976 } 977 return c; 978 } 979 980 struct 981 { 982 char *name; 983 ushort lexical; 984 } itab[] = 985 { 986 "auto", LAUTO, 987 "break", LBREAK, 988 "case", LCASE, 989 "char", LCHAR, 990 "const", LCONSTNT, 991 "continue", LCONTINUE, 992 "default", LDEFAULT, 993 "do", LDO, 994 "double", LDOUBLE, 995 "else", LELSE, 996 "enum", LENUM, 997 "extern", LEXTERN, 998 "float", LFLOAT, 999 "for", LFOR, 1000 "goto", LGOTO, 1001 "if", LIF, 1002 "int", LINT, 1003 "long", LLONG, 1004 "register", LREGISTER, 1005 "return", LRETURN, 1006 "SET", LSET, 1007 "short", LSHORT, 1008 "signed", LSIGNED, 1009 "sizeof", LSIZEOF, 1010 "static", LSTATIC, 1011 "struct", LSTRUCT, 1012 "switch", LSWITCH, 1013 "typedef", LTYPEDEF, 1014 "union", LUNION, 1015 "unsigned", LUNSIGNED, 1016 "USED", LUSED, 1017 "void", LVOID, 1018 "volatile", LVOLATILE, 1019 "while", LWHILE, 1020 0 1021 }; 1022 1023 void 1024 cinit(void) 1025 { 1026 Sym *s; 1027 int i; 1028 Type *t; 1029 1030 nerrors = 0; 1031 lineno = 1; 1032 iostack = I; 1033 iofree = I; 1034 peekc = IGN; 1035 nhunk = 0; 1036 1037 for(i=0; i<NHASH; i++) 1038 hash[i] = S; 1039 for(i=0; itab[i].name; i++) { 1040 s = slookup(itab[i].name); 1041 s->lexical = itab[i].lexical; 1042 } 1043 blockno = 0; 1044 autobn = 0; 1045 autoffset = 0; 1046 1047 types[TXXX] = T; 1048 types[TCHAR] = typ(TCHAR, T); 1049 types[TUCHAR] = typ(TUCHAR, T); 1050 types[TSHORT] = typ(TSHORT, T); 1051 types[TUSHORT] = typ(TUSHORT, T); 1052 types[TLONG] = typ(TLONG, T); 1053 types[TULONG] = typ(TULONG, T); 1054 types[TVLONG] = typ(TVLONG, T); 1055 types[TUVLONG] = typ(TUVLONG, T); 1056 types[TFLOAT] = typ(TFLOAT, T); 1057 types[TDOUBLE] = typ(TDOUBLE, T); 1058 types[TVOID] = typ(TVOID, T); 1059 types[TENUM] = typ(TENUM, T); 1060 types[TFUNC] = typ(TFUNC, types[TLONG]); 1061 types[TIND] = typ(TIND, types[TVOID]); 1062 1063 tint = types[TLONG]; /* assuming long, ginit knows */ 1064 tuint = types[TULONG]; 1065 1066 t = typ(TARRAY, types[TCHAR]); 1067 t->width = 0; 1068 symstring = slookup(".string"); 1069 symstring->class = CSTATIC; 1070 symstring->type = t; 1071 1072 t = typ(TARRAY, types[TCHAR]); 1073 t->width = 0; 1074 1075 nodproto = new(OPROTO, Z, Z); 1076 dclstack = D; 1077 1078 ALLOCN(pathname, 0, 100); 1079 if(getwd(pathname, 99) == 0) { 1080 ALLOCN(pathname, 100, 900); 1081 if(getwd(pathname, 999) == 0) 1082 strcpy(pathname, "/???"); 1083 } 1084 1085 fmtinstall('O', Oconv); 1086 fmtinstall('T', Tconv); 1087 fmtinstall('F', FNconv); 1088 fmtinstall('L', Lconv); 1089 fmtinstall('Q', Qconv); 1090 fmtinstall('|', VBconv); 1091 } 1092 1093 int 1094 filbuf(void) 1095 { 1096 Io *i; 1097 1098 loop: 1099 i = iostack; 1100 if(i == I) 1101 return EOF; 1102 if(i->f < 0) 1103 goto pop; 1104 fi.c = read(i->f, i->b, BUFSIZ) - 1; 1105 if(fi.c < 0) { 1106 close(i->f); 1107 while((ulong)hunk & 3) { 1108 hunk++; 1109 nhunk--; 1110 } 1111 linehist(0, 0); 1112 goto pop; 1113 } 1114 fi.p = i->b + 1; 1115 return i->b[0] & 0xff; 1116 1117 pop: 1118 iostack = i->link; 1119 i->link = iofree; 1120 iofree = i; 1121 i = iostack; 1122 if(i == I) 1123 return EOF; 1124 fi.p = i->p; 1125 fi.c = i->c; 1126 if(--fi.c < 0) 1127 goto loop; 1128 return *fi.p++ & 0xff; 1129 } 1130 1131 int 1132 Oconv(void *o, Fconv *fp) 1133 { 1134 int a; 1135 1136 a = *(int*)o; 1137 if(a < OXXX || a > OEND) 1138 strconv("***badO***", fp); 1139 else 1140 strconv(onames[a], fp); 1141 return sizeof(a); 1142 } 1143 1144 int 1145 Lconv(void *o, Fconv *fp) 1146 { 1147 char str[STRINGSZ], s[STRINGSZ]; 1148 Hist *h; 1149 struct 1150 { 1151 Hist* incl; /* start of this include file */ 1152 long idel; /* delta line number to apply to include */ 1153 Hist* line; /* start of this #line directive */ 1154 long ldel; /* delta line number to apply to #line */ 1155 } a[HISTSZ]; 1156 long l, d; 1157 int i, n; 1158 1159 l = *(long*)o; 1160 n = 0; 1161 for(h = hist; h != H; h = h->link) { 1162 if(l < h->line) 1163 break; 1164 if(h->name) { 1165 if(h->offset != 0) { /* #line directive, not #pragma */ 1166 if(n > 0 && n < HISTSZ && h->offset >= 0) { 1167 a[n-1].line = h; 1168 a[n-1].ldel = h->line - h->offset + 1; 1169 } 1170 } else { 1171 if(n < HISTSZ) { /* beginning of file */ 1172 a[n].incl = h; 1173 a[n].idel = h->line; 1174 a[n].line = 0; 1175 } 1176 n++; 1177 } 1178 continue; 1179 } 1180 n--; 1181 if(n > 0 && n < HISTSZ) { 1182 d = h->line - a[n].incl->line; 1183 a[n-1].ldel += d; 1184 a[n-1].idel += d; 1185 } 1186 } 1187 if(n > HISTSZ) 1188 n = HISTSZ; 1189 str[0] = 0; 1190 for(i=n-1; i>=0; i--) { 1191 if(i != n-1) { 1192 if(fp->f3) 1193 break; 1194 strcat(str, " "); 1195 } 1196 if(a[i].line) 1197 snprint(s, STRINGSZ, "%s:%ld[%s:%ld]", 1198 a[i].line->name, l-a[i].ldel+1, 1199 a[i].incl->name, l-a[i].idel+1); 1200 else 1201 snprint(s, STRINGSZ, "%s:%ld", 1202 a[i].incl->name, l-a[i].idel+1); 1203 if(strlen(s)+strlen(str) >= STRINGSZ-10) 1204 break; 1205 strcat(str, s); 1206 l = a[i].incl->line - 1; /* now print out start of this file */ 1207 } 1208 if(n == 0) 1209 strcat(str, "<eof>"); 1210 strconv(str, fp); 1211 return sizeof(l); 1212 } 1213 1214 int 1215 Tconv(void *o, Fconv *fp) 1216 { 1217 char str[STRINGSZ+20], s[STRINGSZ+20]; 1218 Type *t, *t1; 1219 int et; 1220 1221 str[0] = 0; 1222 for(t = *(Type**)o; t != T; t = t->link) { 1223 et = t->etype; 1224 if(str[0]) 1225 strcat(str, " "); 1226 sprint(s, "%s", tnames[et]); 1227 if(strlen(str) + strlen(s) < STRINGSZ) 1228 strcat(str, s); 1229 if(et == TFUNC && (t1 = t->down)) { 1230 sprint(s, "(%T", t1); 1231 if(strlen(str) + strlen(s) < STRINGSZ) 1232 strcat(str, s); 1233 while(t1 = t1->down) { 1234 sprint(s, ", %T", t1); 1235 if(strlen(str) + strlen(s) < STRINGSZ) 1236 strcat(str, s); 1237 } 1238 if(strlen(str) + strlen(s) < STRINGSZ) 1239 strcat(str, ")"); 1240 } 1241 if(et == TARRAY) { 1242 sprint(s, "[%ld]", t->width); 1243 if(strlen(str) + strlen(s) < STRINGSZ) 1244 strcat(str, s); 1245 } 1246 if(t->nbits) { 1247 sprint(s, " %d:%d", t->shift, t->nbits); 1248 if(strlen(str) + strlen(s) < STRINGSZ) 1249 strcat(str, s); 1250 } 1251 if(typesu[et]) { 1252 if(t->tag) { 1253 strcat(str, " "); 1254 if(strlen(str) + strlen(t->tag->name) < STRINGSZ) 1255 strcat(str, t->tag->name); 1256 } else 1257 strcat(str, " {}"); 1258 break; 1259 } 1260 } 1261 strconv(str, fp); 1262 return sizeof(t); 1263 } 1264 1265 int 1266 FNconv(void *o, Fconv *fp) 1267 { 1268 char *str; 1269 Node *n; 1270 1271 n = *(Node**)o; 1272 str = "<indirect>"; 1273 if(n != Z && (n->op == ONAME || n->op == ODOT || n->op == OELEM)) 1274 str = n->sym->name; 1275 strconv(str, fp); 1276 return sizeof(n); 1277 } 1278 1279 int 1280 Qconv(void *o, Fconv *fp) 1281 { 1282 char str[STRINGSZ+20], *s; 1283 long b; 1284 int i; 1285 1286 str[0] = 0; 1287 for(b = *(long*)o; b;) { 1288 i = bitno(b); 1289 if(str[0]) 1290 strcat(str, " "); 1291 s = qnames[i]; 1292 if(strlen(str) + strlen(s) >= STRINGSZ) 1293 break; 1294 strcat(str, s); 1295 b &= ~(1L << i); 1296 } 1297 strconv(str, fp); 1298 return sizeof(b); 1299 } 1300 1301 int 1302 VBconv(void *o, Fconv *fp) 1303 { 1304 char str[STRINGSZ]; 1305 int i, n, t, pc; 1306 extern printcol; 1307 1308 n = *(int*)o; 1309 pc = printcol; 1310 i = 0; 1311 while(pc < n) { 1312 t = (pc+8) & ~7; 1313 if(t <= n) { 1314 str[i++] = '\t'; 1315 pc = t; 1316 continue; 1317 } 1318 str[i++] = ' '; 1319 pc++; 1320 } 1321 str[i] = 0; 1322 strconv(str, fp); 1323 return sizeof(n); 1324 } 1325 1326 /* 1327 * fake malloc 1328 */ 1329 void* 1330 malloc(long n) 1331 { 1332 void *p; 1333 1334 while(n & 3) 1335 n++; 1336 while(nhunk < n) 1337 gethunk(); 1338 p = hunk; 1339 nhunk -= n; 1340 hunk += n; 1341 return p; 1342 } 1343 1344 void 1345 free(void *p) 1346 { 1347 USED(p); 1348 } 1349 1350 void* 1351 calloc(long m, long n) 1352 { 1353 void *p; 1354 1355 n *= m; 1356 p = malloc(n); 1357 memset(p, 0, n); 1358 return p; 1359 } 1360 1361 void* 1362 realloc(void *p, long n) 1363 { 1364 1365 USED(p); 1366 USED(n); 1367 fprint(2, "realloc called\n"); 1368 abort(); 1369 return 0; 1370 } 1371