1*17461Sralph static char sccsid[] = "@(#)cc.c 4.10 12/04/84"; 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"; 13896Sbill char *c2 = "/lib/c2"; 14896Sbill char *as = "/bin/as"; 15896Sbill char *ld = "/bin/ld"; 16896Sbill char *crt0 = "/lib/crt0.o"; 17611Sbill 18611Sbill char tmp0[30]; /* big enough for /tmp/ctm%05.5d */ 19611Sbill char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5; 20611Sbill char *outfile; 21611Sbill char *savestr(), *strspl(), *setsuf(); 22611Sbill int idexit(); 23611Sbill char **av, **clist, **llist, **plist; 249817Slinton int cflag, eflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag; 2516237Smckusick int gflag, Gflag, Mflag, debug; 26611Sbill char *dflag; 27611Sbill int exfail; 28611Sbill char *chpass; 29611Sbill char *npassname; 30611Sbill 31611Sbill int nc, nl, np, nxo, na; 32611Sbill 33611Sbill #define cunlink(s) if (s) unlink(s) 34611Sbill 35611Sbill main(argc, argv) 36611Sbill char **argv; 37611Sbill { 38611Sbill char *t; 39611Sbill char *assource; 40611Sbill int i, j, c; 41611Sbill 42611Sbill /* ld currently adds upto 5 args; 10 is room to spare */ 43611Sbill av = (char **)calloc(argc+10, sizeof (char **)); 44611Sbill clist = (char **)calloc(argc, sizeof (char **)); 45611Sbill llist = (char **)calloc(argc, sizeof (char **)); 46611Sbill plist = (char **)calloc(argc, sizeof (char **)); 47611Sbill for (i = 1; i < argc; i++) { 48611Sbill if (*argv[i] == '-') switch (argv[i][1]) { 49611Sbill 50611Sbill case 'S': 51611Sbill sflag++; 52611Sbill cflag++; 53611Sbill continue; 54611Sbill case 'o': 55611Sbill if (++i < argc) { 56611Sbill outfile = argv[i]; 57611Sbill switch (getsuf(outfile)) { 58611Sbill 59611Sbill case 'c': 60611Sbill error("-o would overwrite %s", 61611Sbill outfile); 62611Sbill exit(8); 63611Sbill } 64611Sbill } 65611Sbill continue; 66652Sbill case 'R': 67652Sbill Rflag++; 68652Sbill continue; 69611Sbill case 'O': 70611Sbill oflag++; 71611Sbill continue; 72611Sbill case 'p': 73611Sbill proflag++; 745055Smckusic crt0 = "/lib/mcrt0.o"; 755055Smckusic if (argv[i][2] == 'g') 765055Smckusic crt0 = "/usr/lib/gcrt0.o"; 77611Sbill continue; 78611Sbill case 'g': 799817Slinton if (argv[i][2] == 'o') { 809817Slinton Gflag++; /* old format for -go */ 819817Slinton } else { 829817Slinton gflag++; /* new format for -g */ 839817Slinton } 84611Sbill continue; 85611Sbill case 'w': 86611Sbill wflag++; 87611Sbill continue; 88611Sbill case 'E': 89611Sbill exflag++; 90611Sbill case 'P': 91611Sbill pflag++; 92611Sbill if (argv[i][1]=='P') 93611Sbill fprintf(stderr, 94611Sbill "cc: warning: -P option obsolete; you should use -E instead\n"); 95611Sbill plist[np++] = argv[i]; 96611Sbill case 'c': 97611Sbill cflag++; 98611Sbill continue; 9916237Smckusick case 'M': 10016237Smckusick exflag++; 10116237Smckusick pflag++; 10216237Smckusick Mflag++; 10316237Smckusick /* and fall through */ 104611Sbill case 'D': 105611Sbill case 'I': 106611Sbill case 'U': 107611Sbill case 'C': 108611Sbill plist[np++] = argv[i]; 109611Sbill continue; 11017134Ssam case 'L': 11117134Ssam llist[nl++] = argv[i]; 11217134Ssam continue; 113611Sbill case 't': 114611Sbill if (chpass) 115611Sbill error("-t overwrites earlier option", 0); 116611Sbill chpass = argv[i]+2; 117611Sbill if (chpass[0]==0) 118611Sbill chpass = "012p"; 119611Sbill continue; 120611Sbill case 'B': 121611Sbill if (npassname) 122611Sbill error("-B overwrites earlier option", 0); 123611Sbill npassname = argv[i]+2; 124611Sbill if (npassname[0]==0) 125611Sbill npassname = "/usr/c/o"; 126611Sbill continue; 127611Sbill case 'd': 12816237Smckusick if (argv[i][2] == '\0') { 12916237Smckusick debug++; 13016237Smckusick continue; 13116237Smckusick } 132611Sbill dflag = argv[i]; 133611Sbill continue; 134611Sbill } 135611Sbill t = argv[i]; 136611Sbill c = getsuf(t); 137611Sbill if (c=='c' || c=='s' || exflag) { 138611Sbill clist[nc++] = t; 139611Sbill t = setsuf(t, 'o'); 140611Sbill } 141611Sbill if (nodup(llist, t)) { 142611Sbill llist[nl++] = t; 143611Sbill if (getsuf(t)=='o') 144611Sbill nxo++; 145611Sbill } 146611Sbill } 1479817Slinton if (gflag || Gflag) { 148611Sbill if (oflag) 149611Sbill fprintf(stderr, "cc: warning: -g disables -O\n"); 150611Sbill oflag = 0; 151611Sbill } 152611Sbill if (npassname && chpass ==0) 153611Sbill chpass = "012p"; 154611Sbill if (chpass && npassname==0) 155896Sbill npassname = "/usr/new"; 156611Sbill if (chpass) 157611Sbill for (t=chpass; *t; t++) { 158611Sbill switch (*t) { 159611Sbill 160611Sbill case '0': 161611Sbill ccom = strspl(npassname, "ccom"); 162611Sbill continue; 163611Sbill case '2': 164611Sbill c2 = strspl(npassname, "c2"); 165611Sbill continue; 166611Sbill case 'p': 167611Sbill cpp = strspl(npassname, "cpp"); 168611Sbill continue; 169611Sbill } 170611Sbill } 171611Sbill if (nc==0) 172611Sbill goto nocom; 173611Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 174611Sbill signal(SIGINT, idexit); 175611Sbill if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 176611Sbill signal(SIGTERM, idexit); 177611Sbill if (pflag==0) 178611Sbill sprintf(tmp0, "/tmp/ctm%05.5d", getpid()); 179611Sbill tmp1 = strspl(tmp0, "1"); 180611Sbill tmp2 = strspl(tmp0, "2"); 181611Sbill tmp3 = strspl(tmp0, "3"); 182611Sbill if (pflag==0) 183611Sbill tmp4 = strspl(tmp0, "4"); 184611Sbill if (oflag) 185611Sbill tmp5 = strspl(tmp0, "5"); 186611Sbill for (i=0; i<nc; i++) { 18716237Smckusick if (nc > 1 && !Mflag) { 188611Sbill printf("%s:\n", clist[i]); 189611Sbill fflush(stdout); 190611Sbill } 191611Sbill if (getsuf(clist[i]) == 's') { 192611Sbill assource = clist[i]; 193611Sbill goto assemble; 194611Sbill } else 195611Sbill assource = tmp3; 196611Sbill if (pflag) 197611Sbill tmp4 = setsuf(clist[i], 'i'); 19816237Smckusick av[0] = "cpp"; av[1] = clist[i]; 19916237Smckusick na = 2; 20016237Smckusick if (!exflag) 20116237Smckusick av[na++] = tmp4; 202611Sbill for (j = 0; j < np; j++) 203611Sbill av[na++] = plist[j]; 204611Sbill av[na++] = 0; 205611Sbill if (callsys(cpp, av)) { 206611Sbill exfail++; 207611Sbill eflag++; 208611Sbill } 209611Sbill if (pflag || exfail) { 210611Sbill cflag++; 211611Sbill continue; 212611Sbill } 213*17461Sralph if (sflag) { 214*17461Sralph if (nc==1 && outfile) 215*17461Sralph tmp3 = outfile; 216*17461Sralph else 217*17461Sralph tmp3 = setsuf(clist[i], 's'); 218*17461Sralph assource = tmp3; 219*17461Sralph } 220611Sbill av[0] = "ccom"; av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3; 221611Sbill if (proflag) 222611Sbill av[na++] = "-XP"; 2239817Slinton if (gflag) { 224611Sbill av[na++] = "-Xg"; 2259817Slinton } else if (Gflag) { 2269817Slinton av[na++] = "-XG"; 2279817Slinton } 228611Sbill if (wflag) 229611Sbill av[na++] = "-w"; 230611Sbill av[na] = 0; 231611Sbill if (callsys(ccom, av)) { 232611Sbill cflag++; 233611Sbill eflag++; 234611Sbill continue; 235611Sbill } 236611Sbill if (oflag) { 237611Sbill av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; 238611Sbill if (callsys(c2, av)) { 239611Sbill unlink(tmp3); 240611Sbill tmp3 = assource = tmp5; 241611Sbill } else 242611Sbill unlink(tmp5); 243611Sbill } 244611Sbill if (sflag) 245611Sbill continue; 246611Sbill assemble: 247611Sbill cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); 248*17461Sralph av[0] = "as"; av[1] = "-o"; 249*17461Sralph if (cflag && nc==1 && outfile) 250*17461Sralph av[2] = outfile; 251*17461Sralph else 252*17461Sralph av[2] = setsuf(clist[i], 'o'); 253652Sbill na = 3; 254652Sbill if (Rflag) 255652Sbill av[na++] = "-R"; 256611Sbill if (dflag) 257611Sbill av[na++] = dflag; 258652Sbill av[na++] = assource; 259611Sbill av[na] = 0; 260611Sbill if (callsys(as, av) > 1) { 261611Sbill cflag++; 262611Sbill eflag++; 263611Sbill continue; 264611Sbill } 265611Sbill } 266611Sbill nocom: 267611Sbill if (cflag==0 && nl!=0) { 268611Sbill i = 0; 269611Sbill av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3; 270611Sbill if (outfile) { 271611Sbill av[na++] = "-o"; 272611Sbill av[na++] = outfile; 273611Sbill } 274611Sbill while (i < nl) 275611Sbill av[na++] = llist[i++]; 2769817Slinton if (gflag || Gflag) 277611Sbill av[na++] = "-lg"; 2785055Smckusic if (proflag) 2795055Smckusic av[na++] = "-lc_p"; 2805055Smckusic else 2815055Smckusic av[na++] = "-lc"; 282611Sbill av[na++] = 0; 283611Sbill eflag |= callsys(ld, av); 284611Sbill if (nc==1 && nxo==1 && eflag==0) 285611Sbill unlink(setsuf(clist[0], 'o')); 286611Sbill } 287611Sbill dexit(); 288611Sbill } 289611Sbill 290611Sbill idexit() 291611Sbill { 292611Sbill 293611Sbill eflag = 100; 294611Sbill dexit(); 295611Sbill } 296611Sbill 297611Sbill dexit() 298611Sbill { 299611Sbill 300611Sbill if (!pflag) { 301611Sbill cunlink(tmp1); 302611Sbill cunlink(tmp2); 303611Sbill if (sflag==0) 304611Sbill cunlink(tmp3); 305611Sbill cunlink(tmp4); 306611Sbill cunlink(tmp5); 307611Sbill } 308611Sbill exit(eflag); 309611Sbill } 310611Sbill 311611Sbill error(s, x) 312611Sbill char *s, *x; 313611Sbill { 314611Sbill FILE *diag = exflag ? stderr : stdout; 315611Sbill 316611Sbill fprintf(diag, "cc: "); 317611Sbill fprintf(diag, s, x); 318611Sbill putc('\n', diag); 319611Sbill exfail++; 320611Sbill cflag++; 321611Sbill eflag++; 322611Sbill } 323611Sbill 324611Sbill getsuf(as) 325611Sbill char as[]; 326611Sbill { 327611Sbill register int c; 328611Sbill register char *s; 329611Sbill register int t; 330611Sbill 331611Sbill s = as; 332611Sbill c = 0; 333611Sbill while (t = *s++) 334611Sbill if (t=='/') 335611Sbill c = 0; 336611Sbill else 337611Sbill c++; 338611Sbill s -= 3; 3395963Smckusic if (c <= MAXNAMLEN && c > 2 && *s++ == '.') 340611Sbill return (*s); 341611Sbill return (0); 342611Sbill } 343611Sbill 344611Sbill char * 345611Sbill setsuf(as, ch) 346611Sbill char *as; 347611Sbill { 348611Sbill register char *s, *s1; 349611Sbill 350611Sbill s = s1 = savestr(as); 351611Sbill while (*s) 352611Sbill if (*s++ == '/') 353611Sbill s1 = s; 354611Sbill s[-1] = ch; 355611Sbill return (s1); 356611Sbill } 357611Sbill 358611Sbill callsys(f, v) 359611Sbill char *f, **v; 360611Sbill { 361611Sbill int t, status; 36216237Smckusick char **cpp; 363611Sbill 36416237Smckusick if (debug) { 36516237Smckusick fprintf(stderr, "%s:", f); 36616237Smckusick for (cpp = v; *cpp != 0; cpp++) 36716237Smckusick fprintf(stderr, " %s", *cpp); 36816237Smckusick fprintf(stderr, "\n"); 36916237Smckusick } 370611Sbill t = vfork(); 371611Sbill if (t == -1) { 372611Sbill printf("No more processes\n"); 373611Sbill return (100); 374611Sbill } 375611Sbill if (t == 0) { 376611Sbill execv(f, v); 377611Sbill printf("Can't find %s\n", f); 378611Sbill fflush(stdout); 379611Sbill _exit(100); 380611Sbill } 381611Sbill while (t != wait(&status)) 382611Sbill ; 383611Sbill if ((t=(status&0377)) != 0 && t!=14) { 384611Sbill if (t!=2) { 385611Sbill printf("Fatal error in %s\n", f); 386611Sbill eflag = 8; 387611Sbill } 388611Sbill dexit(); 389611Sbill } 390611Sbill return ((status>>8) & 0377); 391611Sbill } 392611Sbill 393611Sbill nodup(l, os) 394611Sbill char **l, *os; 395611Sbill { 396611Sbill register char *t, *s; 397611Sbill register int c; 398611Sbill 399611Sbill s = os; 400611Sbill if (getsuf(s) != 'o') 401611Sbill return (1); 402611Sbill while (t = *l++) { 403611Sbill while (c = *s++) 404611Sbill if (c != *t++) 405611Sbill break; 406611Sbill if (*t==0 && c==0) 407611Sbill return (0); 408611Sbill s = os; 409611Sbill } 410611Sbill return (1); 411611Sbill } 412611Sbill 413611Sbill #define NSAVETAB 1024 414611Sbill char *savetab; 415611Sbill int saveleft; 416611Sbill 417611Sbill char * 418611Sbill savestr(cp) 419611Sbill register char *cp; 420611Sbill { 421611Sbill register int len; 422611Sbill 423611Sbill len = strlen(cp) + 1; 424611Sbill if (len > saveleft) { 425611Sbill saveleft = NSAVETAB; 426611Sbill if (len > saveleft) 427611Sbill saveleft = len; 428611Sbill savetab = (char *)malloc(saveleft); 429611Sbill if (savetab == 0) { 430611Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 431611Sbill exit(1); 432611Sbill } 433611Sbill } 434611Sbill strncpy(savetab, cp, len); 435611Sbill cp = savetab; 436611Sbill savetab += len; 437611Sbill saveleft -= len; 438611Sbill return (cp); 439611Sbill } 440611Sbill 441611Sbill char * 442611Sbill strspl(left, right) 443611Sbill char *left, *right; 444611Sbill { 445611Sbill char buf[BUFSIZ]; 446611Sbill 447611Sbill strcpy(buf, left); 448611Sbill strcat(buf, right); 449611Sbill return (savestr(buf)); 450611Sbill } 451