1*16237Smckusick static char sccsid[] = "@(#)cc.c 4.8 03/24/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; 25*16237Smckusick 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; 100*16237Smckusick case 'M': 101*16237Smckusick exflag++; 102*16237Smckusick pflag++; 103*16237Smckusick Mflag++; 104*16237Smckusick /* and fall through */ 105611Sbill case 'D': 106611Sbill case 'I': 107611Sbill case 'U': 108611Sbill case 'C': 109611Sbill plist[np++] = argv[i]; 110611Sbill continue; 111611Sbill case 't': 112611Sbill if (chpass) 113611Sbill error("-t overwrites earlier option", 0); 114611Sbill chpass = argv[i]+2; 115611Sbill if (chpass[0]==0) 116611Sbill chpass = "012p"; 117611Sbill continue; 118611Sbill case 'B': 119611Sbill if (npassname) 120611Sbill error("-B overwrites earlier option", 0); 121611Sbill npassname = argv[i]+2; 122611Sbill if (npassname[0]==0) 123611Sbill npassname = "/usr/c/o"; 124611Sbill continue; 125611Sbill case 'd': 126*16237Smckusick if (argv[i][2] == '\0') { 127*16237Smckusick debug++; 128*16237Smckusick continue; 129*16237Smckusick } 130611Sbill dflag = argv[i]; 131611Sbill continue; 132611Sbill } 133611Sbill t = argv[i]; 134611Sbill c = getsuf(t); 135611Sbill if (c=='c' || c=='s' || exflag) { 136611Sbill clist[nc++] = t; 137611Sbill t = setsuf(t, 'o'); 138611Sbill } 139611Sbill if (nodup(llist, t)) { 140611Sbill llist[nl++] = t; 141611Sbill if (getsuf(t)=='o') 142611Sbill nxo++; 143611Sbill } 144611Sbill } 1459817Slinton if (gflag || Gflag) { 146611Sbill if (oflag) 147611Sbill fprintf(stderr, "cc: warning: -g disables -O\n"); 148611Sbill oflag = 0; 149611Sbill } 150611Sbill if (npassname && chpass ==0) 151611Sbill chpass = "012p"; 152611Sbill if (chpass && npassname==0) 153896Sbill npassname = "/usr/new"; 154611Sbill if (chpass) 155611Sbill for (t=chpass; *t; t++) { 156611Sbill switch (*t) { 157611Sbill 158611Sbill case '0': 159611Sbill ccom = strspl(npassname, "ccom"); 160611Sbill continue; 161611Sbill case '2': 162611Sbill c2 = strspl(npassname, "c2"); 163611Sbill continue; 164611Sbill case 'p': 165611Sbill cpp = strspl(npassname, "cpp"); 166611Sbill continue; 167611Sbill } 168611Sbill } 169611Sbill if (nc==0) 170611Sbill goto nocom; 171611Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 172611Sbill signal(SIGINT, idexit); 173611Sbill if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 174611Sbill signal(SIGTERM, idexit); 175611Sbill if (pflag==0) 176611Sbill sprintf(tmp0, "/tmp/ctm%05.5d", getpid()); 177611Sbill tmp1 = strspl(tmp0, "1"); 178611Sbill tmp2 = strspl(tmp0, "2"); 179611Sbill tmp3 = strspl(tmp0, "3"); 180611Sbill if (pflag==0) 181611Sbill tmp4 = strspl(tmp0, "4"); 182611Sbill if (oflag) 183611Sbill tmp5 = strspl(tmp0, "5"); 184611Sbill for (i=0; i<nc; i++) { 185*16237Smckusick if (nc > 1 && !Mflag) { 186611Sbill printf("%s:\n", clist[i]); 187611Sbill fflush(stdout); 188611Sbill } 189611Sbill if (getsuf(clist[i]) == 's') { 190611Sbill assource = clist[i]; 191611Sbill goto assemble; 192611Sbill } else 193611Sbill assource = tmp3; 194611Sbill if (pflag) 195611Sbill tmp4 = setsuf(clist[i], 'i'); 196*16237Smckusick av[0] = "cpp"; av[1] = clist[i]; 197*16237Smckusick na = 2; 198*16237Smckusick if (!exflag) 199*16237Smckusick av[na++] = tmp4; 200611Sbill for (j = 0; j < np; j++) 201611Sbill av[na++] = plist[j]; 202611Sbill av[na++] = 0; 203611Sbill if (callsys(cpp, av)) { 204611Sbill exfail++; 205611Sbill eflag++; 206611Sbill } 207611Sbill if (pflag || exfail) { 208611Sbill cflag++; 209611Sbill continue; 210611Sbill } 211611Sbill if (sflag) 212611Sbill assource = tmp3 = setsuf(clist[i], 's'); 213611Sbill av[0] = "ccom"; av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3; 214611Sbill if (proflag) 215611Sbill av[na++] = "-XP"; 2169817Slinton if (gflag) { 217611Sbill av[na++] = "-Xg"; 2189817Slinton } else if (Gflag) { 2199817Slinton av[na++] = "-XG"; 2209817Slinton } 221611Sbill if (wflag) 222611Sbill av[na++] = "-w"; 223611Sbill av[na] = 0; 224611Sbill if (callsys(ccom, av)) { 225611Sbill cflag++; 226611Sbill eflag++; 227611Sbill continue; 228611Sbill } 229611Sbill if (oflag) { 230611Sbill av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; 231611Sbill if (callsys(c2, av)) { 232611Sbill unlink(tmp3); 233611Sbill tmp3 = assource = tmp5; 234611Sbill } else 235611Sbill unlink(tmp5); 236611Sbill } 237611Sbill if (sflag) 238611Sbill continue; 239611Sbill assemble: 240611Sbill cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); 241611Sbill av[0] = "as"; av[1] = "-o"; av[2] = setsuf(clist[i], 'o'); 242652Sbill na = 3; 243652Sbill if (Rflag) 244652Sbill av[na++] = "-R"; 245611Sbill if (dflag) 246611Sbill av[na++] = dflag; 247652Sbill av[na++] = assource; 248611Sbill av[na] = 0; 249611Sbill if (callsys(as, av) > 1) { 250611Sbill cflag++; 251611Sbill eflag++; 252611Sbill continue; 253611Sbill } 254611Sbill } 255611Sbill nocom: 256611Sbill if (cflag==0 && nl!=0) { 257611Sbill i = 0; 258611Sbill av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3; 259611Sbill if (outfile) { 260611Sbill av[na++] = "-o"; 261611Sbill av[na++] = outfile; 262611Sbill } 263611Sbill while (i < nl) 264611Sbill av[na++] = llist[i++]; 2659817Slinton if (gflag || Gflag) 266611Sbill av[na++] = "-lg"; 2675055Smckusic if (proflag) 2685055Smckusic av[na++] = "-lc_p"; 2695055Smckusic else 2705055Smckusic av[na++] = "-lc"; 271611Sbill av[na++] = 0; 272611Sbill eflag |= callsys(ld, av); 273611Sbill if (nc==1 && nxo==1 && eflag==0) 274611Sbill unlink(setsuf(clist[0], 'o')); 275611Sbill } 276611Sbill dexit(); 277611Sbill } 278611Sbill 279611Sbill idexit() 280611Sbill { 281611Sbill 282611Sbill eflag = 100; 283611Sbill dexit(); 284611Sbill } 285611Sbill 286611Sbill dexit() 287611Sbill { 288611Sbill 289611Sbill if (!pflag) { 290611Sbill cunlink(tmp1); 291611Sbill cunlink(tmp2); 292611Sbill if (sflag==0) 293611Sbill cunlink(tmp3); 294611Sbill cunlink(tmp4); 295611Sbill cunlink(tmp5); 296611Sbill } 297611Sbill exit(eflag); 298611Sbill } 299611Sbill 300611Sbill error(s, x) 301611Sbill char *s, *x; 302611Sbill { 303611Sbill FILE *diag = exflag ? stderr : stdout; 304611Sbill 305611Sbill fprintf(diag, "cc: "); 306611Sbill fprintf(diag, s, x); 307611Sbill putc('\n', diag); 308611Sbill exfail++; 309611Sbill cflag++; 310611Sbill eflag++; 311611Sbill } 312611Sbill 313611Sbill getsuf(as) 314611Sbill char as[]; 315611Sbill { 316611Sbill register int c; 317611Sbill register char *s; 318611Sbill register int t; 319611Sbill 320611Sbill s = as; 321611Sbill c = 0; 322611Sbill while (t = *s++) 323611Sbill if (t=='/') 324611Sbill c = 0; 325611Sbill else 326611Sbill c++; 327611Sbill s -= 3; 3285963Smckusic if (c <= MAXNAMLEN && c > 2 && *s++ == '.') 329611Sbill return (*s); 330611Sbill return (0); 331611Sbill } 332611Sbill 333611Sbill char * 334611Sbill setsuf(as, ch) 335611Sbill char *as; 336611Sbill { 337611Sbill register char *s, *s1; 338611Sbill 339611Sbill s = s1 = savestr(as); 340611Sbill while (*s) 341611Sbill if (*s++ == '/') 342611Sbill s1 = s; 343611Sbill s[-1] = ch; 344611Sbill return (s1); 345611Sbill } 346611Sbill 347611Sbill callsys(f, v) 348611Sbill char *f, **v; 349611Sbill { 350611Sbill int t, status; 351*16237Smckusick char **cpp; 352611Sbill 353*16237Smckusick if (debug) { 354*16237Smckusick fprintf(stderr, "%s:", f); 355*16237Smckusick for (cpp = v; *cpp != 0; cpp++) 356*16237Smckusick fprintf(stderr, " %s", *cpp); 357*16237Smckusick fprintf(stderr, "\n"); 358*16237Smckusick } 359611Sbill t = vfork(); 360611Sbill if (t == -1) { 361611Sbill printf("No more processes\n"); 362611Sbill return (100); 363611Sbill } 364611Sbill if (t == 0) { 365611Sbill execv(f, v); 366611Sbill printf("Can't find %s\n", f); 367611Sbill fflush(stdout); 368611Sbill _exit(100); 369611Sbill } 370611Sbill while (t != wait(&status)) 371611Sbill ; 372611Sbill if ((t=(status&0377)) != 0 && t!=14) { 373611Sbill if (t!=2) { 374611Sbill printf("Fatal error in %s\n", f); 375611Sbill eflag = 8; 376611Sbill } 377611Sbill dexit(); 378611Sbill } 379611Sbill return ((status>>8) & 0377); 380611Sbill } 381611Sbill 382611Sbill nodup(l, os) 383611Sbill char **l, *os; 384611Sbill { 385611Sbill register char *t, *s; 386611Sbill register int c; 387611Sbill 388611Sbill s = os; 389611Sbill if (getsuf(s) != 'o') 390611Sbill return (1); 391611Sbill while (t = *l++) { 392611Sbill while (c = *s++) 393611Sbill if (c != *t++) 394611Sbill break; 395611Sbill if (*t==0 && c==0) 396611Sbill return (0); 397611Sbill s = os; 398611Sbill } 399611Sbill return (1); 400611Sbill } 401611Sbill 402611Sbill #define NSAVETAB 1024 403611Sbill char *savetab; 404611Sbill int saveleft; 405611Sbill 406611Sbill char * 407611Sbill savestr(cp) 408611Sbill register char *cp; 409611Sbill { 410611Sbill register int len; 411611Sbill 412611Sbill len = strlen(cp) + 1; 413611Sbill if (len > saveleft) { 414611Sbill saveleft = NSAVETAB; 415611Sbill if (len > saveleft) 416611Sbill saveleft = len; 417611Sbill savetab = (char *)malloc(saveleft); 418611Sbill if (savetab == 0) { 419611Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 420611Sbill exit(1); 421611Sbill } 422611Sbill } 423611Sbill strncpy(savetab, cp, len); 424611Sbill cp = savetab; 425611Sbill savetab += len; 426611Sbill saveleft -= len; 427611Sbill return (cp); 428611Sbill } 429611Sbill 430611Sbill char * 431611Sbill strspl(left, right) 432611Sbill char *left, *right; 433611Sbill { 434611Sbill char buf[BUFSIZ]; 435611Sbill 436611Sbill strcpy(buf, left); 437611Sbill strcat(buf, right); 438611Sbill return (savestr(buf)); 439611Sbill } 440