xref: /csrg-svn/old/pcc/cc/cc.c (revision 611)
1*611Sbill /* USE <wait.h> */
2*611Sbill static	char sccsid[] = "@(#)cc.c 3.1 08/15/80";
3*611Sbill /*
4*611Sbill  * cc - front end for C compiler
5*611Sbill  */
6*611Sbill #include <sys/types.h>
7*611Sbill #include <stdio.h>
8*611Sbill #include <ctype.h>
9*611Sbill #include <signal.h>
10*611Sbill #include <dir.h>
11*611Sbill 
12*611Sbill char	*cpp = "/usr/new/cpp";
13*611Sbill char	*ccom = "/usr/new/ccom";
14*611Sbill char	*c2 = "/usr/new/c2";
15*611Sbill char	*as = "/usr/new/as";
16*611Sbill char	*ld = "/usr/new/ld";
17*611Sbill char	*crt0 = "/usr/new/crt0.o";
18*611Sbill 
19*611Sbill char	tmp0[30];		/* big enough for /tmp/ctm%05.5d */
20*611Sbill char	*tmp1, *tmp2, *tmp3, *tmp4, *tmp5;
21*611Sbill char	*outfile;
22*611Sbill char	*savestr(), *strspl(), *setsuf();
23*611Sbill int	idexit();
24*611Sbill char	**av, **clist, **llist, **plist;
25*611Sbill int	cflag, eflag, gflag, oflag, pflag, sflag, wflag, cps8, exflag, proflag;
26*611Sbill char	*dflag;
27*611Sbill int	exfail;
28*611Sbill char	*chpass;
29*611Sbill char	*npassname;
30*611Sbill 
31*611Sbill int	nc, nl, np, nxo, na;
32*611Sbill 
33*611Sbill #define	cunlink(s)	if (s) unlink(s)
34*611Sbill 
35*611Sbill main(argc, argv)
36*611Sbill 	char **argv;
37*611Sbill {
38*611Sbill 	char *t;
39*611Sbill 	char *assource;
40*611Sbill 	int i, j, c;
41*611Sbill 
42*611Sbill 	/* ld currently adds upto 5 args; 10 is room to spare */
43*611Sbill 	av = (char **)calloc(argc+10, sizeof (char **));
44*611Sbill 	clist = (char **)calloc(argc, sizeof (char **));
45*611Sbill 	llist = (char **)calloc(argc, sizeof (char **));
46*611Sbill 	plist = (char **)calloc(argc, sizeof (char **));
47*611Sbill 	for (i = 1; i < argc; i++) {
48*611Sbill 		if (*argv[i] == '-') switch (argv[i][1]) {
49*611Sbill 
50*611Sbill 		case '8':
51*611Sbill 			cps8++;
52*611Sbill 			cpp = "/usr/bin/8cpp";
53*611Sbill 			ccom = "/usr/lib/8ccom";
54*611Sbill 			c2 = "/usr/bin/8c2";
55*611Sbill 			as = "/usr/bin/8as";
56*611Sbill 			ld = "/usr/bin/8ld";
57*611Sbill 			crt0 = "/usr/lib/8crt0";
58*611Sbill 			continue;
59*611Sbill 		case 'S':
60*611Sbill 			sflag++;
61*611Sbill 			cflag++;
62*611Sbill 			continue;
63*611Sbill 		case 'o':
64*611Sbill 			if (++i < argc) {
65*611Sbill 				outfile = argv[i];
66*611Sbill 				switch (getsuf(outfile)) {
67*611Sbill 
68*611Sbill 				case 'c':
69*611Sbill 				case 'o':
70*611Sbill 					error("-o would overwrite %s",
71*611Sbill 					    outfile);
72*611Sbill 					exit(8);
73*611Sbill 				}
74*611Sbill 			}
75*611Sbill 			continue;
76*611Sbill 		case 'O':
77*611Sbill 			oflag++;
78*611Sbill 			continue;
79*611Sbill 		case 'p':
80*611Sbill 			proflag++;
81*611Sbill 			continue;
82*611Sbill 		case 'g':
83*611Sbill 			gflag++;
84*611Sbill 			continue;
85*611Sbill 		case 'w':
86*611Sbill 			wflag++;
87*611Sbill 			continue;
88*611Sbill 		case 'E':
89*611Sbill 			exflag++;
90*611Sbill 		case 'P':
91*611Sbill 			pflag++;
92*611Sbill 			if (argv[i][1]=='P')
93*611Sbill 				fprintf(stderr,
94*611Sbill 	"cc: warning: -P option obsolete; you should use -E instead\n");
95*611Sbill 			plist[np++] = argv[i];
96*611Sbill 		case 'c':
97*611Sbill 			cflag++;
98*611Sbill 			continue;
99*611Sbill 		case 'D':
100*611Sbill 		case 'I':
101*611Sbill 		case 'U':
102*611Sbill 		case 'C':
103*611Sbill 			plist[np++] = argv[i];
104*611Sbill 			continue;
105*611Sbill 		case 't':
106*611Sbill 			if (chpass)
107*611Sbill 				error("-t overwrites earlier option", 0);
108*611Sbill 			chpass = argv[i]+2;
109*611Sbill 			if (chpass[0]==0)
110*611Sbill 				chpass = "012p";
111*611Sbill 			continue;
112*611Sbill 		case 'B':
113*611Sbill 			if (npassname)
114*611Sbill 				error("-B overwrites earlier option", 0);
115*611Sbill 			npassname = argv[i]+2;
116*611Sbill 			if (npassname[0]==0)
117*611Sbill 				npassname = "/usr/c/o";
118*611Sbill 			continue;
119*611Sbill 		case 'd':
120*611Sbill 			dflag = argv[i];
121*611Sbill 			continue;
122*611Sbill 		}
123*611Sbill 		t = argv[i];
124*611Sbill 		c = getsuf(t);
125*611Sbill 		if (c=='c' || c=='s' || exflag) {
126*611Sbill 			clist[nc++] = t;
127*611Sbill 			t = setsuf(t, 'o');
128*611Sbill 		}
129*611Sbill 		if (nodup(llist, t)) {
130*611Sbill 			llist[nl++] = t;
131*611Sbill 			if (getsuf(t)=='o')
132*611Sbill 				nxo++;
133*611Sbill 		}
134*611Sbill 	}
135*611Sbill 	if (gflag) {
136*611Sbill 		if (oflag)
137*611Sbill 			fprintf(stderr, "cc: warning: -g disables -O\n");
138*611Sbill 		oflag = 0;
139*611Sbill 	}
140*611Sbill 	if (npassname && chpass ==0)
141*611Sbill 		chpass = "012p";
142*611Sbill 	if (chpass && npassname==0)
143*611Sbill 		npassname = "/usr/c/";
144*611Sbill 	if (chpass)
145*611Sbill 	for (t=chpass; *t; t++) {
146*611Sbill 		switch (*t) {
147*611Sbill 
148*611Sbill 		case '0':
149*611Sbill 			ccom = strspl(npassname, "ccom");
150*611Sbill 			continue;
151*611Sbill 		case '2':
152*611Sbill 			c2 = strspl(npassname, "c2");
153*611Sbill 			continue;
154*611Sbill 		case 'p':
155*611Sbill 			cpp = strspl(npassname, "cpp");
156*611Sbill 			continue;
157*611Sbill 		}
158*611Sbill 	}
159*611Sbill 	if (proflag)
160*611Sbill 		crt0 = cps8 ? "/usr/lib/8mcrt0.o" : "/usr/new/mcrt0.o";
161*611Sbill 	if (nc==0)
162*611Sbill 		goto nocom;
163*611Sbill 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
164*611Sbill 		signal(SIGINT, idexit);
165*611Sbill 	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
166*611Sbill 		signal(SIGTERM, idexit);
167*611Sbill 	if (pflag==0)
168*611Sbill 		sprintf(tmp0, "/tmp/ctm%05.5d", getpid());
169*611Sbill 	tmp1 = strspl(tmp0, "1");
170*611Sbill 	tmp2 = strspl(tmp0, "2");
171*611Sbill 	tmp3 = strspl(tmp0, "3");
172*611Sbill 	if (pflag==0)
173*611Sbill 		tmp4 = strspl(tmp0, "4");
174*611Sbill 	if (oflag)
175*611Sbill 		tmp5 = strspl(tmp0, "5");
176*611Sbill 	for (i=0; i<nc; i++) {
177*611Sbill 		if (nc > 1) {
178*611Sbill 			printf("%s:\n", clist[i]);
179*611Sbill 			fflush(stdout);
180*611Sbill 		}
181*611Sbill 		if (getsuf(clist[i]) == 's') {
182*611Sbill 			assource = clist[i];
183*611Sbill 			goto assemble;
184*611Sbill 		} else
185*611Sbill 			assource = tmp3;
186*611Sbill 		if (pflag)
187*611Sbill 			tmp4 = setsuf(clist[i], 'i');
188*611Sbill 		av[0] = "cpp"; av[1] = clist[i]; av[2] = exflag ? "-" : tmp4;
189*611Sbill 		na = 3;
190*611Sbill 		for (j = 0; j < np; j++)
191*611Sbill 			av[na++] = plist[j];
192*611Sbill 		av[na++] = 0;
193*611Sbill 		if (callsys(cpp, av)) {
194*611Sbill 			exfail++;
195*611Sbill 			eflag++;
196*611Sbill 		}
197*611Sbill 		if (pflag || exfail) {
198*611Sbill 			cflag++;
199*611Sbill 			continue;
200*611Sbill 		}
201*611Sbill 		if (sflag)
202*611Sbill 			assource = tmp3 = setsuf(clist[i], 's');
203*611Sbill 		av[0] = "ccom"; av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3;
204*611Sbill 		if (proflag)
205*611Sbill 			av[na++] = "-XP";
206*611Sbill 		if (gflag)
207*611Sbill 			av[na++] = "-Xg";
208*611Sbill 		if (wflag)
209*611Sbill 			av[na++] = "-w";
210*611Sbill 		av[na] = 0;
211*611Sbill 		if (callsys(ccom, av)) {
212*611Sbill 			cflag++;
213*611Sbill 			eflag++;
214*611Sbill 			continue;
215*611Sbill 		}
216*611Sbill 		if (oflag) {
217*611Sbill 			av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0;
218*611Sbill 			if (callsys(c2, av)) {
219*611Sbill 				unlink(tmp3);
220*611Sbill 				tmp3 = assource = tmp5;
221*611Sbill 			} else
222*611Sbill 				unlink(tmp5);
223*611Sbill 		}
224*611Sbill 		if (sflag)
225*611Sbill 			continue;
226*611Sbill 	assemble:
227*611Sbill 		cunlink(tmp1); cunlink(tmp2); cunlink(tmp4);
228*611Sbill 		av[0] = "as"; av[1] = "-o"; av[2] = setsuf(clist[i], 'o');
229*611Sbill 		av[3] = assource; na = 4;
230*611Sbill 		if (dflag)
231*611Sbill 			av[na++] = dflag;
232*611Sbill 		av[na] = 0;
233*611Sbill 		if (callsys(as, av) > 1) {
234*611Sbill 			cflag++;
235*611Sbill 			eflag++;
236*611Sbill 			continue;
237*611Sbill 		}
238*611Sbill 	}
239*611Sbill nocom:
240*611Sbill 	if (cflag==0 && nl!=0) {
241*611Sbill 		i = 0;
242*611Sbill 		av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3;
243*611Sbill 		if (outfile) {
244*611Sbill 			av[na++] = "-o";
245*611Sbill 			av[na++] = outfile;
246*611Sbill 		}
247*611Sbill 		while (i < nl)
248*611Sbill 			av[na++] = llist[i++];
249*611Sbill 		if (gflag)
250*611Sbill 			av[na++] = "-lg";
251*611Sbill 		av[na++] = "-lc";
252*611Sbill 		av[na++] = 0;
253*611Sbill 		eflag |= callsys(ld, av);
254*611Sbill 		if (nc==1 && nxo==1 && eflag==0)
255*611Sbill 			unlink(setsuf(clist[0], 'o'));
256*611Sbill 	}
257*611Sbill 	dexit();
258*611Sbill }
259*611Sbill 
260*611Sbill idexit()
261*611Sbill {
262*611Sbill 
263*611Sbill 	eflag = 100;
264*611Sbill 	dexit();
265*611Sbill }
266*611Sbill 
267*611Sbill dexit()
268*611Sbill {
269*611Sbill 
270*611Sbill 	if (!pflag) {
271*611Sbill 		cunlink(tmp1);
272*611Sbill 		cunlink(tmp2);
273*611Sbill 		if (sflag==0)
274*611Sbill 			cunlink(tmp3);
275*611Sbill 		cunlink(tmp4);
276*611Sbill 		cunlink(tmp5);
277*611Sbill 	}
278*611Sbill 	exit(eflag);
279*611Sbill }
280*611Sbill 
281*611Sbill error(s, x)
282*611Sbill 	char *s, *x;
283*611Sbill {
284*611Sbill 	FILE *diag = exflag ? stderr : stdout;
285*611Sbill 
286*611Sbill 	fprintf(diag, "cc: ");
287*611Sbill 	fprintf(diag, s, x);
288*611Sbill 	putc('\n', diag);
289*611Sbill 	exfail++;
290*611Sbill 	cflag++;
291*611Sbill 	eflag++;
292*611Sbill }
293*611Sbill 
294*611Sbill getsuf(as)
295*611Sbill char as[];
296*611Sbill {
297*611Sbill 	register int c;
298*611Sbill 	register char *s;
299*611Sbill 	register int t;
300*611Sbill 
301*611Sbill 	s = as;
302*611Sbill 	c = 0;
303*611Sbill 	while (t = *s++)
304*611Sbill 		if (t=='/')
305*611Sbill 			c = 0;
306*611Sbill 		else
307*611Sbill 			c++;
308*611Sbill 	s -= 3;
309*611Sbill 	if (c <= DIRSIZ && c > 2 && *s++ == '.')
310*611Sbill 		return (*s);
311*611Sbill 	return (0);
312*611Sbill }
313*611Sbill 
314*611Sbill char *
315*611Sbill setsuf(as, ch)
316*611Sbill 	char *as;
317*611Sbill {
318*611Sbill 	register char *s, *s1;
319*611Sbill 
320*611Sbill 	s = s1 = savestr(as);
321*611Sbill 	while (*s)
322*611Sbill 		if (*s++ == '/')
323*611Sbill 			s1 = s;
324*611Sbill 	s[-1] = ch;
325*611Sbill 	return (s1);
326*611Sbill }
327*611Sbill 
328*611Sbill callsys(f, v)
329*611Sbill 	char *f, **v;
330*611Sbill {
331*611Sbill 	int t, status;
332*611Sbill 
333*611Sbill 	t = vfork();
334*611Sbill 	if (t == -1) {
335*611Sbill 		printf("No more processes\n");
336*611Sbill 		return (100);
337*611Sbill 	}
338*611Sbill 	if (t == 0) {
339*611Sbill 		execv(f, v);
340*611Sbill 		printf("Can't find %s\n", f);
341*611Sbill 		fflush(stdout);
342*611Sbill 		_exit(100);
343*611Sbill 	}
344*611Sbill 	while (t != wait(&status))
345*611Sbill 		;
346*611Sbill 	if ((t=(status&0377)) != 0 && t!=14) {
347*611Sbill 		if (t!=2) {
348*611Sbill 			printf("Fatal error in %s\n", f);
349*611Sbill 			eflag = 8;
350*611Sbill 		}
351*611Sbill 		dexit();
352*611Sbill 	}
353*611Sbill 	return ((status>>8) & 0377);
354*611Sbill }
355*611Sbill 
356*611Sbill nodup(l, os)
357*611Sbill 	char **l, *os;
358*611Sbill {
359*611Sbill 	register char *t, *s;
360*611Sbill 	register int c;
361*611Sbill 
362*611Sbill 	s = os;
363*611Sbill 	if (getsuf(s) != 'o')
364*611Sbill 		return (1);
365*611Sbill 	while (t = *l++) {
366*611Sbill 		while (c = *s++)
367*611Sbill 			if (c != *t++)
368*611Sbill 				break;
369*611Sbill 		if (*t==0 && c==0)
370*611Sbill 			return (0);
371*611Sbill 		s = os;
372*611Sbill 	}
373*611Sbill 	return (1);
374*611Sbill }
375*611Sbill 
376*611Sbill #define	NSAVETAB	1024
377*611Sbill char	*savetab;
378*611Sbill int	saveleft;
379*611Sbill 
380*611Sbill char *
381*611Sbill savestr(cp)
382*611Sbill 	register char *cp;
383*611Sbill {
384*611Sbill 	register int len;
385*611Sbill 
386*611Sbill 	len = strlen(cp) + 1;
387*611Sbill 	if (len > saveleft) {
388*611Sbill 		saveleft = NSAVETAB;
389*611Sbill 		if (len > saveleft)
390*611Sbill 			saveleft = len;
391*611Sbill 		savetab = (char *)malloc(saveleft);
392*611Sbill 		if (savetab == 0) {
393*611Sbill 			fprintf(stderr, "ran out of memory (savestr)\n");
394*611Sbill 			exit(1);
395*611Sbill 		}
396*611Sbill 	}
397*611Sbill 	strncpy(savetab, cp, len);
398*611Sbill 	cp = savetab;
399*611Sbill 	savetab += len;
400*611Sbill 	saveleft -= len;
401*611Sbill 	return (cp);
402*611Sbill }
403*611Sbill 
404*611Sbill char *
405*611Sbill strspl(left, right)
406*611Sbill 	char *left, *right;
407*611Sbill {
408*611Sbill 	char buf[BUFSIZ];
409*611Sbill 
410*611Sbill 	strcpy(buf, left);
411*611Sbill 	strcat(buf, right);
412*611Sbill 	return (savestr(buf));
413*611Sbill }
414