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