|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)cc.c 1.1 86/02/03 SMI"; /* from UCB 4.7 83/07/01 */
3: #endif
4: /*
5: * cc - front end for C compiler
6: */
7: #include <sys/param.h>
8: #include <stdio.h>
9: #include <ctype.h>
10: #include <signal.h>
11: #include <sys/dir.h>
12:
13: char *cpp = "/lib/cpp";
14: char *count = "/usr/lib/bb_count";
15: char *ccom = "/lib/ccom";
16: char *c2 = "/lib/c2";
17: char *as = "/bin/as";
18: char *ld = "/bin/ld";
19: char *libc = "-lc";
20: char *crt0 = "/lib/crt0.o";
21: char *gcrt0 = "/lib/gcrt0.o";
22: char *mcrt0 = "/lib/mcrt0.o";
23:
24: char tmp0[30]; /* big enough for /tmp/ctm%05.5d */
25: char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5, *tmp6;
26: char *outfile;
27: char *savestr(), *strspl(), *setsuf();
28: int idexit();
29: char **av, **clist, **llist, **plist;
30: int cflag, eflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag;
31: int aflag;
32: int gproflag, gflag, Gflag;
33: int vflag;
34:
35: /*
36: * Added to support NRTX
37: */
38: char *libdir;
39: char *expandlib();
40: int nrtxflag;
41: int nofloatcrtflag;
42: #ifdef mc68000
43:
44: /*
45: * starting in release 3.0, we must figure out what kind of processor
46: * we are running on, and generate code accordingly. This requires
47: * some magic routines from libc.a
48: */
49: int is68020(); /* returns 1 if the host is a 68020 */
50:
51: struct mach_info {
52: char *optname;
53: int found;
54: int isatype;
55: char *crt1;
56: };
57:
58: struct mach_info machopts[] = {
59: "-m68010", 0, 1, (char*)0, /* use 68010 subset */
60: "-m68020", 0, 1, (char*)0, /* use 68020 extensions */
61: (char*)0
62: };
63:
64: struct mach_info floatopts[] = {
65: "", /*fpa*/ 0, 1, "Wcrt1.o", /* sun fpa */
66: "-f68881", 0, 1, "Mcrt1.o", /* 68881 */
67: "-fsky", 0, 1, "Scrt1.o", /* sky board */
68: "-fsoft", 0, 1, "Fcrt1.o", /* software floating point */
69: "-fswitch", 0, 1, (char*)0, /* switched floating point */
70: "-fsingle", 0, 0, (char*)0, /* single precision float */
71: "-fsingle2", 0, 0, (char*)0, /* pass float args as floats */
72: (char *)0 ,
73: };
74:
75: extern char *getenv();
76: char *FLOAT_OPTION = "FLOAT_OPTION";
77: struct mach_info *machtype=NULL; /* selected target machine type */
78: struct mach_info *fptype=NULL; /* selected floating pt machine type */
79: struct mach_info *default_machtype(); /* default target machine type */
80: struct mach_info *default_fptype(); /* default floating point machine */
81:
82: #define M_68010 &machopts[0]
83: #define M_68020 &machopts[1]
84: #define F_fpa &floatopts[0]
85: #define F_68881 &floatopts[1]
86: #define F_sky &floatopts[2]
87: #define F_soft &floatopts[3]
88: #define F_switch &floatopts[4]
89:
90: #define use68010 (machtype == M_68010)
91: #define use68020 (machtype == M_68020)
92:
93: #define unsupported(machtype, fptype) \
94: ( machtype == M_68010 && fptype == F_fpa \
95: || machtype == M_68020 && fptype == F_sky )
96:
97: #endif
98: char *dflag;
99: int exfail;
100: char *chpass;
101: char *npassname;
102: char *ccname;
103:
104: int nc, nl, np, nxo, na;
105:
106: #define cunlink(s) if (s) unlink(s)
107:
108: main(argc, argv)
109: register int argc;
110: register char **argv;
111: {
112: char *t;
113: char *assource;
114: register int i, j, c, tmpi;
115: register struct mach_info *mp;
116: int optfound;
117:
118: /* ld currently adds upto 5 args; 10 is room to spare */
119: av = (char **)calloc(argc+20, sizeof (char **));
120: clist = (char **)calloc(argc, sizeof (char **));
121: llist = (char **)calloc(argc, sizeof (char **));
122: plist = (char **)calloc(argc, sizeof (char **));
123: ccname = argv[0];
124: for (i = 1; i < argc; i++) {
125: if (*argv[i] == '-') switch (argv[i][1]) {
126:
127: case 'S':
128: sflag++;
129: cflag++;
130: continue;
131: case 'o':
132: if (++i < argc) {
133: outfile = argv[i];
134: switch (getsuf(outfile)) {
135:
136: case 'c':
137: case 'o':
138: error("-o would overwrite %s",
139: outfile);
140: exit(8);
141: }
142: }
143: continue;
144: case 'R':
145: Rflag++;
146: continue;
147: case 'O':
148: /*
149: * There might be further chars after -O; we just
150: * pass them on to c2 as an extra argument -- later.
151: */
152: oflag++;
153: continue;
154: case 'p':
155: proflag++;
156: if (argv[i][2] == 'g'){
157: crt0 = gcrt0;
158: gproflag++;
159: } else {
160: crt0 = mcrt0;
161: }
162: continue;
163: case 'g':
164: if (argv[i][2] == 'o') {
165: Gflag++; /* old format for -go */
166: } else {
167: gflag++; /* new format for -g */
168: }
169: continue;
170: case 'w':
171: wflag++;
172: continue;
173: case 'E':
174: exflag++;
175: case 'P':
176: pflag++;
177: if (argv[i][1]=='P')
178: fprintf(stderr,
179: "%s: warning: -P option obsolete; you should use -E instead\n", ccname);
180: plist[np++] = argv[i];
181: case 'c':
182: cflag++;
183: continue;
184: case 'D':
185: case 'I':
186: case 'U':
187: case 'C':
188: plist[np++] = argv[i];
189: continue;
190: case 't':
191: if (chpass)
192: error("-t overwrites earlier option", 0);
193: chpass = argv[i]+2;
194: if (chpass[0]==0)
195: chpass = "012palc";
196: continue;
197: case 'f':
198: #ifdef mc68000
199: /*
200: * floating point option switches
201: */
202: optfound = 0;
203: for (mp = floatopts; mp->optname; mp++) {
204: if (!strcmp(argv[i], mp->optname)){
205: if (mp->isatype) {
206: if (fptype != NULL && fptype != mp) {
207: error("%s overwrites earlier option",
208: mp->optname);
209: }
210: fptype = mp;
211: } else {
212: mp->found = 1;
213: }
214: optfound = 1;
215: break;
216: }
217: }
218: if (!optfound) {
219: if (argv[i][2] == '\0') {
220: fprintf(stderr,
221: "%s: warning: -f option is obsolete\n",
222: ccname);
223: } else {
224: fprintf(stderr,
225: "%s: warning: %s option not recognized\n",
226: ccname, argv[i]);
227: }
228: }
229: continue;
230: #else !mc68000
231: fprintf(stderr,
232: "%s: warning: -f option is obsolete\n",
233: ccname);
234: continue;
235: #endif !mc68000
236:
237: #ifdef mc68000
238: case 'm':
239: optfound = 0;
240: for (mp = machopts; mp->optname; mp++) {
241: if (!strcmp(argv[i], mp->optname)) {
242: if (mp->isatype) {
243: if (machtype != NULL && machtype != mp) {
244: error("%s overwrites earlier option",
245: mp->optname);
246: }
247: machtype = mp;
248: } else {
249: mp->found = 1;
250: }
251: optfound = 1;
252: break;
253: }
254: }
255: if (!optfound) {
256: fprintf(stderr,
257: "%s: warning: %s option not recognized\n",
258: ccname, argv[i]);
259: }
260: continue;
261: #endif mc68000
262:
263: case 'B':
264: if (npassname)
265: error("-B overwrites earlier option", 0);
266: npassname = argv[i]+2;
267: if (npassname[0]==0)
268: npassname = "/usr/c/o";
269: continue;
270: case 'd':
271: dflag = argv[i];
272: continue;
273: case 'a':
274: aflag++;
275: continue;
276: case 'A':
277: /*
278: * There might be further chars after -A; we just
279: * pass them on to c2 as an extra argument -- later.
280: */
281: continue;
282: case 'v':
283: vflag++;
284: continue;
285: /*
286: * Local Options
287: * added by D.A. Kapilow 12/3/86 to support NRTX
288: * libraries and startoff files
289: */
290: case 'L':
291: /*
292: * Change path for -l
293: */
294: if (argv[i][2] == 'p') {
295: libdir = &argv[i][3];
296: }
297: /*
298: * Change default crt0.o
299: */
300: else if (argv[i][2] == 's') {
301: crt0 = &argv[i][3];
302: }
303: /*
304: * Set nrtxflag to avoid pulling in crt1.o with -f
305: */
306: else if (argv[i][2] == 'n') {
307: nrtxflag++;
308: }
309: /*
310: * Set nofloatcrtflag to avoid pulling in crt1.o
311: * when not using NRTX. Kludge used for cross
312: * development of version 9.
313: */
314: else if (argv[i][2] == 'f') {
315: nofloatcrtflag++;
316: }
317: continue;
318: }
319: t = argv[i];
320: c = getsuf(t);
321: if (c=='c' || c=='s' || c=='i' || exflag) {
322: clist[nc++] = t;
323: t = setsuf(t, 'o');
324: }
325: if (libdir && t[0] == '-' && t[1] == 'l') {
326: t = expandlib(libdir, &t[2]);
327: }
328: if (nodup(llist, t)) {
329: llist[nl++] = t;
330: if (getsuf(t)=='o')
331: nxo++;
332: }
333: }
334: if (gflag || Gflag) {
335: if (oflag)
336: fprintf(stderr, "%s: warning: -g disables -O\n", ccname);
337: oflag = 0;
338: }
339: #ifdef mc68000
340: /*
341: * if no machine type specified, use the default
342: */
343: if (machtype == NULL) {
344: machtype = default_machtype();
345: }
346: /*
347: * if no floating point machine type specified, use the default
348: */
349: if (fptype == NULL) {
350: fptype = default_fptype(machtype);
351: } else if (unsupported(machtype, fptype)) {
352: t = fptype->optname;
353: fptype = default_fptype(machtype);
354: fprintf(stderr,
355: "%s: warning: %s option not supported with %s; %s used\n",
356: ccname, t, machtype->optname, fptype->optname);
357: }
358: machtype->found = 1;
359: fptype->found = 1;
360: #endif mc68000
361:
362: if (npassname && chpass ==0)
363: chpass = "012palc";
364: if (chpass && npassname==0)
365: npassname = "/usr/new/";
366: if (chpass)
367: for (t=chpass; *t; t++) {
368: switch (*t) {
369:
370: case '0':
371: case '1':
372: ccom = strspl(npassname, "ccom");
373: continue;
374: case '2':
375: c2 = strspl(npassname, "c2");
376: continue;
377: case 'p':
378: cpp = strspl(npassname, "cpp");
379: continue;
380: case 'a':
381: as = strspl(npassname, "as");
382: continue;
383: case 'l':
384: ld = strspl(npassname, "ld");
385: continue;
386: case 'c':
387: libc = strspl(npassname, "libc.a");
388: continue;
389: }
390: }
391: if (nc==0)
392: goto nocom;
393: if (signal(SIGINT, SIG_IGN) != SIG_IGN)
394: signal(SIGINT, idexit);
395: if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
396: signal(SIGTERM, idexit);
397: if (pflag==0)
398: sprintf(tmp0, "/tmp/ctm%05.5d", getpid());
399: tmp1 = strspl(tmp0, "1");
400: tmp2 = strspl(tmp0, "2");
401: tmp3 = strspl(tmp0, "3");
402: if (pflag==0)
403: tmp4 = strspl(tmp0, "4");
404: if (oflag)
405: tmp5 = strspl(tmp0, "5");
406: for (i=0; i<nc; i++) {
407: int suffix = getsuf(clist[i]);
408: if (nc > 1) {
409: printf("%s:\n", clist[i]);
410: fflush(stdout);
411: }
412: if (suffix == 's') {
413: assource = clist[i];
414: goto assemble;
415: } else
416: assource = tmp3;
417: if (suffix == 'i')
418: goto compile;
419: if (pflag)
420: tmp4 = setsuf(clist[i], 'i');
421: av[0] = "cpp"; av[1] = clist[i]; av[2] = exflag ? "-" : tmp4;
422: na = 3;
423: for (j = 0; j < np; j++)
424: av[na++] = plist[j];
425: av[na++] = 0;
426: if (callsys(cpp, av)) {
427: exfail++;
428: eflag++;
429: }
430: if (pflag || exfail) {
431: cflag++;
432: continue;
433: }
434: compile:
435:
436: /*
437: * Call the bb_count preprocessor
438: */
439: if (aflag) {
440: tmp6 = strspl(tmp0, "6");
441: av[0] = "bb_count";
442: av[1] = tmp4;
443: av[2] = clist[i];
444: av[3] = tmp6;
445: av[4] = 0;
446: if (callsys(count, av)) {
447: exfail++;
448: eflag++;
449: }
450: if (pflag || exfail) {
451: cflag++;
452: continue;
453: }
454: }
455: if (sflag)
456: assource = tmp3 = setsuf(clist[i], 's');
457: av[0] = "ccom";
458: av[1] = aflag? tmp6: (suffix=='i'? clist[i] : tmp4);
459: av[2] = oflag? tmp5: tmp3;
460: na = 3;
461: if (proflag)
462: av[na++] = "-XP";
463: if (gflag) {
464: av[na++] = "-Xg";
465: } else if (Gflag) {
466: av[na++] = "-XG";
467: } if (wflag)
468: av[na++] = "-w";
469: #ifdef mc68000
470: /* pass code gen options to ccom */
471: for (mp = machopts; mp->optname; mp++) {
472: if (mp->found) {
473: av[na++] = mp->optname;
474: }
475: }
476: for (mp = floatopts; mp->optname; mp++) {
477: if (mp->found) {
478: av[na++] = mp->optname;
479: }
480: }
481: #endif
482: av[na] = 0;
483: if (callsys(ccom, av)) {
484: cflag++;
485: eflag++;
486: continue;
487: }
488: if (oflag) {
489: av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; na = 3;
490: av[na++] = (use68020 ? "-20" : "-10");
491: /* Pass -Oxxx arguments to optimizer */
492: for (tmpi = 1; tmpi < argc; tmpi++) {
493: if (argv[tmpi][0] == '-'
494: && argv[tmpi][1] == 'O'
495: && argv[tmpi][2] != '\0') {
496: av[na++] = argv[tmpi]+2;
497: }
498: }
499: av[na] = 0;
500: if (callsys(c2, av)) {
501: unlink(tmp3);
502: tmp3 = assource = tmp5;
503: } else
504: unlink(tmp5);
505: }
506: if (sflag)
507: continue;
508: assemble:
509: cunlink(tmp1); cunlink(tmp2); cunlink(tmp4);
510: av[0] = "as"; av[1] = "-o"; av[2] = setsuf(clist[i], 'o');
511: na = 3;
512: av[na++] = (use68020 ? "-20" : "-10");
513: if (Rflag)
514: av[na++] = "-R";
515: if (dflag)
516: av[na++] = dflag;
517: /* Pass -Axxx arguments to assembler */
518: for (tmpi = 1; tmpi < argc; tmpi++) {
519: if (argv[tmpi][0] == '-'
520: && argv[tmpi][1] == 'A'
521: && argv[tmpi][2] != '\0') {
522: av[na++] = argv[tmpi]+2;
523: }
524: }
525: av[na++] = assource;
526: av[na] = 0;
527: if (callsys(as, av) > 1) {
528: cflag++;
529: eflag++;
530: continue;
531: }
532: }
533: nocom:
534: if (cflag==0 && nl!=0) {
535: i = 0;
536: na = 0;
537: av[na++] = "ld";
538: av[na++] = "-X";
539: if (nrtxflag) {
540: av[na++] = "-r";
541: av[na++] = "-d";
542: }
543: av[na++] = crt0;
544: /*
545: if (fptype->crt1 != NULL && !nrtxflag && !nofloatcrtflag) {
546: av[na++] = strspl("/lib/", fptype->crt1);
547: }
548: */
549: if (outfile) {
550: av[na++] = "-o";
551: av[na++] = outfile;
552: }
553: while (i < nl)
554: av[na++] = llist[i++];
555: if (aflag)
556: av[na++] = "/usr/lib/bb_link.o";
557: if (gflag || Gflag) {
558: if (libdir)
559: av[na++] = expandlib(libdir, "g");
560: else
561: av[na++] = "-lg";
562: }
563: if (proflag) {
564: if (libdir)
565: av[na++] = expandlib(libdir, "c_p");
566: else
567: av[na++] = "-lc_p";
568: }
569: else {
570: if (libdir && libc[0] == '-' && libc[1] == 'l')
571: av[na++] = expandlib(libdir, &libc[2]);
572: else
573: av[na++] = libc;
574: }
575: av[na++] = 0;
576: eflag |= callsys(ld, av);
577: if (nc==1 && nxo==1 && eflag==0)
578: unlink(setsuf(clist[0], 'o'));
579: }
580: dexit();
581: }
582:
583: #ifdef mc68000
584:
585: /*
586: * default target machine type is the same as host
587: */
588: struct mach_info *
589: default_machtype()
590: {
591: return (is68020()? M_68020 : M_68010);
592: }
593:
594: /*
595: * Floating point is such a zoo on this machine that
596: * nobody agrees what the default should be. So let
597: * the user decide, and to hell with it.
598: */
599: struct mach_info *
600: default_fptype(mtp)
601: struct mach_info *mtp;
602: {
603: register char *env_string;
604: register struct mach_info *ftp;
605:
606: env_string = getenv(FLOAT_OPTION);
607: if (env_string == NULL) {
608: return (F_soft);
609: }
610: for(ftp = floatopts; ftp->isatype; ftp++) {
611: if (!strcmp(ftp->optname+1, env_string)) {
612: if (unsupported(mtp, ftp)) {
613: ftp = F_soft;
614: fprintf(stderr,
615: "%s: warning: FLOAT_OPTION=%s not supported with %s; %s used\n",
616: ccname, env_string, mtp->optname+1, ftp->optname+1);
617: }
618: return(ftp);
619: }
620: }
621: ftp = F_soft;
622: fprintf(stderr,
623: "%s: warning: FLOAT_OPTION=%s not recognized; %s used\n",
624: ccname, env_string, ftp->optname+1);
625: return(ftp);
626: }
627:
628: #endif mc68000
629:
630: idexit()
631: {
632:
633: eflag = 100;
634: dexit();
635: }
636:
637: dexit()
638: {
639:
640: if (!pflag) {
641: cunlink(tmp1);
642: cunlink(tmp2);
643: if (sflag==0)
644: cunlink(tmp3);
645: cunlink(tmp4);
646: cunlink(tmp5);
647: cunlink(tmp6);
648: }
649: exit(eflag);
650: }
651:
652: /*VARARGS1*/
653: error(s, x1, x2, x3, x4)
654: char *s;
655: {
656: FILE *diag = exflag ? stderr : stdout;
657:
658: fprintf(diag, "%s: ", ccname);
659: fprintf(diag, s, x1, x2, x3, x4);
660: putc('\n', diag);
661: exfail++;
662: cflag++;
663: eflag++;
664: }
665:
666: getsuf(as)
667: char as[];
668: {
669: register int c;
670: register char *s;
671: register int t;
672:
673: s = as;
674: c = 0;
675: while (t = *s++)
676: if (t=='/')
677: c = 0;
678: else
679: c++;
680: s -= 3;
681: if (c <= DIRSIZ && c > 2 && *s++ == '.')
682: return (*s);
683: return (0);
684: }
685:
686: char *
687: setsuf(as, ch)
688: char *as;
689: {
690: register char *s, *s1;
691:
692: s = s1 = savestr(as);
693: while (*s)
694: if (*s++ == '/')
695: s1 = s;
696: s[-1] = ch;
697: return (s1);
698: }
699:
700: callsys(f, v)
701: char *f, **v;
702: {
703: int t, status;
704:
705: #ifdef DEBUG
706: printf("fork %s:", f);
707: for (t = 0; v[t]; t++) printf(" %s", v[t][0]? v[t]: "(empty)");
708: printf("\n");
709: return 0;
710: #else DEBUG
711: if (vflag){
712: fprintf(stderr,"%s: ",f);
713: for (t = 0; v[t]; t++) fprintf(stderr, " %s", v[t][0]? v[t]: "(empty)");
714: fprintf(stderr, "\n");
715: }
716: fflush(stderr); /* purge any junk before the vfork */
717: t = vfork();
718: if (t == -1) {
719: fprintf( stderr, "%s: No more processes\n", ccname);
720: return (100);
721: }
722: if (t == 0) {
723: execv(f, v);
724: /*
725: * We are now in The Vfork Zone, and can't use "fprintf".
726: * We use "write" and "_perror" instead.
727: */
728: write(2, ccname, strlen(ccname));
729: write(2, ": Can't execute ", 16);
730: perror(f);
731: _exit(100);
732: }
733: while (t != wait(&status))
734: ;
735: if ((t=(status&0377)) != 0 && t!=14) {
736: if (t!=2) {
737: fprintf( stderr, "%s: Fatal error in %s\n", ccname, f);
738: eflag = 8;
739: }
740: dexit();
741: }
742: return ((status>>8) & 0377);
743: #endif DEBUG
744: }
745:
746: nodup(l, os)
747: char **l, *os;
748: {
749: register char *t, *s;
750: register int c;
751:
752: s = os;
753: if (getsuf(s) != 'o')
754: return (1);
755: while (t = *l++) {
756: while (c = *s++)
757: if (c != *t++)
758: break;
759: if (*t==0 && c==0)
760: return (0);
761: s = os;
762: }
763: return (1);
764: }
765:
766: #define NSAVETAB 1024
767: char *savetab;
768: int saveleft;
769:
770: char *
771: savestr(cp)
772: register char *cp;
773: {
774: register int len;
775:
776: len = strlen(cp) + 1;
777: if (len > saveleft) {
778: saveleft = NSAVETAB;
779: if (len > saveleft)
780: saveleft = len;
781: savetab = (char *)malloc(saveleft);
782: if (savetab == 0) {
783: fprintf(stderr, "%s: ran out of memory (savestr)\n", ccname);
784: exit(1);
785: }
786: }
787: strncpy(savetab, cp, len);
788: cp = savetab;
789: savetab += len;
790: saveleft -= len;
791: return (cp);
792: }
793:
794: char *
795: strspl(left, right)
796: char *left, *right;
797: {
798: char buf[BUFSIZ];
799:
800: strcpy(buf, left);
801: strcat(buf, right);
802: return (savestr(buf));
803: }
804:
805: char *
806: expandlib(dir, lib)
807: char *dir, *lib;
808: {
809: char buf[BUFSIZ];
810:
811: strcpy(buf, dir);
812: strcat(buf, "/lib");
813: strcat(buf, lib);
814: strcat(buf, ".a");
815: return (savestr(buf));
816: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.