github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/cmd/cc/lex.c (about) 1 // Inferno utils/cc/lex.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/cc/lex.c 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 #include <u.h> 32 #include "cc.h" 33 #include "y.tab.h" 34 35 #ifndef CPP 36 #define CPP "cpp" 37 #endif 38 39 int 40 systemtype(int sys) 41 { 42 #ifdef _WIN32 43 return sys&Windows; 44 #else 45 return sys&Plan9; 46 #endif 47 } 48 49 int 50 pathchar(void) 51 { 52 return '/'; 53 } 54 55 /* 56 * known debug flags 57 * -a acid declaration output 58 * -A !B 59 * -B non ANSI 60 * -d print declarations 61 * -D name define 62 * -F format specification check 63 * -G print pgen stuff 64 * -g print cgen trees 65 * -i print initialization 66 * -I path include 67 * -l generate little-endian code 68 * -L print every NAME symbol 69 * -M constant multiplication 70 * -m print add/sub/mul trees 71 * -n print acid or godefs to file (%.c=%.acid) (with -a or -aa) 72 * -o file output file 73 * -p use standard cpp ANSI preprocessor (not on windows) 74 * -p something with peepholes 75 * -q print equivalent Go code for variables and types (lower-case identifiers) 76 * -Q print equivalent Go code for variables and types (upper-case identifiers) 77 * -r print registerization 78 * -s print structure offsets (with -a or -aa) 79 * -S print assembly 80 * -t print type trees 81 * -V enable void* conversion warnings 82 * -v verbose printing 83 * -w print warnings 84 * -X abort on error 85 * -. Inhibit search for includes in source directory 86 */ 87 88 void 89 usage(void) 90 { 91 print("usage: %cc [options] file.c...\n", thechar); 92 flagprint(1); 93 errorexit(); 94 } 95 96 void 97 dospim(void) 98 { 99 thechar = '0'; 100 thestring = "spim"; 101 } 102 103 char **defs; 104 int ndef; 105 106 void 107 dodef(char *p) 108 { 109 if(ndef%8 == 0) 110 defs = allocn(defs, ndef*sizeof(char *), 111 8*sizeof(char *)); 112 defs[ndef++] = p; 113 dodefine(p); 114 } 115 116 void 117 main(int argc, char *argv[]) 118 { 119 int c; 120 char *p; 121 122 // Allow GOARCH=thestring or GOARCH=thestringsuffix, 123 // but not other values. 124 p = getgoarch(); 125 if(strncmp(p, thestring, strlen(thestring)) != 0) 126 sysfatal("cannot use %cc with GOARCH=%s", thechar, p); 127 if(strcmp(p, "amd64p32") == 0) // must be before cinit 128 ewidth[TIND] = 4; 129 130 nacl = strcmp(getgoos(), "nacl") == 0; 131 if(nacl) 132 flag_largemodel = 1; 133 134 quotefmtinstall(); // before cinit, which overrides %Q 135 136 linkarchinit(); 137 ctxt = linknew(thelinkarch); 138 ctxt->diag = yyerror; 139 ctxt->bso = &bstdout; 140 Binit(&bstdout, 1, OWRITE); 141 142 ensuresymb(NSYMB); 143 memset(debug, 0, sizeof(debug)); 144 tinit(); 145 cinit(); 146 ginit(); 147 arginit(); 148 149 fmtstrinit(&pragcgobuf); 150 151 tufield = simplet((1L<<tfield->etype) | BUNSIGNED); 152 ndef = 0; 153 defs = nil; 154 outfile = 0; 155 setinclude("."); 156 157 flagcount("+", "pass -+ to preprocessor", &debug['+']); 158 flagcount(".", "pass -. to preprocessor", &debug['.']); 159 flagcount("<", "debug shift", &debug['<']); 160 flagcount("A", "debug alignment", &debug['A']); 161 flagcount("B", "allow pre-ANSI code", &debug['B']); 162 if(thechar == '5') 163 flagcount("C", "debug constant propagation", &debug['C']); 164 flagfn1("D", "name[=value]: add #define", dodef); 165 flagcount("F", "enable print format checks", &debug['F']); 166 if(thechar == '5') 167 flagcount("H", "debug shift propagation", &debug['H']); 168 flagfn1("I", "dir: add dir to include path", setinclude); 169 flagcount("L", "debug lexer", &debug['L']); 170 flagcount("M", "debug move generation", &debug['M']); 171 flagcount("N", "disable optimizations", &debug['N']); 172 flagcount("P", "debug peephole optimizer", &debug['P']); 173 flagcount("Q", "print exported Go definitions", &debug['Q']); 174 flagcount("R", "debug register optimizer", &debug['R']); 175 flagcount("S", "print assembly", &debug['S']); 176 flagcount("T", "enable type signatures", &debug['T']); 177 flagcount("V", "enable pointer type checks", &debug['V']); 178 flagcount("W", "debug switch generation", &debug['W']); 179 flagcount("X", "abort on error", &debug['X']); 180 flagcount("Y", "debug index generation", &debug['Y']); 181 flagcount("Z", "skip code generation", &debug['Z']); 182 flagcount("a", "print acid definitions", &debug['a']); 183 flagcount("c", "debug constant evaluation", &debug['c']); 184 flagcount("d", "debug declarations", &debug['d']); 185 flagcount("e", "debug macro expansion", &debug['e']); 186 flagcount("f", "debug pragmas", &debug['f']); 187 flagcount("g", "debug code generation", &debug['g']); 188 flagcount("i", "debug initialization", &debug['i']); 189 if(thechar == 'v') 190 flagfn0("l", "little-endian mips mode", dospim); 191 flagcount("m", "debug multiplication", &debug['m']); 192 flagcount("n", "print acid/Go to file, not stdout", &debug['n']); 193 flagstr("o", "file: set output file", &outfile); 194 flagcount("p", "invoke C preprocessor", &debug['p']); 195 flagcount("q", "print Go definitions", &debug['q']); 196 flagcount("s", "print #define assembly offsets", &debug['s']); 197 flagcount("t", "debug code generation", &debug['t']); 198 flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath); 199 flagcount("w", "enable warnings", &debug['w']); 200 flagcount("v", "increase debug verbosity", &debug['v']); 201 if(thechar == '6') 202 flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel); 203 204 flagparse(&argc, &argv, usage); 205 ctxt->debugasm = debug['S']; 206 207 if(argc < 1 && outfile == 0) 208 usage(); 209 210 if(argc > 1){ 211 print("can't compile multiple files\n"); 212 errorexit(); 213 } 214 215 if(argc == 0) 216 c = compile("stdin", defs, ndef); 217 else 218 c = compile(argv[0], defs, ndef); 219 220 Bflush(&bstdout); 221 if(c) 222 errorexit(); 223 exits(0); 224 } 225 226 int 227 compile(char *file, char **defs, int ndef) 228 { 229 char *ofile; 230 char *p, **av, opt[256]; 231 int i, c, fd[2]; 232 static int first = 1; 233 234 ofile = alloc(strlen(file)+10); 235 strcpy(ofile, file); 236 p = utfrrune(ofile, pathchar()); 237 if(p) { 238 *p++ = 0; 239 if(!debug['.']) 240 include[0] = strdup(ofile); 241 } else 242 p = ofile; 243 244 if(outfile == 0) { 245 outfile = p; 246 if(outfile) { 247 if(p = utfrrune(outfile, '.')) 248 if(p[1] == 'c' && p[2] == 0) 249 p[0] = 0; 250 p = utfrune(outfile, 0); 251 if(debug['a'] && debug['n']) 252 strcat(p, ".acid"); 253 else if((debug['q'] || debug['Q']) && debug['n']) 254 strcat(p, ".go"); 255 else { 256 p[0] = '.'; 257 p[1] = thechar; 258 p[2] = 0; 259 } 260 } else 261 outfile = "/dev/null"; 262 } 263 264 if (first) 265 Binit(&diagbuf, 1, OWRITE); 266 /* 267 * if we're writing acid to standard output, don't keep scratching 268 * outbuf. 269 */ 270 if((debug['a'] || debug['q'] || debug['Q']) && !debug['n']) { 271 if (first) { 272 outfile = 0; 273 Binit(&outbuf, dup(1, -1), OWRITE); 274 dup(2, 1); 275 } 276 } else { 277 c = create(outfile, OWRITE, 0664); 278 if(c < 0) { 279 diag(Z, "cannot open %s - %r", outfile); 280 outfile = 0; 281 errorexit(); 282 } 283 Binit(&outbuf, c, OWRITE); 284 outfile = strdup(outfile); 285 } 286 newio(); 287 first = 0; 288 289 /* Use an ANSI preprocessor */ 290 if(debug['p']) { 291 if(systemtype(Windows)) { 292 diag(Z, "-p option not supported on windows"); 293 errorexit(); 294 } 295 if(access(file, AREAD) < 0) { 296 diag(Z, "%s does not exist", file); 297 errorexit(); 298 } 299 if(pipe(fd) < 0) { 300 diag(Z, "pipe failed"); 301 errorexit(); 302 } 303 switch(fork()) { 304 case -1: 305 diag(Z, "fork failed"); 306 errorexit(); 307 case 0: 308 close(fd[0]); 309 dup(fd[1], 1); 310 close(fd[1]); 311 av = alloc((ndef+ninclude+5)*sizeof(char *)); 312 av[0] = CPP; 313 i = 1; 314 if(debug['.']){ 315 sprint(opt, "-."); 316 av[i++] = strdup(opt); 317 } 318 if(debug['+']) { 319 sprint(opt, "-+"); 320 av[i++] = strdup(opt); 321 } 322 for(c = 0; c < ndef; c++) 323 av[i++] = smprint("-D%s", defs[c]); 324 for(c = 0; c < ninclude; c++) 325 av[i++] = smprint("-I%s", include[c]); 326 if(strcmp(file, "stdin") != 0) 327 av[i++] = file; 328 av[i] = 0; 329 if(debug['p'] > 1) { 330 for(c = 0; c < i; c++) 331 fprint(2, "%s ", av[c]); 332 fprint(2, "\n"); 333 } 334 exec(av[0], av); 335 fprint(2, "can't exec C preprocessor %s: %r\n", CPP); 336 errorexit(); 337 default: 338 close(fd[1]); 339 newfile(file, fd[0]); 340 break; 341 } 342 } else { 343 if(strcmp(file, "stdin") == 0) 344 newfile(file, 0); 345 else 346 newfile(file, -1); 347 } 348 yyparse(); 349 if(!debug['a'] && !debug['q'] && !debug['Q']) 350 gclean(); 351 return nerrors; 352 } 353 354 void 355 errorexit(void) 356 { 357 Bflush(&bstdout); 358 if(outfile) 359 remove(outfile); 360 exits("error"); 361 } 362 363 void 364 pushio(void) 365 { 366 Io *i; 367 368 i = iostack; 369 if(i == I) { 370 yyerror("botch in pushio"); 371 errorexit(); 372 } 373 i->p = fi.p; 374 i->c = fi.c; 375 } 376 377 void 378 newio(void) 379 { 380 Io *i; 381 static int pushdepth = 0; 382 383 i = iofree; 384 if(i == I) { 385 pushdepth++; 386 if(pushdepth > 1000) { 387 yyerror("macro/io expansion too deep"); 388 errorexit(); 389 } 390 i = alloc(sizeof(*i)); 391 } else 392 iofree = i->link; 393 i->c = 0; 394 i->f = -1; 395 ionext = i; 396 } 397 398 void 399 newfile(char *s, int f) 400 { 401 Io *i; 402 403 if(debug['e']) 404 print("%L: %s\n", lineno, s); 405 406 i = ionext; 407 i->link = iostack; 408 iostack = i; 409 i->f = f; 410 if(f < 0) 411 i->f = open(s, 0); 412 if(i->f < 0) { 413 yyerror("%cc: %r: %s", thechar, s); 414 errorexit(); 415 } 416 fi.c = 0; 417 linklinehist(ctxt, lineno, s, 0); 418 } 419 420 Sym* 421 slookup(char *s) 422 { 423 ensuresymb(strlen(s)); 424 strcpy(symb, s); 425 return lookup(); 426 } 427 428 Sym* 429 lookup(void) 430 { 431 Sym *s; 432 uint32 h; 433 char *p; 434 int c, n; 435 char *r, *w; 436 437 if((uchar)symb[0] == 0xc2 && (uchar)symb[1] == 0xb7) { 438 // turn leading · into ""· 439 h = strlen(symb); 440 ensuresymb(h+2); 441 memmove(symb+2, symb, h+1); 442 symb[0] = '"'; 443 symb[1] = '"'; 444 } 445 446 for(r=w=symb; *r; r++) { 447 // turn · (U+00B7) into . 448 // turn ∕ (U+2215) into / 449 if((uchar)*r == 0xc2 && (uchar)*(r+1) == 0xb7) { 450 *w++ = '.'; 451 r++; 452 }else if((uchar)*r == 0xe2 && (uchar)*(r+1) == 0x88 && (uchar)*(r+2) == 0x95) { 453 *w++ = '/'; 454 r++; 455 r++; 456 }else 457 *w++ = *r; 458 } 459 *w = '\0'; 460 461 h = 0; 462 for(p=symb; *p;) { 463 h = h * 3; 464 h += *p++; 465 } 466 n = (p - symb) + 1; 467 h &= 0xffffff; 468 h %= NHASH; 469 c = symb[0]; 470 for(s = hash[h]; s != S; s = s->link) { 471 if(s->name[0] != c) 472 continue; 473 if(strcmp(s->name, symb) == 0) 474 return s; 475 } 476 s = alloc(sizeof(*s)); 477 s->name = alloc(n); 478 memmove(s->name, symb, n); 479 s->link = hash[h]; 480 hash[h] = s; 481 syminit(s); 482 483 return s; 484 } 485 486 void 487 syminit(Sym *s) 488 { 489 s->lexical = LNAME; 490 s->block = 0; 491 s->offset = 0; 492 s->type = T; 493 s->suetag = T; 494 s->class = CXXX; 495 s->aused = 0; 496 s->sig = SIGNONE; 497 } 498 499 #define EOF (-1) 500 #define IGN (-2) 501 #define ESC (1<<20) 502 #define GETC() ((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff)) 503 504 enum 505 { 506 Numdec = 1<<0, 507 Numlong = 1<<1, 508 Numuns = 1<<2, 509 Numvlong = 1<<3, 510 Numflt = 1<<4, 511 }; 512 513 int32 514 yylex(void) 515 { 516 vlong vv; 517 int32 c, c1, t; 518 char *cp; 519 Rune rune; 520 Sym *s; 521 522 if(peekc != IGN) { 523 c = peekc; 524 peekc = IGN; 525 goto l1; 526 } 527 l0: 528 c = GETC(); 529 530 l1: 531 if(c >= Runeself) { 532 /* 533 * extension -- 534 * all multibyte runes are alpha 535 */ 536 cp = symb; 537 goto talph; 538 } 539 if(isspace(c)) { 540 if(c == '\n') 541 lineno++; 542 goto l0; 543 } 544 if(isalpha(c)) { 545 cp = symb; 546 if(c != 'L') 547 goto talph; 548 *cp++ = c; 549 c = GETC(); 550 if(c == '\'') { 551 /* L'x' */ 552 c = escchar('\'', 1, 0); 553 if(c == EOF) 554 c = '\''; 555 c1 = escchar('\'', 1, 0); 556 if(c1 != EOF) { 557 yyerror("missing '"); 558 peekc = c1; 559 } 560 yylval.vval = convvtox(c, TRUNE); 561 return LUCONST; 562 } 563 if(c == '"') { 564 goto caselq; 565 } 566 goto talph; 567 } 568 if(isdigit(c)) 569 goto tnum; 570 switch(c) 571 { 572 573 case EOF: 574 peekc = EOF; 575 return -1; 576 577 case '_': 578 cp = symb; 579 goto talph; 580 581 case '#': 582 domacro(); 583 goto l0; 584 585 case '.': 586 c1 = GETC(); 587 if(isdigit(c1)) { 588 cp = symb; 589 *cp++ = c; 590 c = c1; 591 c1 = 0; 592 goto casedot; 593 } 594 break; 595 596 case '"': 597 strcpy(symb, "\"<string>\""); 598 cp = alloc(0); 599 c1 = 0; 600 601 /* "..." */ 602 for(;;) { 603 c = escchar('"', 0, 1); 604 if(c == EOF) 605 break; 606 if(c & ESC) { 607 cp = allocn(cp, c1, 1); 608 cp[c1++] = c; 609 } else { 610 rune = c; 611 c = runelen(rune); 612 cp = allocn(cp, c1, c); 613 runetochar(cp+c1, &rune); 614 c1 += c; 615 } 616 } 617 yylval.sval.l = c1; 618 do { 619 cp = allocn(cp, c1, 1); 620 cp[c1++] = 0; 621 } while(c1 & MAXALIGN); 622 yylval.sval.s = cp; 623 return LSTRING; 624 625 caselq: 626 /* L"..." */ 627 strcpy(symb, "\"L<string>\""); 628 cp = alloc(0); 629 c1 = 0; 630 for(;;) { 631 c = escchar('"', 1, 0); 632 if(c == EOF) 633 break; 634 cp = allocn(cp, c1, sizeof(TRune)); 635 *(TRune*)(cp + c1) = c; 636 c1 += sizeof(TRune); 637 } 638 yylval.sval.l = c1; 639 do { 640 cp = allocn(cp, c1, sizeof(TRune)); 641 *(TRune*)(cp + c1) = 0; 642 c1 += sizeof(TRune); 643 } while(c1 & MAXALIGN); 644 yylval.sval.s = cp; 645 return LLSTRING; 646 647 case '\'': 648 /* '.' */ 649 c = escchar('\'', 0, 0); 650 if(c == EOF) 651 c = '\''; 652 c1 = escchar('\'', 0, 0); 653 if(c1 != EOF) { 654 yyerror("missing '"); 655 peekc = c1; 656 } 657 vv = c; 658 yylval.vval = convvtox(vv, TUCHAR); 659 if(yylval.vval != vv) 660 yyerror("overflow in character constant: 0x%x", c); 661 else 662 if(c & 0x80){ 663 nearln = lineno; 664 warn(Z, "sign-extended character constant"); 665 } 666 yylval.vval = convvtox(vv, TCHAR); 667 return LCONST; 668 669 case '/': 670 c1 = GETC(); 671 if(c1 == '*') { 672 for(;;) { 673 c = getr(); 674 while(c == '*') { 675 c = getr(); 676 if(c == '/') 677 goto l0; 678 } 679 if(c == EOF) { 680 yyerror("eof in comment"); 681 errorexit(); 682 } 683 } 684 } 685 if(c1 == '/') { 686 for(;;) { 687 c = getr(); 688 if(c == '\n') 689 goto l0; 690 if(c == EOF) { 691 yyerror("eof in comment"); 692 errorexit(); 693 } 694 } 695 } 696 if(c1 == '=') 697 return LDVE; 698 break; 699 700 case '*': 701 c1 = GETC(); 702 if(c1 == '=') 703 return LMLE; 704 break; 705 706 case '%': 707 c1 = GETC(); 708 if(c1 == '=') 709 return LMDE; 710 break; 711 712 case '+': 713 c1 = GETC(); 714 if(c1 == '+') 715 return LPP; 716 if(c1 == '=') 717 return LPE; 718 break; 719 720 case '-': 721 c1 = GETC(); 722 if(c1 == '-') 723 return LMM; 724 if(c1 == '=') 725 return LME; 726 if(c1 == '>') 727 return LMG; 728 break; 729 730 case '>': 731 c1 = GETC(); 732 if(c1 == '>') { 733 c = LRSH; 734 c1 = GETC(); 735 if(c1 == '=') 736 return LRSHE; 737 break; 738 } 739 if(c1 == '=') 740 return LGE; 741 break; 742 743 case '<': 744 c1 = GETC(); 745 if(c1 == '<') { 746 c = LLSH; 747 c1 = GETC(); 748 if(c1 == '=') 749 return LLSHE; 750 break; 751 } 752 if(c1 == '=') 753 return LLE; 754 break; 755 756 case '=': 757 c1 = GETC(); 758 if(c1 == '=') 759 return LEQ; 760 break; 761 762 case '!': 763 c1 = GETC(); 764 if(c1 == '=') 765 return LNE; 766 break; 767 768 case '&': 769 c1 = GETC(); 770 if(c1 == '&') 771 return LANDAND; 772 if(c1 == '=') 773 return LANDE; 774 break; 775 776 case '|': 777 c1 = GETC(); 778 if(c1 == '|') 779 return LOROR; 780 if(c1 == '=') 781 return LORE; 782 break; 783 784 case '^': 785 c1 = GETC(); 786 if(c1 == '=') 787 return LXORE; 788 break; 789 790 default: 791 return c; 792 } 793 peekc = c1; 794 return c; 795 796 talph: 797 /* 798 * cp is set to symb and some 799 * prefix has been stored 800 */ 801 for(;;) { 802 if(c >= Runeself) { 803 for(c1=0;;) { 804 cp[c1++] = c; 805 if(fullrune(cp, c1)) 806 break; 807 c = GETC(); 808 } 809 cp += c1; 810 c = GETC(); 811 continue; 812 } 813 if(!isalnum(c) && c != '_') 814 break; 815 *cp++ = c; 816 c = GETC(); 817 } 818 *cp = 0; 819 if(debug['L']) 820 print("%L: %s\n", lineno, symb); 821 peekc = c; 822 s = lookup(); 823 if(s->macro) { 824 newio(); 825 cp = ionext->b; 826 macexpand(s, cp); 827 pushio(); 828 ionext->link = iostack; 829 iostack = ionext; 830 fi.p = cp; 831 fi.c = strlen(cp); 832 if(peekc != IGN) { 833 cp[fi.c++] = peekc; 834 cp[fi.c] = 0; 835 peekc = IGN; 836 } 837 goto l0; 838 } 839 yylval.sym = s; 840 if(s->class == CTYPEDEF || s->class == CTYPESTR) 841 return LTYPE; 842 return s->lexical; 843 844 tnum: 845 c1 = 0; 846 cp = symb; 847 if(c != '0') { 848 c1 |= Numdec; 849 for(;;) { 850 *cp++ = c; 851 c = GETC(); 852 if(isdigit(c)) 853 continue; 854 goto dc; 855 } 856 } 857 *cp++ = c; 858 c = GETC(); 859 if(c == 'x' || c == 'X') 860 for(;;) { 861 *cp++ = c; 862 c = GETC(); 863 if(isdigit(c)) 864 continue; 865 if(c >= 'a' && c <= 'f') 866 continue; 867 if(c >= 'A' && c <= 'F') 868 continue; 869 if(cp == symb+2) 870 yyerror("malformed hex constant"); 871 goto ncu; 872 } 873 if(c < '0' || c > '7') 874 goto dc; 875 for(;;) { 876 if(c >= '0' && c <= '7') { 877 *cp++ = c; 878 c = GETC(); 879 continue; 880 } 881 goto ncu; 882 } 883 884 dc: 885 if(c == '.') 886 goto casedot; 887 if(c == 'e' || c == 'E') 888 goto casee; 889 890 ncu: 891 if((c == 'U' || c == 'u') && !(c1 & Numuns)) { 892 c = GETC(); 893 c1 |= Numuns; 894 goto ncu; 895 } 896 if((c == 'L' || c == 'l') && !(c1 & Numvlong)) { 897 c = GETC(); 898 if(c1 & Numlong) 899 c1 |= Numvlong; 900 c1 |= Numlong; 901 goto ncu; 902 } 903 *cp = 0; 904 peekc = c; 905 if(mpatov(symb, &yylval.vval)) 906 yyerror("overflow in constant"); 907 908 vv = yylval.vval; 909 if(c1 & Numvlong) { 910 if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) { 911 c = LUVLCONST; 912 t = TUVLONG; 913 goto nret; 914 } 915 c = LVLCONST; 916 t = TVLONG; 917 goto nret; 918 } 919 if(c1 & Numlong) { 920 if((c1 & Numuns) || convvtox(vv, TLONG) < 0) { 921 c = LULCONST; 922 t = TULONG; 923 goto nret; 924 } 925 c = LLCONST; 926 t = TLONG; 927 goto nret; 928 } 929 if((c1 & Numuns) || convvtox(vv, TINT) < 0) { 930 c = LUCONST; 931 t = TUINT; 932 goto nret; 933 } 934 c = LCONST; 935 t = TINT; 936 goto nret; 937 938 nret: 939 yylval.vval = convvtox(vv, t); 940 if(yylval.vval != vv){ 941 nearln = lineno; 942 warn(Z, "truncated constant: %T %s", types[t], symb); 943 } 944 return c; 945 946 casedot: 947 for(;;) { 948 *cp++ = c; 949 c = GETC(); 950 if(!isdigit(c)) 951 break; 952 } 953 if(c != 'e' && c != 'E') 954 goto caseout; 955 956 casee: 957 *cp++ = 'e'; 958 c = GETC(); 959 if(c == '+' || c == '-') { 960 *cp++ = c; 961 c = GETC(); 962 } 963 if(!isdigit(c)) 964 yyerror("malformed fp constant exponent"); 965 while(isdigit(c)) { 966 *cp++ = c; 967 c = GETC(); 968 } 969 970 caseout: 971 if(c == 'L' || c == 'l') { 972 c = GETC(); 973 c1 |= Numlong; 974 } else 975 if(c == 'F' || c == 'f') { 976 c = GETC(); 977 c1 |= Numflt; 978 } 979 *cp = 0; 980 peekc = c; 981 yylval.dval = strtod(symb, nil); 982 if(isInf(yylval.dval, 1) || isInf(yylval.dval, -1)) { 983 yyerror("overflow in float constant"); 984 yylval.dval = 0; 985 } 986 if(c1 & Numflt) 987 return LFCONST; 988 return LDCONST; 989 } 990 991 /* 992 * convert a string, s, to vlong in *v 993 * return conversion overflow. 994 * required syntax is [0[x]]d* 995 */ 996 int 997 mpatov(char *s, vlong *v) 998 { 999 vlong n, nn; 1000 int c; 1001 1002 n = 0; 1003 c = *s; 1004 if(c == '0') 1005 goto oct; 1006 while(c = *s++) { 1007 if(c >= '0' && c <= '9') 1008 nn = n*10 + c-'0'; 1009 else 1010 goto bad; 1011 if(n < 0 && nn >= 0) 1012 goto bad; 1013 n = nn; 1014 } 1015 goto out; 1016 1017 oct: 1018 s++; 1019 c = *s; 1020 if(c == 'x' || c == 'X') 1021 goto hex; 1022 while(c = *s++) { 1023 if(c >= '0' || c <= '7') 1024 nn = n*8 + c-'0'; 1025 else 1026 goto bad; 1027 if(n < 0 && nn >= 0) 1028 goto bad; 1029 n = nn; 1030 } 1031 goto out; 1032 1033 hex: 1034 s++; 1035 while(c = *s++) { 1036 if(c >= '0' && c <= '9') 1037 c += 0-'0'; 1038 else 1039 if(c >= 'a' && c <= 'f') 1040 c += 10-'a'; 1041 else 1042 if(c >= 'A' && c <= 'F') 1043 c += 10-'A'; 1044 else 1045 goto bad; 1046 nn = (uvlong)n*16 + c; 1047 if(n < 0 && nn >= 0) 1048 goto bad; 1049 n = nn; 1050 } 1051 out: 1052 *v = n; 1053 return 0; 1054 1055 bad: 1056 *v = ~0; 1057 return 1; 1058 } 1059 1060 int 1061 getc(void) 1062 { 1063 int c; 1064 1065 if(peekc != IGN) { 1066 c = peekc; 1067 peekc = IGN; 1068 } else 1069 c = GETC(); 1070 if(c == '\n') 1071 lineno++; 1072 if(c == EOF) { 1073 yyerror("End of file"); 1074 errorexit(); 1075 } 1076 return c; 1077 } 1078 1079 int32 1080 getr(void) 1081 { 1082 int c, i; 1083 char str[UTFmax+1]; 1084 Rune rune; 1085 1086 1087 c = getc(); 1088 if(c < Runeself) 1089 return c; 1090 i = 0; 1091 str[i++] = c; 1092 1093 loop: 1094 c = getc(); 1095 str[i++] = c; 1096 if(!fullrune(str, i)) 1097 goto loop; 1098 c = chartorune(&rune, str); 1099 if(rune == Runeerror && c == 1) { 1100 nearln = lineno; 1101 diag(Z, "illegal rune in string"); 1102 for(c=0; c<i; c++) 1103 print(" %.2x", *(uchar*)(str+c)); 1104 print("\n"); 1105 } 1106 return rune; 1107 } 1108 1109 int 1110 getnsc(void) 1111 { 1112 int c; 1113 1114 if(peekc != IGN) { 1115 c = peekc; 1116 peekc = IGN; 1117 } else 1118 c = GETC(); 1119 for(;;) { 1120 if(c >= Runeself || !isspace(c)) 1121 return c; 1122 if(c == '\n') { 1123 lineno++; 1124 return c; 1125 } 1126 c = GETC(); 1127 } 1128 } 1129 1130 void 1131 unget(int c) 1132 { 1133 1134 peekc = c; 1135 if(c == '\n') 1136 lineno--; 1137 } 1138 1139 int32 1140 escchar(int32 e, int longflg, int escflg) 1141 { 1142 int32 c, l; 1143 int i; 1144 1145 loop: 1146 c = getr(); 1147 if(c == '\n') { 1148 yyerror("newline in string"); 1149 return EOF; 1150 } 1151 if(c != '\\') { 1152 if(c == e) 1153 c = EOF; 1154 return c; 1155 } 1156 c = getr(); 1157 if(c == 'x') { 1158 /* 1159 * note this is not ansi, 1160 * supposed to only accept 2 hex 1161 */ 1162 i = 2; 1163 if(longflg) 1164 i = 6; 1165 l = 0; 1166 for(; i>0; i--) { 1167 c = getc(); 1168 if(c >= '0' && c <= '9') { 1169 l = l*16 + c-'0'; 1170 continue; 1171 } 1172 if(c >= 'a' && c <= 'f') { 1173 l = l*16 + c-'a' + 10; 1174 continue; 1175 } 1176 if(c >= 'A' && c <= 'F') { 1177 l = l*16 + c-'A' + 10; 1178 continue; 1179 } 1180 unget(c); 1181 break; 1182 } 1183 if(escflg) 1184 l |= ESC; 1185 return l; 1186 } 1187 if(c >= '0' && c <= '7') { 1188 /* 1189 * note this is not ansi, 1190 * supposed to only accept 3 oct 1191 */ 1192 i = 2; 1193 if(longflg) 1194 i = 8; 1195 l = c - '0'; 1196 for(; i>0; i--) { 1197 c = getc(); 1198 if(c >= '0' && c <= '7') { 1199 l = l*8 + c-'0'; 1200 continue; 1201 } 1202 unget(c); 1203 } 1204 if(escflg) 1205 l |= ESC; 1206 return l; 1207 } 1208 switch(c) 1209 { 1210 case '\n': goto loop; 1211 case 'n': return '\n'; 1212 case 't': return '\t'; 1213 case 'b': return '\b'; 1214 case 'r': return '\r'; 1215 case 'f': return '\f'; 1216 case 'a': return '\a'; 1217 case 'v': return '\v'; 1218 } 1219 return c; 1220 } 1221 1222 struct 1223 { 1224 char *name; 1225 ushort lexical; 1226 ushort type; 1227 } itab[] = 1228 { 1229 "auto", LAUTO, 0, 1230 "break", LBREAK, 0, 1231 "case", LCASE, 0, 1232 "char", LCHAR, TCHAR, 1233 "const", LCONSTNT, 0, 1234 "continue", LCONTINUE, 0, 1235 "default", LDEFAULT, 0, 1236 "do", LDO, 0, 1237 "double", LDOUBLE, TDOUBLE, 1238 "else", LELSE, 0, 1239 "enum", LENUM, 0, 1240 "extern", LEXTERN, 0, 1241 "float", LFLOAT, TFLOAT, 1242 "for", LFOR, 0, 1243 "goto", LGOTO, 0, 1244 "if", LIF, 0, 1245 "inline", LINLINE, 0, 1246 "int", LINT, TINT, 1247 "long", LLONG, TLONG, 1248 "PREFETCH", LPREFETCH, 0, 1249 "register", LREGISTER, 0, 1250 "restrict", LRESTRICT, 0, 1251 "return", LRETURN, 0, 1252 "SET", LSET, 0, 1253 "short", LSHORT, TSHORT, 1254 "signed", LSIGNED, 0, 1255 "signof", LSIGNOF, 0, 1256 "sizeof", LSIZEOF, 0, 1257 "static", LSTATIC, 0, 1258 "struct", LSTRUCT, 0, 1259 "switch", LSWITCH, 0, 1260 "typedef", LTYPEDEF, 0, 1261 "typestr", LTYPESTR, 0, 1262 "union", LUNION, 0, 1263 "unsigned", LUNSIGNED, 0, 1264 "USED", LUSED, 0, 1265 "void", LVOID, TVOID, 1266 "volatile", LVOLATILE, 0, 1267 "while", LWHILE, 0, 1268 0 1269 }; 1270 1271 void 1272 cinit(void) 1273 { 1274 Sym *s; 1275 int i; 1276 Type *t; 1277 1278 nerrors = 0; 1279 lineno = 1; 1280 iostack = I; 1281 iofree = I; 1282 peekc = IGN; 1283 nhunk = 0; 1284 1285 types[TXXX] = T; 1286 types[TCHAR] = typ(TCHAR, T); 1287 types[TUCHAR] = typ(TUCHAR, T); 1288 types[TSHORT] = typ(TSHORT, T); 1289 types[TUSHORT] = typ(TUSHORT, T); 1290 types[TINT] = typ(TINT, T); 1291 types[TUINT] = typ(TUINT, T); 1292 types[TLONG] = typ(TLONG, T); 1293 types[TULONG] = typ(TULONG, T); 1294 types[TVLONG] = typ(TVLONG, T); 1295 types[TUVLONG] = typ(TUVLONG, T); 1296 types[TFLOAT] = typ(TFLOAT, T); 1297 types[TDOUBLE] = typ(TDOUBLE, T); 1298 types[TVOID] = typ(TVOID, T); 1299 types[TENUM] = typ(TENUM, T); 1300 types[TFUNC] = typ(TFUNC, types[TINT]); 1301 types[TIND] = typ(TIND, types[TVOID]); 1302 1303 for(i=0; i<NHASH; i++) 1304 hash[i] = S; 1305 for(i=0; itab[i].name; i++) { 1306 s = slookup(itab[i].name); 1307 s->lexical = itab[i].lexical; 1308 if(itab[i].type != 0) 1309 s->type = types[itab[i].type]; 1310 } 1311 blockno = 0; 1312 autobn = 0; 1313 autoffset = 0; 1314 1315 t = typ(TARRAY, types[TCHAR]); 1316 t->width = 0; 1317 symstring = slookup(".string"); 1318 symstring->class = CSTATIC; 1319 symstring->type = t; 1320 1321 t = typ(TARRAY, types[TCHAR]); 1322 t->width = 0; 1323 1324 nodproto = new(OPROTO, Z, Z); 1325 dclstack = D; 1326 1327 fmtinstall('O', Oconv); 1328 fmtinstall('T', Tconv); 1329 fmtinstall('F', FNconv); 1330 fmtinstall('L', Lconv); 1331 fmtinstall('Q', Qconv); 1332 fmtinstall('|', VBconv); 1333 fmtinstall('U', Uconv); 1334 fmtinstall('B', Bconv); 1335 } 1336 1337 int 1338 filbuf(void) 1339 { 1340 Io *i; 1341 1342 loop: 1343 i = iostack; 1344 if(i == I) 1345 return EOF; 1346 if(i->f < 0) 1347 goto pop; 1348 fi.c = read(i->f, i->b, BUFSIZ) - 1; 1349 if(fi.c < 0) { 1350 close(i->f); 1351 linklinehist(ctxt, lineno, nil, 0); 1352 goto pop; 1353 } 1354 fi.p = i->b + 1; 1355 return i->b[0] & 0xff; 1356 1357 pop: 1358 iostack = i->link; 1359 i->link = iofree; 1360 iofree = i; 1361 i = iostack; 1362 if(i == I) 1363 return EOF; 1364 fi.p = i->p; 1365 fi.c = i->c; 1366 if(--fi.c < 0) 1367 goto loop; 1368 return *fi.p++ & 0xff; 1369 } 1370 1371 int 1372 Oconv(Fmt *fp) 1373 { 1374 int a; 1375 1376 a = va_arg(fp->args, int); 1377 if(a < OXXX || a > OEND) 1378 return fmtprint(fp, "***badO %d***", a); 1379 1380 return fmtstrcpy(fp, onames[a]); 1381 } 1382 1383 int 1384 Lconv(Fmt *fp) 1385 { 1386 return linklinefmt(ctxt, fp); 1387 } 1388 1389 int 1390 Tconv(Fmt *fp) 1391 { 1392 char str[STRINGSZ+20], s[STRINGSZ+20]; 1393 Type *t, *t1; 1394 int et; 1395 int32 n; 1396 1397 str[0] = 0; 1398 for(t = va_arg(fp->args, Type*); t != T; t = t->link) { 1399 et = t->etype; 1400 if(str[0]) 1401 strcat(str, " "); 1402 if(t->garb&~GINCOMPLETE) { 1403 sprint(s, "%s ", gnames[t->garb&~GINCOMPLETE]); 1404 if(strlen(str) + strlen(s) < STRINGSZ) 1405 strcat(str, s); 1406 } 1407 sprint(s, "%s", tnames[et]); 1408 if(strlen(str) + strlen(s) < STRINGSZ) 1409 strcat(str, s); 1410 if(et == TFUNC && (t1 = t->down)) { 1411 sprint(s, "(%T", t1); 1412 if(strlen(str) + strlen(s) < STRINGSZ) 1413 strcat(str, s); 1414 while(t1 = t1->down) { 1415 sprint(s, ", %T", t1); 1416 if(strlen(str) + strlen(s) < STRINGSZ) 1417 strcat(str, s); 1418 } 1419 if(strlen(str) + strlen(s) < STRINGSZ) 1420 strcat(str, ")"); 1421 } 1422 if(et == TARRAY) { 1423 n = t->width; 1424 if(t->link && t->link->width) 1425 n /= t->link->width; 1426 sprint(s, "[%d]", n); 1427 if(strlen(str) + strlen(s) < STRINGSZ) 1428 strcat(str, s); 1429 } 1430 if(t->nbits) { 1431 sprint(s, " %d:%d", t->shift, t->nbits); 1432 if(strlen(str) + strlen(s) < STRINGSZ) 1433 strcat(str, s); 1434 } 1435 if(typesu[et]) { 1436 if(t->tag) { 1437 strcat(str, " "); 1438 if(strlen(str) + strlen(t->tag->name) < STRINGSZ) 1439 strcat(str, t->tag->name); 1440 } else 1441 strcat(str, " {}"); 1442 break; 1443 } 1444 } 1445 return fmtstrcpy(fp, str); 1446 } 1447 1448 int 1449 FNconv(Fmt *fp) 1450 { 1451 char *str; 1452 Node *n; 1453 1454 n = va_arg(fp->args, Node*); 1455 str = "<indirect>"; 1456 if(n != Z && (n->op == ONAME || n->op == ODOT || n->op == OELEM)) 1457 str = n->sym->name; 1458 return fmtstrcpy(fp, str); 1459 } 1460 1461 int 1462 Qconv(Fmt *fp) 1463 { 1464 char str[STRINGSZ+20], *s; 1465 int32 b; 1466 int i; 1467 1468 str[0] = 0; 1469 for(b = va_arg(fp->args, int32); b;) { 1470 i = bitno(b); 1471 if(str[0]) 1472 strcat(str, " "); 1473 s = qnames[i]; 1474 if(strlen(str) + strlen(s) >= STRINGSZ) 1475 break; 1476 strcat(str, s); 1477 b &= ~(1L << i); 1478 } 1479 return fmtstrcpy(fp, str); 1480 } 1481 1482 int 1483 VBconv(Fmt *fp) 1484 { 1485 char str[STRINGSZ]; 1486 int i, n, t, pc; 1487 1488 n = va_arg(fp->args, int); 1489 pc = 0; /* BUG: was printcol */ 1490 i = 0; 1491 while(pc < n) { 1492 t = (pc+4) & ~3; 1493 if(t <= n) { 1494 str[i++] = '\t'; 1495 pc = t; 1496 continue; 1497 } 1498 str[i++] = ' '; 1499 pc++; 1500 } 1501 str[i] = 0; 1502 1503 return fmtstrcpy(fp, str); 1504 } 1505 1506 int 1507 Bconv(Fmt *fp) 1508 { 1509 char str[STRINGSZ], ss[STRINGSZ], *s; 1510 Bits bits; 1511 int i; 1512 1513 str[0] = 0; 1514 bits = va_arg(fp->args, Bits); 1515 while(bany(&bits)) { 1516 i = bnum(bits); 1517 if(str[0]) 1518 strcat(str, " "); 1519 if(var[i].sym == nil) { 1520 sprint(ss, "$%lld", var[i].offset); 1521 s = ss; 1522 } else 1523 s = var[i].sym->name; 1524 if(strlen(str) + strlen(s) + 1 >= STRINGSZ) 1525 break; 1526 strcat(str, s); 1527 bits.b[i/32] &= ~(1L << (i%32)); 1528 } 1529 return fmtstrcpy(fp, str); 1530 } 1531 1532 void 1533 setinclude(char *p) 1534 { 1535 int i; 1536 1537 if(*p != 0) { 1538 for(i=1; i < ninclude; i++) 1539 if(strcmp(p, include[i]) == 0) 1540 return; 1541 1542 if(ninclude%8 == 0) 1543 include = allocn(include, ninclude*sizeof(char *), 1544 8*sizeof(char *)); 1545 include[ninclude++] = p; 1546 } 1547 } 1548 1549 void* 1550 alloc(int32 n) 1551 { 1552 void *p; 1553 1554 p = malloc(n); 1555 if(p == nil) { 1556 print("alloc out of mem\n"); 1557 exits("alloc: out of mem"); 1558 } 1559 memset(p, 0, n); 1560 return p; 1561 } 1562 1563 void* 1564 allocn(void *p, int32 n, int32 d) 1565 { 1566 if(p == nil) 1567 return alloc(n+d); 1568 p = realloc(p, n+d); 1569 if(p == nil) { 1570 print("allocn out of mem\n"); 1571 exits("allocn: out of mem"); 1572 } 1573 if(d > 0) 1574 memset((char*)p+n, 0, d); 1575 return p; 1576 } 1577 1578 void 1579 ensuresymb(int32 n) 1580 { 1581 if(symb == nil) { 1582 symb = alloc(NSYMB+1); 1583 nsymb = NSYMB; 1584 } 1585 1586 if(n > nsymb) { 1587 symb = allocn(symb, nsymb, n+1-nsymb); 1588 nsymb = n; 1589 } 1590 }