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