1*9817Slinton static char sccsid[] = "@(#)cc.c 4.6 12/18/82"; 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> 96646Smckusick #include <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; 24*9817Slinton int cflag, eflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag; 25*9817Slinton int gflag, Gflag; 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': 80*9817Slinton if (argv[i][2] == 'o') { 81*9817Slinton Gflag++; /* old format for -go */ 82*9817Slinton } else { 83*9817Slinton gflag++; /* new format for -g */ 84*9817Slinton } 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; 100611Sbill case 'D': 101611Sbill case 'I': 102611Sbill case 'U': 103611Sbill case 'C': 104611Sbill plist[np++] = argv[i]; 105611Sbill continue; 106611Sbill case 't': 107611Sbill if (chpass) 108611Sbill error("-t overwrites earlier option", 0); 109611Sbill chpass = argv[i]+2; 110611Sbill if (chpass[0]==0) 111611Sbill chpass = "012p"; 112611Sbill continue; 113611Sbill case 'B': 114611Sbill if (npassname) 115611Sbill error("-B overwrites earlier option", 0); 116611Sbill npassname = argv[i]+2; 117611Sbill if (npassname[0]==0) 118611Sbill npassname = "/usr/c/o"; 119611Sbill continue; 120611Sbill case 'd': 121611Sbill dflag = argv[i]; 122611Sbill continue; 123611Sbill } 124611Sbill t = argv[i]; 125611Sbill c = getsuf(t); 126611Sbill if (c=='c' || c=='s' || exflag) { 127611Sbill clist[nc++] = t; 128611Sbill t = setsuf(t, 'o'); 129611Sbill } 130611Sbill if (nodup(llist, t)) { 131611Sbill llist[nl++] = t; 132611Sbill if (getsuf(t)=='o') 133611Sbill nxo++; 134611Sbill } 135611Sbill } 136*9817Slinton if (gflag || Gflag) { 137611Sbill if (oflag) 138611Sbill fprintf(stderr, "cc: warning: -g disables -O\n"); 139611Sbill oflag = 0; 140611Sbill } 141611Sbill if (npassname && chpass ==0) 142611Sbill chpass = "012p"; 143611Sbill if (chpass && npassname==0) 144896Sbill npassname = "/usr/new"; 145611Sbill if (chpass) 146611Sbill for (t=chpass; *t; t++) { 147611Sbill switch (*t) { 148611Sbill 149611Sbill case '0': 150611Sbill ccom = strspl(npassname, "ccom"); 151611Sbill continue; 152611Sbill case '2': 153611Sbill c2 = strspl(npassname, "c2"); 154611Sbill continue; 155611Sbill case 'p': 156611Sbill cpp = strspl(npassname, "cpp"); 157611Sbill continue; 158611Sbill } 159611Sbill } 160611Sbill if (nc==0) 161611Sbill goto nocom; 162611Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 163611Sbill signal(SIGINT, idexit); 164611Sbill if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 165611Sbill signal(SIGTERM, idexit); 166611Sbill if (pflag==0) 167611Sbill sprintf(tmp0, "/tmp/ctm%05.5d", getpid()); 168611Sbill tmp1 = strspl(tmp0, "1"); 169611Sbill tmp2 = strspl(tmp0, "2"); 170611Sbill tmp3 = strspl(tmp0, "3"); 171611Sbill if (pflag==0) 172611Sbill tmp4 = strspl(tmp0, "4"); 173611Sbill if (oflag) 174611Sbill tmp5 = strspl(tmp0, "5"); 175611Sbill for (i=0; i<nc; i++) { 176611Sbill if (nc > 1) { 177611Sbill printf("%s:\n", clist[i]); 178611Sbill fflush(stdout); 179611Sbill } 180611Sbill if (getsuf(clist[i]) == 's') { 181611Sbill assource = clist[i]; 182611Sbill goto assemble; 183611Sbill } else 184611Sbill assource = tmp3; 185611Sbill if (pflag) 186611Sbill tmp4 = setsuf(clist[i], 'i'); 187611Sbill av[0] = "cpp"; av[1] = clist[i]; av[2] = exflag ? "-" : tmp4; 188611Sbill na = 3; 189611Sbill for (j = 0; j < np; j++) 190611Sbill av[na++] = plist[j]; 191611Sbill av[na++] = 0; 192611Sbill if (callsys(cpp, av)) { 193611Sbill exfail++; 194611Sbill eflag++; 195611Sbill } 196611Sbill if (pflag || exfail) { 197611Sbill cflag++; 198611Sbill continue; 199611Sbill } 200611Sbill if (sflag) 201611Sbill assource = tmp3 = setsuf(clist[i], 's'); 202611Sbill av[0] = "ccom"; av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3; 203611Sbill if (proflag) 204611Sbill av[na++] = "-XP"; 205*9817Slinton if (gflag) { 206611Sbill av[na++] = "-Xg"; 207*9817Slinton } else if (Gflag) { 208*9817Slinton av[na++] = "-XG"; 209*9817Slinton } 210611Sbill if (wflag) 211611Sbill av[na++] = "-w"; 212611Sbill av[na] = 0; 213611Sbill if (callsys(ccom, av)) { 214611Sbill cflag++; 215611Sbill eflag++; 216611Sbill continue; 217611Sbill } 218611Sbill if (oflag) { 219611Sbill av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; 220611Sbill if (callsys(c2, av)) { 221611Sbill unlink(tmp3); 222611Sbill tmp3 = assource = tmp5; 223611Sbill } else 224611Sbill unlink(tmp5); 225611Sbill } 226611Sbill if (sflag) 227611Sbill continue; 228611Sbill assemble: 229611Sbill cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); 230611Sbill av[0] = "as"; av[1] = "-o"; av[2] = setsuf(clist[i], 'o'); 231652Sbill na = 3; 232652Sbill if (Rflag) 233652Sbill av[na++] = "-R"; 234611Sbill if (dflag) 235611Sbill av[na++] = dflag; 236652Sbill av[na++] = assource; 237611Sbill av[na] = 0; 238611Sbill if (callsys(as, av) > 1) { 239611Sbill cflag++; 240611Sbill eflag++; 241611Sbill continue; 242611Sbill } 243611Sbill } 244611Sbill nocom: 245611Sbill if (cflag==0 && nl!=0) { 246611Sbill i = 0; 247611Sbill av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3; 248611Sbill if (outfile) { 249611Sbill av[na++] = "-o"; 250611Sbill av[na++] = outfile; 251611Sbill } 252611Sbill while (i < nl) 253611Sbill av[na++] = llist[i++]; 254*9817Slinton if (gflag || Gflag) 255611Sbill av[na++] = "-lg"; 2565055Smckusic if (proflag) 2575055Smckusic av[na++] = "-lc_p"; 2585055Smckusic else 2595055Smckusic av[na++] = "-lc"; 260611Sbill av[na++] = 0; 261611Sbill eflag |= callsys(ld, av); 262611Sbill if (nc==1 && nxo==1 && eflag==0) 263611Sbill unlink(setsuf(clist[0], 'o')); 264611Sbill } 265611Sbill dexit(); 266611Sbill } 267611Sbill 268611Sbill idexit() 269611Sbill { 270611Sbill 271611Sbill eflag = 100; 272611Sbill dexit(); 273611Sbill } 274611Sbill 275611Sbill dexit() 276611Sbill { 277611Sbill 278611Sbill if (!pflag) { 279611Sbill cunlink(tmp1); 280611Sbill cunlink(tmp2); 281611Sbill if (sflag==0) 282611Sbill cunlink(tmp3); 283611Sbill cunlink(tmp4); 284611Sbill cunlink(tmp5); 285611Sbill } 286611Sbill exit(eflag); 287611Sbill } 288611Sbill 289611Sbill error(s, x) 290611Sbill char *s, *x; 291611Sbill { 292611Sbill FILE *diag = exflag ? stderr : stdout; 293611Sbill 294611Sbill fprintf(diag, "cc: "); 295611Sbill fprintf(diag, s, x); 296611Sbill putc('\n', diag); 297611Sbill exfail++; 298611Sbill cflag++; 299611Sbill eflag++; 300611Sbill } 301611Sbill 302611Sbill getsuf(as) 303611Sbill char as[]; 304611Sbill { 305611Sbill register int c; 306611Sbill register char *s; 307611Sbill register int t; 308611Sbill 309611Sbill s = as; 310611Sbill c = 0; 311611Sbill while (t = *s++) 312611Sbill if (t=='/') 313611Sbill c = 0; 314611Sbill else 315611Sbill c++; 316611Sbill s -= 3; 3175963Smckusic if (c <= MAXNAMLEN && c > 2 && *s++ == '.') 318611Sbill return (*s); 319611Sbill return (0); 320611Sbill } 321611Sbill 322611Sbill char * 323611Sbill setsuf(as, ch) 324611Sbill char *as; 325611Sbill { 326611Sbill register char *s, *s1; 327611Sbill 328611Sbill s = s1 = savestr(as); 329611Sbill while (*s) 330611Sbill if (*s++ == '/') 331611Sbill s1 = s; 332611Sbill s[-1] = ch; 333611Sbill return (s1); 334611Sbill } 335611Sbill 336611Sbill callsys(f, v) 337611Sbill char *f, **v; 338611Sbill { 339611Sbill int t, status; 340611Sbill 341611Sbill t = vfork(); 342611Sbill if (t == -1) { 343611Sbill printf("No more processes\n"); 344611Sbill return (100); 345611Sbill } 346611Sbill if (t == 0) { 347611Sbill execv(f, v); 348611Sbill printf("Can't find %s\n", f); 349611Sbill fflush(stdout); 350611Sbill _exit(100); 351611Sbill } 352611Sbill while (t != wait(&status)) 353611Sbill ; 354611Sbill if ((t=(status&0377)) != 0 && t!=14) { 355611Sbill if (t!=2) { 356611Sbill printf("Fatal error in %s\n", f); 357611Sbill eflag = 8; 358611Sbill } 359611Sbill dexit(); 360611Sbill } 361611Sbill return ((status>>8) & 0377); 362611Sbill } 363611Sbill 364611Sbill nodup(l, os) 365611Sbill char **l, *os; 366611Sbill { 367611Sbill register char *t, *s; 368611Sbill register int c; 369611Sbill 370611Sbill s = os; 371611Sbill if (getsuf(s) != 'o') 372611Sbill return (1); 373611Sbill while (t = *l++) { 374611Sbill while (c = *s++) 375611Sbill if (c != *t++) 376611Sbill break; 377611Sbill if (*t==0 && c==0) 378611Sbill return (0); 379611Sbill s = os; 380611Sbill } 381611Sbill return (1); 382611Sbill } 383611Sbill 384611Sbill #define NSAVETAB 1024 385611Sbill char *savetab; 386611Sbill int saveleft; 387611Sbill 388611Sbill char * 389611Sbill savestr(cp) 390611Sbill register char *cp; 391611Sbill { 392611Sbill register int len; 393611Sbill 394611Sbill len = strlen(cp) + 1; 395611Sbill if (len > saveleft) { 396611Sbill saveleft = NSAVETAB; 397611Sbill if (len > saveleft) 398611Sbill saveleft = len; 399611Sbill savetab = (char *)malloc(saveleft); 400611Sbill if (savetab == 0) { 401611Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 402611Sbill exit(1); 403611Sbill } 404611Sbill } 405611Sbill strncpy(savetab, cp, len); 406611Sbill cp = savetab; 407611Sbill savetab += len; 408611Sbill saveleft -= len; 409611Sbill return (cp); 410611Sbill } 411611Sbill 412611Sbill char * 413611Sbill strspl(left, right) 414611Sbill char *left, *right; 415611Sbill { 416611Sbill char buf[BUFSIZ]; 417611Sbill 418611Sbill strcpy(buf, left); 419611Sbill strcat(buf, right); 420611Sbill return (savestr(buf)); 421611Sbill } 422