Research V7 development
[unix-history] / usr / src / cmd / cc.c
CommitLineData
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
12char *tmp0;
13char *tmp1;
14char *tmp2;
15char *tmp3;
16char *tmp4;
17char *tmp5;
18char *outfile;
19# define CHSPACE 1000
20char ts[CHSPACE+50];
21char *tsa = ts;
22char *tsp = ts;
23char *av[50];
24char *clist[MAXFIL];
25char *llist[MAXLIB];
26int pflag;
27int sflag;
28int cflag;
29int eflag;
30int exflag;
31int oflag;
32int proflag;
33int noflflag;
34char *chpass ;
35char *npassname ;
36char pass0[20] = "/lib/c0";
37char pass1[20] = "/lib/c1";
38char pass2[20] = "/lib/c2";
39char passp[20] = "/lib/cpp";
40char *pref = "/lib/crt0.o";
41char *copy();
42char *setsuf();
43char *strcat();
44char *strcpy();
45
46main(argc, argv)
47char *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 {
134passa:
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;
282assemble:
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 }
298nocom:
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
328idexit()
329{
330 eflag = 100;
331 dexit();
332}
333
334dexit()
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
348error(s, x)
349char *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
360getsuf(as)
361char 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
380char *
381setsuf(as, ch)
382char *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
394callsys(f, v)
395char 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
420char *
421copy(as)
422char *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
441nodup(l, os)
442char **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
461cunlink(f)
462char *f;
463{
464 if (f==NULL)
465 return;
466 unlink(f);
467}