Commit | Line | Data |
---|---|---|
31cef89c | 1 | static char sccsid[] = "@(#)cc.c 4.1 10/1/80"; |
34d9b70e BJ |
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 | ||
c6802205 BJ |
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"; | |
34d9b70e BJ |
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; | |
b82dd559 | 24 | int cflag, eflag, gflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag; |
34d9b70e BJ |
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 | ||
34d9b70e BJ |
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; | |
b82dd559 BJ |
66 | case 'R': |
67 | Rflag++; | |
68 | continue; | |
34d9b70e BJ |
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) | |
c6802205 | 136 | npassname = "/usr/new"; |
34d9b70e BJ |
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) | |
c6802205 | 153 | crt0 = "/lib/mcrt0.o"; |
34d9b70e BJ |
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'); | |
b82dd559 BJ |
222 | na = 3; |
223 | if (Rflag) | |
224 | av[na++] = "-R"; | |
34d9b70e BJ |
225 | if (dflag) |
226 | av[na++] = dflag; | |
b82dd559 | 227 | av[na++] = assource; |
34d9b70e BJ |
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 | } |