xref: /csrg-svn/old/pcc/cc/cc.c (revision 652)
1611Sbill /* USE <wait.h> */
2*652Sbill static	char sccsid[] = "@(#)cc.c 3.2 08/17/80";
3611Sbill /*
4611Sbill  * cc - front end for C compiler
5611Sbill  */
6611Sbill #include <sys/types.h>
7611Sbill #include <stdio.h>
8611Sbill #include <ctype.h>
9611Sbill #include <signal.h>
10611Sbill #include <dir.h>
11611Sbill 
12611Sbill char	*cpp = "/usr/new/cpp";
13611Sbill char	*ccom = "/usr/new/ccom";
14611Sbill char	*c2 = "/usr/new/c2";
15611Sbill char	*as = "/usr/new/as";
16611Sbill char	*ld = "/usr/new/ld";
17611Sbill char	*crt0 = "/usr/new/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;
25*652Sbill int	cflag, eflag, gflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag;
26*652Sbill int	cps8;
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 '8':
52611Sbill 			cps8++;
53611Sbill 			cpp = "/usr/bin/8cpp";
54611Sbill 			ccom = "/usr/lib/8ccom";
55611Sbill 			c2 = "/usr/bin/8c2";
56611Sbill 			as = "/usr/bin/8as";
57611Sbill 			ld = "/usr/bin/8ld";
58611Sbill 			crt0 = "/usr/lib/8crt0";
59611Sbill 			continue;
60611Sbill 		case 'S':
61611Sbill 			sflag++;
62611Sbill 			cflag++;
63611Sbill 			continue;
64611Sbill 		case 'o':
65611Sbill 			if (++i < argc) {
66611Sbill 				outfile = argv[i];
67611Sbill 				switch (getsuf(outfile)) {
68611Sbill 
69611Sbill 				case 'c':
70611Sbill 				case 'o':
71611Sbill 					error("-o would overwrite %s",
72611Sbill 					    outfile);
73611Sbill 					exit(8);
74611Sbill 				}
75611Sbill 			}
76611Sbill 			continue;
77*652Sbill 		case 'R':
78*652Sbill 			Rflag++;
79*652Sbill 			continue;
80611Sbill 		case 'O':
81611Sbill 			oflag++;
82611Sbill 			continue;
83611Sbill 		case 'p':
84611Sbill 			proflag++;
85611Sbill 			continue;
86611Sbill 		case 'g':
87611Sbill 			gflag++;
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;
103611Sbill 		case 'D':
104611Sbill 		case 'I':
105611Sbill 		case 'U':
106611Sbill 		case 'C':
107611Sbill 			plist[np++] = argv[i];
108611Sbill 			continue;
109611Sbill 		case 't':
110611Sbill 			if (chpass)
111611Sbill 				error("-t overwrites earlier option", 0);
112611Sbill 			chpass = argv[i]+2;
113611Sbill 			if (chpass[0]==0)
114611Sbill 				chpass = "012p";
115611Sbill 			continue;
116611Sbill 		case 'B':
117611Sbill 			if (npassname)
118611Sbill 				error("-B overwrites earlier option", 0);
119611Sbill 			npassname = argv[i]+2;
120611Sbill 			if (npassname[0]==0)
121611Sbill 				npassname = "/usr/c/o";
122611Sbill 			continue;
123611Sbill 		case 'd':
124611Sbill 			dflag = argv[i];
125611Sbill 			continue;
126611Sbill 		}
127611Sbill 		t = argv[i];
128611Sbill 		c = getsuf(t);
129611Sbill 		if (c=='c' || c=='s' || exflag) {
130611Sbill 			clist[nc++] = t;
131611Sbill 			t = setsuf(t, 'o');
132611Sbill 		}
133611Sbill 		if (nodup(llist, t)) {
134611Sbill 			llist[nl++] = t;
135611Sbill 			if (getsuf(t)=='o')
136611Sbill 				nxo++;
137611Sbill 		}
138611Sbill 	}
139611Sbill 	if (gflag) {
140611Sbill 		if (oflag)
141611Sbill 			fprintf(stderr, "cc: warning: -g disables -O\n");
142611Sbill 		oflag = 0;
143611Sbill 	}
144611Sbill 	if (npassname && chpass ==0)
145611Sbill 		chpass = "012p";
146611Sbill 	if (chpass && npassname==0)
147611Sbill 		npassname = "/usr/c/";
148611Sbill 	if (chpass)
149611Sbill 	for (t=chpass; *t; t++) {
150611Sbill 		switch (*t) {
151611Sbill 
152611Sbill 		case '0':
153611Sbill 			ccom = strspl(npassname, "ccom");
154611Sbill 			continue;
155611Sbill 		case '2':
156611Sbill 			c2 = strspl(npassname, "c2");
157611Sbill 			continue;
158611Sbill 		case 'p':
159611Sbill 			cpp = strspl(npassname, "cpp");
160611Sbill 			continue;
161611Sbill 		}
162611Sbill 	}
163611Sbill 	if (proflag)
164611Sbill 		crt0 = cps8 ? "/usr/lib/8mcrt0.o" : "/usr/new/mcrt0.o";
165611Sbill 	if (nc==0)
166611Sbill 		goto nocom;
167611Sbill 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
168611Sbill 		signal(SIGINT, idexit);
169611Sbill 	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
170611Sbill 		signal(SIGTERM, idexit);
171611Sbill 	if (pflag==0)
172611Sbill 		sprintf(tmp0, "/tmp/ctm%05.5d", getpid());
173611Sbill 	tmp1 = strspl(tmp0, "1");
174611Sbill 	tmp2 = strspl(tmp0, "2");
175611Sbill 	tmp3 = strspl(tmp0, "3");
176611Sbill 	if (pflag==0)
177611Sbill 		tmp4 = strspl(tmp0, "4");
178611Sbill 	if (oflag)
179611Sbill 		tmp5 = strspl(tmp0, "5");
180611Sbill 	for (i=0; i<nc; i++) {
181611Sbill 		if (nc > 1) {
182611Sbill 			printf("%s:\n", clist[i]);
183611Sbill 			fflush(stdout);
184611Sbill 		}
185611Sbill 		if (getsuf(clist[i]) == 's') {
186611Sbill 			assource = clist[i];
187611Sbill 			goto assemble;
188611Sbill 		} else
189611Sbill 			assource = tmp3;
190611Sbill 		if (pflag)
191611Sbill 			tmp4 = setsuf(clist[i], 'i');
192611Sbill 		av[0] = "cpp"; av[1] = clist[i]; av[2] = exflag ? "-" : tmp4;
193611Sbill 		na = 3;
194611Sbill 		for (j = 0; j < np; j++)
195611Sbill 			av[na++] = plist[j];
196611Sbill 		av[na++] = 0;
197611Sbill 		if (callsys(cpp, av)) {
198611Sbill 			exfail++;
199611Sbill 			eflag++;
200611Sbill 		}
201611Sbill 		if (pflag || exfail) {
202611Sbill 			cflag++;
203611Sbill 			continue;
204611Sbill 		}
205611Sbill 		if (sflag)
206611Sbill 			assource = tmp3 = setsuf(clist[i], 's');
207611Sbill 		av[0] = "ccom"; av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3;
208611Sbill 		if (proflag)
209611Sbill 			av[na++] = "-XP";
210611Sbill 		if (gflag)
211611Sbill 			av[na++] = "-Xg";
212611Sbill 		if (wflag)
213611Sbill 			av[na++] = "-w";
214611Sbill 		av[na] = 0;
215611Sbill 		if (callsys(ccom, av)) {
216611Sbill 			cflag++;
217611Sbill 			eflag++;
218611Sbill 			continue;
219611Sbill 		}
220611Sbill 		if (oflag) {
221611Sbill 			av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0;
222611Sbill 			if (callsys(c2, av)) {
223611Sbill 				unlink(tmp3);
224611Sbill 				tmp3 = assource = tmp5;
225611Sbill 			} else
226611Sbill 				unlink(tmp5);
227611Sbill 		}
228611Sbill 		if (sflag)
229611Sbill 			continue;
230611Sbill 	assemble:
231611Sbill 		cunlink(tmp1); cunlink(tmp2); cunlink(tmp4);
232611Sbill 		av[0] = "as"; av[1] = "-o"; av[2] = setsuf(clist[i], 'o');
233*652Sbill 		na = 3;
234*652Sbill 		if (Rflag)
235*652Sbill 			av[na++] = "-R";
236611Sbill 		if (dflag)
237611Sbill 			av[na++] = dflag;
238*652Sbill 		av[na++] = assource;
239611Sbill 		av[na] = 0;
240611Sbill 		if (callsys(as, av) > 1) {
241611Sbill 			cflag++;
242611Sbill 			eflag++;
243611Sbill 			continue;
244611Sbill 		}
245611Sbill 	}
246611Sbill nocom:
247611Sbill 	if (cflag==0 && nl!=0) {
248611Sbill 		i = 0;
249611Sbill 		av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3;
250611Sbill 		if (outfile) {
251611Sbill 			av[na++] = "-o";
252611Sbill 			av[na++] = outfile;
253611Sbill 		}
254611Sbill 		while (i < nl)
255611Sbill 			av[na++] = llist[i++];
256611Sbill 		if (gflag)
257611Sbill 			av[na++] = "-lg";
258611Sbill 		av[na++] = "-lc";
259611Sbill 		av[na++] = 0;
260611Sbill 		eflag |= callsys(ld, av);
261611Sbill 		if (nc==1 && nxo==1 && eflag==0)
262611Sbill 			unlink(setsuf(clist[0], 'o'));
263611Sbill 	}
264611Sbill 	dexit();
265611Sbill }
266611Sbill 
267611Sbill idexit()
268611Sbill {
269611Sbill 
270611Sbill 	eflag = 100;
271611Sbill 	dexit();
272611Sbill }
273611Sbill 
274611Sbill dexit()
275611Sbill {
276611Sbill 
277611Sbill 	if (!pflag) {
278611Sbill 		cunlink(tmp1);
279611Sbill 		cunlink(tmp2);
280611Sbill 		if (sflag==0)
281611Sbill 			cunlink(tmp3);
282611Sbill 		cunlink(tmp4);
283611Sbill 		cunlink(tmp5);
284611Sbill 	}
285611Sbill 	exit(eflag);
286611Sbill }
287611Sbill 
288611Sbill error(s, x)
289611Sbill 	char *s, *x;
290611Sbill {
291611Sbill 	FILE *diag = exflag ? stderr : stdout;
292611Sbill 
293611Sbill 	fprintf(diag, "cc: ");
294611Sbill 	fprintf(diag, s, x);
295611Sbill 	putc('\n', diag);
296611Sbill 	exfail++;
297611Sbill 	cflag++;
298611Sbill 	eflag++;
299611Sbill }
300611Sbill 
301611Sbill getsuf(as)
302611Sbill char as[];
303611Sbill {
304611Sbill 	register int c;
305611Sbill 	register char *s;
306611Sbill 	register int t;
307611Sbill 
308611Sbill 	s = as;
309611Sbill 	c = 0;
310611Sbill 	while (t = *s++)
311611Sbill 		if (t=='/')
312611Sbill 			c = 0;
313611Sbill 		else
314611Sbill 			c++;
315611Sbill 	s -= 3;
316611Sbill 	if (c <= DIRSIZ && c > 2 && *s++ == '.')
317611Sbill 		return (*s);
318611Sbill 	return (0);
319611Sbill }
320611Sbill 
321611Sbill char *
322611Sbill setsuf(as, ch)
323611Sbill 	char *as;
324611Sbill {
325611Sbill 	register char *s, *s1;
326611Sbill 
327611Sbill 	s = s1 = savestr(as);
328611Sbill 	while (*s)
329611Sbill 		if (*s++ == '/')
330611Sbill 			s1 = s;
331611Sbill 	s[-1] = ch;
332611Sbill 	return (s1);
333611Sbill }
334611Sbill 
335611Sbill callsys(f, v)
336611Sbill 	char *f, **v;
337611Sbill {
338611Sbill 	int t, status;
339611Sbill 
340611Sbill 	t = vfork();
341611Sbill 	if (t == -1) {
342611Sbill 		printf("No more processes\n");
343611Sbill 		return (100);
344611Sbill 	}
345611Sbill 	if (t == 0) {
346611Sbill 		execv(f, v);
347611Sbill 		printf("Can't find %s\n", f);
348611Sbill 		fflush(stdout);
349611Sbill 		_exit(100);
350611Sbill 	}
351611Sbill 	while (t != wait(&status))
352611Sbill 		;
353611Sbill 	if ((t=(status&0377)) != 0 && t!=14) {
354611Sbill 		if (t!=2) {
355611Sbill 			printf("Fatal error in %s\n", f);
356611Sbill 			eflag = 8;
357611Sbill 		}
358611Sbill 		dexit();
359611Sbill 	}
360611Sbill 	return ((status>>8) & 0377);
361611Sbill }
362611Sbill 
363611Sbill nodup(l, os)
364611Sbill 	char **l, *os;
365611Sbill {
366611Sbill 	register char *t, *s;
367611Sbill 	register int c;
368611Sbill 
369611Sbill 	s = os;
370611Sbill 	if (getsuf(s) != 'o')
371611Sbill 		return (1);
372611Sbill 	while (t = *l++) {
373611Sbill 		while (c = *s++)
374611Sbill 			if (c != *t++)
375611Sbill 				break;
376611Sbill 		if (*t==0 && c==0)
377611Sbill 			return (0);
378611Sbill 		s = os;
379611Sbill 	}
380611Sbill 	return (1);
381611Sbill }
382611Sbill 
383611Sbill #define	NSAVETAB	1024
384611Sbill char	*savetab;
385611Sbill int	saveleft;
386611Sbill 
387611Sbill char *
388611Sbill savestr(cp)
389611Sbill 	register char *cp;
390611Sbill {
391611Sbill 	register int len;
392611Sbill 
393611Sbill 	len = strlen(cp) + 1;
394611Sbill 	if (len > saveleft) {
395611Sbill 		saveleft = NSAVETAB;
396611Sbill 		if (len > saveleft)
397611Sbill 			saveleft = len;
398611Sbill 		savetab = (char *)malloc(saveleft);
399611Sbill 		if (savetab == 0) {
400611Sbill 			fprintf(stderr, "ran out of memory (savestr)\n");
401611Sbill 			exit(1);
402611Sbill 		}
403611Sbill 	}
404611Sbill 	strncpy(savetab, cp, len);
405611Sbill 	cp = savetab;
406611Sbill 	savetab += len;
407611Sbill 	saveleft -= len;
408611Sbill 	return (cp);
409611Sbill }
410611Sbill 
411611Sbill char *
412611Sbill strspl(left, right)
413611Sbill 	char *left, *right;
414611Sbill {
415611Sbill 	char buf[BUFSIZ];
416611Sbill 
417611Sbill 	strcpy(buf, left);
418611Sbill 	strcat(buf, right);
419611Sbill 	return (savestr(buf));
420611Sbill }
421