BSD 4 release
[unix-history] / usr / src / cmd / cc.c
CommitLineData
31cef89c 1static char sccsid[] = "@(#)cc.c 4.1 10/1/80";
34d9b70e
BJ
2/*
3 * cc - front end for C compiler
4 */
5#include <sys/types.h>
6#include <stdio.h>
7#include <ctype.h>
8#include <signal.h>
9#include <dir.h>
10
c6802205
BJ
11char *cpp = "/lib/cpp";
12char *ccom = "/lib/ccom";
13char *c2 = "/lib/c2";
14char *as = "/bin/as";
15char *ld = "/bin/ld";
16char *crt0 = "/lib/crt0.o";
34d9b70e
BJ
17
18char tmp0[30]; /* big enough for /tmp/ctm%05.5d */
19char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5;
20char *outfile;
21char *savestr(), *strspl(), *setsuf();
22int idexit();
23char **av, **clist, **llist, **plist;
b82dd559 24int cflag, eflag, gflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag;
34d9b70e
BJ
25char *dflag;
26int exfail;
27char *chpass;
28char *npassname;
29
30int nc, nl, np, nxo, na;
31
32#define cunlink(s) if (s) unlink(s)
33
34main(argc, argv)
35 char **argv;
36{
37 char *t;
38 char *assource;
39 int i, j, c;
40
41 /* ld currently adds upto 5 args; 10 is room to spare */
42 av = (char **)calloc(argc+10, sizeof (char **));
43 clist = (char **)calloc(argc, sizeof (char **));
44 llist = (char **)calloc(argc, sizeof (char **));
45 plist = (char **)calloc(argc, sizeof (char **));
46 for (i = 1; i < argc; i++) {
47 if (*argv[i] == '-') switch (argv[i][1]) {
48
34d9b70e
BJ
49 case 'S':
50 sflag++;
51 cflag++;
52 continue;
53 case 'o':
54 if (++i < argc) {
55 outfile = argv[i];
56 switch (getsuf(outfile)) {
57
58 case 'c':
59 case 'o':
60 error("-o would overwrite %s",
61 outfile);
62 exit(8);
63 }
64 }
65 continue;
b82dd559
BJ
66 case 'R':
67 Rflag++;
68 continue;
34d9b70e
BJ
69 case 'O':
70 oflag++;
71 continue;
72 case 'p':
73 proflag++;
74 continue;
75 case 'g':
76 gflag++;
77 continue;
78 case 'w':
79 wflag++;
80 continue;
81 case 'E':
82 exflag++;
83 case 'P':
84 pflag++;
85 if (argv[i][1]=='P')
86 fprintf(stderr,
87 "cc: warning: -P option obsolete; you should use -E instead\n");
88 plist[np++] = argv[i];
89 case 'c':
90 cflag++;
91 continue;
92 case 'D':
93 case 'I':
94 case 'U':
95 case 'C':
96 plist[np++] = argv[i];
97 continue;
98 case 't':
99 if (chpass)
100 error("-t overwrites earlier option", 0);
101 chpass = argv[i]+2;
102 if (chpass[0]==0)
103 chpass = "012p";
104 continue;
105 case 'B':
106 if (npassname)
107 error("-B overwrites earlier option", 0);
108 npassname = argv[i]+2;
109 if (npassname[0]==0)
110 npassname = "/usr/c/o";
111 continue;
112 case 'd':
113 dflag = argv[i];
114 continue;
115 }
116 t = argv[i];
117 c = getsuf(t);
118 if (c=='c' || c=='s' || exflag) {
119 clist[nc++] = t;
120 t = setsuf(t, 'o');
121 }
122 if (nodup(llist, t)) {
123 llist[nl++] = t;
124 if (getsuf(t)=='o')
125 nxo++;
126 }
127 }
128 if (gflag) {
129 if (oflag)
130 fprintf(stderr, "cc: warning: -g disables -O\n");
131 oflag = 0;
132 }
133 if (npassname && chpass ==0)
134 chpass = "012p";
135 if (chpass && npassname==0)
c6802205 136 npassname = "/usr/new";
34d9b70e
BJ
137 if (chpass)
138 for (t=chpass; *t; t++) {
139 switch (*t) {
140
141 case '0':
142 ccom = strspl(npassname, "ccom");
143 continue;
144 case '2':
145 c2 = strspl(npassname, "c2");
146 continue;
147 case 'p':
148 cpp = strspl(npassname, "cpp");
149 continue;
150 }
151 }
152 if (proflag)
c6802205 153 crt0 = "/lib/mcrt0.o";
34d9b70e
BJ
154 if (nc==0)
155 goto nocom;
156 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
157 signal(SIGINT, idexit);
158 if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
159 signal(SIGTERM, idexit);
160 if (pflag==0)
161 sprintf(tmp0, "/tmp/ctm%05.5d", getpid());
162 tmp1 = strspl(tmp0, "1");
163 tmp2 = strspl(tmp0, "2");
164 tmp3 = strspl(tmp0, "3");
165 if (pflag==0)
166 tmp4 = strspl(tmp0, "4");
167 if (oflag)
168 tmp5 = strspl(tmp0, "5");
169 for (i=0; i<nc; i++) {
170 if (nc > 1) {
171 printf("%s:\n", clist[i]);
172 fflush(stdout);
173 }
174 if (getsuf(clist[i]) == 's') {
175 assource = clist[i];
176 goto assemble;
177 } else
178 assource = tmp3;
179 if (pflag)
180 tmp4 = setsuf(clist[i], 'i');
181 av[0] = "cpp"; av[1] = clist[i]; av[2] = exflag ? "-" : tmp4;
182 na = 3;
183 for (j = 0; j < np; j++)
184 av[na++] = plist[j];
185 av[na++] = 0;
186 if (callsys(cpp, av)) {
187 exfail++;
188 eflag++;
189 }
190 if (pflag || exfail) {
191 cflag++;
192 continue;
193 }
194 if (sflag)
195 assource = tmp3 = setsuf(clist[i], 's');
196 av[0] = "ccom"; av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3;
197 if (proflag)
198 av[na++] = "-XP";
199 if (gflag)
200 av[na++] = "-Xg";
201 if (wflag)
202 av[na++] = "-w";
203 av[na] = 0;
204 if (callsys(ccom, av)) {
205 cflag++;
206 eflag++;
207 continue;
208 }
209 if (oflag) {
210 av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0;
211 if (callsys(c2, av)) {
212 unlink(tmp3);
213 tmp3 = assource = tmp5;
214 } else
215 unlink(tmp5);
216 }
217 if (sflag)
218 continue;
219 assemble:
220 cunlink(tmp1); cunlink(tmp2); cunlink(tmp4);
221 av[0] = "as"; av[1] = "-o"; av[2] = setsuf(clist[i], 'o');
b82dd559
BJ
222 na = 3;
223 if (Rflag)
224 av[na++] = "-R";
34d9b70e
BJ
225 if (dflag)
226 av[na++] = dflag;
b82dd559 227 av[na++] = assource;
34d9b70e
BJ
228 av[na] = 0;
229 if (callsys(as, av) > 1) {
230 cflag++;
231 eflag++;
232 continue;
233 }
234 }
235nocom:
236 if (cflag==0 && nl!=0) {
237 i = 0;
238 av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3;
239 if (outfile) {
240 av[na++] = "-o";
241 av[na++] = outfile;
242 }
243 while (i < nl)
244 av[na++] = llist[i++];
245 if (gflag)
246 av[na++] = "-lg";
247 av[na++] = "-lc";
248 av[na++] = 0;
249 eflag |= callsys(ld, av);
250 if (nc==1 && nxo==1 && eflag==0)
251 unlink(setsuf(clist[0], 'o'));
252 }
253 dexit();
254}
255
256idexit()
257{
258
259 eflag = 100;
260 dexit();
261}
262
263dexit()
264{
265
266 if (!pflag) {
267 cunlink(tmp1);
268 cunlink(tmp2);
269 if (sflag==0)
270 cunlink(tmp3);
271 cunlink(tmp4);
272 cunlink(tmp5);
273 }
274 exit(eflag);
275}
276
277error(s, x)
278 char *s, *x;
279{
280 FILE *diag = exflag ? stderr : stdout;
281
282 fprintf(diag, "cc: ");
283 fprintf(diag, s, x);
284 putc('\n', diag);
285 exfail++;
286 cflag++;
287 eflag++;
288}
289
290getsuf(as)
291char as[];
292{
293 register int c;
294 register char *s;
295 register int t;
296
297 s = as;
298 c = 0;
299 while (t = *s++)
300 if (t=='/')
301 c = 0;
302 else
303 c++;
304 s -= 3;
305 if (c <= DIRSIZ && c > 2 && *s++ == '.')
306 return (*s);
307 return (0);
308}
309
310char *
311setsuf(as, ch)
312 char *as;
313{
314 register char *s, *s1;
315
316 s = s1 = savestr(as);
317 while (*s)
318 if (*s++ == '/')
319 s1 = s;
320 s[-1] = ch;
321 return (s1);
322}
323
324callsys(f, v)
325 char *f, **v;
326{
327 int t, status;
328
329 t = vfork();
330 if (t == -1) {
331 printf("No more processes\n");
332 return (100);
333 }
334 if (t == 0) {
335 execv(f, v);
336 printf("Can't find %s\n", f);
337 fflush(stdout);
338 _exit(100);
339 }
340 while (t != wait(&status))
341 ;
342 if ((t=(status&0377)) != 0 && t!=14) {
343 if (t!=2) {
344 printf("Fatal error in %s\n", f);
345 eflag = 8;
346 }
347 dexit();
348 }
349 return ((status>>8) & 0377);
350}
351
352nodup(l, os)
353 char **l, *os;
354{
355 register char *t, *s;
356 register int c;
357
358 s = os;
359 if (getsuf(s) != 'o')
360 return (1);
361 while (t = *l++) {
362 while (c = *s++)
363 if (c != *t++)
364 break;
365 if (*t==0 && c==0)
366 return (0);
367 s = os;
368 }
369 return (1);
370}
371
372#define NSAVETAB 1024
373char *savetab;
374int saveleft;
375
376char *
377savestr(cp)
378 register char *cp;
379{
380 register int len;
381
382 len = strlen(cp) + 1;
383 if (len > saveleft) {
384 saveleft = NSAVETAB;
385 if (len > saveleft)
386 saveleft = len;
387 savetab = (char *)malloc(saveleft);
388 if (savetab == 0) {
389 fprintf(stderr, "ran out of memory (savestr)\n");
390 exit(1);
391 }
392 }
393 strncpy(savetab, cp, len);
394 cp = savetab;
395 savetab += len;
396 saveleft -= len;
397 return (cp);
398}
399
400char *
401strspl(left, right)
402 char *left, *right;
403{
404 char buf[BUFSIZ];
405
406 strcpy(buf, left);
407 strcat(buf, right);
408 return (savestr(buf));
409}