1*611Sbill /* USE <wait.h> */ 2*611Sbill static char sccsid[] = "@(#)cc.c 3.1 08/15/80"; 3*611Sbill /* 4*611Sbill * cc - front end for C compiler 5*611Sbill */ 6*611Sbill #include <sys/types.h> 7*611Sbill #include <stdio.h> 8*611Sbill #include <ctype.h> 9*611Sbill #include <signal.h> 10*611Sbill #include <dir.h> 11*611Sbill 12*611Sbill char *cpp = "/usr/new/cpp"; 13*611Sbill char *ccom = "/usr/new/ccom"; 14*611Sbill char *c2 = "/usr/new/c2"; 15*611Sbill char *as = "/usr/new/as"; 16*611Sbill char *ld = "/usr/new/ld"; 17*611Sbill char *crt0 = "/usr/new/crt0.o"; 18*611Sbill 19*611Sbill char tmp0[30]; /* big enough for /tmp/ctm%05.5d */ 20*611Sbill char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5; 21*611Sbill char *outfile; 22*611Sbill char *savestr(), *strspl(), *setsuf(); 23*611Sbill int idexit(); 24*611Sbill char **av, **clist, **llist, **plist; 25*611Sbill int cflag, eflag, gflag, oflag, pflag, sflag, wflag, cps8, exflag, proflag; 26*611Sbill char *dflag; 27*611Sbill int exfail; 28*611Sbill char *chpass; 29*611Sbill char *npassname; 30*611Sbill 31*611Sbill int nc, nl, np, nxo, na; 32*611Sbill 33*611Sbill #define cunlink(s) if (s) unlink(s) 34*611Sbill 35*611Sbill main(argc, argv) 36*611Sbill char **argv; 37*611Sbill { 38*611Sbill char *t; 39*611Sbill char *assource; 40*611Sbill int i, j, c; 41*611Sbill 42*611Sbill /* ld currently adds upto 5 args; 10 is room to spare */ 43*611Sbill av = (char **)calloc(argc+10, sizeof (char **)); 44*611Sbill clist = (char **)calloc(argc, sizeof (char **)); 45*611Sbill llist = (char **)calloc(argc, sizeof (char **)); 46*611Sbill plist = (char **)calloc(argc, sizeof (char **)); 47*611Sbill for (i = 1; i < argc; i++) { 48*611Sbill if (*argv[i] == '-') switch (argv[i][1]) { 49*611Sbill 50*611Sbill case '8': 51*611Sbill cps8++; 52*611Sbill cpp = "/usr/bin/8cpp"; 53*611Sbill ccom = "/usr/lib/8ccom"; 54*611Sbill c2 = "/usr/bin/8c2"; 55*611Sbill as = "/usr/bin/8as"; 56*611Sbill ld = "/usr/bin/8ld"; 57*611Sbill crt0 = "/usr/lib/8crt0"; 58*611Sbill continue; 59*611Sbill case 'S': 60*611Sbill sflag++; 61*611Sbill cflag++; 62*611Sbill continue; 63*611Sbill case 'o': 64*611Sbill if (++i < argc) { 65*611Sbill outfile = argv[i]; 66*611Sbill switch (getsuf(outfile)) { 67*611Sbill 68*611Sbill case 'c': 69*611Sbill case 'o': 70*611Sbill error("-o would overwrite %s", 71*611Sbill outfile); 72*611Sbill exit(8); 73*611Sbill } 74*611Sbill } 75*611Sbill continue; 76*611Sbill case 'O': 77*611Sbill oflag++; 78*611Sbill continue; 79*611Sbill case 'p': 80*611Sbill proflag++; 81*611Sbill continue; 82*611Sbill case 'g': 83*611Sbill gflag++; 84*611Sbill continue; 85*611Sbill case 'w': 86*611Sbill wflag++; 87*611Sbill continue; 88*611Sbill case 'E': 89*611Sbill exflag++; 90*611Sbill case 'P': 91*611Sbill pflag++; 92*611Sbill if (argv[i][1]=='P') 93*611Sbill fprintf(stderr, 94*611Sbill "cc: warning: -P option obsolete; you should use -E instead\n"); 95*611Sbill plist[np++] = argv[i]; 96*611Sbill case 'c': 97*611Sbill cflag++; 98*611Sbill continue; 99*611Sbill case 'D': 100*611Sbill case 'I': 101*611Sbill case 'U': 102*611Sbill case 'C': 103*611Sbill plist[np++] = argv[i]; 104*611Sbill continue; 105*611Sbill case 't': 106*611Sbill if (chpass) 107*611Sbill error("-t overwrites earlier option", 0); 108*611Sbill chpass = argv[i]+2; 109*611Sbill if (chpass[0]==0) 110*611Sbill chpass = "012p"; 111*611Sbill continue; 112*611Sbill case 'B': 113*611Sbill if (npassname) 114*611Sbill error("-B overwrites earlier option", 0); 115*611Sbill npassname = argv[i]+2; 116*611Sbill if (npassname[0]==0) 117*611Sbill npassname = "/usr/c/o"; 118*611Sbill continue; 119*611Sbill case 'd': 120*611Sbill dflag = argv[i]; 121*611Sbill continue; 122*611Sbill } 123*611Sbill t = argv[i]; 124*611Sbill c = getsuf(t); 125*611Sbill if (c=='c' || c=='s' || exflag) { 126*611Sbill clist[nc++] = t; 127*611Sbill t = setsuf(t, 'o'); 128*611Sbill } 129*611Sbill if (nodup(llist, t)) { 130*611Sbill llist[nl++] = t; 131*611Sbill if (getsuf(t)=='o') 132*611Sbill nxo++; 133*611Sbill } 134*611Sbill } 135*611Sbill if (gflag) { 136*611Sbill if (oflag) 137*611Sbill fprintf(stderr, "cc: warning: -g disables -O\n"); 138*611Sbill oflag = 0; 139*611Sbill } 140*611Sbill if (npassname && chpass ==0) 141*611Sbill chpass = "012p"; 142*611Sbill if (chpass && npassname==0) 143*611Sbill npassname = "/usr/c/"; 144*611Sbill if (chpass) 145*611Sbill for (t=chpass; *t; t++) { 146*611Sbill switch (*t) { 147*611Sbill 148*611Sbill case '0': 149*611Sbill ccom = strspl(npassname, "ccom"); 150*611Sbill continue; 151*611Sbill case '2': 152*611Sbill c2 = strspl(npassname, "c2"); 153*611Sbill continue; 154*611Sbill case 'p': 155*611Sbill cpp = strspl(npassname, "cpp"); 156*611Sbill continue; 157*611Sbill } 158*611Sbill } 159*611Sbill if (proflag) 160*611Sbill crt0 = cps8 ? "/usr/lib/8mcrt0.o" : "/usr/new/mcrt0.o"; 161*611Sbill if (nc==0) 162*611Sbill goto nocom; 163*611Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 164*611Sbill signal(SIGINT, idexit); 165*611Sbill if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 166*611Sbill signal(SIGTERM, idexit); 167*611Sbill if (pflag==0) 168*611Sbill sprintf(tmp0, "/tmp/ctm%05.5d", getpid()); 169*611Sbill tmp1 = strspl(tmp0, "1"); 170*611Sbill tmp2 = strspl(tmp0, "2"); 171*611Sbill tmp3 = strspl(tmp0, "3"); 172*611Sbill if (pflag==0) 173*611Sbill tmp4 = strspl(tmp0, "4"); 174*611Sbill if (oflag) 175*611Sbill tmp5 = strspl(tmp0, "5"); 176*611Sbill for (i=0; i<nc; i++) { 177*611Sbill if (nc > 1) { 178*611Sbill printf("%s:\n", clist[i]); 179*611Sbill fflush(stdout); 180*611Sbill } 181*611Sbill if (getsuf(clist[i]) == 's') { 182*611Sbill assource = clist[i]; 183*611Sbill goto assemble; 184*611Sbill } else 185*611Sbill assource = tmp3; 186*611Sbill if (pflag) 187*611Sbill tmp4 = setsuf(clist[i], 'i'); 188*611Sbill av[0] = "cpp"; av[1] = clist[i]; av[2] = exflag ? "-" : tmp4; 189*611Sbill na = 3; 190*611Sbill for (j = 0; j < np; j++) 191*611Sbill av[na++] = plist[j]; 192*611Sbill av[na++] = 0; 193*611Sbill if (callsys(cpp, av)) { 194*611Sbill exfail++; 195*611Sbill eflag++; 196*611Sbill } 197*611Sbill if (pflag || exfail) { 198*611Sbill cflag++; 199*611Sbill continue; 200*611Sbill } 201*611Sbill if (sflag) 202*611Sbill assource = tmp3 = setsuf(clist[i], 's'); 203*611Sbill av[0] = "ccom"; av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3; 204*611Sbill if (proflag) 205*611Sbill av[na++] = "-XP"; 206*611Sbill if (gflag) 207*611Sbill av[na++] = "-Xg"; 208*611Sbill if (wflag) 209*611Sbill av[na++] = "-w"; 210*611Sbill av[na] = 0; 211*611Sbill if (callsys(ccom, av)) { 212*611Sbill cflag++; 213*611Sbill eflag++; 214*611Sbill continue; 215*611Sbill } 216*611Sbill if (oflag) { 217*611Sbill av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; 218*611Sbill if (callsys(c2, av)) { 219*611Sbill unlink(tmp3); 220*611Sbill tmp3 = assource = tmp5; 221*611Sbill } else 222*611Sbill unlink(tmp5); 223*611Sbill } 224*611Sbill if (sflag) 225*611Sbill continue; 226*611Sbill assemble: 227*611Sbill cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); 228*611Sbill av[0] = "as"; av[1] = "-o"; av[2] = setsuf(clist[i], 'o'); 229*611Sbill av[3] = assource; na = 4; 230*611Sbill if (dflag) 231*611Sbill av[na++] = dflag; 232*611Sbill av[na] = 0; 233*611Sbill if (callsys(as, av) > 1) { 234*611Sbill cflag++; 235*611Sbill eflag++; 236*611Sbill continue; 237*611Sbill } 238*611Sbill } 239*611Sbill nocom: 240*611Sbill if (cflag==0 && nl!=0) { 241*611Sbill i = 0; 242*611Sbill av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3; 243*611Sbill if (outfile) { 244*611Sbill av[na++] = "-o"; 245*611Sbill av[na++] = outfile; 246*611Sbill } 247*611Sbill while (i < nl) 248*611Sbill av[na++] = llist[i++]; 249*611Sbill if (gflag) 250*611Sbill av[na++] = "-lg"; 251*611Sbill av[na++] = "-lc"; 252*611Sbill av[na++] = 0; 253*611Sbill eflag |= callsys(ld, av); 254*611Sbill if (nc==1 && nxo==1 && eflag==0) 255*611Sbill unlink(setsuf(clist[0], 'o')); 256*611Sbill } 257*611Sbill dexit(); 258*611Sbill } 259*611Sbill 260*611Sbill idexit() 261*611Sbill { 262*611Sbill 263*611Sbill eflag = 100; 264*611Sbill dexit(); 265*611Sbill } 266*611Sbill 267*611Sbill dexit() 268*611Sbill { 269*611Sbill 270*611Sbill if (!pflag) { 271*611Sbill cunlink(tmp1); 272*611Sbill cunlink(tmp2); 273*611Sbill if (sflag==0) 274*611Sbill cunlink(tmp3); 275*611Sbill cunlink(tmp4); 276*611Sbill cunlink(tmp5); 277*611Sbill } 278*611Sbill exit(eflag); 279*611Sbill } 280*611Sbill 281*611Sbill error(s, x) 282*611Sbill char *s, *x; 283*611Sbill { 284*611Sbill FILE *diag = exflag ? stderr : stdout; 285*611Sbill 286*611Sbill fprintf(diag, "cc: "); 287*611Sbill fprintf(diag, s, x); 288*611Sbill putc('\n', diag); 289*611Sbill exfail++; 290*611Sbill cflag++; 291*611Sbill eflag++; 292*611Sbill } 293*611Sbill 294*611Sbill getsuf(as) 295*611Sbill char as[]; 296*611Sbill { 297*611Sbill register int c; 298*611Sbill register char *s; 299*611Sbill register int t; 300*611Sbill 301*611Sbill s = as; 302*611Sbill c = 0; 303*611Sbill while (t = *s++) 304*611Sbill if (t=='/') 305*611Sbill c = 0; 306*611Sbill else 307*611Sbill c++; 308*611Sbill s -= 3; 309*611Sbill if (c <= DIRSIZ && c > 2 && *s++ == '.') 310*611Sbill return (*s); 311*611Sbill return (0); 312*611Sbill } 313*611Sbill 314*611Sbill char * 315*611Sbill setsuf(as, ch) 316*611Sbill char *as; 317*611Sbill { 318*611Sbill register char *s, *s1; 319*611Sbill 320*611Sbill s = s1 = savestr(as); 321*611Sbill while (*s) 322*611Sbill if (*s++ == '/') 323*611Sbill s1 = s; 324*611Sbill s[-1] = ch; 325*611Sbill return (s1); 326*611Sbill } 327*611Sbill 328*611Sbill callsys(f, v) 329*611Sbill char *f, **v; 330*611Sbill { 331*611Sbill int t, status; 332*611Sbill 333*611Sbill t = vfork(); 334*611Sbill if (t == -1) { 335*611Sbill printf("No more processes\n"); 336*611Sbill return (100); 337*611Sbill } 338*611Sbill if (t == 0) { 339*611Sbill execv(f, v); 340*611Sbill printf("Can't find %s\n", f); 341*611Sbill fflush(stdout); 342*611Sbill _exit(100); 343*611Sbill } 344*611Sbill while (t != wait(&status)) 345*611Sbill ; 346*611Sbill if ((t=(status&0377)) != 0 && t!=14) { 347*611Sbill if (t!=2) { 348*611Sbill printf("Fatal error in %s\n", f); 349*611Sbill eflag = 8; 350*611Sbill } 351*611Sbill dexit(); 352*611Sbill } 353*611Sbill return ((status>>8) & 0377); 354*611Sbill } 355*611Sbill 356*611Sbill nodup(l, os) 357*611Sbill char **l, *os; 358*611Sbill { 359*611Sbill register char *t, *s; 360*611Sbill register int c; 361*611Sbill 362*611Sbill s = os; 363*611Sbill if (getsuf(s) != 'o') 364*611Sbill return (1); 365*611Sbill while (t = *l++) { 366*611Sbill while (c = *s++) 367*611Sbill if (c != *t++) 368*611Sbill break; 369*611Sbill if (*t==0 && c==0) 370*611Sbill return (0); 371*611Sbill s = os; 372*611Sbill } 373*611Sbill return (1); 374*611Sbill } 375*611Sbill 376*611Sbill #define NSAVETAB 1024 377*611Sbill char *savetab; 378*611Sbill int saveleft; 379*611Sbill 380*611Sbill char * 381*611Sbill savestr(cp) 382*611Sbill register char *cp; 383*611Sbill { 384*611Sbill register int len; 385*611Sbill 386*611Sbill len = strlen(cp) + 1; 387*611Sbill if (len > saveleft) { 388*611Sbill saveleft = NSAVETAB; 389*611Sbill if (len > saveleft) 390*611Sbill saveleft = len; 391*611Sbill savetab = (char *)malloc(saveleft); 392*611Sbill if (savetab == 0) { 393*611Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 394*611Sbill exit(1); 395*611Sbill } 396*611Sbill } 397*611Sbill strncpy(savetab, cp, len); 398*611Sbill cp = savetab; 399*611Sbill savetab += len; 400*611Sbill saveleft -= len; 401*611Sbill return (cp); 402*611Sbill } 403*611Sbill 404*611Sbill char * 405*611Sbill strspl(left, right) 406*611Sbill char *left, *right; 407*611Sbill { 408*611Sbill char buf[BUFSIZ]; 409*611Sbill 410*611Sbill strcpy(buf, left); 411*611Sbill strcat(buf, right); 412*611Sbill return (savestr(buf)); 413*611Sbill } 414