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