1*32409Sbostic static char sccsid[] = "@(#)cc.c 4.15 10/22/87"; 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); 18424937Slepreau if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 18524937Slepreau signal(SIGHUP, idexit); 186611Sbill if (pflag==0) 187*32409Sbostic (void)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++; 21732207Sbostic cflag++; 21832207Sbostic continue; 219611Sbill } 22032207Sbostic if (pflag) { 221611Sbill cflag++; 222611Sbill continue; 223611Sbill } 22417461Sralph if (sflag) { 22517461Sralph if (nc==1 && outfile) 22617461Sralph tmp3 = outfile; 22717461Sralph else 22817461Sralph tmp3 = setsuf(clist[i], 's'); 22917461Sralph assource = tmp3; 23017461Sralph } 23117862Sralph av[0] = fflag ? "sccom" : "ccom"; 23217862Sralph av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3; 233611Sbill if (proflag) 234611Sbill av[na++] = "-XP"; 2359817Slinton if (gflag) { 236611Sbill av[na++] = "-Xg"; 2379817Slinton } else if (Gflag) { 2389817Slinton av[na++] = "-XG"; 2399817Slinton } 240611Sbill if (wflag) 241611Sbill av[na++] = "-w"; 242611Sbill av[na] = 0; 24317862Sralph if (callsys(fflag ? sccom : ccom, av)) { 244611Sbill cflag++; 245611Sbill eflag++; 246611Sbill continue; 247611Sbill } 248611Sbill if (oflag) { 249611Sbill av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; 250611Sbill if (callsys(c2, av)) { 251611Sbill unlink(tmp3); 252611Sbill tmp3 = assource = tmp5; 253611Sbill } else 254611Sbill unlink(tmp5); 255611Sbill } 256611Sbill if (sflag) 257611Sbill continue; 258611Sbill assemble: 259611Sbill cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); 26017461Sralph av[0] = "as"; av[1] = "-o"; 26117461Sralph if (cflag && nc==1 && outfile) 26217461Sralph av[2] = outfile; 26317461Sralph else 26417461Sralph av[2] = setsuf(clist[i], 'o'); 265652Sbill na = 3; 266652Sbill if (Rflag) 267652Sbill av[na++] = "-R"; 268611Sbill if (dflag) 269611Sbill av[na++] = dflag; 270652Sbill av[na++] = assource; 271611Sbill av[na] = 0; 272611Sbill if (callsys(as, av) > 1) { 273611Sbill cflag++; 274611Sbill eflag++; 275611Sbill continue; 276611Sbill } 277611Sbill } 278611Sbill nocom: 279611Sbill if (cflag==0 && nl!=0) { 280611Sbill i = 0; 281611Sbill av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3; 282611Sbill if (outfile) { 283611Sbill av[na++] = "-o"; 284611Sbill av[na++] = outfile; 285611Sbill } 286611Sbill while (i < nl) 287611Sbill av[na++] = llist[i++]; 2889817Slinton if (gflag || Gflag) 289611Sbill av[na++] = "-lg"; 2905055Smckusic if (proflag) 2915055Smckusic av[na++] = "-lc_p"; 2925055Smckusic else 2935055Smckusic av[na++] = "-lc"; 294611Sbill av[na++] = 0; 295611Sbill eflag |= callsys(ld, av); 296611Sbill if (nc==1 && nxo==1 && eflag==0) 297611Sbill unlink(setsuf(clist[0], 'o')); 298611Sbill } 299611Sbill dexit(); 300611Sbill } 301611Sbill 302611Sbill idexit() 303611Sbill { 304611Sbill 305611Sbill eflag = 100; 306611Sbill dexit(); 307611Sbill } 308611Sbill 309611Sbill dexit() 310611Sbill { 311611Sbill 312611Sbill if (!pflag) { 313611Sbill cunlink(tmp1); 314611Sbill cunlink(tmp2); 315611Sbill if (sflag==0) 316611Sbill cunlink(tmp3); 317611Sbill cunlink(tmp4); 318611Sbill cunlink(tmp5); 319611Sbill } 320611Sbill exit(eflag); 321611Sbill } 322611Sbill 323611Sbill error(s, x) 324611Sbill char *s, *x; 325611Sbill { 326611Sbill FILE *diag = exflag ? stderr : stdout; 327611Sbill 328611Sbill fprintf(diag, "cc: "); 329611Sbill fprintf(diag, s, x); 330611Sbill putc('\n', diag); 331611Sbill exfail++; 332611Sbill cflag++; 333611Sbill eflag++; 334611Sbill } 335611Sbill 336611Sbill getsuf(as) 337611Sbill char as[]; 338611Sbill { 339611Sbill register int c; 340611Sbill register char *s; 341611Sbill register int t; 342611Sbill 343611Sbill s = as; 344611Sbill c = 0; 345611Sbill while (t = *s++) 346611Sbill if (t=='/') 347611Sbill c = 0; 348611Sbill else 349611Sbill c++; 350611Sbill s -= 3; 3515963Smckusic if (c <= MAXNAMLEN && c > 2 && *s++ == '.') 352611Sbill return (*s); 353611Sbill return (0); 354611Sbill } 355611Sbill 356611Sbill char * 357611Sbill setsuf(as, ch) 358611Sbill char *as; 359611Sbill { 360611Sbill register char *s, *s1; 361611Sbill 362611Sbill s = s1 = savestr(as); 363611Sbill while (*s) 364611Sbill if (*s++ == '/') 365611Sbill s1 = s; 366611Sbill s[-1] = ch; 367611Sbill return (s1); 368611Sbill } 369611Sbill 370611Sbill callsys(f, v) 371611Sbill char *f, **v; 372611Sbill { 373611Sbill int t, status; 37416237Smckusick char **cpp; 375611Sbill 37616237Smckusick if (debug) { 37716237Smckusick fprintf(stderr, "%s:", f); 37816237Smckusick for (cpp = v; *cpp != 0; cpp++) 37916237Smckusick fprintf(stderr, " %s", *cpp); 38016237Smckusick fprintf(stderr, "\n"); 38116237Smckusick } 382611Sbill t = vfork(); 383611Sbill if (t == -1) { 384611Sbill printf("No more processes\n"); 385611Sbill return (100); 386611Sbill } 387611Sbill if (t == 0) { 388611Sbill execv(f, v); 389611Sbill printf("Can't find %s\n", f); 390611Sbill fflush(stdout); 391611Sbill _exit(100); 392611Sbill } 393611Sbill while (t != wait(&status)) 394611Sbill ; 395611Sbill if ((t=(status&0377)) != 0 && t!=14) { 396611Sbill if (t!=2) { 397611Sbill printf("Fatal error in %s\n", f); 398611Sbill eflag = 8; 399611Sbill } 400611Sbill dexit(); 401611Sbill } 402611Sbill return ((status>>8) & 0377); 403611Sbill } 404611Sbill 405611Sbill nodup(l, os) 406611Sbill char **l, *os; 407611Sbill { 408611Sbill register char *t, *s; 409611Sbill register int c; 410611Sbill 411611Sbill s = os; 412611Sbill if (getsuf(s) != 'o') 413611Sbill return (1); 414611Sbill while (t = *l++) { 415611Sbill while (c = *s++) 416611Sbill if (c != *t++) 417611Sbill break; 418611Sbill if (*t==0 && c==0) 419611Sbill return (0); 420611Sbill s = os; 421611Sbill } 422611Sbill return (1); 423611Sbill } 424611Sbill 425611Sbill #define NSAVETAB 1024 426611Sbill char *savetab; 427611Sbill int saveleft; 428611Sbill 429611Sbill char * 430611Sbill savestr(cp) 431611Sbill register char *cp; 432611Sbill { 433611Sbill register int len; 434611Sbill 435611Sbill len = strlen(cp) + 1; 436611Sbill if (len > saveleft) { 437611Sbill saveleft = NSAVETAB; 438611Sbill if (len > saveleft) 439611Sbill saveleft = len; 440611Sbill savetab = (char *)malloc(saveleft); 441611Sbill if (savetab == 0) { 442611Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 443611Sbill exit(1); 444611Sbill } 445611Sbill } 446611Sbill strncpy(savetab, cp, len); 447611Sbill cp = savetab; 448611Sbill savetab += len; 449611Sbill saveleft -= len; 450611Sbill return (cp); 451611Sbill } 452611Sbill 453611Sbill char * 454611Sbill strspl(left, right) 455611Sbill char *left, *right; 456611Sbill { 457611Sbill char buf[BUFSIZ]; 458611Sbill 459611Sbill strcpy(buf, left); 460611Sbill strcat(buf, right); 461611Sbill return (savestr(buf)); 462611Sbill } 463