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