1 static char sccsid[] = "@(#)cc.c 4.21 06/30/90";
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
main(argc,argv)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 (proflag)
290 av[na++] = "-lc_p";
291 else
292 av[na++] = "-lc";
293 av[na++] = 0;
294 eflag |= callsys(ld, av);
295 if (nc==1 && nxo==1 && eflag==0)
296 unlink(setsuf(clist[0], 'o'));
297 }
298 dexit();
299 }
300
idexit()301 idexit()
302 {
303
304 eflag = 100;
305 dexit();
306 }
307
dexit()308 dexit()
309 {
310
311 if (!pflag) {
312 cunlink(tmp1);
313 cunlink(tmp2);
314 if (sflag==0)
315 cunlink(tmp3);
316 cunlink(tmp4);
317 cunlink(tmp5);
318 }
319 exit(eflag);
320 }
321
error(s,x)322 error(s, x)
323 char *s, *x;
324 {
325 FILE *diag = exflag ? stderr : stdout;
326
327 fprintf(diag, "cc: ");
328 fprintf(diag, s, x);
329 putc('\n', diag);
330 exfail++;
331 cflag++;
332 eflag++;
333 }
334
getsuf(as)335 getsuf(as)
336 char as[];
337 {
338 register int c;
339 register char *s;
340 register int t;
341
342 s = as;
343 c = 0;
344 while (t = *s++)
345 if (t=='/')
346 c = 0;
347 else
348 c++;
349 s -= 3;
350 if (c <= MAXNAMLEN && c > 2 && *s++ == '.')
351 return (*s);
352 return (0);
353 }
354
355 char *
setsuf(as,ch)356 setsuf(as, ch)
357 char *as;
358 {
359 register char *s, *s1;
360
361 s = s1 = savestr(as);
362 while (*s)
363 if (*s++ == '/')
364 s1 = s;
365 s[-1] = ch;
366 return (s1);
367 }
368
callsys(f,v)369 callsys(f, v)
370 char *f, **v;
371 {
372 int t, status;
373 char **cpp;
374
375 if (debug) {
376 fprintf(stderr, "%s:", f);
377 for (cpp = v; *cpp != 0; cpp++)
378 fprintf(stderr, " %s", *cpp);
379 fprintf(stderr, "\n");
380 }
381 t = vfork();
382 if (t == -1) {
383 printf("No more processes\n");
384 return (100);
385 }
386 if (t == 0) {
387 execv(f, v);
388 printf("Can't find %s\n", f);
389 fflush(stdout);
390 _exit(100);
391 }
392 while (t != wait(&status))
393 ;
394 if ((t=(status&0377)) != 0 && t!=14) {
395 if (t!=2) {
396 printf("Fatal error in %s\n", f);
397 eflag = 8;
398 }
399 dexit();
400 }
401 return ((status>>8) & 0377);
402 }
403
nodup(l,os)404 nodup(l, os)
405 char **l, *os;
406 {
407 register char *t, *s;
408 register int c;
409
410 s = os;
411 if (getsuf(s) != 'o')
412 return (1);
413 while (t = *l++) {
414 while (c = *s++)
415 if (c != *t++)
416 break;
417 if (*t==0 && c==0)
418 return (0);
419 s = os;
420 }
421 return (1);
422 }
423
424 #define NSAVETAB 1024
425 char *savetab;
426 int saveleft;
427
428 char *
savestr(cp)429 savestr(cp)
430 register char *cp;
431 {
432 register int len;
433
434 len = strlen(cp) + 1;
435 if (len > saveleft) {
436 saveleft = NSAVETAB;
437 if (len > saveleft)
438 saveleft = len;
439 savetab = (char *)malloc(saveleft);
440 if (savetab == 0) {
441 fprintf(stderr, "ran out of memory (savestr)\n");
442 exit(1);
443 }
444 }
445 strncpy(savetab, cp, len);
446 cp = savetab;
447 savetab += len;
448 saveleft -= len;
449 return (cp);
450 }
451
452 char *
strspl(left,right)453 strspl(left, right)
454 char *left, *right;
455 {
456 char buf[BUFSIZ];
457
458 strcpy(buf, left);
459 strcat(buf, right);
460 return (savestr(buf));
461 }
462