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