Commit | Line | Data |
---|---|---|
a077d6a3 KT |
1 | # |
2 | # include <stdio.h> | |
3 | # include <ctype.h> | |
4 | # include <signal.h> | |
5 | ||
6 | /* cc command */ | |
7 | ||
8 | # define MAXINC 10 | |
9 | # define MAXFIL 100 | |
10 | # define MAXLIB 100 | |
11 | # define MAXOPT 100 | |
12 | char *tmp0; | |
13 | char *tmp1; | |
14 | char *tmp2; | |
15 | char *tmp3; | |
16 | char *tmp4; | |
17 | char *tmp5; | |
18 | char *outfile; | |
19 | # define CHSPACE 1000 | |
20 | char ts[CHSPACE+50]; | |
21 | char *tsa = ts; | |
22 | char *tsp = ts; | |
23 | char *av[50]; | |
24 | char *clist[MAXFIL]; | |
25 | char *llist[MAXLIB]; | |
26 | int pflag; | |
27 | int sflag; | |
28 | int cflag; | |
29 | int eflag; | |
30 | int exflag; | |
31 | int oflag; | |
32 | int proflag; | |
33 | int noflflag; | |
34 | char *chpass ; | |
35 | char *npassname ; | |
36 | char pass0[20] = "/lib/c0"; | |
37 | char pass1[20] = "/lib/c1"; | |
38 | char pass2[20] = "/lib/c2"; | |
39 | char passp[20] = "/lib/cpp"; | |
40 | char *pref = "/lib/crt0.o"; | |
41 | char *copy(); | |
42 | char *setsuf(); | |
43 | char *strcat(); | |
44 | char *strcpy(); | |
45 | ||
46 | main(argc, argv) | |
47 | char *argv[]; | |
48 | { | |
49 | char *t; | |
50 | char *savetsp; | |
51 | char *assource; | |
52 | char **pv, *ptemp[MAXOPT], **pvt; | |
53 | int nc, nl, i, j, c, f20, nxo, na; | |
54 | int idexit(); | |
55 | ||
56 | i = nc = nl = f20 = nxo = 0; | |
57 | setbuf(stdout, (char *)NULL); | |
58 | pv = ptemp; | |
59 | while(++i < argc) { | |
60 | if(*argv[i] == '-') switch (argv[i][1]) { | |
61 | default: | |
62 | goto passa; | |
63 | case 'S': | |
64 | sflag++; | |
65 | cflag++; | |
66 | break; | |
67 | case 'o': | |
68 | if (++i < argc) { | |
69 | outfile = argv[i]; | |
70 | if ((c=getsuf(outfile))=='c'||c=='o') { | |
71 | error("Would overwrite %s", outfile); | |
72 | exit(8); | |
73 | } | |
74 | } | |
75 | break; | |
76 | case 'O': | |
77 | oflag++; | |
78 | break; | |
79 | case 'p': | |
80 | proflag++; | |
81 | break; | |
82 | case 'E': | |
83 | exflag++; | |
84 | case 'P': | |
85 | pflag++; | |
86 | *pv++ = argv[i]; | |
87 | case 'c': | |
88 | cflag++; | |
89 | break; | |
90 | ||
91 | case 'f': | |
92 | noflflag++; | |
93 | if (npassname || chpass) | |
94 | error("-f overwrites earlier option", (char *)NULL); | |
95 | npassname = "/lib/f"; | |
96 | chpass = "1"; | |
97 | break; | |
98 | ||
99 | case '2': | |
100 | if(argv[i][2] == '\0') | |
101 | pref = "/lib/crt2.o"; | |
102 | else { | |
103 | pref = "/lib/crt20.o"; | |
104 | f20 = 1; | |
105 | } | |
106 | break; | |
107 | case 'D': | |
108 | case 'I': | |
109 | case 'U': | |
110 | case 'C': | |
111 | *pv++ = argv[i]; | |
112 | if (pv >= ptemp+MAXOPT) { | |
113 | error("Too many DIUC options", (char *)NULL); | |
114 | --pv; | |
115 | } | |
116 | break; | |
117 | case 't': | |
118 | if (chpass) | |
119 | error("-t overwrites earlier option", (char *)NULL); | |
120 | chpass = argv[i]+2; | |
121 | if (chpass[0]==0) | |
122 | chpass = "012p"; | |
123 | break; | |
124 | ||
125 | case 'B': | |
126 | if (npassname) | |
127 | error("-B overwrites earlier option", (char *)NULL); | |
128 | npassname = argv[i]+2; | |
129 | if (npassname[0]==0) | |
130 | npassname = "/usr/src/cmd/c/o"; | |
131 | break; | |
132 | } | |
133 | else { | |
134 | passa: | |
135 | t = argv[i]; | |
136 | if((c=getsuf(t))=='c' || c=='s'|| exflag) { | |
137 | clist[nc++] = t; | |
138 | if (nc>=MAXFIL) { | |
139 | error("Too many source files", (char *)NULL); | |
140 | exit(1); | |
141 | } | |
142 | t = setsuf(t, 'o'); | |
143 | } | |
144 | if (nodup(llist, t)) { | |
145 | llist[nl++] = t; | |
146 | if (nl >= MAXLIB) { | |
147 | error("Too many object/library files", (char *)NULL); | |
148 | exit(1); | |
149 | } | |
150 | if (getsuf(t)=='o') | |
151 | nxo++; | |
152 | } | |
153 | } | |
154 | } | |
155 | if (npassname && chpass ==0) | |
156 | chpass = "012p"; | |
157 | if (chpass && npassname==0) | |
158 | npassname = "/usr/src/cmd/c/"; | |
159 | if (chpass) | |
160 | for (t=chpass; *t; t++) { | |
161 | switch (*t) { | |
162 | case '0': | |
163 | strcpy (pass0, npassname); | |
164 | strcat (pass0, "c0"); | |
165 | continue; | |
166 | case '1': | |
167 | strcpy (pass1, npassname); | |
168 | strcat (pass1, "c1"); | |
169 | continue; | |
170 | case '2': | |
171 | strcpy (pass2, npassname); | |
172 | strcat (pass2, "c2"); | |
173 | continue; | |
174 | case 'p': | |
175 | strcpy (passp, npassname); | |
176 | strcat (passp, "cpp"); | |
177 | continue; | |
178 | } | |
179 | } | |
180 | if (noflflag) | |
181 | pref = proflag ? "/lib/fmcrt0.o" : "/lib/fcrt0.o"; | |
182 | else if (proflag) | |
183 | pref = "/lib/mcrt0.o"; | |
184 | if(nc==0) | |
185 | goto nocom; | |
186 | if (pflag==0) { | |
187 | tmp0 = copy("/tmp/ctm0a"); | |
188 | while (access(tmp0, 0)==0) | |
189 | tmp0[9]++; | |
190 | while((creat(tmp0, 0400))<0) { | |
191 | if (tmp0[9]=='z') { | |
192 | error("cc: cannot create temp", NULL); | |
193 | exit(1); | |
194 | } | |
195 | tmp0[9]++; | |
196 | } | |
197 | } | |
198 | if (signal(SIGINT, SIG_IGN) != SIG_IGN) | |
199 | signal(SIGINT, idexit); | |
200 | if (signal(SIGTERM, SIG_IGN) != SIG_IGN) | |
201 | signal(SIGTERM, idexit); | |
202 | (tmp1 = copy(tmp0))[8] = '1'; | |
203 | (tmp2 = copy(tmp0))[8] = '2'; | |
204 | (tmp3 = copy(tmp0))[8] = '3'; | |
205 | if (oflag) | |
206 | (tmp5 = copy(tmp0))[8] = '5'; | |
207 | if (pflag==0) | |
208 | (tmp4 = copy(tmp0))[8] = '4'; | |
209 | pvt = pv; | |
210 | for (i=0; i<nc; i++) { | |
211 | if (nc>1) | |
212 | printf("%s:\n", clist[i]); | |
213 | if (getsuf(clist[i])=='s') { | |
214 | assource = clist[i]; | |
215 | goto assemble; | |
216 | } | |
217 | else | |
218 | assource = tmp3; | |
219 | if (pflag) | |
220 | tmp4 = setsuf(clist[i], 'i'); | |
221 | savetsp = tsp; | |
222 | av[0] = "cpp"; | |
223 | av[1] = clist[i]; | |
224 | av[2] = exflag ? "-" : tmp4; | |
225 | na = 3; | |
226 | for(pv=ptemp; pv <pvt; pv++) | |
227 | av[na++] = *pv; | |
228 | av[na++]=0; | |
229 | if (callsys(passp, av)) { | |
230 | cflag++; | |
231 | eflag++; | |
232 | continue; | |
233 | } | |
234 | av[1] = tmp4; | |
235 | tsp = savetsp; | |
236 | av[0]= "c0"; | |
237 | if (pflag) { | |
238 | cflag++; | |
239 | continue; | |
240 | } | |
241 | av[2] = tmp1; | |
242 | av[3] = tmp2; | |
243 | if (proflag) { | |
244 | av[4] = "-P"; | |
245 | av[5] = 0; | |
246 | } | |
247 | else | |
248 | av[4] = 0; | |
249 | if (callsys(pass0, av)) { | |
250 | cflag++; | |
251 | eflag++; | |
252 | continue; | |
253 | } | |
254 | av[0] = "c1"; | |
255 | av[1] = tmp1; | |
256 | av[2] = tmp2; | |
257 | if (sflag) | |
258 | assource = tmp3 = setsuf(clist[i], 's'); | |
259 | av[3] = tmp3; | |
260 | if (oflag) | |
261 | av[3] = tmp5; | |
262 | av[4] = 0; | |
263 | if(callsys(pass1, av)) { | |
264 | cflag++; | |
265 | eflag++; | |
266 | continue; | |
267 | } | |
268 | if (oflag) { | |
269 | av[0] = "c2"; | |
270 | av[1] = tmp5; | |
271 | av[2] = tmp3; | |
272 | av[3] = 0; | |
273 | if (callsys(pass2, av)) { | |
274 | unlink(tmp3); | |
275 | tmp3 = assource = tmp5; | |
276 | } | |
277 | else | |
278 | unlink(tmp5); | |
279 | } | |
280 | if (sflag) | |
281 | continue; | |
282 | assemble: | |
283 | av[0] = "as"; | |
284 | av[1] = "-u"; | |
285 | av[2] = "-o"; | |
286 | av[3] = setsuf(clist[i], 'o'); | |
287 | av[4] = assource; | |
288 | av[5] = 0; | |
289 | cunlink(tmp1); | |
290 | cunlink(tmp2); | |
291 | cunlink(tmp4); | |
292 | if (callsys("/bin/as", av) > 1) { | |
293 | cflag++; | |
294 | eflag++; | |
295 | continue; | |
296 | } | |
297 | } | |
298 | nocom: | |
299 | if (cflag==0 && nl!=0) { | |
300 | i = 0; | |
301 | av[0] = "ld"; | |
302 | av[1] = "-X"; | |
303 | av[2] = pref; | |
304 | j = 3; | |
305 | if (noflflag) { | |
306 | j = 4; | |
307 | av[3] = "-lfpsim"; | |
308 | } | |
309 | if (outfile) { | |
310 | av[j++] = "-o"; | |
311 | av[j++] = outfile; | |
312 | } | |
313 | while(i<nl) | |
314 | av[j++] = llist[i++]; | |
315 | if(f20) | |
316 | av[j++] = "-l2"; | |
317 | else { | |
318 | av[j++] = "-lc"; | |
319 | } | |
320 | av[j++] = 0; | |
321 | eflag |= callsys("/bin/ld", av); | |
322 | if (nc==1 && nxo==1 && eflag==0) | |
323 | cunlink(setsuf(clist[0], 'o')); | |
324 | } | |
325 | dexit(); | |
326 | } | |
327 | ||
328 | idexit() | |
329 | { | |
330 | eflag = 100; | |
331 | dexit(); | |
332 | } | |
333 | ||
334 | dexit() | |
335 | { | |
336 | if (!pflag) { | |
337 | cunlink(tmp1); | |
338 | cunlink(tmp2); | |
339 | if (sflag==0) | |
340 | cunlink(tmp3); | |
341 | cunlink(tmp4); | |
342 | cunlink(tmp5); | |
343 | cunlink(tmp0); | |
344 | } | |
345 | exit(eflag); | |
346 | } | |
347 | ||
348 | error(s, x) | |
349 | char *s, *x; | |
350 | { | |
351 | fprintf(exflag?stderr:stdout, s, x); | |
352 | putc('\n', exflag? stderr : stdout); | |
353 | cflag++; | |
354 | eflag++; | |
355 | } | |
356 | ||
357 | ||
358 | ||
359 | ||
360 | getsuf(as) | |
361 | char as[]; | |
362 | { | |
363 | register int c; | |
364 | register char *s; | |
365 | register int t; | |
366 | ||
367 | s = as; | |
368 | c = 0; | |
369 | while(t = *s++) | |
370 | if (t=='/') | |
371 | c = 0; | |
372 | else | |
373 | c++; | |
374 | s -= 3; | |
375 | if (c<=14 && c>2 && *s++=='.') | |
376 | return(*s); | |
377 | return(0); | |
378 | } | |
379 | ||
380 | char * | |
381 | setsuf(as, ch) | |
382 | char *as; | |
383 | { | |
384 | register char *s, *s1; | |
385 | ||
386 | s = s1 = copy(as); | |
387 | while(*s) | |
388 | if (*s++ == '/') | |
389 | s1 = s; | |
390 | s[-1] = ch; | |
391 | return(s1); | |
392 | } | |
393 | ||
394 | callsys(f, v) | |
395 | char f[], *v[]; | |
396 | { | |
397 | int t, status; | |
398 | ||
399 | if ((t=fork())==0) { | |
400 | execv(f, v); | |
401 | printf("Can't find %s\n", f); | |
402 | exit(100); | |
403 | } else | |
404 | if (t == -1) { | |
405 | printf("Try again\n"); | |
406 | return(100); | |
407 | } | |
408 | while(t!=wait(&status)) | |
409 | ; | |
410 | if (t = status&0377) { | |
411 | if (t!=SIGINT) { | |
412 | printf("Fatal error in %s\n", f); | |
413 | eflag = 8; | |
414 | } | |
415 | dexit(); | |
416 | } | |
417 | return((status>>8) & 0377); | |
418 | } | |
419 | ||
420 | char * | |
421 | copy(as) | |
422 | char *as; | |
423 | { | |
424 | char *malloc(); | |
425 | register char *otsp, *s; | |
426 | ||
427 | otsp = tsp; | |
428 | s = as; | |
429 | while (*tsp++ = *s++) | |
430 | ; | |
431 | if (tsp > tsa+CHSPACE) { | |
432 | tsp = tsa = malloc(CHSPACE+50); | |
433 | if (tsp==NULL) { | |
434 | error("no space for file names", (char *)NULL); | |
435 | dexit(); | |
436 | } | |
437 | } | |
438 | return(otsp); | |
439 | } | |
440 | ||
441 | nodup(l, os) | |
442 | char **l, *os; | |
443 | { | |
444 | register char *t, *s; | |
445 | register int c; | |
446 | ||
447 | s = os; | |
448 | if (getsuf(s) != 'o') | |
449 | return(1); | |
450 | while(t = *l++) { | |
451 | while(c = *s++) | |
452 | if (c != *t++) | |
453 | break; | |
454 | if (*t=='\0' && c=='\0') | |
455 | return(0); | |
456 | s = os; | |
457 | } | |
458 | return(1); | |
459 | } | |
460 | ||
461 | cunlink(f) | |
462 | char *f; | |
463 | { | |
464 | if (f==NULL) | |
465 | return; | |
466 | unlink(f); | |
467 | } |