1*37021Sbostic static char sccsid[] = "@(#)cc.c 4.16 03/05/89"; 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> 10*37021Sbostic #include "pathnames.h" 11611Sbill 12*37021Sbostic char *cpp = _PATH_CPP; 13*37021Sbostic char *ccom = _PATH_CCOM; 14*37021Sbostic char *sccom = _PATH_SCCOM; 15*37021Sbostic char *c2 = _PATH_C2; 16*37021Sbostic char *as = _PATH_AS; 17*37021Sbostic char *ld = _PATH_LD; 18*37021Sbostic char *crt0 = _PATH_CRT0; 19611Sbill 20611Sbill char tmp0[30]; /* big enough for /tmp/ctm%05.5d */ 21611Sbill char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5; 22611Sbill char *outfile; 23611Sbill char *savestr(), *strspl(), *setsuf(); 24611Sbill int idexit(); 25611Sbill char **av, **clist, **llist, **plist; 269817Slinton int cflag, eflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag; 2717862Sralph int fflag, gflag, Gflag, Mflag, debug; 28611Sbill char *dflag; 29611Sbill int exfail; 30611Sbill char *chpass; 31611Sbill char *npassname; 32611Sbill 33611Sbill int nc, nl, np, nxo, na; 34611Sbill 35611Sbill #define cunlink(s) if (s) unlink(s) 36611Sbill 37611Sbill main(argc, argv) 38611Sbill char **argv; 39611Sbill { 40611Sbill char *t; 41611Sbill char *assource; 42611Sbill int i, j, c; 43611Sbill 44611Sbill /* ld currently adds upto 5 args; 10 is room to spare */ 45611Sbill av = (char **)calloc(argc+10, sizeof (char **)); 46611Sbill clist = (char **)calloc(argc, sizeof (char **)); 47611Sbill llist = (char **)calloc(argc, sizeof (char **)); 48611Sbill plist = (char **)calloc(argc, sizeof (char **)); 49611Sbill for (i = 1; i < argc; i++) { 50611Sbill if (*argv[i] == '-') switch (argv[i][1]) { 51611Sbill 52611Sbill case 'S': 53611Sbill sflag++; 54611Sbill cflag++; 55611Sbill continue; 56611Sbill case 'o': 57611Sbill if (++i < argc) { 58611Sbill outfile = argv[i]; 59611Sbill switch (getsuf(outfile)) { 60611Sbill 61611Sbill case 'c': 62611Sbill error("-o would overwrite %s", 63611Sbill outfile); 64611Sbill exit(8); 65611Sbill } 66611Sbill } 67611Sbill continue; 68652Sbill case 'R': 69652Sbill Rflag++; 70652Sbill continue; 71611Sbill case 'O': 72611Sbill oflag++; 73611Sbill continue; 74611Sbill case 'p': 75611Sbill proflag++; 765055Smckusic crt0 = "/lib/mcrt0.o"; 775055Smckusic if (argv[i][2] == 'g') 785055Smckusic crt0 = "/usr/lib/gcrt0.o"; 79611Sbill continue; 8017862Sralph case 'f': 8117862Sralph fflag++; 8217862Sralph continue; 83611Sbill case 'g': 849817Slinton if (argv[i][2] == 'o') { 859817Slinton Gflag++; /* old format for -go */ 869817Slinton } else { 879817Slinton gflag++; /* new format for -g */ 889817Slinton } 89611Sbill continue; 90611Sbill case 'w': 91611Sbill wflag++; 92611Sbill continue; 93611Sbill case 'E': 94611Sbill exflag++; 95611Sbill case 'P': 96611Sbill pflag++; 97611Sbill if (argv[i][1]=='P') 98611Sbill fprintf(stderr, 99611Sbill "cc: warning: -P option obsolete; you should use -E instead\n"); 100611Sbill plist[np++] = argv[i]; 101611Sbill case 'c': 102611Sbill cflag++; 103611Sbill continue; 10416237Smckusick case 'M': 10516237Smckusick exflag++; 10616237Smckusick pflag++; 10716237Smckusick Mflag++; 10816237Smckusick /* and fall through */ 109611Sbill case 'D': 110611Sbill case 'I': 111611Sbill case 'U': 112611Sbill case 'C': 113611Sbill plist[np++] = argv[i]; 114611Sbill continue; 11517134Ssam case 'L': 11617134Ssam llist[nl++] = argv[i]; 11717134Ssam continue; 118611Sbill case 't': 119611Sbill if (chpass) 120611Sbill error("-t overwrites earlier option", 0); 121611Sbill chpass = argv[i]+2; 122611Sbill if (chpass[0]==0) 123611Sbill chpass = "012p"; 124611Sbill continue; 125611Sbill case 'B': 126611Sbill if (npassname) 127611Sbill error("-B overwrites earlier option", 0); 128611Sbill npassname = argv[i]+2; 129611Sbill if (npassname[0]==0) 130611Sbill npassname = "/usr/c/o"; 131611Sbill continue; 132611Sbill case 'd': 13316237Smckusick if (argv[i][2] == '\0') { 13416237Smckusick debug++; 13516237Smckusick continue; 13616237Smckusick } 137611Sbill dflag = argv[i]; 138611Sbill continue; 139611Sbill } 140611Sbill t = argv[i]; 141611Sbill c = getsuf(t); 142611Sbill if (c=='c' || c=='s' || exflag) { 143611Sbill clist[nc++] = t; 144611Sbill t = setsuf(t, 'o'); 145611Sbill } 146611Sbill if (nodup(llist, t)) { 147611Sbill llist[nl++] = t; 148611Sbill if (getsuf(t)=='o') 149611Sbill nxo++; 150611Sbill } 151611Sbill } 1529817Slinton if (gflag || Gflag) { 153611Sbill if (oflag) 154611Sbill fprintf(stderr, "cc: warning: -g disables -O\n"); 155611Sbill oflag = 0; 156611Sbill } 157611Sbill if (npassname && chpass ==0) 158611Sbill chpass = "012p"; 159611Sbill if (chpass && npassname==0) 160896Sbill npassname = "/usr/new"; 161611Sbill if (chpass) 162611Sbill for (t=chpass; *t; t++) { 163611Sbill switch (*t) { 164611Sbill 165611Sbill case '0': 16617862Sralph if (fflag) 16717862Sralph sccom = strspl(npassname, "sccom"); 16817862Sralph else 16917862Sralph ccom = strspl(npassname, "ccom"); 170611Sbill continue; 171611Sbill case '2': 172611Sbill c2 = strspl(npassname, "c2"); 173611Sbill continue; 174611Sbill case 'p': 175611Sbill cpp = strspl(npassname, "cpp"); 176611Sbill continue; 177611Sbill } 178611Sbill } 179611Sbill if (nc==0) 180611Sbill goto nocom; 181611Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 182611Sbill signal(SIGINT, idexit); 183611Sbill if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 184611Sbill signal(SIGTERM, idexit); 18524937Slepreau if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 18624937Slepreau signal(SIGHUP, idexit); 187611Sbill if (pflag==0) 18832409Sbostic (void)sprintf(tmp0, "/tmp/ctm%05.5d", getpid()); 189611Sbill tmp1 = strspl(tmp0, "1"); 190611Sbill tmp2 = strspl(tmp0, "2"); 191611Sbill tmp3 = strspl(tmp0, "3"); 192611Sbill if (pflag==0) 193611Sbill tmp4 = strspl(tmp0, "4"); 194611Sbill if (oflag) 195611Sbill tmp5 = strspl(tmp0, "5"); 196611Sbill for (i=0; i<nc; i++) { 19716237Smckusick if (nc > 1 && !Mflag) { 198611Sbill printf("%s:\n", clist[i]); 199611Sbill fflush(stdout); 200611Sbill } 20124538Sbloom if (!Mflag && getsuf(clist[i]) == 's') { 202611Sbill assource = clist[i]; 203611Sbill goto assemble; 204611Sbill } else 205611Sbill assource = tmp3; 206611Sbill if (pflag) 207611Sbill tmp4 = setsuf(clist[i], 'i'); 20816237Smckusick av[0] = "cpp"; av[1] = clist[i]; 20916237Smckusick na = 2; 21016237Smckusick if (!exflag) 21116237Smckusick av[na++] = tmp4; 212611Sbill for (j = 0; j < np; j++) 213611Sbill av[na++] = plist[j]; 214611Sbill av[na++] = 0; 215611Sbill if (callsys(cpp, av)) { 216611Sbill exfail++; 217611Sbill eflag++; 21832207Sbostic cflag++; 21932207Sbostic continue; 220611Sbill } 22132207Sbostic if (pflag) { 222611Sbill cflag++; 223611Sbill continue; 224611Sbill } 22517461Sralph if (sflag) { 22617461Sralph if (nc==1 && outfile) 22717461Sralph tmp3 = outfile; 22817461Sralph else 22917461Sralph tmp3 = setsuf(clist[i], 's'); 23017461Sralph assource = tmp3; 23117461Sralph } 23217862Sralph av[0] = fflag ? "sccom" : "ccom"; 23317862Sralph av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3; 234611Sbill if (proflag) 235611Sbill av[na++] = "-XP"; 2369817Slinton if (gflag) { 237611Sbill av[na++] = "-Xg"; 2389817Slinton } else if (Gflag) { 2399817Slinton av[na++] = "-XG"; 2409817Slinton } 241611Sbill if (wflag) 242611Sbill av[na++] = "-w"; 243611Sbill av[na] = 0; 24417862Sralph if (callsys(fflag ? sccom : ccom, av)) { 245611Sbill cflag++; 246611Sbill eflag++; 247611Sbill continue; 248611Sbill } 249611Sbill if (oflag) { 250611Sbill av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; 251611Sbill if (callsys(c2, av)) { 252611Sbill unlink(tmp3); 253611Sbill tmp3 = assource = tmp5; 254611Sbill } else 255611Sbill unlink(tmp5); 256611Sbill } 257611Sbill if (sflag) 258611Sbill continue; 259611Sbill assemble: 260611Sbill cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); 26117461Sralph av[0] = "as"; av[1] = "-o"; 26217461Sralph if (cflag && nc==1 && outfile) 26317461Sralph av[2] = outfile; 26417461Sralph else 26517461Sralph av[2] = setsuf(clist[i], 'o'); 266652Sbill na = 3; 267652Sbill if (Rflag) 268652Sbill av[na++] = "-R"; 269611Sbill if (dflag) 270611Sbill av[na++] = dflag; 271652Sbill av[na++] = assource; 272611Sbill av[na] = 0; 273611Sbill if (callsys(as, av) > 1) { 274611Sbill cflag++; 275611Sbill eflag++; 276611Sbill continue; 277611Sbill } 278611Sbill } 279611Sbill nocom: 280611Sbill if (cflag==0 && nl!=0) { 281611Sbill i = 0; 282611Sbill av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3; 283611Sbill if (outfile) { 284611Sbill av[na++] = "-o"; 285611Sbill av[na++] = outfile; 286611Sbill } 287611Sbill while (i < nl) 288611Sbill av[na++] = llist[i++]; 2899817Slinton if (gflag || Gflag) 290611Sbill av[na++] = "-lg"; 2915055Smckusic if (proflag) 2925055Smckusic av[na++] = "-lc_p"; 2935055Smckusic else 2945055Smckusic av[na++] = "-lc"; 295611Sbill av[na++] = 0; 296611Sbill eflag |= callsys(ld, av); 297611Sbill if (nc==1 && nxo==1 && eflag==0) 298611Sbill unlink(setsuf(clist[0], 'o')); 299611Sbill } 300611Sbill dexit(); 301611Sbill } 302611Sbill 303611Sbill idexit() 304611Sbill { 305611Sbill 306611Sbill eflag = 100; 307611Sbill dexit(); 308611Sbill } 309611Sbill 310611Sbill dexit() 311611Sbill { 312611Sbill 313611Sbill if (!pflag) { 314611Sbill cunlink(tmp1); 315611Sbill cunlink(tmp2); 316611Sbill if (sflag==0) 317611Sbill cunlink(tmp3); 318611Sbill cunlink(tmp4); 319611Sbill cunlink(tmp5); 320611Sbill } 321611Sbill exit(eflag); 322611Sbill } 323611Sbill 324611Sbill error(s, x) 325611Sbill char *s, *x; 326611Sbill { 327611Sbill FILE *diag = exflag ? stderr : stdout; 328611Sbill 329611Sbill fprintf(diag, "cc: "); 330611Sbill fprintf(diag, s, x); 331611Sbill putc('\n', diag); 332611Sbill exfail++; 333611Sbill cflag++; 334611Sbill eflag++; 335611Sbill } 336611Sbill 337611Sbill getsuf(as) 338611Sbill char as[]; 339611Sbill { 340611Sbill register int c; 341611Sbill register char *s; 342611Sbill register int t; 343611Sbill 344611Sbill s = as; 345611Sbill c = 0; 346611Sbill while (t = *s++) 347611Sbill if (t=='/') 348611Sbill c = 0; 349611Sbill else 350611Sbill c++; 351611Sbill s -= 3; 3525963Smckusic if (c <= MAXNAMLEN && c > 2 && *s++ == '.') 353611Sbill return (*s); 354611Sbill return (0); 355611Sbill } 356611Sbill 357611Sbill char * 358611Sbill setsuf(as, ch) 359611Sbill char *as; 360611Sbill { 361611Sbill register char *s, *s1; 362611Sbill 363611Sbill s = s1 = savestr(as); 364611Sbill while (*s) 365611Sbill if (*s++ == '/') 366611Sbill s1 = s; 367611Sbill s[-1] = ch; 368611Sbill return (s1); 369611Sbill } 370611Sbill 371611Sbill callsys(f, v) 372611Sbill char *f, **v; 373611Sbill { 374611Sbill int t, status; 37516237Smckusick char **cpp; 376611Sbill 37716237Smckusick if (debug) { 37816237Smckusick fprintf(stderr, "%s:", f); 37916237Smckusick for (cpp = v; *cpp != 0; cpp++) 38016237Smckusick fprintf(stderr, " %s", *cpp); 38116237Smckusick fprintf(stderr, "\n"); 38216237Smckusick } 383611Sbill t = vfork(); 384611Sbill if (t == -1) { 385611Sbill printf("No more processes\n"); 386611Sbill return (100); 387611Sbill } 388611Sbill if (t == 0) { 389611Sbill execv(f, v); 390611Sbill printf("Can't find %s\n", f); 391611Sbill fflush(stdout); 392611Sbill _exit(100); 393611Sbill } 394611Sbill while (t != wait(&status)) 395611Sbill ; 396611Sbill if ((t=(status&0377)) != 0 && t!=14) { 397611Sbill if (t!=2) { 398611Sbill printf("Fatal error in %s\n", f); 399611Sbill eflag = 8; 400611Sbill } 401611Sbill dexit(); 402611Sbill } 403611Sbill return ((status>>8) & 0377); 404611Sbill } 405611Sbill 406611Sbill nodup(l, os) 407611Sbill char **l, *os; 408611Sbill { 409611Sbill register char *t, *s; 410611Sbill register int c; 411611Sbill 412611Sbill s = os; 413611Sbill if (getsuf(s) != 'o') 414611Sbill return (1); 415611Sbill while (t = *l++) { 416611Sbill while (c = *s++) 417611Sbill if (c != *t++) 418611Sbill break; 419611Sbill if (*t==0 && c==0) 420611Sbill return (0); 421611Sbill s = os; 422611Sbill } 423611Sbill return (1); 424611Sbill } 425611Sbill 426611Sbill #define NSAVETAB 1024 427611Sbill char *savetab; 428611Sbill int saveleft; 429611Sbill 430611Sbill char * 431611Sbill savestr(cp) 432611Sbill register char *cp; 433611Sbill { 434611Sbill register int len; 435611Sbill 436611Sbill len = strlen(cp) + 1; 437611Sbill if (len > saveleft) { 438611Sbill saveleft = NSAVETAB; 439611Sbill if (len > saveleft) 440611Sbill saveleft = len; 441611Sbill savetab = (char *)malloc(saveleft); 442611Sbill if (savetab == 0) { 443611Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 444611Sbill exit(1); 445611Sbill } 446611Sbill } 447611Sbill strncpy(savetab, cp, len); 448611Sbill cp = savetab; 449611Sbill savetab += len; 450611Sbill saveleft -= len; 451611Sbill return (cp); 452611Sbill } 453611Sbill 454611Sbill char * 455611Sbill strspl(left, right) 456611Sbill char *left, *right; 457611Sbill { 458611Sbill char buf[BUFSIZ]; 459611Sbill 460611Sbill strcpy(buf, left); 461611Sbill strcat(buf, right); 462611Sbill return (savestr(buf)); 463611Sbill } 464