Commit | Line | Data |
---|---|---|
34d9b70e BJ |
1 | /* USE <wait.h> */ |
2 | static char sccsid[] = "@(#)cc.c 3.1 %G%"; | |
3 | /* | |
4 | * cc - front end for C compiler | |
5 | */ | |
6 | #include <sys/types.h> | |
7 | #include <stdio.h> | |
8 | #include <ctype.h> | |
9 | #include <signal.h> | |
10 | #include <dir.h> | |
11 | ||
12 | char *cpp = "/usr/new/cpp"; | |
13 | char *ccom = "/usr/new/ccom"; | |
14 | char *c2 = "/usr/new/c2"; | |
15 | char *as = "/usr/new/as"; | |
16 | char *ld = "/usr/new/ld"; | |
17 | char *crt0 = "/usr/new/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, gflag, oflag, pflag, sflag, wflag, cps8, exflag, proflag; | |
26 | char *dflag; | |
27 | int exfail; | |
28 | char *chpass; | |
29 | char *npassname; | |
30 | ||
31 | int nc, nl, np, nxo, na; | |
32 | ||
33 | #define cunlink(s) if (s) unlink(s) | |
34 | ||
35 | main(argc, argv) | |
36 | char **argv; | |
37 | { | |
38 | char *t; | |
39 | char *assource; | |
40 | int i, j, c; | |
41 | ||
42 | /* ld currently adds upto 5 args; 10 is room to spare */ | |
43 | av = (char **)calloc(argc+10, sizeof (char **)); | |
44 | clist = (char **)calloc(argc, sizeof (char **)); | |
45 | llist = (char **)calloc(argc, sizeof (char **)); | |
46 | plist = (char **)calloc(argc, sizeof (char **)); | |
47 | for (i = 1; i < argc; i++) { | |
48 | if (*argv[i] == '-') switch (argv[i][1]) { | |
49 | ||
50 | case '8': | |
51 | cps8++; | |
52 | cpp = "/usr/bin/8cpp"; | |
53 | ccom = "/usr/lib/8ccom"; | |
54 | c2 = "/usr/bin/8c2"; | |
55 | as = "/usr/bin/8as"; | |
56 | ld = "/usr/bin/8ld"; | |
57 | crt0 = "/usr/lib/8crt0"; | |
58 | continue; | |
59 | case 'S': | |
60 | sflag++; | |
61 | cflag++; | |
62 | continue; | |
63 | case 'o': | |
64 | if (++i < argc) { | |
65 | outfile = argv[i]; | |
66 | switch (getsuf(outfile)) { | |
67 | ||
68 | case 'c': | |
69 | case 'o': | |
70 | error("-o would overwrite %s", | |
71 | outfile); | |
72 | exit(8); | |
73 | } | |
74 | } | |
75 | continue; | |
76 | case 'O': | |
77 | oflag++; | |
78 | continue; | |
79 | case 'p': | |
80 | proflag++; | |
81 | continue; | |
82 | case 'g': | |
83 | gflag++; | |
84 | continue; | |
85 | case 'w': | |
86 | wflag++; | |
87 | continue; | |
88 | case 'E': | |
89 | exflag++; | |
90 | case 'P': | |
91 | pflag++; | |
92 | if (argv[i][1]=='P') | |
93 | fprintf(stderr, | |
94 | "cc: warning: -P option obsolete; you should use -E instead\n"); | |
95 | plist[np++] = argv[i]; | |
96 | case 'c': | |
97 | cflag++; | |
98 | continue; | |
99 | case 'D': | |
100 | case 'I': | |
101 | case 'U': | |
102 | case 'C': | |
103 | plist[np++] = argv[i]; | |
104 | continue; | |
105 | case 't': | |
106 | if (chpass) | |
107 | error("-t overwrites earlier option", 0); | |
108 | chpass = argv[i]+2; | |
109 | if (chpass[0]==0) | |
110 | chpass = "012p"; | |
111 | continue; | |
112 | case 'B': | |
113 | if (npassname) | |
114 | error("-B overwrites earlier option", 0); | |
115 | npassname = argv[i]+2; | |
116 | if (npassname[0]==0) | |
117 | npassname = "/usr/c/o"; | |
118 | continue; | |
119 | case 'd': | |
120 | dflag = argv[i]; | |
121 | continue; | |
122 | } | |
123 | t = argv[i]; | |
124 | c = getsuf(t); | |
125 | if (c=='c' || c=='s' || exflag) { | |
126 | clist[nc++] = t; | |
127 | t = setsuf(t, 'o'); | |
128 | } | |
129 | if (nodup(llist, t)) { | |
130 | llist[nl++] = t; | |
131 | if (getsuf(t)=='o') | |
132 | nxo++; | |
133 | } | |
134 | } | |
135 | if (gflag) { | |
136 | if (oflag) | |
137 | fprintf(stderr, "cc: warning: -g disables -O\n"); | |
138 | oflag = 0; | |
139 | } | |
140 | if (npassname && chpass ==0) | |
141 | chpass = "012p"; | |
142 | if (chpass && npassname==0) | |
143 | npassname = "/usr/c/"; | |
144 | if (chpass) | |
145 | for (t=chpass; *t; t++) { | |
146 | switch (*t) { | |
147 | ||
148 | case '0': | |
149 | ccom = strspl(npassname, "ccom"); | |
150 | continue; | |
151 | case '2': | |
152 | c2 = strspl(npassname, "c2"); | |
153 | continue; | |
154 | case 'p': | |
155 | cpp = strspl(npassname, "cpp"); | |
156 | continue; | |
157 | } | |
158 | } | |
159 | if (proflag) | |
160 | crt0 = cps8 ? "/usr/lib/8mcrt0.o" : "/usr/new/mcrt0.o"; | |
161 | if (nc==0) | |
162 | goto nocom; | |
163 | if (signal(SIGINT, SIG_IGN) != SIG_IGN) | |
164 | signal(SIGINT, idexit); | |
165 | if (signal(SIGTERM, SIG_IGN) != SIG_IGN) | |
166 | signal(SIGTERM, idexit); | |
167 | if (pflag==0) | |
168 | sprintf(tmp0, "/tmp/ctm%05.5d", getpid()); | |
169 | tmp1 = strspl(tmp0, "1"); | |
170 | tmp2 = strspl(tmp0, "2"); | |
171 | tmp3 = strspl(tmp0, "3"); | |
172 | if (pflag==0) | |
173 | tmp4 = strspl(tmp0, "4"); | |
174 | if (oflag) | |
175 | tmp5 = strspl(tmp0, "5"); | |
176 | for (i=0; i<nc; i++) { | |
177 | if (nc > 1) { | |
178 | printf("%s:\n", clist[i]); | |
179 | fflush(stdout); | |
180 | } | |
181 | if (getsuf(clist[i]) == 's') { | |
182 | assource = clist[i]; | |
183 | goto assemble; | |
184 | } else | |
185 | assource = tmp3; | |
186 | if (pflag) | |
187 | tmp4 = setsuf(clist[i], 'i'); | |
188 | av[0] = "cpp"; av[1] = clist[i]; av[2] = exflag ? "-" : tmp4; | |
189 | na = 3; | |
190 | for (j = 0; j < np; j++) | |
191 | av[na++] = plist[j]; | |
192 | av[na++] = 0; | |
193 | if (callsys(cpp, av)) { | |
194 | exfail++; | |
195 | eflag++; | |
196 | } | |
197 | if (pflag || exfail) { | |
198 | cflag++; | |
199 | continue; | |
200 | } | |
201 | if (sflag) | |
202 | assource = tmp3 = setsuf(clist[i], 's'); | |
203 | av[0] = "ccom"; av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3; | |
204 | if (proflag) | |
205 | av[na++] = "-XP"; | |
206 | if (gflag) | |
207 | av[na++] = "-Xg"; | |
208 | if (wflag) | |
209 | av[na++] = "-w"; | |
210 | av[na] = 0; | |
211 | if (callsys(ccom, av)) { | |
212 | cflag++; | |
213 | eflag++; | |
214 | continue; | |
215 | } | |
216 | if (oflag) { | |
217 | av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; | |
218 | if (callsys(c2, av)) { | |
219 | unlink(tmp3); | |
220 | tmp3 = assource = tmp5; | |
221 | } else | |
222 | unlink(tmp5); | |
223 | } | |
224 | if (sflag) | |
225 | continue; | |
226 | assemble: | |
227 | cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); | |
228 | av[0] = "as"; av[1] = "-o"; av[2] = setsuf(clist[i], 'o'); | |
229 | av[3] = assource; na = 4; | |
230 | if (dflag) | |
231 | av[na++] = dflag; | |
232 | av[na] = 0; | |
233 | if (callsys(as, av) > 1) { | |
234 | cflag++; | |
235 | eflag++; | |
236 | continue; | |
237 | } | |
238 | } | |
239 | nocom: | |
240 | if (cflag==0 && nl!=0) { | |
241 | i = 0; | |
242 | av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3; | |
243 | if (outfile) { | |
244 | av[na++] = "-o"; | |
245 | av[na++] = outfile; | |
246 | } | |
247 | while (i < nl) | |
248 | av[na++] = llist[i++]; | |
249 | if (gflag) | |
250 | av[na++] = "-lg"; | |
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 <= DIRSIZ && 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 | } |