1*24538Sbloom static char sccsid[] = "@(#)cc.c 4.12 09/05/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); 184611Sbill if (pflag==0) 185611Sbill sprintf(tmp0, "/tmp/ctm%05.5d", getpid()); 186611Sbill tmp1 = strspl(tmp0, "1"); 187611Sbill tmp2 = strspl(tmp0, "2"); 188611Sbill tmp3 = strspl(tmp0, "3"); 189611Sbill if (pflag==0) 190611Sbill tmp4 = strspl(tmp0, "4"); 191611Sbill if (oflag) 192611Sbill tmp5 = strspl(tmp0, "5"); 193611Sbill for (i=0; i<nc; i++) { 19416237Smckusick if (nc > 1 && !Mflag) { 195611Sbill printf("%s:\n", clist[i]); 196611Sbill fflush(stdout); 197611Sbill } 198*24538Sbloom if (!Mflag && getsuf(clist[i]) == 's') { 199611Sbill assource = clist[i]; 200611Sbill goto assemble; 201611Sbill } else 202611Sbill assource = tmp3; 203611Sbill if (pflag) 204611Sbill tmp4 = setsuf(clist[i], 'i'); 20516237Smckusick av[0] = "cpp"; av[1] = clist[i]; 20616237Smckusick na = 2; 20716237Smckusick if (!exflag) 20816237Smckusick av[na++] = tmp4; 209611Sbill for (j = 0; j < np; j++) 210611Sbill av[na++] = plist[j]; 211611Sbill av[na++] = 0; 212611Sbill if (callsys(cpp, av)) { 213611Sbill exfail++; 214611Sbill eflag++; 215611Sbill } 216611Sbill if (pflag || exfail) { 217611Sbill cflag++; 218611Sbill continue; 219611Sbill } 22017461Sralph if (sflag) { 22117461Sralph if (nc==1 && outfile) 22217461Sralph tmp3 = outfile; 22317461Sralph else 22417461Sralph tmp3 = setsuf(clist[i], 's'); 22517461Sralph assource = tmp3; 22617461Sralph } 22717862Sralph av[0] = fflag ? "sccom" : "ccom"; 22817862Sralph av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3; 229611Sbill if (proflag) 230611Sbill av[na++] = "-XP"; 2319817Slinton if (gflag) { 232611Sbill av[na++] = "-Xg"; 2339817Slinton } else if (Gflag) { 2349817Slinton av[na++] = "-XG"; 2359817Slinton } 236611Sbill if (wflag) 237611Sbill av[na++] = "-w"; 238611Sbill av[na] = 0; 23917862Sralph if (callsys(fflag ? sccom : ccom, av)) { 240611Sbill cflag++; 241611Sbill eflag++; 242611Sbill continue; 243611Sbill } 244611Sbill if (oflag) { 245611Sbill av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; 246611Sbill if (callsys(c2, av)) { 247611Sbill unlink(tmp3); 248611Sbill tmp3 = assource = tmp5; 249611Sbill } else 250611Sbill unlink(tmp5); 251611Sbill } 252611Sbill if (sflag) 253611Sbill continue; 254611Sbill assemble: 255611Sbill cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); 25617461Sralph av[0] = "as"; av[1] = "-o"; 25717461Sralph if (cflag && nc==1 && outfile) 25817461Sralph av[2] = outfile; 25917461Sralph else 26017461Sralph av[2] = setsuf(clist[i], 'o'); 261652Sbill na = 3; 262652Sbill if (Rflag) 263652Sbill av[na++] = "-R"; 264611Sbill if (dflag) 265611Sbill av[na++] = dflag; 266652Sbill av[na++] = assource; 267611Sbill av[na] = 0; 268611Sbill if (callsys(as, av) > 1) { 269611Sbill cflag++; 270611Sbill eflag++; 271611Sbill continue; 272611Sbill } 273611Sbill } 274611Sbill nocom: 275611Sbill if (cflag==0 && nl!=0) { 276611Sbill i = 0; 277611Sbill av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3; 278611Sbill if (outfile) { 279611Sbill av[na++] = "-o"; 280611Sbill av[na++] = outfile; 281611Sbill } 282611Sbill while (i < nl) 283611Sbill av[na++] = llist[i++]; 2849817Slinton if (gflag || Gflag) 285611Sbill av[na++] = "-lg"; 2865055Smckusic if (proflag) 2875055Smckusic av[na++] = "-lc_p"; 2885055Smckusic else 2895055Smckusic av[na++] = "-lc"; 290611Sbill av[na++] = 0; 291611Sbill eflag |= callsys(ld, av); 292611Sbill if (nc==1 && nxo==1 && eflag==0) 293611Sbill unlink(setsuf(clist[0], 'o')); 294611Sbill } 295611Sbill dexit(); 296611Sbill } 297611Sbill 298611Sbill idexit() 299611Sbill { 300611Sbill 301611Sbill eflag = 100; 302611Sbill dexit(); 303611Sbill } 304611Sbill 305611Sbill dexit() 306611Sbill { 307611Sbill 308611Sbill if (!pflag) { 309611Sbill cunlink(tmp1); 310611Sbill cunlink(tmp2); 311611Sbill if (sflag==0) 312611Sbill cunlink(tmp3); 313611Sbill cunlink(tmp4); 314611Sbill cunlink(tmp5); 315611Sbill } 316611Sbill exit(eflag); 317611Sbill } 318611Sbill 319611Sbill error(s, x) 320611Sbill char *s, *x; 321611Sbill { 322611Sbill FILE *diag = exflag ? stderr : stdout; 323611Sbill 324611Sbill fprintf(diag, "cc: "); 325611Sbill fprintf(diag, s, x); 326611Sbill putc('\n', diag); 327611Sbill exfail++; 328611Sbill cflag++; 329611Sbill eflag++; 330611Sbill } 331611Sbill 332611Sbill getsuf(as) 333611Sbill char as[]; 334611Sbill { 335611Sbill register int c; 336611Sbill register char *s; 337611Sbill register int t; 338611Sbill 339611Sbill s = as; 340611Sbill c = 0; 341611Sbill while (t = *s++) 342611Sbill if (t=='/') 343611Sbill c = 0; 344611Sbill else 345611Sbill c++; 346611Sbill s -= 3; 3475963Smckusic if (c <= MAXNAMLEN && c > 2 && *s++ == '.') 348611Sbill return (*s); 349611Sbill return (0); 350611Sbill } 351611Sbill 352611Sbill char * 353611Sbill setsuf(as, ch) 354611Sbill char *as; 355611Sbill { 356611Sbill register char *s, *s1; 357611Sbill 358611Sbill s = s1 = savestr(as); 359611Sbill while (*s) 360611Sbill if (*s++ == '/') 361611Sbill s1 = s; 362611Sbill s[-1] = ch; 363611Sbill return (s1); 364611Sbill } 365611Sbill 366611Sbill callsys(f, v) 367611Sbill char *f, **v; 368611Sbill { 369611Sbill int t, status; 37016237Smckusick char **cpp; 371611Sbill 37216237Smckusick if (debug) { 37316237Smckusick fprintf(stderr, "%s:", f); 37416237Smckusick for (cpp = v; *cpp != 0; cpp++) 37516237Smckusick fprintf(stderr, " %s", *cpp); 37616237Smckusick fprintf(stderr, "\n"); 37716237Smckusick } 378611Sbill t = vfork(); 379611Sbill if (t == -1) { 380611Sbill printf("No more processes\n"); 381611Sbill return (100); 382611Sbill } 383611Sbill if (t == 0) { 384611Sbill execv(f, v); 385611Sbill printf("Can't find %s\n", f); 386611Sbill fflush(stdout); 387611Sbill _exit(100); 388611Sbill } 389611Sbill while (t != wait(&status)) 390611Sbill ; 391611Sbill if ((t=(status&0377)) != 0 && t!=14) { 392611Sbill if (t!=2) { 393611Sbill printf("Fatal error in %s\n", f); 394611Sbill eflag = 8; 395611Sbill } 396611Sbill dexit(); 397611Sbill } 398611Sbill return ((status>>8) & 0377); 399611Sbill } 400611Sbill 401611Sbill nodup(l, os) 402611Sbill char **l, *os; 403611Sbill { 404611Sbill register char *t, *s; 405611Sbill register int c; 406611Sbill 407611Sbill s = os; 408611Sbill if (getsuf(s) != 'o') 409611Sbill return (1); 410611Sbill while (t = *l++) { 411611Sbill while (c = *s++) 412611Sbill if (c != *t++) 413611Sbill break; 414611Sbill if (*t==0 && c==0) 415611Sbill return (0); 416611Sbill s = os; 417611Sbill } 418611Sbill return (1); 419611Sbill } 420611Sbill 421611Sbill #define NSAVETAB 1024 422611Sbill char *savetab; 423611Sbill int saveleft; 424611Sbill 425611Sbill char * 426611Sbill savestr(cp) 427611Sbill register char *cp; 428611Sbill { 429611Sbill register int len; 430611Sbill 431611Sbill len = strlen(cp) + 1; 432611Sbill if (len > saveleft) { 433611Sbill saveleft = NSAVETAB; 434611Sbill if (len > saveleft) 435611Sbill saveleft = len; 436611Sbill savetab = (char *)malloc(saveleft); 437611Sbill if (savetab == 0) { 438611Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 439611Sbill exit(1); 440611Sbill } 441611Sbill } 442611Sbill strncpy(savetab, cp, len); 443611Sbill cp = savetab; 444611Sbill savetab += len; 445611Sbill saveleft -= len; 446611Sbill return (cp); 447611Sbill } 448611Sbill 449611Sbill char * 450611Sbill strspl(left, right) 451611Sbill char *left, *right; 452611Sbill { 453611Sbill char buf[BUFSIZ]; 454611Sbill 455611Sbill strcpy(buf, left); 456611Sbill strcat(buf, right); 457611Sbill return (savestr(buf)); 458611Sbill } 459