1*17134Ssam static char sccsid[] = "@(#)cc.c 4.9 08/30/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 case 'o': 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; 79611Sbill case 'g': 809817Slinton if (argv[i][2] == 'o') { 819817Slinton Gflag++; /* old format for -go */ 829817Slinton } else { 839817Slinton gflag++; /* new format for -g */ 849817Slinton } 85611Sbill continue; 86611Sbill case 'w': 87611Sbill wflag++; 88611Sbill continue; 89611Sbill case 'E': 90611Sbill exflag++; 91611Sbill case 'P': 92611Sbill pflag++; 93611Sbill if (argv[i][1]=='P') 94611Sbill fprintf(stderr, 95611Sbill "cc: warning: -P option obsolete; you should use -E instead\n"); 96611Sbill plist[np++] = argv[i]; 97611Sbill case 'c': 98611Sbill cflag++; 99611Sbill continue; 10016237Smckusick case 'M': 10116237Smckusick exflag++; 10216237Smckusick pflag++; 10316237Smckusick Mflag++; 10416237Smckusick /* and fall through */ 105611Sbill case 'D': 106611Sbill case 'I': 107611Sbill case 'U': 108611Sbill case 'C': 109611Sbill plist[np++] = argv[i]; 110611Sbill continue; 111*17134Ssam case 'L': 112*17134Ssam llist[nl++] = argv[i]; 113*17134Ssam continue; 114611Sbill case 't': 115611Sbill if (chpass) 116611Sbill error("-t overwrites earlier option", 0); 117611Sbill chpass = argv[i]+2; 118611Sbill if (chpass[0]==0) 119611Sbill chpass = "012p"; 120611Sbill continue; 121611Sbill case 'B': 122611Sbill if (npassname) 123611Sbill error("-B overwrites earlier option", 0); 124611Sbill npassname = argv[i]+2; 125611Sbill if (npassname[0]==0) 126611Sbill npassname = "/usr/c/o"; 127611Sbill continue; 128611Sbill case 'd': 12916237Smckusick if (argv[i][2] == '\0') { 13016237Smckusick debug++; 13116237Smckusick continue; 13216237Smckusick } 133611Sbill dflag = argv[i]; 134611Sbill continue; 135611Sbill } 136611Sbill t = argv[i]; 137611Sbill c = getsuf(t); 138611Sbill if (c=='c' || c=='s' || exflag) { 139611Sbill clist[nc++] = t; 140611Sbill t = setsuf(t, 'o'); 141611Sbill } 142611Sbill if (nodup(llist, t)) { 143611Sbill llist[nl++] = t; 144611Sbill if (getsuf(t)=='o') 145611Sbill nxo++; 146611Sbill } 147611Sbill } 1489817Slinton if (gflag || Gflag) { 149611Sbill if (oflag) 150611Sbill fprintf(stderr, "cc: warning: -g disables -O\n"); 151611Sbill oflag = 0; 152611Sbill } 153611Sbill if (npassname && chpass ==0) 154611Sbill chpass = "012p"; 155611Sbill if (chpass && npassname==0) 156896Sbill npassname = "/usr/new"; 157611Sbill if (chpass) 158611Sbill for (t=chpass; *t; t++) { 159611Sbill switch (*t) { 160611Sbill 161611Sbill case '0': 162611Sbill ccom = strspl(npassname, "ccom"); 163611Sbill continue; 164611Sbill case '2': 165611Sbill c2 = strspl(npassname, "c2"); 166611Sbill continue; 167611Sbill case 'p': 168611Sbill cpp = strspl(npassname, "cpp"); 169611Sbill continue; 170611Sbill } 171611Sbill } 172611Sbill if (nc==0) 173611Sbill goto nocom; 174611Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 175611Sbill signal(SIGINT, idexit); 176611Sbill if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 177611Sbill signal(SIGTERM, idexit); 178611Sbill if (pflag==0) 179611Sbill sprintf(tmp0, "/tmp/ctm%05.5d", getpid()); 180611Sbill tmp1 = strspl(tmp0, "1"); 181611Sbill tmp2 = strspl(tmp0, "2"); 182611Sbill tmp3 = strspl(tmp0, "3"); 183611Sbill if (pflag==0) 184611Sbill tmp4 = strspl(tmp0, "4"); 185611Sbill if (oflag) 186611Sbill tmp5 = strspl(tmp0, "5"); 187611Sbill for (i=0; i<nc; i++) { 18816237Smckusick if (nc > 1 && !Mflag) { 189611Sbill printf("%s:\n", clist[i]); 190611Sbill fflush(stdout); 191611Sbill } 192611Sbill if (getsuf(clist[i]) == 's') { 193611Sbill assource = clist[i]; 194611Sbill goto assemble; 195611Sbill } else 196611Sbill assource = tmp3; 197611Sbill if (pflag) 198611Sbill tmp4 = setsuf(clist[i], 'i'); 19916237Smckusick av[0] = "cpp"; av[1] = clist[i]; 20016237Smckusick na = 2; 20116237Smckusick if (!exflag) 20216237Smckusick av[na++] = tmp4; 203611Sbill for (j = 0; j < np; j++) 204611Sbill av[na++] = plist[j]; 205611Sbill av[na++] = 0; 206611Sbill if (callsys(cpp, av)) { 207611Sbill exfail++; 208611Sbill eflag++; 209611Sbill } 210611Sbill if (pflag || exfail) { 211611Sbill cflag++; 212611Sbill continue; 213611Sbill } 214611Sbill if (sflag) 215611Sbill assource = tmp3 = setsuf(clist[i], 's'); 216611Sbill av[0] = "ccom"; av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3; 217611Sbill if (proflag) 218611Sbill av[na++] = "-XP"; 2199817Slinton if (gflag) { 220611Sbill av[na++] = "-Xg"; 2219817Slinton } else if (Gflag) { 2229817Slinton av[na++] = "-XG"; 2239817Slinton } 224611Sbill if (wflag) 225611Sbill av[na++] = "-w"; 226611Sbill av[na] = 0; 227611Sbill if (callsys(ccom, av)) { 228611Sbill cflag++; 229611Sbill eflag++; 230611Sbill continue; 231611Sbill } 232611Sbill if (oflag) { 233611Sbill av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; 234611Sbill if (callsys(c2, av)) { 235611Sbill unlink(tmp3); 236611Sbill tmp3 = assource = tmp5; 237611Sbill } else 238611Sbill unlink(tmp5); 239611Sbill } 240611Sbill if (sflag) 241611Sbill continue; 242611Sbill assemble: 243611Sbill cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); 244611Sbill av[0] = "as"; av[1] = "-o"; av[2] = setsuf(clist[i], 'o'); 245652Sbill na = 3; 246652Sbill if (Rflag) 247652Sbill av[na++] = "-R"; 248611Sbill if (dflag) 249611Sbill av[na++] = dflag; 250652Sbill av[na++] = assource; 251611Sbill av[na] = 0; 252611Sbill if (callsys(as, av) > 1) { 253611Sbill cflag++; 254611Sbill eflag++; 255611Sbill continue; 256611Sbill } 257611Sbill } 258611Sbill nocom: 259611Sbill if (cflag==0 && nl!=0) { 260611Sbill i = 0; 261611Sbill av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3; 262611Sbill if (outfile) { 263611Sbill av[na++] = "-o"; 264611Sbill av[na++] = outfile; 265611Sbill } 266611Sbill while (i < nl) 267611Sbill av[na++] = llist[i++]; 2689817Slinton if (gflag || Gflag) 269611Sbill av[na++] = "-lg"; 2705055Smckusic if (proflag) 2715055Smckusic av[na++] = "-lc_p"; 2725055Smckusic else 2735055Smckusic av[na++] = "-lc"; 274611Sbill av[na++] = 0; 275611Sbill eflag |= callsys(ld, av); 276611Sbill if (nc==1 && nxo==1 && eflag==0) 277611Sbill unlink(setsuf(clist[0], 'o')); 278611Sbill } 279611Sbill dexit(); 280611Sbill } 281611Sbill 282611Sbill idexit() 283611Sbill { 284611Sbill 285611Sbill eflag = 100; 286611Sbill dexit(); 287611Sbill } 288611Sbill 289611Sbill dexit() 290611Sbill { 291611Sbill 292611Sbill if (!pflag) { 293611Sbill cunlink(tmp1); 294611Sbill cunlink(tmp2); 295611Sbill if (sflag==0) 296611Sbill cunlink(tmp3); 297611Sbill cunlink(tmp4); 298611Sbill cunlink(tmp5); 299611Sbill } 300611Sbill exit(eflag); 301611Sbill } 302611Sbill 303611Sbill error(s, x) 304611Sbill char *s, *x; 305611Sbill { 306611Sbill FILE *diag = exflag ? stderr : stdout; 307611Sbill 308611Sbill fprintf(diag, "cc: "); 309611Sbill fprintf(diag, s, x); 310611Sbill putc('\n', diag); 311611Sbill exfail++; 312611Sbill cflag++; 313611Sbill eflag++; 314611Sbill } 315611Sbill 316611Sbill getsuf(as) 317611Sbill char as[]; 318611Sbill { 319611Sbill register int c; 320611Sbill register char *s; 321611Sbill register int t; 322611Sbill 323611Sbill s = as; 324611Sbill c = 0; 325611Sbill while (t = *s++) 326611Sbill if (t=='/') 327611Sbill c = 0; 328611Sbill else 329611Sbill c++; 330611Sbill s -= 3; 3315963Smckusic if (c <= MAXNAMLEN && c > 2 && *s++ == '.') 332611Sbill return (*s); 333611Sbill return (0); 334611Sbill } 335611Sbill 336611Sbill char * 337611Sbill setsuf(as, ch) 338611Sbill char *as; 339611Sbill { 340611Sbill register char *s, *s1; 341611Sbill 342611Sbill s = s1 = savestr(as); 343611Sbill while (*s) 344611Sbill if (*s++ == '/') 345611Sbill s1 = s; 346611Sbill s[-1] = ch; 347611Sbill return (s1); 348611Sbill } 349611Sbill 350611Sbill callsys(f, v) 351611Sbill char *f, **v; 352611Sbill { 353611Sbill int t, status; 35416237Smckusick char **cpp; 355611Sbill 35616237Smckusick if (debug) { 35716237Smckusick fprintf(stderr, "%s:", f); 35816237Smckusick for (cpp = v; *cpp != 0; cpp++) 35916237Smckusick fprintf(stderr, " %s", *cpp); 36016237Smckusick fprintf(stderr, "\n"); 36116237Smckusick } 362611Sbill t = vfork(); 363611Sbill if (t == -1) { 364611Sbill printf("No more processes\n"); 365611Sbill return (100); 366611Sbill } 367611Sbill if (t == 0) { 368611Sbill execv(f, v); 369611Sbill printf("Can't find %s\n", f); 370611Sbill fflush(stdout); 371611Sbill _exit(100); 372611Sbill } 373611Sbill while (t != wait(&status)) 374611Sbill ; 375611Sbill if ((t=(status&0377)) != 0 && t!=14) { 376611Sbill if (t!=2) { 377611Sbill printf("Fatal error in %s\n", f); 378611Sbill eflag = 8; 379611Sbill } 380611Sbill dexit(); 381611Sbill } 382611Sbill return ((status>>8) & 0377); 383611Sbill } 384611Sbill 385611Sbill nodup(l, os) 386611Sbill char **l, *os; 387611Sbill { 388611Sbill register char *t, *s; 389611Sbill register int c; 390611Sbill 391611Sbill s = os; 392611Sbill if (getsuf(s) != 'o') 393611Sbill return (1); 394611Sbill while (t = *l++) { 395611Sbill while (c = *s++) 396611Sbill if (c != *t++) 397611Sbill break; 398611Sbill if (*t==0 && c==0) 399611Sbill return (0); 400611Sbill s = os; 401611Sbill } 402611Sbill return (1); 403611Sbill } 404611Sbill 405611Sbill #define NSAVETAB 1024 406611Sbill char *savetab; 407611Sbill int saveleft; 408611Sbill 409611Sbill char * 410611Sbill savestr(cp) 411611Sbill register char *cp; 412611Sbill { 413611Sbill register int len; 414611Sbill 415611Sbill len = strlen(cp) + 1; 416611Sbill if (len > saveleft) { 417611Sbill saveleft = NSAVETAB; 418611Sbill if (len > saveleft) 419611Sbill saveleft = len; 420611Sbill savetab = (char *)malloc(saveleft); 421611Sbill if (savetab == 0) { 422611Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 423611Sbill exit(1); 424611Sbill } 425611Sbill } 426611Sbill strncpy(savetab, cp, len); 427611Sbill cp = savetab; 428611Sbill savetab += len; 429611Sbill saveleft -= len; 430611Sbill return (cp); 431611Sbill } 432611Sbill 433611Sbill char * 434611Sbill strspl(left, right) 435611Sbill char *left, *right; 436611Sbill { 437611Sbill char buf[BUFSIZ]; 438611Sbill 439611Sbill strcpy(buf, left); 440611Sbill strcat(buf, right); 441611Sbill return (savestr(buf)); 442611Sbill } 443