xref: /csrg-svn/old/pcc/cc/cc.c (revision 32409)
1*32409Sbostic static	char sccsid[] = "@(#)cc.c 4.15 10/22/87";
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>
10611Sbill 
11896Sbill char	*cpp = "/lib/cpp";
12896Sbill char	*ccom = "/lib/ccom";
1317862Sralph char	*sccom = "/lib/sccom";
14896Sbill char	*c2 = "/lib/c2";
15896Sbill char	*as = "/bin/as";
16896Sbill char	*ld = "/bin/ld";
17896Sbill char	*crt0 = "/lib/crt0.o";
18611Sbill 
19611Sbill char	tmp0[30];		/* big enough for /tmp/ctm%05.5d */
20611Sbill char	*tmp1, *tmp2, *tmp3, *tmp4, *tmp5;
21611Sbill char	*outfile;
22611Sbill char	*savestr(), *strspl(), *setsuf();
23611Sbill int	idexit();
24611Sbill char	**av, **clist, **llist, **plist;
259817Slinton int	cflag, eflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag;
2617862Sralph int	fflag, gflag, Gflag, Mflag, debug;
27611Sbill char	*dflag;
28611Sbill int	exfail;
29611Sbill char	*chpass;
30611Sbill char	*npassname;
31611Sbill 
32611Sbill int	nc, nl, np, nxo, na;
33611Sbill 
34611Sbill #define	cunlink(s)	if (s) unlink(s)
35611Sbill 
36611Sbill main(argc, argv)
37611Sbill 	char **argv;
38611Sbill {
39611Sbill 	char *t;
40611Sbill 	char *assource;
41611Sbill 	int i, j, c;
42611Sbill 
43611Sbill 	/* ld currently adds upto 5 args; 10 is room to spare */
44611Sbill 	av = (char **)calloc(argc+10, sizeof (char **));
45611Sbill 	clist = (char **)calloc(argc, sizeof (char **));
46611Sbill 	llist = (char **)calloc(argc, sizeof (char **));
47611Sbill 	plist = (char **)calloc(argc, sizeof (char **));
48611Sbill 	for (i = 1; i < argc; i++) {
49611Sbill 		if (*argv[i] == '-') switch (argv[i][1]) {
50611Sbill 
51611Sbill 		case 'S':
52611Sbill 			sflag++;
53611Sbill 			cflag++;
54611Sbill 			continue;
55611Sbill 		case 'o':
56611Sbill 			if (++i < argc) {
57611Sbill 				outfile = argv[i];
58611Sbill 				switch (getsuf(outfile)) {
59611Sbill 
60611Sbill 				case 'c':
61611Sbill 					error("-o would overwrite %s",
62611Sbill 					    outfile);
63611Sbill 					exit(8);
64611Sbill 				}
65611Sbill 			}
66611Sbill 			continue;
67652Sbill 		case 'R':
68652Sbill 			Rflag++;
69652Sbill 			continue;
70611Sbill 		case 'O':
71611Sbill 			oflag++;
72611Sbill 			continue;
73611Sbill 		case 'p':
74611Sbill 			proflag++;
755055Smckusic 			crt0 = "/lib/mcrt0.o";
765055Smckusic 			if (argv[i][2] == 'g')
775055Smckusic 				crt0 = "/usr/lib/gcrt0.o";
78611Sbill 			continue;
7917862Sralph 		case 'f':
8017862Sralph 			fflag++;
8117862Sralph 			continue;
82611Sbill 		case 'g':
839817Slinton 			if (argv[i][2] == 'o') {
849817Slinton 			    Gflag++;	/* old format for -go */
859817Slinton 			} else {
869817Slinton 			    gflag++;	/* new format for -g */
879817Slinton 			}
88611Sbill 			continue;
89611Sbill 		case 'w':
90611Sbill 			wflag++;
91611Sbill 			continue;
92611Sbill 		case 'E':
93611Sbill 			exflag++;
94611Sbill 		case 'P':
95611Sbill 			pflag++;
96611Sbill 			if (argv[i][1]=='P')
97611Sbill 				fprintf(stderr,
98611Sbill 	"cc: warning: -P option obsolete; you should use -E instead\n");
99611Sbill 			plist[np++] = argv[i];
100611Sbill 		case 'c':
101611Sbill 			cflag++;
102611Sbill 			continue;
10316237Smckusick 		case 'M':
10416237Smckusick 			exflag++;
10516237Smckusick 			pflag++;
10616237Smckusick 			Mflag++;
10716237Smckusick 			/* and fall through */
108611Sbill 		case 'D':
109611Sbill 		case 'I':
110611Sbill 		case 'U':
111611Sbill 		case 'C':
112611Sbill 			plist[np++] = argv[i];
113611Sbill 			continue;
11417134Ssam 		case 'L':
11517134Ssam 			llist[nl++] = argv[i];
11617134Ssam 			continue;
117611Sbill 		case 't':
118611Sbill 			if (chpass)
119611Sbill 				error("-t overwrites earlier option", 0);
120611Sbill 			chpass = argv[i]+2;
121611Sbill 			if (chpass[0]==0)
122611Sbill 				chpass = "012p";
123611Sbill 			continue;
124611Sbill 		case 'B':
125611Sbill 			if (npassname)
126611Sbill 				error("-B overwrites earlier option", 0);
127611Sbill 			npassname = argv[i]+2;
128611Sbill 			if (npassname[0]==0)
129611Sbill 				npassname = "/usr/c/o";
130611Sbill 			continue;
131611Sbill 		case 'd':
13216237Smckusick 			if (argv[i][2] == '\0') {
13316237Smckusick 				debug++;
13416237Smckusick 				continue;
13516237Smckusick 			}
136611Sbill 			dflag = argv[i];
137611Sbill 			continue;
138611Sbill 		}
139611Sbill 		t = argv[i];
140611Sbill 		c = getsuf(t);
141611Sbill 		if (c=='c' || c=='s' || exflag) {
142611Sbill 			clist[nc++] = t;
143611Sbill 			t = setsuf(t, 'o');
144611Sbill 		}
145611Sbill 		if (nodup(llist, t)) {
146611Sbill 			llist[nl++] = t;
147611Sbill 			if (getsuf(t)=='o')
148611Sbill 				nxo++;
149611Sbill 		}
150611Sbill 	}
1519817Slinton 	if (gflag || Gflag) {
152611Sbill 		if (oflag)
153611Sbill 			fprintf(stderr, "cc: warning: -g disables -O\n");
154611Sbill 		oflag = 0;
155611Sbill 	}
156611Sbill 	if (npassname && chpass ==0)
157611Sbill 		chpass = "012p";
158611Sbill 	if (chpass && npassname==0)
159896Sbill 		npassname = "/usr/new";
160611Sbill 	if (chpass)
161611Sbill 	for (t=chpass; *t; t++) {
162611Sbill 		switch (*t) {
163611Sbill 
164611Sbill 		case '0':
16517862Sralph 			if (fflag)
16617862Sralph 				sccom = strspl(npassname, "sccom");
16717862Sralph 			else
16817862Sralph 				ccom = strspl(npassname, "ccom");
169611Sbill 			continue;
170611Sbill 		case '2':
171611Sbill 			c2 = strspl(npassname, "c2");
172611Sbill 			continue;
173611Sbill 		case 'p':
174611Sbill 			cpp = strspl(npassname, "cpp");
175611Sbill 			continue;
176611Sbill 		}
177611Sbill 	}
178611Sbill 	if (nc==0)
179611Sbill 		goto nocom;
180611Sbill 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
181611Sbill 		signal(SIGINT, idexit);
182611Sbill 	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
183611Sbill 		signal(SIGTERM, idexit);
18424937Slepreau 	if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
18524937Slepreau 		signal(SIGHUP, idexit);
186611Sbill 	if (pflag==0)
187*32409Sbostic 		(void)sprintf(tmp0, "/tmp/ctm%05.5d", getpid());
188611Sbill 	tmp1 = strspl(tmp0, "1");
189611Sbill 	tmp2 = strspl(tmp0, "2");
190611Sbill 	tmp3 = strspl(tmp0, "3");
191611Sbill 	if (pflag==0)
192611Sbill 		tmp4 = strspl(tmp0, "4");
193611Sbill 	if (oflag)
194611Sbill 		tmp5 = strspl(tmp0, "5");
195611Sbill 	for (i=0; i<nc; i++) {
19616237Smckusick 		if (nc > 1 && !Mflag) {
197611Sbill 			printf("%s:\n", clist[i]);
198611Sbill 			fflush(stdout);
199611Sbill 		}
20024538Sbloom 		if (!Mflag && getsuf(clist[i]) == 's') {
201611Sbill 			assource = clist[i];
202611Sbill 			goto assemble;
203611Sbill 		} else
204611Sbill 			assource = tmp3;
205611Sbill 		if (pflag)
206611Sbill 			tmp4 = setsuf(clist[i], 'i');
20716237Smckusick 		av[0] = "cpp"; av[1] = clist[i];
20816237Smckusick 		na = 2;
20916237Smckusick 		if (!exflag)
21016237Smckusick 			av[na++] = tmp4;
211611Sbill 		for (j = 0; j < np; j++)
212611Sbill 			av[na++] = plist[j];
213611Sbill 		av[na++] = 0;
214611Sbill 		if (callsys(cpp, av)) {
215611Sbill 			exfail++;
216611Sbill 			eflag++;
21732207Sbostic 			cflag++;
21832207Sbostic 			continue;
219611Sbill 		}
22032207Sbostic 		if (pflag) {
221611Sbill 			cflag++;
222611Sbill 			continue;
223611Sbill 		}
22417461Sralph 		if (sflag) {
22517461Sralph 			if (nc==1 && outfile)
22617461Sralph 				tmp3 = outfile;
22717461Sralph 			else
22817461Sralph 				tmp3 = setsuf(clist[i], 's');
22917461Sralph 			assource = tmp3;
23017461Sralph 		}
23117862Sralph 		av[0] = fflag ? "sccom" : "ccom";
23217862Sralph 		av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3;
233611Sbill 		if (proflag)
234611Sbill 			av[na++] = "-XP";
2359817Slinton 		if (gflag) {
236611Sbill 			av[na++] = "-Xg";
2379817Slinton 		} else if (Gflag) {
2389817Slinton 			av[na++] = "-XG";
2399817Slinton 		}
240611Sbill 		if (wflag)
241611Sbill 			av[na++] = "-w";
242611Sbill 		av[na] = 0;
24317862Sralph 		if (callsys(fflag ? sccom : ccom, av)) {
244611Sbill 			cflag++;
245611Sbill 			eflag++;
246611Sbill 			continue;
247611Sbill 		}
248611Sbill 		if (oflag) {
249611Sbill 			av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0;
250611Sbill 			if (callsys(c2, av)) {
251611Sbill 				unlink(tmp3);
252611Sbill 				tmp3 = assource = tmp5;
253611Sbill 			} else
254611Sbill 				unlink(tmp5);
255611Sbill 		}
256611Sbill 		if (sflag)
257611Sbill 			continue;
258611Sbill 	assemble:
259611Sbill 		cunlink(tmp1); cunlink(tmp2); cunlink(tmp4);
26017461Sralph 		av[0] = "as"; av[1] = "-o";
26117461Sralph 		if (cflag && nc==1 && outfile)
26217461Sralph 			av[2] = outfile;
26317461Sralph 		else
26417461Sralph 			av[2] = setsuf(clist[i], 'o');
265652Sbill 		na = 3;
266652Sbill 		if (Rflag)
267652Sbill 			av[na++] = "-R";
268611Sbill 		if (dflag)
269611Sbill 			av[na++] = dflag;
270652Sbill 		av[na++] = assource;
271611Sbill 		av[na] = 0;
272611Sbill 		if (callsys(as, av) > 1) {
273611Sbill 			cflag++;
274611Sbill 			eflag++;
275611Sbill 			continue;
276611Sbill 		}
277611Sbill 	}
278611Sbill nocom:
279611Sbill 	if (cflag==0 && nl!=0) {
280611Sbill 		i = 0;
281611Sbill 		av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3;
282611Sbill 		if (outfile) {
283611Sbill 			av[na++] = "-o";
284611Sbill 			av[na++] = outfile;
285611Sbill 		}
286611Sbill 		while (i < nl)
287611Sbill 			av[na++] = llist[i++];
2889817Slinton 		if (gflag || Gflag)
289611Sbill 			av[na++] = "-lg";
2905055Smckusic 		if (proflag)
2915055Smckusic 			av[na++] = "-lc_p";
2925055Smckusic 		else
2935055Smckusic 			av[na++] = "-lc";
294611Sbill 		av[na++] = 0;
295611Sbill 		eflag |= callsys(ld, av);
296611Sbill 		if (nc==1 && nxo==1 && eflag==0)
297611Sbill 			unlink(setsuf(clist[0], 'o'));
298611Sbill 	}
299611Sbill 	dexit();
300611Sbill }
301611Sbill 
302611Sbill idexit()
303611Sbill {
304611Sbill 
305611Sbill 	eflag = 100;
306611Sbill 	dexit();
307611Sbill }
308611Sbill 
309611Sbill dexit()
310611Sbill {
311611Sbill 
312611Sbill 	if (!pflag) {
313611Sbill 		cunlink(tmp1);
314611Sbill 		cunlink(tmp2);
315611Sbill 		if (sflag==0)
316611Sbill 			cunlink(tmp3);
317611Sbill 		cunlink(tmp4);
318611Sbill 		cunlink(tmp5);
319611Sbill 	}
320611Sbill 	exit(eflag);
321611Sbill }
322611Sbill 
323611Sbill error(s, x)
324611Sbill 	char *s, *x;
325611Sbill {
326611Sbill 	FILE *diag = exflag ? stderr : stdout;
327611Sbill 
328611Sbill 	fprintf(diag, "cc: ");
329611Sbill 	fprintf(diag, s, x);
330611Sbill 	putc('\n', diag);
331611Sbill 	exfail++;
332611Sbill 	cflag++;
333611Sbill 	eflag++;
334611Sbill }
335611Sbill 
336611Sbill getsuf(as)
337611Sbill char as[];
338611Sbill {
339611Sbill 	register int c;
340611Sbill 	register char *s;
341611Sbill 	register int t;
342611Sbill 
343611Sbill 	s = as;
344611Sbill 	c = 0;
345611Sbill 	while (t = *s++)
346611Sbill 		if (t=='/')
347611Sbill 			c = 0;
348611Sbill 		else
349611Sbill 			c++;
350611Sbill 	s -= 3;
3515963Smckusic 	if (c <= MAXNAMLEN && c > 2 && *s++ == '.')
352611Sbill 		return (*s);
353611Sbill 	return (0);
354611Sbill }
355611Sbill 
356611Sbill char *
357611Sbill setsuf(as, ch)
358611Sbill 	char *as;
359611Sbill {
360611Sbill 	register char *s, *s1;
361611Sbill 
362611Sbill 	s = s1 = savestr(as);
363611Sbill 	while (*s)
364611Sbill 		if (*s++ == '/')
365611Sbill 			s1 = s;
366611Sbill 	s[-1] = ch;
367611Sbill 	return (s1);
368611Sbill }
369611Sbill 
370611Sbill callsys(f, v)
371611Sbill 	char *f, **v;
372611Sbill {
373611Sbill 	int t, status;
37416237Smckusick 	char **cpp;
375611Sbill 
37616237Smckusick 	if (debug) {
37716237Smckusick 		fprintf(stderr, "%s:", f);
37816237Smckusick 		for (cpp = v; *cpp != 0; cpp++)
37916237Smckusick 			fprintf(stderr, " %s", *cpp);
38016237Smckusick 		fprintf(stderr, "\n");
38116237Smckusick 	}
382611Sbill 	t = vfork();
383611Sbill 	if (t == -1) {
384611Sbill 		printf("No more processes\n");
385611Sbill 		return (100);
386611Sbill 	}
387611Sbill 	if (t == 0) {
388611Sbill 		execv(f, v);
389611Sbill 		printf("Can't find %s\n", f);
390611Sbill 		fflush(stdout);
391611Sbill 		_exit(100);
392611Sbill 	}
393611Sbill 	while (t != wait(&status))
394611Sbill 		;
395611Sbill 	if ((t=(status&0377)) != 0 && t!=14) {
396611Sbill 		if (t!=2) {
397611Sbill 			printf("Fatal error in %s\n", f);
398611Sbill 			eflag = 8;
399611Sbill 		}
400611Sbill 		dexit();
401611Sbill 	}
402611Sbill 	return ((status>>8) & 0377);
403611Sbill }
404611Sbill 
405611Sbill nodup(l, os)
406611Sbill 	char **l, *os;
407611Sbill {
408611Sbill 	register char *t, *s;
409611Sbill 	register int c;
410611Sbill 
411611Sbill 	s = os;
412611Sbill 	if (getsuf(s) != 'o')
413611Sbill 		return (1);
414611Sbill 	while (t = *l++) {
415611Sbill 		while (c = *s++)
416611Sbill 			if (c != *t++)
417611Sbill 				break;
418611Sbill 		if (*t==0 && c==0)
419611Sbill 			return (0);
420611Sbill 		s = os;
421611Sbill 	}
422611Sbill 	return (1);
423611Sbill }
424611Sbill 
425611Sbill #define	NSAVETAB	1024
426611Sbill char	*savetab;
427611Sbill int	saveleft;
428611Sbill 
429611Sbill char *
430611Sbill savestr(cp)
431611Sbill 	register char *cp;
432611Sbill {
433611Sbill 	register int len;
434611Sbill 
435611Sbill 	len = strlen(cp) + 1;
436611Sbill 	if (len > saveleft) {
437611Sbill 		saveleft = NSAVETAB;
438611Sbill 		if (len > saveleft)
439611Sbill 			saveleft = len;
440611Sbill 		savetab = (char *)malloc(saveleft);
441611Sbill 		if (savetab == 0) {
442611Sbill 			fprintf(stderr, "ran out of memory (savestr)\n");
443611Sbill 			exit(1);
444611Sbill 		}
445611Sbill 	}
446611Sbill 	strncpy(savetab, cp, len);
447611Sbill 	cp = savetab;
448611Sbill 	savetab += len;
449611Sbill 	saveleft -= len;
450611Sbill 	return (cp);
451611Sbill }
452611Sbill 
453611Sbill char *
454611Sbill strspl(left, right)
455611Sbill 	char *left, *right;
456611Sbill {
457611Sbill 	char buf[BUFSIZ];
458611Sbill 
459611Sbill 	strcpy(buf, left);
460611Sbill 	strcat(buf, right);
461611Sbill 	return (savestr(buf));
462611Sbill }
463