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