1: #define SBSIZE 2000 2: char sbf[SBSIZE]; 3: /* C command */ 4: 5: char *tmp0; 6: char *tmp1; 7: char *tmp2; 8: char *tmp3; 9: char *tmp4; 10: char *tmp5; 11: char ts[1000]; 12: char *tsp ts; 13: char *av[50]; 14: char *clist[50]; 15: char *llist[50]; 16: int instring; 17: int pflag; 18: int sflag; 19: int cflag; 20: int oflag; 21: int proflag; 22: int depth; 23: int *ibuf; 24: int *ibuf1; 25: int *ibuf2; 26: int *obuf; 27: char *lp; 28: char *line; 29: int lineno; 30: int exfail; 31: struct symtab { 32: char name[8]; 33: char *value; 34: } *symtab; 35: int symsiz 200; 36: struct symtab *defloc; 37: struct symtab *incloc; 38: struct symtab *eifloc; 39: struct symtab *ifdloc; 40: struct symtab *ifnloc; 41: struct symtab *unxloc; 42: int trulvl; 43: int flslvl; 44: char *stringbuf; 45: char *pass0 "/lib/c0"; 46: char *pass1 "/lib/c1"; 47: char *pass2 "/lib/c2"; 48: char *pref "/lib/crt0.o"; 49: 50: main(argc, argv) 51: char *argv[]; { 52: char *t; 53: int nc, nl, i, j, c, f20, nxo; 54: int dexit(); 55: 56: i = nc = nl = f20 = nxo = 0; 57: while(++i < argc) { 58: if(*argv[i] == '-') 59: switch (argv[i][1]) { 60: default: 61: goto passa; 62: case 'S': 63: sflag++; 64: cflag++; 65: break; 66: case 'O': 67: oflag++; 68: break; 69: case 'p': 70: proflag++; 71: pref = "/lib/mcrt0.o"; 72: break; 73: case 'P': 74: pflag++; 75: case 'c': 76: cflag++; 77: break; 78: 79: case 'f': 80: pref = "/lib/fcrt0.o"; 81: pass0 = "/lib/fc0"; 82: pass1 = "/lib/fc1"; 83: break; 84: 85: case '2': 86: if(argv[i][2] == '\0') 87: pref = "/lib/crt2.o"; 88: else { 89: pref = "/lib/crt20.o"; 90: f20 = 1; 91: } 92: break; 93: case 't': 94: if (argv[i][2]=='0') 95: pass0 = "/usr/c/c0"; 96: if (argv[i][2]=='1') 97: pass1 = "/usr/c/c1"; 98: if (argv[i][2]=='2') 99: pass2 = "/usr/c/c2"; 100: break; 101: } 102: else { 103: passa: 104: t = argv[i]; 105: if(getsuf(t)=='c') { 106: clist[nc++] = t; 107: t = setsuf(t, 'o'); 108: } 109: if (nodup(llist, t)) { 110: llist[nl++] = t; 111: if (getsuf(t)=='o') 112: nxo++; 113: } 114: } 115: } 116: if(nc==0) 117: goto nocom; 118: if (pflag==0) { 119: tmp0 = copy("/tmp/ctm0a"); 120: while((c=open(tmp0, 0))>=0) { 121: close(c); 122: tmp0[9]++; 123: } 124: while((creat(tmp0, 0400))<0) 125: tmp0[9]++; 126: } 127: if ((signal(2, 1) & 01) == 0) 128: signal(2, &dexit); 129: (tmp1 = copy(tmp0))[8] = '1'; 130: (tmp2 = copy(tmp0))[8] = '2'; 131: (tmp3 = copy(tmp0))[8] = '3'; 132: if (oflag) 133: (tmp5 = copy(tmp0))[8] = '5'; 134: if (pflag==0) 135: (tmp4 = copy(tmp0))[8] = '4'; 136: for (i=0; i<nc; i++) { 137: if (nc>1) 138: printf("%s:\n", clist[i]); 139: av[0] = "c0"; 140: if (pflag) 141: tmp4 = setsuf(clist[i], 'i'); 142: av[1] = expand(clist[i]); 143: if (pflag || exfail) 144: continue; 145: if (av[1] == 0) { 146: cflag++; 147: continue; 148: } 149: av[2] = tmp1; 150: av[3] = tmp2; 151: if (proflag) { 152: av[4] = "-P"; 153: av[5] = 0; 154: } else 155: av[4] = 0; 156: if (callsys(pass0, av)) { 157: cflag++; 158: continue; 159: } 160: av[0] = "c1"; 161: av[1] = tmp1; 162: av[2] = tmp2; 163: if (sflag) 164: tmp3 = setsuf(clist[i], 's'); 165: av[3] = tmp3; 166: if (oflag) 167: av[3] = tmp5; 168: av[4] = 0; 169: if(callsys(pass1, av)) { 170: cflag++; 171: continue; 172: } 173: if (oflag) { 174: av[0] = "c2"; 175: av[1] = tmp5; 176: av[2] = tmp3; 177: av[3] = 0; 178: callsys(pass2, av); 179: unlink(tmp5); 180: } 181: if (sflag) 182: continue; 183: av[0] = "as"; 184: av[1] = "-"; 185: av[2] = tmp3; 186: av[3] = 0; 187: cunlink(tmp1); 188: cunlink(tmp2); 189: cunlink(tmp4); 190: callsys("/bin/as", av); 191: t = setsuf(clist[i], 'o'); 192: cunlink(t); 193: if(link("a.out", t) || cunlink("a.out")) { 194: printf("move failed: %s\n", t); 195: cflag++; 196: } 197: } 198: nocom: 199: if (cflag==0 && nl!=0) { 200: i = 0; 201: av[0] = "ld"; 202: av[1] = "-X"; 203: av[2] = pref; 204: j = 3; 205: while(i<nl) 206: av[j++] = llist[i++]; 207: if(f20) 208: av[j++] = "-l2"; 209: else { 210: av[j++] = "-lc"; 211: av[j++] = "-l"; 212: } 213: av[j++] = 0; 214: callsys("/bin/ld", av); 215: if (nc==1 && nxo==1) 216: cunlink(setsuf(clist[0], 'o')); 217: } 218: dexit(); 219: } 220: 221: dexit() 222: { 223: if (!pflag) { 224: cunlink(tmp1); 225: cunlink(tmp2); 226: if (sflag==0) 227: cunlink(tmp3); 228: cunlink(tmp4); 229: cunlink(tmp5); 230: cunlink(tmp0); 231: } 232: exit(); 233: } 234: 235: expand(file) 236: char *file; 237: { 238: int ib1[259], ib2[259], ob[259]; 239: struct symtab stab[200]; 240: char ln[196]; 241: register int c; 242: register char *rlp; 243: 244: exfail = 0; 245: ibuf = ibuf1 = ib1; 246: ibuf2 = ib2; 247: if (fopen(file, ibuf1)<0) 248: return(file); 249: if (getc(ibuf1) != '#') { 250: close(ibuf1[0]); 251: return(file); 252: } 253: ibuf1[1]++; 254: ibuf1[2]--; 255: obuf = ob; 256: symtab = stab; 257: for (c=0; c<200; c++) { 258: stab[c].name[0] = '\0'; 259: stab[c].value = 0; 260: } 261: insym(&defloc, "define"); 262: insym(&incloc, "include"); 263: insym(&eifloc, "endif"); 264: insym(&ifdloc, "ifdef"); 265: insym(&ifnloc, "ifndef"); 266: insym(&unxloc, "unix"); 267: stringbuf = sbf; 268: trulvl = 0; 269: flslvl = 0; 270: line = ln; 271: lineno = 0; 272: if (fcreat(tmp4, obuf) < 0) { 273: printf("Can't creat %s\n", tmp4); 274: dexit(); 275: } 276: while(getline()) { 277: if (ibuf==ibuf2 && pflag==0) 278: putc(001, obuf); /*SOH: insert */ 279: if (ln[0] != '#' && flslvl==0) 280: for (rlp = line; c = *rlp++;) 281: putc(c, obuf); 282: putc('\n', obuf); 283: } 284: for(rlp=line; c = *rlp++;) 285: putc(c,obuf); 286: fflush(obuf); 287: close(obuf[0]); 288: close(ibuf1[0]); 289: return(tmp4); 290: } 291: 292: getline() 293: { 294: register int c, sc, state; 295: struct symtab *np; 296: char *namep, *filname; 297: 298: if (ibuf==ibuf1) 299: lineno++; 300: lp = line; 301: *lp = '\0'; 302: state = 0; 303: if ((c=getch()) == '#') 304: state = 1; 305: while (c!='\n' && c!='\0') { 306: if ('a'<=c && c<='z' || 'A'<=c && c<='Z' || c=='_') { 307: namep = lp; 308: sch(c); 309: while ('a'<=(c=getch()) && c<='z' 310: ||'A'<=c && c<='Z' 311: ||'0'<=c && c<='9' 312: ||c=='_') 313: sch(c); 314: sch('\0'); 315: lp--; 316: if (state>3) { 317: if (flslvl==0 &&(state+!lookup(namep,-1)->name[0])==5) 318: trulvl++; 319: else 320: flslvl++; 321: out: 322: while (c!='\n' && c!= '\0') 323: c = getch(); 324: return(c); 325: } 326: if (state!=2 || flslvl==0) 327: { 328: ungetc(c); 329: np = lookup(namep, state); 330: c = getch(); 331: } 332: if (state==1) { 333: if (np==defloc) 334: state = 2; 335: else if (np==incloc) 336: state = 3; 337: else if (np==ifnloc) 338: state = 4; 339: else if (np==ifdloc) 340: state = 5; 341: else if (np==eifloc) { 342: if (flslvl) 343: --flslvl; 344: else if (trulvl) 345: --trulvl; 346: else error("If-less endif"); 347: goto out; 348: } 349: else { 350: error("Undefined control"); 351: while (c!='\n' && c!='\0') 352: c = getch(); 353: return(c); 354: } 355: } else if (state==2) { 356: if (flslvl) 357: goto out; 358: np->value = stringbuf; 359: savch(c); 360: while ((c=getch())!='\n' && c!='\0') 361: savch(c); 362: savch('\0'); 363: return(1); 364: } 365: continue; 366: } else if ((sc=c)=='\'' || sc=='"') { 367: sch(sc); 368: filname = lp; 369: instring++; 370: while ((c=getch())!=sc && c!='\n' && c!='\0') { 371: sch(c); 372: if (c=='\\') 373: sch(getch()); 374: } 375: instring = 0; 376: if (flslvl) 377: goto out; 378: if (state==3) { 379: if (flslvl) 380: goto out; 381: *lp = '\0'; 382: while ((c=getch())!='\n' && c!='\0'); 383: if (ibuf==ibuf2) 384: error("Nested 'include'"); 385: if (fopen(filname, ibuf2)<0) 386: error("Missing file %s", filname); 387: else 388: ibuf = ibuf2; 389: return(c); 390: } 391: } 392: sch(c); 393: c = getch(); 394: } 395: sch('\0'); 396: if (state>1) 397: error("Control syntax"); 398: return(c); 399: } 400: 401: insym(sp, namep) 402: struct symtab **sp; 403: char *namep; 404: { 405: register struct symtab *np; 406: 407: *sp = np = lookup(namep, 1); 408: np->value = np->name; 409: } 410: 411: error(s, x) 412: { 413: printf("%d: ", lineno); 414: printf(s, x); 415: putchar('\n'); 416: exfail++; 417: cflag++; 418: } 419: 420: sch(c) 421: { 422: register char *rlp; 423: 424: rlp = lp; 425: if (rlp==line+194) 426: error("Line overflow"); 427: *rlp++ = c; 428: if (rlp>line+195) 429: rlp = line+195; 430: lp = rlp; 431: } 432: 433: savch(c) 434: { 435: *stringbuf++ = c; 436: if (stringbuf-sbf < SBSIZE) 437: return; 438: error("Too much defining"); 439: dexit(); 440: } 441: 442: getch() 443: { 444: register int c; 445: 446: loop: 447: if ((c=getc1())=='/' && !instring) { 448: if ((c=getc1())!='*') 449: { 450: ungetc(c); 451: return('/'); 452: } 453: for(;;) { 454: c = getc1(); 455: cloop: 456: switch (c) { 457: 458: case '\0': 459: return('\0'); 460: 461: case '*': 462: if ((c=getc1())=='/') 463: goto loop; 464: goto cloop; 465: 466: case '\n': 467: if (ibuf==ibuf1) { 468: putc('\n', obuf); 469: lineno++; 470: } 471: continue; 472: } 473: } 474: } 475: return(c); 476: } 477: char pushbuff[300]; 478: char *pushp pushbuff; 479: ungetc(c) 480: { 481: *++pushp = c; 482: } 483: 484: getc1() 485: { 486: register c; 487: 488: if (*pushp !=0) 489: return(*pushp--); 490: depth=0; 491: if ((c = getc(ibuf)) < 0 && ibuf==ibuf2) { 492: close(ibuf2[0]); 493: ibuf = ibuf1; 494: putc('\n', obuf); 495: lineno++; 496: c = getc1(); 497: } 498: if (c<0) 499: return(0); 500: return(c); 501: } 502: 503: lookup(namep, enterf) 504: char *namep; 505: { 506: register char *np, *snp; 507: register struct symtab *sp; 508: int i, c, around; 509: np = namep; 510: around = i = 0; 511: while (c = *np++) 512: i =+ c; 513: i =% symsiz; 514: sp = &symtab[i]; 515: while (sp->name[0]) { 516: snp = sp; 517: np = namep; 518: while (*snp++ == *np) 519: if (*np++ == '\0' || np==namep+8) { 520: if (!enterf) 521: subst(namep, sp); 522: return(sp); 523: } 524: if (++sp >= &symtab[symsiz]) 525: if (around++) 526: { 527: error("too many defines"); 528: dexit(); 529: } 530: else 531: sp = symtab; 532: } 533: if (enterf>0) { 534: snp = namep; 535: for (np = &sp->name[0]; np < &sp->name[8];) 536: if (*np++ = *snp) 537: snp++; 538: } 539: return(sp); 540: } 541: char revbuff[200]; 542: char *bp; 543: backsch(c) 544: { 545: if (bp-revbuff > 200) 546: error("Excessive define looping", bp--); 547: *bp++ = c; 548: } 549: 550: subst(np, sp) 551: char *np; 552: struct symtab *sp; 553: { 554: register char *vp; 555: 556: lp = np; 557: bp = revbuff; 558: if (depth++>100) 559: { 560: error("define recursion loop\n"); 561: return; 562: } 563: if ((vp = sp->value) == 0) 564: return; 565: /* arrange that define unix unix still 566: has no effect, avoiding rescanning */ 567: if (streq(sp->name,sp->value)) 568: { 569: while (*vp) 570: sch(*vp++); 571: return; 572: } 573: backsch(' '); 574: if (*vp == '(') 575: expdef(vp); 576: else 577: while (*vp) 578: backsch(*vp++); 579: backsch(' '); 580: while (bp>revbuff) 581: ungetc(*--bp); 582: } 583: 584: getsuf(as) 585: char as[]; 586: { 587: register int c; 588: register char *s; 589: register int t; 590: 591: s = as; 592: c = 0; 593: while(t = *s++) 594: if (t=='/') 595: c = 0; 596: else 597: c++; 598: s =- 3; 599: if (c<=14 && c>2 && *s++=='.') 600: return(*s); 601: return(0); 602: } 603: 604: setsuf(as, ch) 605: char as[]; 606: { 607: register char *s, *s1; 608: 609: s = s1 = copy(as); 610: while(*s) 611: if (*s++ == '/') 612: s1 = s; 613: s[-1] = ch; 614: return(s1); 615: } 616: 617: callsys(f, v) 618: char f[], *v[]; { 619: int t, status; 620: 621: if ((t=fork())==0) { 622: execv(f, v); 623: printf("Can't find %s\n", f); 624: exit(1); 625: } else 626: if (t == -1) { 627: printf("Try again\n"); 628: return(1); 629: } 630: while(t!=wait(&status)); 631: if ((t=(status&0377)) != 0 && t!=14) { 632: if (t!=2) /* interrupt */ 633: printf("Fatal error in %s\n", f); 634: dexit(); 635: } 636: return((status>>8) & 0377); 637: } 638: 639: copy(as) 640: char as[]; 641: { 642: register char *otsp, *s; 643: 644: otsp = tsp; 645: s = as; 646: while(*tsp++ = *s++); 647: return(otsp); 648: } 649: 650: nodup(l, os) 651: char **l, *os; 652: { 653: register char *t, *s; 654: register int c; 655: 656: s = os; 657: if (getsuf(s) != 'o') 658: return(1); 659: while(t = *l++) { 660: while(c = *s++) 661: if (c != *t++) 662: break; 663: if (*t=='\0' && c=='\0') 664: return(0); 665: s = os; 666: } 667: return(1); 668: } 669: 670: cunlink(f) 671: char *f; 672: { 673: if (f==0) 674: return(0); 675: return(unlink(f)); 676: } 677: expdef(proto) 678: char *proto; 679: { 680: char buffer[100], *parg[20], *pval[20], name[20], *cspace, *wp; 681: char protcop[100], *pr; 682: int narg, k, i, c; 683: pr = protcop; 684: while (*pr++ = *proto++); 685: proto= protcop; 686: for (narg=0; (parg[narg] = token(&proto)) != 0; narg++) 687: ; 688: /* now scan input */ 689: cspace = buffer; 690: while ((c=getch()) == ' '); 691: if (c != '(') 692: { 693: error("defined function requires arguments"); 694: return; 695: } 696: ungetc(c); 697: for(k=0; pval[k] = coptok(&cspace); k++); 698: if (k!=narg) 699: { 700: error("define argument mismatch"); 701: return; 702: } 703: while (c= *proto++) 704: { 705: if (!letter(c)) 706: backsch(c); 707: else 708: { 709: wp = name; 710: *wp++ = c; 711: while (letnum(*proto)) 712: *wp++ = *proto++; 713: *wp = 0; 714: for (k=0; k<narg; k++) 715: if(streq(name,parg[k])) 716: break; 717: wp = k <narg ? pval[k] : name; 718: while (*wp) backsch(*wp++); 719: } 720: } 721: } 722: token(cpp) char **cpp; 723: { 724: char *val; 725: int stc; 726: stc = **cpp; 727: *(*cpp)++ = '\0'; 728: if (stc==')') return(0); 729: while (**cpp == ' ') (*cpp)++; 730: for (val = *cpp; (stc= **cpp) != ',' && stc!= ')'; (*cpp)++) 731: { 732: if (!letnum(stc) || (val == *cpp && !letter(stc))) 733: { 734: error("define prototype argument error"); 735: break; 736: } 737: } 738: return(val); 739: } 740: coptok (cpp) char **cpp; { 741: char *val; 742: int stc, stop,paren; 743: paren = 0; 744: val = *cpp; 745: if (getch() == ')') 746: return(0); 747: while (((stc = getch()) != ',' && stc != ')') || paren > 0) 748: { 749: if (stc == '"' || stc == '\'') 750: { 751: stop = stc; 752: if (stop == '\'') 753: *(*cpp)++ = '\''; 754: while ( (stc = getch()) != stop) 755: { 756: if (stc == '\n') 757: { 758: error ("non-terminated string"); 759: break; 760: } 761: if (stc == '\\') 762: if ((stc= getch()) != stop && stc != '\\') 763: *(*cpp)++ = '\\'; 764: *(*cpp)++ = stc; 765: } 766: if (stop == '\'') 767: *(*cpp)++ = '\''; 768: } 769: else if (stc == '\\') 770: { 771: stc = getch(); 772: if (stc != '"' && stc != '\\') 773: *(*cpp)++ = '\\'; 774: *(*cpp)++ = stc; 775: } 776: else 777: { 778: *(*cpp)++ = stc; 779: if (stc == '(') 780: paren++; 781: if (stc == ')') 782: paren--; 783: } 784: } 785: *(*cpp)++ = 0; 786: ungetc(stc); 787: return(val); 788: } 789: letter(c) 790: { 791: if ((c >= 'a' && c <= 'z') || 792: (c >= 'A' && c <= 'Z') || 793: (c == '_')) 794: return (1); 795: else 796: return(0); 797: } 798: letnum(c) 799: { 800: if (letter(c) || (c >= '0' && c <= '9')) 801: return(1); 802: else 803: return(0); 804: } 805: streq(s,t) char *s, *t; 806: { 807: int c; 808: while ( (c= *s++) == *t++) 809: if (c==0) return(1); 810: return(0); 811: }