1: static char sccsid[] = "@(#)cc.c 2.6"; /* SCCS id keyword */ 2: # 3: # include <stdio.h> 4: # include <ctype.h> 5: # include <signal.h> 6: # include <whoami.h> 7: 8: /* cc command */ 9: 10: # define MAXINC 10 11: # define MAXFIL 100 12: # define MAXLIB 100 13: # define MAXOPT 100 14: char *tmp0; 15: char *tmp1; 16: char *tmp2; 17: char *tmp3; 18: char *tmp4; 19: char *tmp5; 20: char *outfile; 21: # define CHSPACE 1000 22: char ts[CHSPACE+50]; 23: char *tsa = ts; 24: char *tsp = ts; 25: char *av[50]; 26: char *clist[MAXFIL]; 27: char *llist[MAXLIB]; 28: int pflag; 29: int sflag; 30: int cflag; 31: int eflag; 32: int iflag; 33: int vflag; 34: int exflag; 35: int oflag; 36: int proflag; 37: #ifdef MENLO_OVLY 38: int ovlyflag; 39: /* 40: * Predefined constant always true for an overlay compilation. 41: * Useful for sorting through include files... 42: */ 43: #define OVL_DEF "-DC_OVERLAY" 44: #define OVLIBC "-lovc" 45: #endif MENLO_OVLY 46: #define LD "/bin/ld" 47: #define AS "/bin/as" 48: #define LIBC "-lc" 49: int noflflag; 50: char *chpass ; 51: char *npassname ; 52: char pass0[20] = "/lib/c0"; 53: char pass1[20] = "/lib/c1"; 54: char pass2[20] = "/lib/c2"; 55: char passp[20] = "/lib/cpp"; 56: char *pref = "/lib/crt0.o"; 57: char *copy(); 58: char *setsuf(); 59: char *strcat(); 60: char *strcpy(); 61: 62: main(argc, argv) 63: char *argv[]; 64: { 65: char *t; 66: char *savetsp; 67: char *assource; 68: char **pv, *ptemp[MAXOPT], **pvt; 69: int nc, nl, i, j, c, f20, nxo, na; 70: int idexit(); 71: 72: i = nc = nl = f20 = nxo = 0; 73: setbuf(stdout, (char *)NULL); 74: pv = ptemp; 75: while(++i < argc) { 76: if(*argv[i] == '-') switch (argv[i][1]) { 77: default: 78: goto passa; 79: case 'S': 80: sflag++; 81: cflag++; 82: break; 83: case 'o': 84: if (++i < argc) { 85: outfile = argv[i]; 86: if ((c=getsuf(outfile))=='c'||c=='o') { 87: error("Would overwrite %s", outfile); 88: exit(8); 89: } 90: } 91: break; 92: case 'O': 93: oflag++; 94: break; 95: case 'p': 96: proflag++; 97: break; 98: #ifdef MENLO_OVLY 99: case 'V': 100: ovlyflag++; 101: *pv++ = OVL_DEF; 102: if (pv >= ptemp+MAXOPT) { 103: error("Too many DIUC options", (char *)NULL); 104: --pv; 105: } 106: break; 107: #endif MENLO_OVLY 108: case 'E': 109: exflag++; 110: case 'P': 111: pflag++; 112: *pv++ = argv[i]; 113: case 'c': 114: cflag++; 115: break; 116: 117: case 'f': 118: noflflag++; 119: if (npassname || chpass) 120: error("-f overwrites earlier option", (char *)NULL); 121: npassname = "/lib/f"; 122: chpass = "1"; 123: break; 124: 125: case '2': 126: if(argv[i][2] == '\0') 127: pref = "/lib/crt2.o"; 128: else { 129: pref = "/lib/crt20.o"; 130: f20 = 1; 131: } 132: break; 133: case 'D': 134: case 'I': 135: case 'U': 136: case 'C': 137: *pv++ = argv[i]; 138: if (pv >= ptemp+MAXOPT) { 139: error("Too many DIUC options", (char *)NULL); 140: --pv; 141: } 142: break; 143: case 't': 144: if (chpass) 145: error("-t overwrites earlier option", (char *)NULL); 146: chpass = argv[i]+2; 147: if (chpass[0]==0) 148: chpass = "012p"; 149: break; 150: 151: case 'B': 152: if (npassname) 153: error("-B overwrites earlier option", (char *)NULL); 154: npassname = argv[i]+2; 155: if (npassname[0]==0) 156: npassname = "/usr/src/cmd/c/o"; 157: break; 158: 159: case 'v': 160: vflag++; 161: break; 162: 163: case 'i': 164: iflag++; 165: break; 166: } 167: else { 168: passa: 169: t = argv[i]; 170: if((c=getsuf(t))=='c' || c=='s'|| exflag) { 171: clist[nc++] = t; 172: if (nc>=MAXFIL) { 173: error("Too many source files", (char *)NULL); 174: exit(1); 175: } 176: t = setsuf(t, 'o'); 177: } 178: if (nodup(llist, t)) { 179: llist[nl++] = t; 180: if (nl >= MAXLIB) { 181: error("Too many object/library files", (char *)NULL); 182: exit(1); 183: } 184: if (getsuf(t)=='o') 185: nxo++; 186: } 187: } 188: } 189: if (npassname && chpass ==0) 190: chpass = "012p"; 191: if (chpass && npassname==0) 192: npassname = "/usr/src/cmd/c/"; 193: if (chpass) 194: for (t=chpass; *t; t++) { 195: switch (*t) { 196: case '0': 197: strcpy (pass0, npassname); 198: strcat (pass0, "c0"); 199: continue; 200: case '1': 201: strcpy (pass1, npassname); 202: strcat (pass1, "c1"); 203: continue; 204: case '2': 205: strcpy (pass2, npassname); 206: strcat (pass2, "c2"); 207: continue; 208: case 'p': 209: strcpy (passp, npassname); 210: strcat (passp, "cpp"); 211: continue; 212: } 213: } 214: if (noflflag) 215: pref = proflag ? "/lib/fmcrt0.o" : "/lib/fcrt0.o"; 216: else if (proflag) 217: pref = "/lib/mcrt0.o"; 218: if(nc==0) 219: goto nocom; 220: if (pflag==0) { 221: char FD; 222: 223: tmp0 = copy("/tmp/ctm0XXXXX"); 224: mktemp (tmp0); 225: FD = creat (tmp0); 226: if (FD < 0) 227: { 228: error("cc: cannot create temp", NULL); 229: exit(1); 230: } 231: close (FD); 232: } 233: if (signal(SIGINT, SIG_IGN) != SIG_IGN) 234: signal(SIGINT, idexit); 235: if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 236: signal(SIGTERM, idexit); 237: (tmp1 = copy(tmp0))[8] = '1'; 238: (tmp2 = copy(tmp0))[8] = '2'; 239: (tmp3 = copy(tmp0))[8] = '3'; 240: if (oflag) 241: (tmp5 = copy(tmp0))[8] = '5'; 242: if (pflag==0) 243: (tmp4 = copy(tmp0))[8] = '4'; 244: pvt = pv; 245: for (i=0; i<nc; i++) { 246: if (nc>1 || vflag) 247: printf("%s:\n", clist[i]); 248: if (getsuf(clist[i])=='s') { 249: assource = clist[i]; 250: goto assemble; 251: } 252: else 253: assource = tmp3; 254: if (pflag) 255: tmp4 = setsuf(clist[i], 'i'); 256: savetsp = tsp; 257: av[0] = "cpp"; 258: av[1] = clist[i]; 259: av[2] = exflag ? "-" : tmp4; 260: na = 3; 261: for(pv=ptemp; pv <pvt; pv++) 262: av[na++] = *pv; 263: av[na++]=0; 264: if(vflag) 265: doecho(passp, av); 266: if (callsys(passp, av)) { 267: cflag++; 268: eflag++; 269: continue; 270: } 271: av[1] = tmp4; 272: tsp = savetsp; 273: av[0]= "c0"; 274: if (pflag) { 275: cflag++; 276: continue; 277: } 278: na = 2; 279: av[na++] = tmp1; 280: av[na++] = tmp2; 281: if (proflag) 282: av[na++] = "-P"; 283: #ifdef MENLO_OVLY 284: if (ovlyflag) 285: av[na++] = "-V"; 286: #endif 287: av[na++] = 0; 288: if(vflag) 289: doecho(pass0, av); 290: if (callsys(pass0, av)) { 291: cflag++; 292: eflag++; 293: continue; 294: } 295: av[0] = "c1"; 296: av[1] = tmp1; 297: av[2] = tmp2; 298: if (sflag) 299: assource = tmp3 = setsuf(clist[i], 's'); 300: av[3] = tmp3; 301: if (oflag) 302: av[3] = tmp5; 303: na = 4; 304: #ifdef MENLO_OVLY 305: if (ovlyflag) 306: av[na++] = "-V"; 307: #endif 308: av[na++] = 0; 309: if(vflag) 310: doecho(pass1, av); 311: if(callsys(pass1, av)) { 312: cflag++; 313: eflag++; 314: continue; 315: } 316: if (oflag) { 317: av[0] = "c2"; 318: av[1] = tmp5; 319: av[2] = tmp3; 320: av[3] = 0; 321: if(vflag) 322: doecho(pass2, av); 323: if (callsys(pass2, av)) { 324: unlink(tmp3); 325: tmp3 = assource = tmp5; 326: } 327: else 328: unlink(tmp5); 329: } 330: if (sflag) 331: continue; 332: assemble: 333: av[0] = "as"; 334: av[1] = "-u"; 335: na = 2; 336: #ifdef MENLO_OVLY 337: if (ovlyflag) 338: av[na++] = "-V"; 339: #endif MENLO_OVLY 340: av[na++] = "-o"; 341: av[na++] = setsuf(clist[i], 'o'); 342: av[na++] = assource; 343: av[na++] = 0; 344: cunlink(tmp1); 345: cunlink(tmp2); 346: cunlink(tmp4); 347: if(vflag) 348: doecho(AS, av); 349: if (callsys(AS, av) > 1) { 350: cflag++; 351: eflag++; 352: continue; 353: } 354: } 355: nocom: 356: if (cflag==0 && nl!=0) { 357: i = 0; 358: av[0] = "ld"; 359: av[1] = "-X"; 360: av[2] = pref; 361: j = 3; 362: if (noflflag) { 363: j = 4; 364: if (iflag) 365: av[3] = "-lfpsim_sep"; 366: else 367: av[3] = "-lfpsim"; 368: } 369: if (outfile) { 370: av[j++] = "-o"; 371: av[j++] = outfile; 372: } 373: while(i<nl) 374: av[j++] = llist[i++]; 375: if(f20) 376: av[j++] = "-l2"; 377: else { 378: #ifdef MENLO_OVLY 379: av[j++] = ovlyflag ? OVLIBC : LIBC; 380: #else 381: av[j++] = LIBC; 382: #endif MENLO_OVLY 383: } 384: av[j++] = 0; 385: if(vflag) 386: doecho(LD, av); 387: eflag |= callsys(LD, av); 388: if (nc==1 && nxo==1 && eflag==0) 389: cunlink(setsuf(clist[0], 'o')); 390: } 391: dexit(); 392: } 393: 394: idexit() 395: { 396: eflag = 100; 397: dexit(); 398: } 399: 400: dexit() 401: { 402: if (!pflag) { 403: cunlink(tmp1); 404: cunlink(tmp2); 405: if (sflag==0) 406: cunlink(tmp3); 407: cunlink(tmp4); 408: cunlink(tmp5); 409: cunlink(tmp0); 410: } 411: exit(eflag); 412: } 413: 414: error(s, x) 415: char *s, *x; 416: { 417: fprintf(exflag?stderr:stdout, s, x); 418: putc('\n', exflag? stderr : stdout); 419: cflag++; 420: eflag++; 421: } 422: 423: 424: 425: 426: getsuf(as) 427: char as[]; 428: { 429: register int c; 430: register char *s; 431: register int t; 432: 433: s = as; 434: c = 0; 435: while(t = *s++) 436: if (t=='/') 437: c = 0; 438: else 439: c++; 440: s -= 3; 441: if (c<=14 && c>2 && *s++=='.') 442: return(*s); 443: return(0); 444: } 445: 446: char * 447: setsuf(as, ch) 448: char *as; 449: { 450: register char *s, *s1; 451: 452: s = s1 = copy(as); 453: while(*s) 454: if (*s++ == '/') 455: s1 = s; 456: s[-1] = ch; 457: return(s1); 458: } 459: 460: callsys(f, v) 461: char f[], *v[]; 462: { 463: int t, status; 464: 465: if ((t=fork())==0) { 466: execv(f, v); 467: printf("Can't find %s\n", f); 468: exit(100); 469: } else 470: if (t == -1) { 471: printf("Try again\n"); 472: return(100); 473: } 474: while(t!=wait(&status)) 475: ; 476: if (t = status&0377) { 477: if (t!=SIGINT) { 478: printf("Fatal error in %s\n", f); 479: eflag = 8; 480: } 481: dexit(); 482: } 483: return((status>>8) & 0377); 484: } 485: 486: char * 487: copy(as) 488: char *as; 489: { 490: char *malloc(); 491: register char *otsp, *s; 492: 493: otsp = tsp; 494: s = as; 495: while (*tsp++ = *s++) 496: ; 497: if (tsp > tsa+CHSPACE) { 498: tsp = tsa = malloc(CHSPACE+50); 499: if (tsp==NULL) { 500: error("no space for file names", (char *)NULL); 501: dexit(); 502: } 503: } 504: return(otsp); 505: } 506: 507: nodup(l, os) 508: char **l, *os; 509: { 510: register char *t, *s; 511: register int c; 512: 513: s = os; 514: if (getsuf(s) != 'o') 515: return(1); 516: while(t = *l++) { 517: while(c = *s++) 518: if (c != *t++) 519: break; 520: if (*t=='\0' && c=='\0') 521: return(0); 522: s = os; 523: } 524: return(1); 525: } 526: 527: cunlink(f) 528: char *f; 529: { 530: if (f==NULL) 531: return; 532: unlink(f); 533: } 534: 535: doecho(s, v) 536: char *s; 537: register char **v; 538: { 539: printf ("%s", s); 540: while (*v) 541: printf (" %s", *v++); 542: putchar ('\n'); 543: fflush (stdout); 544: }