/* @(#)cc.c 1.3 */ /* * cc command -- calls the appropriate passes of the * c compiler, assembler, and loader. */ char release[] = "@(#)C rel 5.0"; # include <stdio.h> # include <ctype.h> # include <signal.h> #ifndef CSW #include "*****ERROR: CSW undefined*****" #endif #define DMR 0 #define SCJ1 1 #define SCJ2 2 #define JFR 3 #define SCPTR sizeof(char *) #define Xc0 0 #define Xc1 1 #define Xc2 2 #define Xcp 3 #define Xas 4 #define Xld 5 #define NPASS 6 #if CSW == DMR #define NAMEc0 "c0" #define NAMEc1 "c1" #endif #if CSW == SCJ1 #define NAMEc0 "comp" #define NAMEc1 0 #endif #if CSW == SCJ2 #define NAMEc0 "front" #define NAMEc1 "back" #endif #if CSW == JFR #define NAMEc0 "ccom" #define NAMEc1 0 #endif #define NAMEc2 "c2" #define NAMEcp "cpp" #define NAMEas "as" #define NAMEld "ld" #define TEMPDIR "" char *tmp1 = NULL; char *tmp2 = NULL; char *tmp3 = NULL; char *tmp4 = NULL; char *tmp5 = NULL; char *outfile; char **clist; char **list[NPASS]; int nlist[NPASS]; char **av; int pflag; int sflag; int cflag; int eflag; int gflag; int exflag; int oflag; int proflag; int noflflag; char fchar; char bflag; char debug = 0; #ifndef CCNAME #define CCNAME "cc" #endif char *chpass ; char *npassname ; char rpassname[] = "/lib//"; char alpassname[] = "/bin//"; char minusl[4] = "-l\000"; /*template for "-lXc", "-lc", etc.*/ char *nameps[NPASS] = {NAMEc0, NAMEc1, NAMEc2, NAMEcp, NAMEas, NAMEld}; char *passes[NPASS]; char altpass[NPASS]; char *pref = "crt0.o"; extern int optind; extern int opterr; extern char *optarg; extern int optopt; char *copy(), *setsuf(), *stralloc(); char *strcat(), *strncat(), *strtok(); char *strncpy(), *strcpy(), *strrchr(); char *mktemp(), *malloc(), *tempnam(); main(argc, argv) char *argv[]; { char *t; char *assource; int nc, nargs, nxo; char *f20; int i, j, c, na, ic; int idexit(); opterr = 0; i = nc = nxo = 0; f20 = (char *)NULL; nargs = argc + 1; j = SCPTR * nargs - 1; /*stralloc allocates extra byte.*/ for (i=NPASS; i-- > 0; ) { nlist[i] = 0; list[i] = (char **) stralloc(j); } clist = (char **)stralloc(j); av = (char **)stralloc(j + 5 * SCPTR); setbuf(stdout, (char *)NULL); if((t = strrchr(argv[0], '/')) == NULL) fchar = *argv[0]; else fchar = t[1]; if(fchar == CCNAME[0]) fchar = 0; while (optind<argc) switch (c = getopt(argc, argv, "So:OpcfEPD:I:U:Ct:B:#gZ:W:0:1:2:A:L:d:l:V:")) { case 'S': sflag++; cflag++; continue; case 'o': outfile = optarg; if ((c=getsuf(outfile))=='c'||c=='o') error("'-o %s': Illegal name for output of ld", outfile); continue; case 'O': oflag++; continue; case 'p': proflag++; continue; case 'c': cflag++; continue; case 'f': #if pdp11 noflflag++; #else fprintf(stderr, "'-f' option ignored on VAX\n"); #endif continue; case 'E': exflag++; case 'P': pflag++; cflag++; case 'D': case 'I': case 'U': case 'C': if (nlist[Xcp] >= nargs) { error("Too many EPDIUC options", (char *)NULL); continue; } list[Xcp][nlist[Xcp]] = stralloc(strlen(optarg)+2); list[Xcp][nlist[Xcp]][0] = '-'; list[Xcp][nlist[Xcp]][1] = c; list[Xcp][nlist[Xcp]][2] = '\0'; strcat(list[Xcp][nlist[Xcp]], optarg); nlist[Xcp]++; continue; case 't': if (chpass) error("-t overwrites earlier option", (char *)NULL); chpass = optarg; if (chpass[0]==0) chpass = "012p"; continue; case 'B': if (npassname) error("-B overwrites earlier option", (char *)NULL); npassname = optarg; if (npassname[0]==0){ npassname = "/lib/o"; bflag = 0; }else bflag = 1; continue; case '#': debug = 1; continue; case 'g': #if CSW == DMR fprintf(stderr, "'-g' option not supported on the pdp11 cc compiler\n"); #else gflag++; #endif continue; case 'Z': if(optarg[1] != 0){ error("'-Z' needs one-letter subargument: -Z%s", optarg); continue; } (pref = "crt2.o")[3] = optarg[0]; (f20 = "-l2")[2] = optarg[0];; continue; case 'W': if((optarg[1] != ',') || ((t = strtok(optarg, ",")) != optarg)){ error("Invalid subargument: -W%s", optarg); continue; } if((i = getXpass((ic = *t), "-W")) == -1) continue; while((t = strtok(NULL, ",")) != NULL) { if(nlist[i] >= nargs){ error("Too many arguments for pass -W%c", ic); continue; } list[i][nlist[i]++] = t; } continue; case '0': case '1': case '2': case 'A': case 'L': case 'd': error("The cc option '-%c%s' is no longer supported.",c,optarg); error("Please use '-Wc,arg'", (char *)NULL); continue; case 'l': case 'V': t = stralloc(strlen(optarg)+2); t[0] = '-'; t[1] = c; t[2] = '\0'; strcat(t, optarg); goto checknl; case '?': t = stralloc(2); t[0] = '-'; t[1] = optopt; t[2] = '\0'; checknl: if(nlist[Xld] >= nargs){ free(t); error("Too many ld options", (char *)NULL); continue; } list[Xld][nlist[Xld]++] = t; continue; case EOF: t = argv[optind]; optind++; if((c=getsuf(t))=='c' || c=='s'|| exflag) { clist[nc++] = t; t = setsuf(t, 'o'); } if (nodup(list[Xld], t)) { if(nlist[Xld] >= nargs){ error("Too many ld arguments", (char *)NULL); continue; } list[Xld][nlist[Xld]++] = t; if (getsuf(t)=='o') nxo++; } } if (gflag) oflag = 0; if(fchar) { (list[Xcp][nlist[Xcp]] = "-I/usr/Xinclude")[7] = fchar; nlist[Xcp]++; } if (npassname && chpass ==0) chpass = "012p"; if (chpass && npassname==0) npassname = "/lib/n"; if (chpass) for (t=chpass; *t; t++) { if((i = getXpass(*t, "-t")) == -1) continue; mkpname (i, npassname); altpass[i] = !bflag; continue; } rpassname[sizeof(rpassname)-2] = fchar; alpassname[sizeof(alpassname)-2] = fchar; for (i = 0; i < NPASS; i++) if(passes[i] == 0){ mkpname (i, i < Xas ? rpassname : alpassname); altpass[i] = 1; } if (noflflag) pref = proflag ? "fmcrt0.o" : "fcrt0.o"; else if (proflag) pref = "mcrt0.o"; if(nc==0) goto nocom; if (pflag==0) { tmp1 = tempnam(TEMPDIR, "ctm1"); tmp2 = tempnam(TEMPDIR, "ctm2"); tmp3 = tempnam(TEMPDIR, "ctm3"); tmp4 = tempnam(TEMPDIR, "ctm4"); if (oflag) tmp5 = tempnam(TEMPDIR, "ctm5"); if (!(tmp1 && tmp2 && tmp3 && tmp4 && (tmp5 || !oflag)) || creat(tmp1, 0666) < 0) error("cc: cannot create temporaries: %s", tmp1); } if(eflag) dexit(); if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, idexit); if (signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, idexit); for (i=0; i<nc; i++) { if (nc>1) printf("%s:\n", clist[i]); if (getsuf(clist[i])=='s') { assource = clist[i]; goto assemble; } else assource = tmp3; if (pflag) tmp4 = setsuf(clist[i], 'i'); av[0] = nameps[Xcp]; av[1] = clist[i]; av[2] = exflag ? "-" : tmp4; na = 3; for(j=0; j < nlist[Xcp]; j++) av[na++] = list[Xcp][j]; av[na]=0; if (callsys(passes[Xcp], av, &altpass[Xcp])) { cflag++; eflag++; continue; } if (pflag) continue; na = 0; av[na++] = nameps[Xc0]; for (j=0; j < nlist[Xc0]; j++) av[na++] = list[Xc0][j]; av[na++] = tmp4; if (nameps[Xc1] == 0){ if (sflag) assource = tmp3 = setsuf(clist[i], 's'); av[na++] = tmp3; if (oflag) av[na-1] = tmp5; }else av[na++] = tmp1; #if CSW == DMR av[na++] = tmp2; #endif if (proflag) { #if CSW == DMR av[na++] = "-P"; #else av[na++] = "-XP"; #endif } if (gflag) av[na++] = "-Xg"; #if CSW == SCJ1 if(sflag) av[na++] = "-l"; #endif av[na] = 0; if (callsys(passes[Xc0], av, &altpass[Xc0])) { cflag++; eflag++; continue; } if(nameps[Xc1] != (char *)0){ na = 0; av[na++] = nameps[Xc1]; for (j=0; j < nlist[Xc1]; j++) av[na++] = list[Xc1][j]; av[na++] = tmp1; #if CSW == DMR av[na++] = tmp2; #endif if (sflag) assource = tmp3 = setsuf(clist[i], 's'); av[na++] = tmp3; if (oflag) av[na-1] = tmp5; #if CSW == SCJ2 if(sflag) av[na++] = "-l"; #endif av[na] = 0; if(callsys(passes[Xc1], av, &altpass[Xc1])) { cflag++; eflag++; continue; } } if (oflag) { na = 0; av[na++] = nameps[Xc2]; for (j=0; j < nlist[Xc2]; j++) av[na++] = list[Xc2][j]; av[na++] = tmp5; av[na++] = tmp3; av[na] = 0; if (callsys(passes[Xc2], av, &altpass[Xc2])) { unlink(tmp3); assource = tmp5; } else unlink(tmp5); } if (sflag) continue; assemble: na = 0; av[na++] = nameps[Xas]; for (j=0; j < nlist[Xas]; j++) av[na++] = list[Xas][j]; #if pdp11 av[na++] = "-u"; #endif av[na++] = "-o"; av[na++] = setsuf(clist[i], 'o'); av[na++] = assource; av[na] = 0; cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); if (callsys(passes[Xas], av, &altpass[Xas]) > 0) { /*this test used to be "> 1" for old pdp11 as*/ cflag++; eflag++; continue; } } nocom: if (cflag==0 && nlist[Xld]!=0) { na = i = 0; av[na++] = nameps[Xld]; j = sizeof("/lib//") - 1; av[na++] = t = stralloc(j + strlen(pref)); strcpy(t, "/lib//"); strcat(t, pref); if(fchar){ t[j-1] = fchar; if(access(t, 04) != 0) t[j-1] = '/'; } if (outfile) { av[na++] = "-o"; av[na++] = outfile; } #if CSW == JFR if ( proflag ) av[na++] = "-L/lib/libp"; #endif while(i<nlist[Xld]) av[na++] = list[Xld][i++]; if(fchar) minusl[2] = fchar; /*set up for "-lnc", etc.*/ if (gflag) av[na++] = strcat( strcpy( "-lXg", minusl), "g"); if(f20 != NULL) av[na++] = f20; else av[na++] = strcat( strcpy( "-lXc", minusl), "c"); av[na] = 0; eflag |= callsys(passes[Xld], av, &altpass[Xld]); if (nc==1 && nxo==1 && eflag==0) cunlink(setsuf(clist[0], 'o')); } dexit(); } idexit() { eflag += 100; dexit(); } dexit() { if (!pflag) { cunlink(tmp1); cunlink(tmp2); if (sflag==0) cunlink(tmp3); cunlink(tmp4); cunlink(tmp5); } exit(eflag); } /*VARARGS*/ error(s, a, b) char *s, *a, *b; { fprintf(stderr, s, a, b); putc('\n', stderr); cflag++; eflag++; } getsuf(as) char as[]; { register int c; register char *s; register int t; s = as; c = 0; while(t = *s++) if (t=='/') c = 0; else c++; s -= 3; if (c<=14 && c>2 && *s++=='.') return(*s); return(0); } char * setsuf(as, ch) char *as; { register char *s, *s1; s = s1 = copy(as); while(*s) if (*s++ == '/') s1 = s; s[-1] = ch; return(s1); } callsys(f, v, alt) char f[], *v[]; char *alt; { int t, status; char **p; if (debug) { printf("callsys %s:", f); for (p=v; *p != NULL; p++) printf(" '%s'", *p); printf(" .\n"); return(0); } if ((t=fork())==0) { execv(f, v); if(*alt != 0){ alt = stralloc(4 + strlen(f)); strcpy(alt, "/usr"); strcat(alt, f); execv(alt, v); } error("Can't find %s, %s", f, alt); exit(300); } else if (t == -1) { error("Can't fork; Try again"); return(1); } while(t!=wait(&status)) ; if (t = status&0377) { if (t!=SIGINT) error("Fatal error in %s", f); eflag += 200; dexit(); } return((status>>8) & 0377); } char * copy(s) register char *s; { register char *ns; ns = stralloc(strlen(s)); return(strcpy(ns, s)); } char * stralloc(n) int n; { char *malloc(); register char *s; s = malloc(n+1); if (s==NULL) { error("out of space", (char *)NULL); dexit(); } return(s); } nodup(l, os) char **l, *os; { register char *t, *s; register int c; s = os; if (getsuf(s) != 'o') return(1); while(t = *l++) { while(c = *s++) if (c != *t++) break; if (*t=='\0' && c=='\0') return(0); s = os; } return(1); } cunlink(f) char *f; { if (f==NULL) return; unlink(f); } mkpname(n, pname) int n; char *pname; { if (nameps[n] == 0) return; passes[n] = stralloc(strlen(pname) + strlen(nameps[n])); strcpy(passes[n], pname); strcat(passes[n], nameps[n]); } getXpass(c, opt) char c, *opt; { switch (c) { default: error("Unrecognized pass name: '%s%c'", opt, c); return(-1); case '0': case '1': case '2': return(c - '0'); case 'p': return(Xcp); case 'a': return(Xas); case 'l': return(Xld); } }