xref: /csrg-svn/old/pcc/cc/cc.c (revision 44767)
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