1611Sbill /* USE <wait.h> */ 2*652Sbill static char sccsid[] = "@(#)cc.c 3.2 08/17/80"; 3611Sbill /* 4611Sbill * cc - front end for C compiler 5611Sbill */ 6611Sbill #include <sys/types.h> 7611Sbill #include <stdio.h> 8611Sbill #include <ctype.h> 9611Sbill #include <signal.h> 10611Sbill #include <dir.h> 11611Sbill 12611Sbill char *cpp = "/usr/new/cpp"; 13611Sbill char *ccom = "/usr/new/ccom"; 14611Sbill char *c2 = "/usr/new/c2"; 15611Sbill char *as = "/usr/new/as"; 16611Sbill char *ld = "/usr/new/ld"; 17611Sbill char *crt0 = "/usr/new/crt0.o"; 18611Sbill 19611Sbill char tmp0[30]; /* big enough for /tmp/ctm%05.5d */ 20611Sbill char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5; 21611Sbill char *outfile; 22611Sbill char *savestr(), *strspl(), *setsuf(); 23611Sbill int idexit(); 24611Sbill char **av, **clist, **llist, **plist; 25*652Sbill int cflag, eflag, gflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag; 26*652Sbill int cps8; 27611Sbill char *dflag; 28611Sbill int exfail; 29611Sbill char *chpass; 30611Sbill char *npassname; 31611Sbill 32611Sbill int nc, nl, np, nxo, na; 33611Sbill 34611Sbill #define cunlink(s) if (s) unlink(s) 35611Sbill 36611Sbill main(argc, argv) 37611Sbill char **argv; 38611Sbill { 39611Sbill char *t; 40611Sbill char *assource; 41611Sbill int i, j, c; 42611Sbill 43611Sbill /* ld currently adds upto 5 args; 10 is room to spare */ 44611Sbill av = (char **)calloc(argc+10, sizeof (char **)); 45611Sbill clist = (char **)calloc(argc, sizeof (char **)); 46611Sbill llist = (char **)calloc(argc, sizeof (char **)); 47611Sbill plist = (char **)calloc(argc, sizeof (char **)); 48611Sbill for (i = 1; i < argc; i++) { 49611Sbill if (*argv[i] == '-') switch (argv[i][1]) { 50611Sbill 51611Sbill case '8': 52611Sbill cps8++; 53611Sbill cpp = "/usr/bin/8cpp"; 54611Sbill ccom = "/usr/lib/8ccom"; 55611Sbill c2 = "/usr/bin/8c2"; 56611Sbill as = "/usr/bin/8as"; 57611Sbill ld = "/usr/bin/8ld"; 58611Sbill crt0 = "/usr/lib/8crt0"; 59611Sbill continue; 60611Sbill case 'S': 61611Sbill sflag++; 62611Sbill cflag++; 63611Sbill continue; 64611Sbill case 'o': 65611Sbill if (++i < argc) { 66611Sbill outfile = argv[i]; 67611Sbill switch (getsuf(outfile)) { 68611Sbill 69611Sbill case 'c': 70611Sbill case 'o': 71611Sbill error("-o would overwrite %s", 72611Sbill outfile); 73611Sbill exit(8); 74611Sbill } 75611Sbill } 76611Sbill continue; 77*652Sbill case 'R': 78*652Sbill Rflag++; 79*652Sbill continue; 80611Sbill case 'O': 81611Sbill oflag++; 82611Sbill continue; 83611Sbill case 'p': 84611Sbill proflag++; 85611Sbill continue; 86611Sbill case 'g': 87611Sbill gflag++; 88611Sbill continue; 89611Sbill case 'w': 90611Sbill wflag++; 91611Sbill continue; 92611Sbill case 'E': 93611Sbill exflag++; 94611Sbill case 'P': 95611Sbill pflag++; 96611Sbill if (argv[i][1]=='P') 97611Sbill fprintf(stderr, 98611Sbill "cc: warning: -P option obsolete; you should use -E instead\n"); 99611Sbill plist[np++] = argv[i]; 100611Sbill case 'c': 101611Sbill cflag++; 102611Sbill continue; 103611Sbill case 'D': 104611Sbill case 'I': 105611Sbill case 'U': 106611Sbill case 'C': 107611Sbill plist[np++] = argv[i]; 108611Sbill continue; 109611Sbill case 't': 110611Sbill if (chpass) 111611Sbill error("-t overwrites earlier option", 0); 112611Sbill chpass = argv[i]+2; 113611Sbill if (chpass[0]==0) 114611Sbill chpass = "012p"; 115611Sbill continue; 116611Sbill case 'B': 117611Sbill if (npassname) 118611Sbill error("-B overwrites earlier option", 0); 119611Sbill npassname = argv[i]+2; 120611Sbill if (npassname[0]==0) 121611Sbill npassname = "/usr/c/o"; 122611Sbill continue; 123611Sbill case 'd': 124611Sbill dflag = argv[i]; 125611Sbill continue; 126611Sbill } 127611Sbill t = argv[i]; 128611Sbill c = getsuf(t); 129611Sbill if (c=='c' || c=='s' || exflag) { 130611Sbill clist[nc++] = t; 131611Sbill t = setsuf(t, 'o'); 132611Sbill } 133611Sbill if (nodup(llist, t)) { 134611Sbill llist[nl++] = t; 135611Sbill if (getsuf(t)=='o') 136611Sbill nxo++; 137611Sbill } 138611Sbill } 139611Sbill if (gflag) { 140611Sbill if (oflag) 141611Sbill fprintf(stderr, "cc: warning: -g disables -O\n"); 142611Sbill oflag = 0; 143611Sbill } 144611Sbill if (npassname && chpass ==0) 145611Sbill chpass = "012p"; 146611Sbill if (chpass && npassname==0) 147611Sbill npassname = "/usr/c/"; 148611Sbill if (chpass) 149611Sbill for (t=chpass; *t; t++) { 150611Sbill switch (*t) { 151611Sbill 152611Sbill case '0': 153611Sbill ccom = strspl(npassname, "ccom"); 154611Sbill continue; 155611Sbill case '2': 156611Sbill c2 = strspl(npassname, "c2"); 157611Sbill continue; 158611Sbill case 'p': 159611Sbill cpp = strspl(npassname, "cpp"); 160611Sbill continue; 161611Sbill } 162611Sbill } 163611Sbill if (proflag) 164611Sbill crt0 = cps8 ? "/usr/lib/8mcrt0.o" : "/usr/new/mcrt0.o"; 165611Sbill if (nc==0) 166611Sbill goto nocom; 167611Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 168611Sbill signal(SIGINT, idexit); 169611Sbill if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 170611Sbill signal(SIGTERM, idexit); 171611Sbill if (pflag==0) 172611Sbill sprintf(tmp0, "/tmp/ctm%05.5d", getpid()); 173611Sbill tmp1 = strspl(tmp0, "1"); 174611Sbill tmp2 = strspl(tmp0, "2"); 175611Sbill tmp3 = strspl(tmp0, "3"); 176611Sbill if (pflag==0) 177611Sbill tmp4 = strspl(tmp0, "4"); 178611Sbill if (oflag) 179611Sbill tmp5 = strspl(tmp0, "5"); 180611Sbill for (i=0; i<nc; i++) { 181611Sbill if (nc > 1) { 182611Sbill printf("%s:\n", clist[i]); 183611Sbill fflush(stdout); 184611Sbill } 185611Sbill if (getsuf(clist[i]) == 's') { 186611Sbill assource = clist[i]; 187611Sbill goto assemble; 188611Sbill } else 189611Sbill assource = tmp3; 190611Sbill if (pflag) 191611Sbill tmp4 = setsuf(clist[i], 'i'); 192611Sbill av[0] = "cpp"; av[1] = clist[i]; av[2] = exflag ? "-" : tmp4; 193611Sbill na = 3; 194611Sbill for (j = 0; j < np; j++) 195611Sbill av[na++] = plist[j]; 196611Sbill av[na++] = 0; 197611Sbill if (callsys(cpp, av)) { 198611Sbill exfail++; 199611Sbill eflag++; 200611Sbill } 201611Sbill if (pflag || exfail) { 202611Sbill cflag++; 203611Sbill continue; 204611Sbill } 205611Sbill if (sflag) 206611Sbill assource = tmp3 = setsuf(clist[i], 's'); 207611Sbill av[0] = "ccom"; av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3; 208611Sbill if (proflag) 209611Sbill av[na++] = "-XP"; 210611Sbill if (gflag) 211611Sbill av[na++] = "-Xg"; 212611Sbill if (wflag) 213611Sbill av[na++] = "-w"; 214611Sbill av[na] = 0; 215611Sbill if (callsys(ccom, av)) { 216611Sbill cflag++; 217611Sbill eflag++; 218611Sbill continue; 219611Sbill } 220611Sbill if (oflag) { 221611Sbill av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; 222611Sbill if (callsys(c2, av)) { 223611Sbill unlink(tmp3); 224611Sbill tmp3 = assource = tmp5; 225611Sbill } else 226611Sbill unlink(tmp5); 227611Sbill } 228611Sbill if (sflag) 229611Sbill continue; 230611Sbill assemble: 231611Sbill cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); 232611Sbill av[0] = "as"; av[1] = "-o"; av[2] = setsuf(clist[i], 'o'); 233*652Sbill na = 3; 234*652Sbill if (Rflag) 235*652Sbill av[na++] = "-R"; 236611Sbill if (dflag) 237611Sbill av[na++] = dflag; 238*652Sbill av[na++] = assource; 239611Sbill av[na] = 0; 240611Sbill if (callsys(as, av) > 1) { 241611Sbill cflag++; 242611Sbill eflag++; 243611Sbill continue; 244611Sbill } 245611Sbill } 246611Sbill nocom: 247611Sbill if (cflag==0 && nl!=0) { 248611Sbill i = 0; 249611Sbill av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3; 250611Sbill if (outfile) { 251611Sbill av[na++] = "-o"; 252611Sbill av[na++] = outfile; 253611Sbill } 254611Sbill while (i < nl) 255611Sbill av[na++] = llist[i++]; 256611Sbill if (gflag) 257611Sbill av[na++] = "-lg"; 258611Sbill av[na++] = "-lc"; 259611Sbill av[na++] = 0; 260611Sbill eflag |= callsys(ld, av); 261611Sbill if (nc==1 && nxo==1 && eflag==0) 262611Sbill unlink(setsuf(clist[0], 'o')); 263611Sbill } 264611Sbill dexit(); 265611Sbill } 266611Sbill 267611Sbill idexit() 268611Sbill { 269611Sbill 270611Sbill eflag = 100; 271611Sbill dexit(); 272611Sbill } 273611Sbill 274611Sbill dexit() 275611Sbill { 276611Sbill 277611Sbill if (!pflag) { 278611Sbill cunlink(tmp1); 279611Sbill cunlink(tmp2); 280611Sbill if (sflag==0) 281611Sbill cunlink(tmp3); 282611Sbill cunlink(tmp4); 283611Sbill cunlink(tmp5); 284611Sbill } 285611Sbill exit(eflag); 286611Sbill } 287611Sbill 288611Sbill error(s, x) 289611Sbill char *s, *x; 290611Sbill { 291611Sbill FILE *diag = exflag ? stderr : stdout; 292611Sbill 293611Sbill fprintf(diag, "cc: "); 294611Sbill fprintf(diag, s, x); 295611Sbill putc('\n', diag); 296611Sbill exfail++; 297611Sbill cflag++; 298611Sbill eflag++; 299611Sbill } 300611Sbill 301611Sbill getsuf(as) 302611Sbill char as[]; 303611Sbill { 304611Sbill register int c; 305611Sbill register char *s; 306611Sbill register int t; 307611Sbill 308611Sbill s = as; 309611Sbill c = 0; 310611Sbill while (t = *s++) 311611Sbill if (t=='/') 312611Sbill c = 0; 313611Sbill else 314611Sbill c++; 315611Sbill s -= 3; 316611Sbill if (c <= DIRSIZ && c > 2 && *s++ == '.') 317611Sbill return (*s); 318611Sbill return (0); 319611Sbill } 320611Sbill 321611Sbill char * 322611Sbill setsuf(as, ch) 323611Sbill char *as; 324611Sbill { 325611Sbill register char *s, *s1; 326611Sbill 327611Sbill s = s1 = savestr(as); 328611Sbill while (*s) 329611Sbill if (*s++ == '/') 330611Sbill s1 = s; 331611Sbill s[-1] = ch; 332611Sbill return (s1); 333611Sbill } 334611Sbill 335611Sbill callsys(f, v) 336611Sbill char *f, **v; 337611Sbill { 338611Sbill int t, status; 339611Sbill 340611Sbill t = vfork(); 341611Sbill if (t == -1) { 342611Sbill printf("No more processes\n"); 343611Sbill return (100); 344611Sbill } 345611Sbill if (t == 0) { 346611Sbill execv(f, v); 347611Sbill printf("Can't find %s\n", f); 348611Sbill fflush(stdout); 349611Sbill _exit(100); 350611Sbill } 351611Sbill while (t != wait(&status)) 352611Sbill ; 353611Sbill if ((t=(status&0377)) != 0 && t!=14) { 354611Sbill if (t!=2) { 355611Sbill printf("Fatal error in %s\n", f); 356611Sbill eflag = 8; 357611Sbill } 358611Sbill dexit(); 359611Sbill } 360611Sbill return ((status>>8) & 0377); 361611Sbill } 362611Sbill 363611Sbill nodup(l, os) 364611Sbill char **l, *os; 365611Sbill { 366611Sbill register char *t, *s; 367611Sbill register int c; 368611Sbill 369611Sbill s = os; 370611Sbill if (getsuf(s) != 'o') 371611Sbill return (1); 372611Sbill while (t = *l++) { 373611Sbill while (c = *s++) 374611Sbill if (c != *t++) 375611Sbill break; 376611Sbill if (*t==0 && c==0) 377611Sbill return (0); 378611Sbill s = os; 379611Sbill } 380611Sbill return (1); 381611Sbill } 382611Sbill 383611Sbill #define NSAVETAB 1024 384611Sbill char *savetab; 385611Sbill int saveleft; 386611Sbill 387611Sbill char * 388611Sbill savestr(cp) 389611Sbill register char *cp; 390611Sbill { 391611Sbill register int len; 392611Sbill 393611Sbill len = strlen(cp) + 1; 394611Sbill if (len > saveleft) { 395611Sbill saveleft = NSAVETAB; 396611Sbill if (len > saveleft) 397611Sbill saveleft = len; 398611Sbill savetab = (char *)malloc(saveleft); 399611Sbill if (savetab == 0) { 400611Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 401611Sbill exit(1); 402611Sbill } 403611Sbill } 404611Sbill strncpy(savetab, cp, len); 405611Sbill cp = savetab; 406611Sbill savetab += len; 407611Sbill saveleft -= len; 408611Sbill return (cp); 409611Sbill } 410611Sbill 411611Sbill char * 412611Sbill strspl(left, right) 413611Sbill char *left, *right; 414611Sbill { 415611Sbill char buf[BUFSIZ]; 416611Sbill 417611Sbill strcpy(buf, left); 418611Sbill strcat(buf, right); 419611Sbill return (savestr(buf)); 420611Sbill } 421