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