1*24937Slepreau static char sccsid[] = "@(#)cc.c 4.13 09/18/85"; 2611Sbill /* 3611Sbill * cc - front end for C compiler 4611Sbill */ 56413Smckusic #include <sys/param.h> 6611Sbill #include <stdio.h> 7611Sbill #include <ctype.h> 8611Sbill #include <signal.h> 913597Swnj #include <sys/dir.h> 10611Sbill 11896Sbill char *cpp = "/lib/cpp"; 12896Sbill char *ccom = "/lib/ccom"; 1317862Sralph char *sccom = "/lib/sccom"; 14896Sbill char *c2 = "/lib/c2"; 15896Sbill char *as = "/bin/as"; 16896Sbill char *ld = "/bin/ld"; 17896Sbill char *crt0 = "/lib/crt0.o"; 18611Sbill 19611Sbill char tmp0[30]; /* big enough for /tmp/ctm%05.5d */ 20611Sbill char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5; 21611Sbill char *outfile; 22611Sbill char *savestr(), *strspl(), *setsuf(); 23611Sbill int idexit(); 24611Sbill char **av, **clist, **llist, **plist; 259817Slinton int cflag, eflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag; 2617862Sralph int fflag, gflag, Gflag, Mflag, debug; 27611Sbill char *dflag; 28611Sbill int exfail; 29611Sbill char *chpass; 30611Sbill char *npassname; 31611Sbill 32611Sbill int nc, nl, np, nxo, na; 33611Sbill 34611Sbill #define cunlink(s) if (s) unlink(s) 35611Sbill 36611Sbill main(argc, argv) 37611Sbill char **argv; 38611Sbill { 39611Sbill char *t; 40611Sbill char *assource; 41611Sbill int i, j, c; 42611Sbill 43611Sbill /* ld currently adds upto 5 args; 10 is room to spare */ 44611Sbill av = (char **)calloc(argc+10, sizeof (char **)); 45611Sbill clist = (char **)calloc(argc, sizeof (char **)); 46611Sbill llist = (char **)calloc(argc, sizeof (char **)); 47611Sbill plist = (char **)calloc(argc, sizeof (char **)); 48611Sbill for (i = 1; i < argc; i++) { 49611Sbill if (*argv[i] == '-') switch (argv[i][1]) { 50611Sbill 51611Sbill case 'S': 52611Sbill sflag++; 53611Sbill cflag++; 54611Sbill continue; 55611Sbill case 'o': 56611Sbill if (++i < argc) { 57611Sbill outfile = argv[i]; 58611Sbill switch (getsuf(outfile)) { 59611Sbill 60611Sbill case 'c': 61611Sbill error("-o would overwrite %s", 62611Sbill outfile); 63611Sbill exit(8); 64611Sbill } 65611Sbill } 66611Sbill continue; 67652Sbill case 'R': 68652Sbill Rflag++; 69652Sbill continue; 70611Sbill case 'O': 71611Sbill oflag++; 72611Sbill continue; 73611Sbill case 'p': 74611Sbill proflag++; 755055Smckusic crt0 = "/lib/mcrt0.o"; 765055Smckusic if (argv[i][2] == 'g') 775055Smckusic crt0 = "/usr/lib/gcrt0.o"; 78611Sbill continue; 7917862Sralph case 'f': 8017862Sralph fflag++; 8117862Sralph continue; 82611Sbill case 'g': 839817Slinton if (argv[i][2] == 'o') { 849817Slinton Gflag++; /* old format for -go */ 859817Slinton } else { 869817Slinton gflag++; /* new format for -g */ 879817Slinton } 88611Sbill continue; 89611Sbill case 'w': 90611Sbill wflag++; 91611Sbill continue; 92611Sbill case 'E': 93611Sbill exflag++; 94611Sbill case 'P': 95611Sbill pflag++; 96611Sbill if (argv[i][1]=='P') 97611Sbill fprintf(stderr, 98611Sbill "cc: warning: -P option obsolete; you should use -E instead\n"); 99611Sbill plist[np++] = argv[i]; 100611Sbill case 'c': 101611Sbill cflag++; 102611Sbill continue; 10316237Smckusick case 'M': 10416237Smckusick exflag++; 10516237Smckusick pflag++; 10616237Smckusick Mflag++; 10716237Smckusick /* and fall through */ 108611Sbill case 'D': 109611Sbill case 'I': 110611Sbill case 'U': 111611Sbill case 'C': 112611Sbill plist[np++] = argv[i]; 113611Sbill continue; 11417134Ssam case 'L': 11517134Ssam llist[nl++] = argv[i]; 11617134Ssam continue; 117611Sbill case 't': 118611Sbill if (chpass) 119611Sbill error("-t overwrites earlier option", 0); 120611Sbill chpass = argv[i]+2; 121611Sbill if (chpass[0]==0) 122611Sbill chpass = "012p"; 123611Sbill continue; 124611Sbill case 'B': 125611Sbill if (npassname) 126611Sbill error("-B overwrites earlier option", 0); 127611Sbill npassname = argv[i]+2; 128611Sbill if (npassname[0]==0) 129611Sbill npassname = "/usr/c/o"; 130611Sbill continue; 131611Sbill case 'd': 13216237Smckusick if (argv[i][2] == '\0') { 13316237Smckusick debug++; 13416237Smckusick continue; 13516237Smckusick } 136611Sbill dflag = argv[i]; 137611Sbill continue; 138611Sbill } 139611Sbill t = argv[i]; 140611Sbill c = getsuf(t); 141611Sbill if (c=='c' || c=='s' || exflag) { 142611Sbill clist[nc++] = t; 143611Sbill t = setsuf(t, 'o'); 144611Sbill } 145611Sbill if (nodup(llist, t)) { 146611Sbill llist[nl++] = t; 147611Sbill if (getsuf(t)=='o') 148611Sbill nxo++; 149611Sbill } 150611Sbill } 1519817Slinton if (gflag || Gflag) { 152611Sbill if (oflag) 153611Sbill fprintf(stderr, "cc: warning: -g disables -O\n"); 154611Sbill oflag = 0; 155611Sbill } 156611Sbill if (npassname && chpass ==0) 157611Sbill chpass = "012p"; 158611Sbill if (chpass && npassname==0) 159896Sbill npassname = "/usr/new"; 160611Sbill if (chpass) 161611Sbill for (t=chpass; *t; t++) { 162611Sbill switch (*t) { 163611Sbill 164611Sbill case '0': 16517862Sralph if (fflag) 16617862Sralph sccom = strspl(npassname, "sccom"); 16717862Sralph else 16817862Sralph ccom = strspl(npassname, "ccom"); 169611Sbill continue; 170611Sbill case '2': 171611Sbill c2 = strspl(npassname, "c2"); 172611Sbill continue; 173611Sbill case 'p': 174611Sbill cpp = strspl(npassname, "cpp"); 175611Sbill continue; 176611Sbill } 177611Sbill } 178611Sbill if (nc==0) 179611Sbill goto nocom; 180611Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 181611Sbill signal(SIGINT, idexit); 182611Sbill if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 183611Sbill signal(SIGTERM, idexit); 184*24937Slepreau if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 185*24937Slepreau signal(SIGHUP, idexit); 186611Sbill if (pflag==0) 187611Sbill sprintf(tmp0, "/tmp/ctm%05.5d", getpid()); 188611Sbill tmp1 = strspl(tmp0, "1"); 189611Sbill tmp2 = strspl(tmp0, "2"); 190611Sbill tmp3 = strspl(tmp0, "3"); 191611Sbill if (pflag==0) 192611Sbill tmp4 = strspl(tmp0, "4"); 193611Sbill if (oflag) 194611Sbill tmp5 = strspl(tmp0, "5"); 195611Sbill for (i=0; i<nc; i++) { 19616237Smckusick if (nc > 1 && !Mflag) { 197611Sbill printf("%s:\n", clist[i]); 198611Sbill fflush(stdout); 199611Sbill } 20024538Sbloom if (!Mflag && getsuf(clist[i]) == 's') { 201611Sbill assource = clist[i]; 202611Sbill goto assemble; 203611Sbill } else 204611Sbill assource = tmp3; 205611Sbill if (pflag) 206611Sbill tmp4 = setsuf(clist[i], 'i'); 20716237Smckusick av[0] = "cpp"; av[1] = clist[i]; 20816237Smckusick na = 2; 20916237Smckusick if (!exflag) 21016237Smckusick av[na++] = tmp4; 211611Sbill for (j = 0; j < np; j++) 212611Sbill av[na++] = plist[j]; 213611Sbill av[na++] = 0; 214611Sbill if (callsys(cpp, av)) { 215611Sbill exfail++; 216611Sbill eflag++; 217611Sbill } 218611Sbill if (pflag || exfail) { 219611Sbill cflag++; 220611Sbill continue; 221611Sbill } 22217461Sralph if (sflag) { 22317461Sralph if (nc==1 && outfile) 22417461Sralph tmp3 = outfile; 22517461Sralph else 22617461Sralph tmp3 = setsuf(clist[i], 's'); 22717461Sralph assource = tmp3; 22817461Sralph } 22917862Sralph av[0] = fflag ? "sccom" : "ccom"; 23017862Sralph av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3; 231611Sbill if (proflag) 232611Sbill av[na++] = "-XP"; 2339817Slinton if (gflag) { 234611Sbill av[na++] = "-Xg"; 2359817Slinton } else if (Gflag) { 2369817Slinton av[na++] = "-XG"; 2379817Slinton } 238611Sbill if (wflag) 239611Sbill av[na++] = "-w"; 240611Sbill av[na] = 0; 24117862Sralph if (callsys(fflag ? sccom : ccom, av)) { 242611Sbill cflag++; 243611Sbill eflag++; 244611Sbill continue; 245611Sbill } 246611Sbill if (oflag) { 247611Sbill av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; 248611Sbill if (callsys(c2, av)) { 249611Sbill unlink(tmp3); 250611Sbill tmp3 = assource = tmp5; 251611Sbill } else 252611Sbill unlink(tmp5); 253611Sbill } 254611Sbill if (sflag) 255611Sbill continue; 256611Sbill assemble: 257611Sbill cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); 25817461Sralph av[0] = "as"; av[1] = "-o"; 25917461Sralph if (cflag && nc==1 && outfile) 26017461Sralph av[2] = outfile; 26117461Sralph else 26217461Sralph av[2] = setsuf(clist[i], 'o'); 263652Sbill na = 3; 264652Sbill if (Rflag) 265652Sbill av[na++] = "-R"; 266611Sbill if (dflag) 267611Sbill av[na++] = dflag; 268652Sbill av[na++] = assource; 269611Sbill av[na] = 0; 270611Sbill if (callsys(as, av) > 1) { 271611Sbill cflag++; 272611Sbill eflag++; 273611Sbill continue; 274611Sbill } 275611Sbill } 276611Sbill nocom: 277611Sbill if (cflag==0 && nl!=0) { 278611Sbill i = 0; 279611Sbill av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3; 280611Sbill if (outfile) { 281611Sbill av[na++] = "-o"; 282611Sbill av[na++] = outfile; 283611Sbill } 284611Sbill while (i < nl) 285611Sbill av[na++] = llist[i++]; 2869817Slinton if (gflag || Gflag) 287611Sbill av[na++] = "-lg"; 2885055Smckusic if (proflag) 2895055Smckusic av[na++] = "-lc_p"; 2905055Smckusic else 2915055Smckusic av[na++] = "-lc"; 292611Sbill av[na++] = 0; 293611Sbill eflag |= callsys(ld, av); 294611Sbill if (nc==1 && nxo==1 && eflag==0) 295611Sbill unlink(setsuf(clist[0], 'o')); 296611Sbill } 297611Sbill dexit(); 298611Sbill } 299611Sbill 300611Sbill idexit() 301611Sbill { 302611Sbill 303611Sbill eflag = 100; 304611Sbill dexit(); 305611Sbill } 306611Sbill 307611Sbill dexit() 308611Sbill { 309611Sbill 310611Sbill if (!pflag) { 311611Sbill cunlink(tmp1); 312611Sbill cunlink(tmp2); 313611Sbill if (sflag==0) 314611Sbill cunlink(tmp3); 315611Sbill cunlink(tmp4); 316611Sbill cunlink(tmp5); 317611Sbill } 318611Sbill exit(eflag); 319611Sbill } 320611Sbill 321611Sbill error(s, x) 322611Sbill char *s, *x; 323611Sbill { 324611Sbill FILE *diag = exflag ? stderr : stdout; 325611Sbill 326611Sbill fprintf(diag, "cc: "); 327611Sbill fprintf(diag, s, x); 328611Sbill putc('\n', diag); 329611Sbill exfail++; 330611Sbill cflag++; 331611Sbill eflag++; 332611Sbill } 333611Sbill 334611Sbill getsuf(as) 335611Sbill char as[]; 336611Sbill { 337611Sbill register int c; 338611Sbill register char *s; 339611Sbill register int t; 340611Sbill 341611Sbill s = as; 342611Sbill c = 0; 343611Sbill while (t = *s++) 344611Sbill if (t=='/') 345611Sbill c = 0; 346611Sbill else 347611Sbill c++; 348611Sbill s -= 3; 3495963Smckusic if (c <= MAXNAMLEN && c > 2 && *s++ == '.') 350611Sbill return (*s); 351611Sbill return (0); 352611Sbill } 353611Sbill 354611Sbill char * 355611Sbill setsuf(as, ch) 356611Sbill char *as; 357611Sbill { 358611Sbill register char *s, *s1; 359611Sbill 360611Sbill s = s1 = savestr(as); 361611Sbill while (*s) 362611Sbill if (*s++ == '/') 363611Sbill s1 = s; 364611Sbill s[-1] = ch; 365611Sbill return (s1); 366611Sbill } 367611Sbill 368611Sbill callsys(f, v) 369611Sbill char *f, **v; 370611Sbill { 371611Sbill int t, status; 37216237Smckusick char **cpp; 373611Sbill 37416237Smckusick if (debug) { 37516237Smckusick fprintf(stderr, "%s:", f); 37616237Smckusick for (cpp = v; *cpp != 0; cpp++) 37716237Smckusick fprintf(stderr, " %s", *cpp); 37816237Smckusick fprintf(stderr, "\n"); 37916237Smckusick } 380611Sbill t = vfork(); 381611Sbill if (t == -1) { 382611Sbill printf("No more processes\n"); 383611Sbill return (100); 384611Sbill } 385611Sbill if (t == 0) { 386611Sbill execv(f, v); 387611Sbill printf("Can't find %s\n", f); 388611Sbill fflush(stdout); 389611Sbill _exit(100); 390611Sbill } 391611Sbill while (t != wait(&status)) 392611Sbill ; 393611Sbill if ((t=(status&0377)) != 0 && t!=14) { 394611Sbill if (t!=2) { 395611Sbill printf("Fatal error in %s\n", f); 396611Sbill eflag = 8; 397611Sbill } 398611Sbill dexit(); 399611Sbill } 400611Sbill return ((status>>8) & 0377); 401611Sbill } 402611Sbill 403611Sbill nodup(l, os) 404611Sbill char **l, *os; 405611Sbill { 406611Sbill register char *t, *s; 407611Sbill register int c; 408611Sbill 409611Sbill s = os; 410611Sbill if (getsuf(s) != 'o') 411611Sbill return (1); 412611Sbill while (t = *l++) { 413611Sbill while (c = *s++) 414611Sbill if (c != *t++) 415611Sbill break; 416611Sbill if (*t==0 && c==0) 417611Sbill return (0); 418611Sbill s = os; 419611Sbill } 420611Sbill return (1); 421611Sbill } 422611Sbill 423611Sbill #define NSAVETAB 1024 424611Sbill char *savetab; 425611Sbill int saveleft; 426611Sbill 427611Sbill char * 428611Sbill savestr(cp) 429611Sbill register char *cp; 430611Sbill { 431611Sbill register int len; 432611Sbill 433611Sbill len = strlen(cp) + 1; 434611Sbill if (len > saveleft) { 435611Sbill saveleft = NSAVETAB; 436611Sbill if (len > saveleft) 437611Sbill saveleft = len; 438611Sbill savetab = (char *)malloc(saveleft); 439611Sbill if (savetab == 0) { 440611Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 441611Sbill exit(1); 442611Sbill } 443611Sbill } 444611Sbill strncpy(savetab, cp, len); 445611Sbill cp = savetab; 446611Sbill savetab += len; 447611Sbill saveleft -= len; 448611Sbill return (cp); 449611Sbill } 450611Sbill 451611Sbill char * 452611Sbill strspl(left, right) 453611Sbill char *left, *right; 454611Sbill { 455611Sbill char buf[BUFSIZ]; 456611Sbill 457611Sbill strcpy(buf, left); 458611Sbill strcat(buf, right); 459611Sbill return (savestr(buf)); 460611Sbill } 461