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