1*44767Sbostic static char sccsid[] = "@(#)cc.c 4.21 06/30/90";
2611Sbill /*
3611Sbill * cc - front end for C compiler
4611Sbill */
56413Smckusic #include <sys/param.h>
6611Sbill #include <stdio.h>
7611Sbill #include <ctype.h>
8611Sbill #include <signal.h>
913597Swnj #include <sys/dir.h>
1037021Sbostic #include "pathnames.h"
11611Sbill
1237021Sbostic char *cpp = _PATH_CPP;
1337021Sbostic char *ccom = _PATH_CCOM;
1437021Sbostic char *sccom = _PATH_SCCOM;
1537021Sbostic char *c2 = _PATH_C2;
1637021Sbostic char *as = _PATH_AS;
1737021Sbostic char *ld = _PATH_LD;
1837021Sbostic char *crt0 = _PATH_CRT0;
19611Sbill
2037788Sbostic char tmp0[MAXPATHLEN];
21611Sbill char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5;
22611Sbill char *outfile;
23611Sbill char *savestr(), *strspl(), *setsuf();
24611Sbill int idexit();
25611Sbill char **av, **clist, **llist, **plist;
269817Slinton int cflag, eflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag;
2717862Sralph int fflag, gflag, Gflag, Mflag, debug;
28611Sbill char *dflag;
29611Sbill int exfail;
30611Sbill char *chpass;
31611Sbill char *npassname;
32611Sbill
33611Sbill int nc, nl, np, nxo, na;
34611Sbill
35611Sbill #define cunlink(s) if (s) unlink(s)
36611Sbill
main(argc,argv)37611Sbill main(argc, argv)
38611Sbill char **argv;
39611Sbill {
40611Sbill char *t;
41611Sbill char *assource;
42611Sbill int i, j, c;
43611Sbill
44611Sbill /* ld currently adds upto 5 args; 10 is room to spare */
45611Sbill av = (char **)calloc(argc+10, sizeof (char **));
46611Sbill clist = (char **)calloc(argc, sizeof (char **));
47611Sbill llist = (char **)calloc(argc, sizeof (char **));
48611Sbill plist = (char **)calloc(argc, sizeof (char **));
49611Sbill for (i = 1; i < argc; i++) {
50611Sbill if (*argv[i] == '-') switch (argv[i][1]) {
51611Sbill
52611Sbill case 'S':
53611Sbill sflag++;
54611Sbill cflag++;
55611Sbill continue;
56611Sbill case 'o':
57611Sbill if (++i < argc) {
58611Sbill outfile = argv[i];
59611Sbill switch (getsuf(outfile)) {
60611Sbill
61611Sbill case 'c':
62611Sbill error("-o would overwrite %s",
63611Sbill outfile);
64611Sbill exit(8);
65611Sbill }
66611Sbill }
67611Sbill continue;
68652Sbill case 'R':
69652Sbill Rflag++;
70652Sbill continue;
71611Sbill case 'O':
72611Sbill oflag++;
73611Sbill continue;
74611Sbill case 'p':
75611Sbill proflag++;
7637250Sbostic crt0 = _PATH_MCRT0;
775055Smckusic if (argv[i][2] == 'g')
7837250Sbostic crt0 = _PATH_GCRT0;
79611Sbill continue;
8017862Sralph case 'f':
8117862Sralph fflag++;
8217862Sralph continue;
83611Sbill case 'g':
849817Slinton if (argv[i][2] == 'o') {
859817Slinton Gflag++; /* old format for -go */
869817Slinton } else {
879817Slinton gflag++; /* new format for -g */
889817Slinton }
89611Sbill continue;
90611Sbill case 'w':
91611Sbill wflag++;
92611Sbill continue;
93611Sbill case 'E':
94611Sbill exflag++;
95611Sbill case 'P':
96611Sbill pflag++;
97611Sbill if (argv[i][1]=='P')
98611Sbill fprintf(stderr,
99611Sbill "cc: warning: -P option obsolete; you should use -E instead\n");
100611Sbill plist[np++] = argv[i];
101611Sbill case 'c':
102611Sbill cflag++;
103611Sbill continue;
10416237Smckusick case 'M':
10516237Smckusick exflag++;
10616237Smckusick pflag++;
10716237Smckusick Mflag++;
10816237Smckusick /* and fall through */
109611Sbill case 'D':
110611Sbill case 'I':
111611Sbill case 'U':
112611Sbill case 'C':
113611Sbill plist[np++] = argv[i];
114611Sbill continue;
11517134Ssam case 'L':
11617134Ssam llist[nl++] = argv[i];
11717134Ssam continue;
118611Sbill case 't':
119611Sbill if (chpass)
120611Sbill error("-t overwrites earlier option", 0);
121611Sbill chpass = argv[i]+2;
122611Sbill if (chpass[0]==0)
123611Sbill chpass = "012p";
124611Sbill continue;
125611Sbill case 'B':
126611Sbill if (npassname)
127611Sbill error("-B overwrites earlier option", 0);
128611Sbill npassname = argv[i]+2;
129611Sbill if (npassname[0]==0)
13037788Sbostic error("-B requires an argument", 0);
131611Sbill continue;
132611Sbill case 'd':
13316237Smckusick if (argv[i][2] == '\0') {
13416237Smckusick debug++;
13516237Smckusick continue;
13616237Smckusick }
137611Sbill dflag = argv[i];
138611Sbill continue;
139611Sbill }
140611Sbill t = argv[i];
141611Sbill c = getsuf(t);
142611Sbill if (c=='c' || c=='s' || exflag) {
143611Sbill clist[nc++] = t;
144611Sbill t = setsuf(t, 'o');
145611Sbill }
146611Sbill if (nodup(llist, t)) {
147611Sbill llist[nl++] = t;
148611Sbill if (getsuf(t)=='o')
149611Sbill nxo++;
150611Sbill }
151611Sbill }
1529817Slinton if (gflag || Gflag) {
153611Sbill if (oflag)
154611Sbill fprintf(stderr, "cc: warning: -g disables -O\n");
155611Sbill oflag = 0;
156611Sbill }
157611Sbill if (npassname && chpass ==0)
158611Sbill chpass = "012p";
159611Sbill if (chpass && npassname==0)
16037250Sbostic npassname = _PATH_USRNEW;
161611Sbill if (chpass)
162611Sbill for (t=chpass; *t; t++) {
163611Sbill switch (*t) {
164611Sbill
165611Sbill case '0':
16617862Sralph if (fflag)
16717862Sralph sccom = strspl(npassname, "sccom");
16817862Sralph else
16917862Sralph ccom = strspl(npassname, "ccom");
170611Sbill continue;
171611Sbill case '2':
172611Sbill c2 = strspl(npassname, "c2");
173611Sbill continue;
174611Sbill case 'p':
175611Sbill cpp = strspl(npassname, "cpp");
176611Sbill continue;
177611Sbill }
178611Sbill }
179611Sbill if (nc==0)
180611Sbill goto nocom;
181611Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN)
182611Sbill signal(SIGINT, idexit);
183611Sbill if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
184611Sbill signal(SIGTERM, idexit);
18524937Slepreau if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
18624937Slepreau signal(SIGHUP, idexit);
187611Sbill if (pflag==0)
18837788Sbostic (void)sprintf(tmp0, "%s/ctm%05.5d", _PATH_TMP, getpid());
189611Sbill tmp1 = strspl(tmp0, "1");
190611Sbill tmp2 = strspl(tmp0, "2");
191611Sbill tmp3 = strspl(tmp0, "3");
192611Sbill if (pflag==0)
193611Sbill tmp4 = strspl(tmp0, "4");
194611Sbill if (oflag)
195611Sbill tmp5 = strspl(tmp0, "5");
196611Sbill for (i=0; i<nc; i++) {
19716237Smckusick if (nc > 1 && !Mflag) {
198611Sbill printf("%s:\n", clist[i]);
199611Sbill fflush(stdout);
200611Sbill }
20124538Sbloom if (!Mflag && getsuf(clist[i]) == 's') {
202611Sbill assource = clist[i];
203611Sbill goto assemble;
204611Sbill } else
205611Sbill assource = tmp3;
206611Sbill if (pflag)
207611Sbill tmp4 = setsuf(clist[i], 'i');
20816237Smckusick av[0] = "cpp"; av[1] = clist[i];
20916237Smckusick na = 2;
21016237Smckusick if (!exflag)
21116237Smckusick av[na++] = tmp4;
212611Sbill for (j = 0; j < np; j++)
213611Sbill av[na++] = plist[j];
214611Sbill av[na++] = 0;
215611Sbill if (callsys(cpp, av)) {
216611Sbill exfail++;
217611Sbill eflag++;
21832207Sbostic cflag++;
21932207Sbostic continue;
220611Sbill }
22132207Sbostic if (pflag) {
222611Sbill cflag++;
223611Sbill continue;
224611Sbill }
22517461Sralph if (sflag) {
22617461Sralph if (nc==1 && outfile)
22717461Sralph tmp3 = outfile;
22817461Sralph else
22917461Sralph tmp3 = setsuf(clist[i], 's');
23017461Sralph assource = tmp3;
23117461Sralph }
23217862Sralph av[0] = fflag ? "sccom" : "ccom";
23317862Sralph av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3;
234611Sbill if (proflag)
235611Sbill av[na++] = "-XP";
2369817Slinton if (gflag) {
237611Sbill av[na++] = "-Xg";
2389817Slinton } else if (Gflag) {
2399817Slinton av[na++] = "-XG";
2409817Slinton }
241611Sbill if (wflag)
242611Sbill av[na++] = "-w";
243611Sbill av[na] = 0;
24417862Sralph if (callsys(fflag ? sccom : ccom, av)) {
245611Sbill cflag++;
246611Sbill eflag++;
247611Sbill continue;
248611Sbill }
249611Sbill if (oflag) {
250611Sbill av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0;
251611Sbill if (callsys(c2, av)) {
252611Sbill unlink(tmp3);
253611Sbill tmp3 = assource = tmp5;
254611Sbill } else
255611Sbill unlink(tmp5);
256611Sbill }
257611Sbill if (sflag)
258611Sbill continue;
259611Sbill assemble:
260611Sbill cunlink(tmp1); cunlink(tmp2); cunlink(tmp4);
26117461Sralph av[0] = "as"; av[1] = "-o";
26217461Sralph if (cflag && nc==1 && outfile)
26317461Sralph av[2] = outfile;
26417461Sralph else
26517461Sralph av[2] = setsuf(clist[i], 'o');
266652Sbill na = 3;
267652Sbill if (Rflag)
268652Sbill av[na++] = "-R";
269611Sbill if (dflag)
270611Sbill av[na++] = dflag;
271652Sbill av[na++] = assource;
272611Sbill av[na] = 0;
273611Sbill if (callsys(as, av) > 1) {
274611Sbill cflag++;
275611Sbill eflag++;
276611Sbill continue;
277611Sbill }
278611Sbill }
279611Sbill nocom:
280611Sbill if (cflag==0 && nl!=0) {
281611Sbill i = 0;
282611Sbill av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3;
283611Sbill if (outfile) {
284611Sbill av[na++] = "-o";
285611Sbill av[na++] = outfile;
286611Sbill }
287611Sbill while (i < nl)
288611Sbill av[na++] = llist[i++];
2895055Smckusic if (proflag)
2905055Smckusic av[na++] = "-lc_p";
2915055Smckusic else
2925055Smckusic av[na++] = "-lc";
293611Sbill av[na++] = 0;
294611Sbill eflag |= callsys(ld, av);
295611Sbill if (nc==1 && nxo==1 && eflag==0)
296*44767Sbostic unlink(setsuf(clist[0], 'o'));
297611Sbill }
298611Sbill dexit();
299611Sbill }
300611Sbill
idexit()301611Sbill idexit()
302611Sbill {
303611Sbill
304611Sbill eflag = 100;
305611Sbill dexit();
306611Sbill }
307611Sbill
dexit()308611Sbill dexit()
309611Sbill {
310611Sbill
311611Sbill if (!pflag) {
312611Sbill cunlink(tmp1);
313611Sbill cunlink(tmp2);
314611Sbill if (sflag==0)
315611Sbill cunlink(tmp3);
316611Sbill cunlink(tmp4);
317611Sbill cunlink(tmp5);
318611Sbill }
319611Sbill exit(eflag);
320611Sbill }
321611Sbill
error(s,x)322611Sbill error(s, x)
323611Sbill char *s, *x;
324611Sbill {
325611Sbill FILE *diag = exflag ? stderr : stdout;
326611Sbill
327611Sbill fprintf(diag, "cc: ");
328611Sbill fprintf(diag, s, x);
329611Sbill putc('\n', diag);
330611Sbill exfail++;
331611Sbill cflag++;
332611Sbill eflag++;
333611Sbill }
334611Sbill
getsuf(as)335611Sbill getsuf(as)
336611Sbill char as[];
337611Sbill {
338611Sbill register int c;
339611Sbill register char *s;
340611Sbill register int t;
341611Sbill
342611Sbill s = as;
343611Sbill c = 0;
344611Sbill while (t = *s++)
345611Sbill if (t=='/')
346611Sbill c = 0;
347611Sbill else
348611Sbill c++;
349611Sbill s -= 3;
3505963Smckusic if (c <= MAXNAMLEN && c > 2 && *s++ == '.')
351611Sbill return (*s);
352611Sbill return (0);
353611Sbill }
354611Sbill
355611Sbill char *
setsuf(as,ch)356611Sbill setsuf(as, ch)
357611Sbill char *as;
358611Sbill {
359611Sbill register char *s, *s1;
360611Sbill
361611Sbill s = s1 = savestr(as);
362611Sbill while (*s)
363611Sbill if (*s++ == '/')
364611Sbill s1 = s;
365611Sbill s[-1] = ch;
366611Sbill return (s1);
367611Sbill }
368611Sbill
callsys(f,v)369611Sbill callsys(f, v)
370611Sbill char *f, **v;
371611Sbill {
372611Sbill int t, status;
37316237Smckusick char **cpp;
374611Sbill
37516237Smckusick if (debug) {
37616237Smckusick fprintf(stderr, "%s:", f);
37716237Smckusick for (cpp = v; *cpp != 0; cpp++)
37816237Smckusick fprintf(stderr, " %s", *cpp);
37916237Smckusick fprintf(stderr, "\n");
38016237Smckusick }
381611Sbill t = vfork();
382611Sbill if (t == -1) {
383611Sbill printf("No more processes\n");
384611Sbill return (100);
385611Sbill }
386611Sbill if (t == 0) {
387611Sbill execv(f, v);
388611Sbill printf("Can't find %s\n", f);
389611Sbill fflush(stdout);
390611Sbill _exit(100);
391611Sbill }
392611Sbill while (t != wait(&status))
393611Sbill ;
394611Sbill if ((t=(status&0377)) != 0 && t!=14) {
395611Sbill if (t!=2) {
396611Sbill printf("Fatal error in %s\n", f);
397611Sbill eflag = 8;
398611Sbill }
399611Sbill dexit();
400611Sbill }
401611Sbill return ((status>>8) & 0377);
402611Sbill }
403611Sbill
nodup(l,os)404611Sbill nodup(l, os)
405611Sbill char **l, *os;
406611Sbill {
407611Sbill register char *t, *s;
408611Sbill register int c;
409611Sbill
410611Sbill s = os;
411611Sbill if (getsuf(s) != 'o')
412611Sbill return (1);
413611Sbill while (t = *l++) {
414611Sbill while (c = *s++)
415611Sbill if (c != *t++)
416611Sbill break;
417611Sbill if (*t==0 && c==0)
418611Sbill return (0);
419611Sbill s = os;
420611Sbill }
421611Sbill return (1);
422611Sbill }
423611Sbill
424611Sbill #define NSAVETAB 1024
425611Sbill char *savetab;
426611Sbill int saveleft;
427611Sbill
428611Sbill char *
savestr(cp)429611Sbill savestr(cp)
430611Sbill register char *cp;
431611Sbill {
432611Sbill register int len;
433611Sbill
434611Sbill len = strlen(cp) + 1;
435611Sbill if (len > saveleft) {
436611Sbill saveleft = NSAVETAB;
437611Sbill if (len > saveleft)
438611Sbill saveleft = len;
439611Sbill savetab = (char *)malloc(saveleft);
440611Sbill if (savetab == 0) {
441611Sbill fprintf(stderr, "ran out of memory (savestr)\n");
442611Sbill exit(1);
443611Sbill }
444611Sbill }
445611Sbill strncpy(savetab, cp, len);
446611Sbill cp = savetab;
447611Sbill savetab += len;
448611Sbill saveleft -= len;
449611Sbill return (cp);
450611Sbill }
451611Sbill
452611Sbill char *
strspl(left,right)453611Sbill strspl(left, right)
454611Sbill char *left, *right;
455611Sbill {
456611Sbill char buf[BUFSIZ];
457611Sbill
458611Sbill strcpy(buf, left);
459611Sbill strcat(buf, right);
460611Sbill return (savestr(buf));
461611Sbill }
462