1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)f77.c 5.3 (Berkeley) 1/7/86";
9: #endif
10:
11: /*
12: * f77.c
13: *
14: * Driver program for the 4.2 BSD f77 compiler.
15: *
16: * University of Utah CS Dept modification history:
17: *
18: * $Log: f77.c,v $
19: * Revision 5.4 85/12/17 19:12:14 donn
20: * Dynamically allocate buffer; add lint fixes.
21: *
22: * Revision 5.3 85/11/25 00:00:02 donn
23: * 4.3 beta
24: *
25: * Revision 5.2 85/08/10 05:16:14 donn
26: * Ifdeffed 66 code, added -r8 flag. From Jerry Berkman.
27: *
28: * Revision 5.1 85/08/10 03:32:12 donn
29: * 4.3 alpha
30: *
31: * Revision 1.14 85/03/01 00:07:57 donn
32: * Portability fix from Ralph Campbell.
33: *
34: * Revision 1.13 85/02/12 19:31:47 donn
35: * Use CATNAME to get the name of a concatenation command instead of
36: * explicitly running 'cat' -- you can get the wrong 'cat' the old way!
37: *
38: * Revision 1.12 85/01/14 06:42:30 donn
39: * Changed to call the peephole optimizer with the '-f' flag, so that
40: * floating point moves are translated to integer moves.
41: *
42: * Revision 1.11 85/01/14 04:38:59 donn
43: * Jerry's change to pass -O to f1 so it knows whether the peephole optimizer
44: * will be run. This is necessary in order to handle movf/movl translation.
45: *
46: * Revision 1.10 85/01/14 03:59:12 donn
47: * Added Jerry Berkman's fix for the '-q' flag.
48: *
49: * Revision 1.9 84/11/09 01:51:26 donn
50: * Cosmetic change to stupid() suggested by John McCarthy at Memorial
51: * University, St. Johns.
52: *
53: * Revision 1.8 84/09/14 16:02:34 donn
54: * Added changes to notice when people do 'f77 -c foo.f -o bar.o' and tell
55: * them why it doesn't do what they think it does.
56: *
57: * Revision 1.7 84/08/24 21:08:31 donn
58: * Added call to setrlimit() to prevent core dumps when not debugging.
59: * Reorganized the include file arrangment somewhat.
60: *
61: * Revision 1.6 84/08/24 20:20:24 donn
62: * Changed stupidity check on Jerry Berkman's suggestion -- now it balks if
63: * the load file exists and has a sensitive suffix.
64: *
65: * Revision 1.5 84/08/15 18:56:44 donn
66: * Added test for -O combined with -g, suggested by Raleigh Romine. To keep
67: * things simple, if both are specified then the second in the list is thrown
68: * out and the user is warned.
69: *
70: * Revision 1.4 84/08/05 21:33:15 donn
71: * Added stupidity check -- f77 won't load on a file that it's asked to
72: * compile as well.
73: *
74: * Revision 1.3 84/08/04 22:58:24 donn
75: * Improved error reporting -- we now explain why we died and what we did.
76: * Only works on 4.2. Added at the instigation of Jerry Berkman.
77: *
78: * Revision 1.2 84/07/28 13:11:24 donn
79: * Added Ralph Campbell's changes to reduce offsets to data.
80: *
81: */
82:
83: char *xxxvers[] = "\n@(#) F77 DRIVER, VERSION 4.2, 1984 JULY 28\n";
84: #include <stdio.h>
85: #include <sys/types.h>
86: #include <sys/stat.h>
87: #include <ctype.h>
88: #include <signal.h>
89:
90: #ifdef SIGPROF
91: /*
92: * Some 4.2 BSD capabilities.
93: */
94: #include <sys/time.h>
95: #include <sys/resource.h>
96: #define NOCORE 1
97: #include <sys/wait.h>
98: #define PSIGNAL 1
99: #endif
100:
101: #include "defines.h"
102: #include "machdefs.h"
103: #include "drivedefs.h"
104: #include "version.h"
105:
106: static FILEP diagfile = {stderr} ;
107: static int pid;
108: static int sigivalue = 0;
109: static int sigqvalue = 0;
110: static int sighvalue = 0;
111: static int sigtvalue = 0;
112:
113: static char *pass1name = PASS1NAME ;
114: static char *pass2name = PASS2NAME ;
115: static char *pass2opt = PASS2OPT ;
116: static char *asmname = ASMNAME ;
117: static char *ldname = LDNAME ;
118: static char * = FOOTNAME;
119: static char * = PROFFOOT;
120: static char *macroname = "m4";
121: static char *shellname = "/bin/sh";
122: static char *cppname = "/lib/cpp";
123: static char *aoutname = "a.out" ;
124: static char *temppref = TEMPPREF;
125:
126: static char *infname;
127: static char textfname[44];
128: static char asmfname[44];
129: static char asmpass2[44];
130: static char initfname[44];
131: static char sortfname[44];
132: static char prepfname[44];
133: static char objfdefault[44];
134: static char optzfname[44];
135: static char setfname[44];
136:
137: static char fflags[50] = "-";
138: static char f2flags[50];
139: static char cflags[50] = "-c";
140: #if TARGET == GCOS
141: static char eflags[30] = "system=gcos ";
142: #else
143: static char eflags[30] = "system=unix ";
144: #endif
145: static char rflags[30] = "";
146: static char lflag[3] = "-x";
147: static char *fflagp = fflags+1;
148: static char *f2flagp = f2flags;
149: static char *eflagp = eflags+12;
150: static char *rflagp = rflags;
151: static char *cppflags = "";
152: static char **cppargs;
153: static char **loadargs;
154: static char **loadp;
155:
156: static flag erred = NO;
157: static flag loadflag = YES;
158: static flag saveasmflag = NO;
159: static flag profileflag = NO;
160: static flag optimflag = NO;
161: static flag debugflag = NO;
162: static flag verbose = NO;
163: static flag fortonly = NO;
164: static flag macroflag = NO;
165: static flag sdbflag = NO;
166: static flag namesflag = YES;
167:
168: #if TARGET == PDP11
169: static flag nofloating = NO;
170: #endif
171:
172: static int ncpp;
173:
174:
175: main(argc, argv)
176: int argc;
177: char **argv;
178: {
179: register int i, n;
180: int c, status;
181: char *setdoto(), *lastchar(), *lastfield(), *copys(), *argvtos();
182: ptr ckalloc();
183: char *strcat();
184: register char *s;
185: char fortfile[20], *t;
186: char *buff;
187: int intrupt();
188: int new_aoutname = NO;
189:
190: sigivalue = signal(SIGINT, SIG_IGN) == SIG_IGN;
191: sigqvalue = signal(SIGQUIT,SIG_IGN) == SIG_IGN;
192: sighvalue = signal(SIGHUP, SIG_IGN) == SIG_IGN;
193: sigtvalue = signal(SIGTERM,SIG_IGN) == SIG_IGN;
194: enbint(intrupt);
195:
196: pid = getpid();
197: crfnames();
198:
199: cppargs = (char **) ckalloc( argc * sizeof(*cppargs) );
200: loadargs = (char **) ckalloc( (argc+20) * sizeof(*loadargs) );
201: loadargs[1] = "-X";
202: loadargs[2] = "-u";
203: #if HERE==PDP11 || HERE==VAX
204: loadargs[3] = "_MAIN_";
205: #endif
206: #if HERE == INTERDATA
207: loadargs[3] = "main";
208: #endif
209: loadp = loadargs + 4;
210:
211: --argc;
212: ++argv;
213:
214: for (i = 0, n = 50; i < argc; ++i)
215: n += strlen(argv[i]) + 1;
216: buff = (char *) ckalloc(n);
217:
218: while(argc>0 && argv[0][0]=='-' && argv[0][1]!='\0')
219: {
220: for(s = argv[0]+1 ; *s ; ++s) switch(*s)
221: {
222: case 'T': /* use special passes */
223: switch(*++s)
224: {
225: case '1':
226: pass1name = s+1; goto endfor;
227: case '2':
228: pass2name = s+1; goto endfor;
229: case 'p':
230: pass2opt = s+1; goto endfor;
231: case 'a':
232: asmname = s+1; goto endfor;
233: case 'l':
234: ldname = s+1; goto endfor;
235: case 'F':
236: footname = s+1; goto endfor;
237: case 'm':
238: macroname = s+1; goto endfor;
239: case 't':
240: temppref = s+1; goto endfor;
241: default:
242: fatali("bad option -T%c", *s);
243: }
244: break;
245:
246: #ifdef ONLY66
247: case '6':
248: if(s[1]=='6')
249: {
250: *fflagp++ = *s++;
251: goto copyfflag;
252: }
253: else {
254: fprintf(diagfile, "invalid flag 6%c\n", s[1]);
255: done(1);
256: }
257: #endif
258:
259: case 'w':
260: if(s[1]=='6' && s[2]=='6')
261: {
262: *fflagp++ = *s++;
263: *fflagp++ = *s++;
264: }
265:
266: copyfflag:
267: case 'u':
268: case 'U':
269: case '1':
270: case 'C':
271: *fflagp++ = *s;
272: break;
273:
274: case 'O':
275: if(sdbflag)
276: {
277: fprintf(diagfile, "-O and -g are incompatible; -O ignored\n");
278: break;
279: }
280: optimflag = YES;
281: *f2flagp++ = '-';
282: *f2flagp++ = 'O';
283: *f2flagp++ = ' ';
284: #if TARGET == INTERDATA
285: *loadp++ = "-r";
286: *loadp++ = "-d";
287: #endif
288: *fflagp++ = 'O';
289: break;
290:
291: case 'N':
292: *fflagp++ = 'N';
293: if( oneof(*++s, "qxscn") )
294: *fflagp++ = *s++;
295: else {
296: fprintf(diagfile, "invalid flag -N%c\n", *s);
297: done(1);
298: }
299: while( isdigit(*s) )
300: *fflagp++ = *s++;
301: *fflagp++ = 'X';
302: goto endfor;
303:
304: case 'm':
305: if(s[1] == '4')
306: ++s;
307: macroflag = YES;
308: break;
309:
310: case 'S':
311: (void) strcat(cflags, " -S");
312: saveasmflag = YES;
313:
314: case 'c':
315: if( new_aoutname == YES ){
316: fprintf(diagfile, "-c prevents loading, -o %s ignored\n", aoutname);
317: new_aoutname = NO;
318: }
319: loadflag = NO;
320: break;
321:
322: case 'v':
323: verbose = YES;
324: fprintf(diagfile,"\nBerkeley F77, version %s\n",
325: VERSIONNUMBER);
326: break;
327:
328: case 'd':
329: debugflag = YES;
330: *fflagp++ = 'd';
331: s++;
332: while( isdigit(*s) || *s == ',' )
333: *fflagp++ = *s++;
334: *fflagp++ = 'X';
335: goto endfor;
336:
337: case 'M':
338: *loadp++ = "-M";
339: break;
340:
341: case 'g':
342: if(optimflag)
343: {
344: fprintf(diagfile, "-g and -O are incompatible; -g ignored\n");
345: break;
346: }
347: (void) strcat(cflags," -g");
348: sdbflag = YES;
349: goto copyfflag;
350:
351: case 'p':
352: profileflag = YES;
353: (void) strcat(cflags," -p");
354: *fflagp++ = 'p';
355: if(s[1] == 'g')
356: {
357: proffoot = GPRFFOOT;
358: s++;
359: }
360: break;
361:
362: case 'q':
363: namesflag = NO;
364: *fflagp++ = *s;
365: break;
366:
367: case 'o':
368: if( ! strcmp(s, "onetrip") )
369: {
370: *fflagp++ = '1';
371: goto endfor;
372: }
373: new_aoutname = YES;
374: aoutname = *++argv;
375: --argc;
376: if( loadflag == NO ){
377: fprintf(diagfile, "-c prevents loading, -o %s ignored\n", aoutname);
378: new_aoutname = NO;
379: }
380: break;
381:
382: #if TARGET == PDP11
383: case 'f':
384: nofloating = YES;
385: pass2name = NOFLPASS2;
386: break;
387: #endif
388:
389: case 'F':
390: fortonly = YES;
391: loadflag = NO;
392: break;
393: case 'D':
394: case 'I':
395: cppargs[ncpp++] = *argv;
396: goto endfor;
397:
398: case 'i':
399: if((s[1]=='2' || s[1]=='4') && s[2] == '\0')
400: {
401: *fflagp++ = *s++;
402: goto copyfflag;
403: }
404: fprintf(diagfile, "invalid flag -i%c\n", s[1]);
405: done(1);
406:
407: case 'r': /* -r8 - double the precision */
408: if(s[1] == '8' && s[2] == '\0')
409: {
410: s++;
411: goto copyfflag;
412: }
413: else
414: {
415: *loadp++ = "-r";
416: break;
417: }
418:
419: case 'l': /* letter ell--library */
420: s[-1] = '-';
421: *loadp++ = s-1;
422: goto endfor;
423:
424: case 'E': /* EFL flag argument */
425: while( *eflagp++ = *++s)
426: ;
427: *eflagp++ = ' ';
428: goto endfor;
429: case 'R':
430: while( *rflagp++ = *++s )
431: ;
432: *rflagp++ = ' ';
433: goto endfor;
434: default:
435: lflag[1] = *s;
436: *loadp++ = copys(lflag);
437: break;
438: }
439: endfor:
440: --argc;
441: ++argv;
442: }
443:
444: #ifdef NOCORE
445: if(!debugflag)
446: {
447: struct rlimit r;
448:
449: r.rlim_cur = r.rlim_max = 0;
450: (void) setrlimit(RLIMIT_CORE, &r);
451: }
452: #endif NOCORE
453:
454: *fflagp = '\0';
455:
456: if (ncpp > 0)
457: cppflags = argvtos (ncpp,cppargs);
458:
459: loadargs[0] = ldname;
460: #if TARGET == PDP11
461: if(nofloating)
462: *loadp++ = (profileflag ? NOFLPROF : NOFLFOOT);
463: else
464: #endif
465: *loadp++ = (profileflag ? proffoot : footname);
466:
467: for(i = 0 ; i<argc ; ++i)
468: switch(c = dotchar(infname = argv[i]) )
469: {
470: case 'r': /* Ratfor file */
471: case 'e': /* EFL file */
472: if( unreadable(argv[i]) )
473: {
474: erred = YES;
475: break;
476: }
477: s = fortfile;
478: t = lastfield(argv[i]);
479: while( *s++ = *t++)
480: ;
481: s[-2] = 'f';
482:
483: if(macroflag)
484: {
485: sprintf(buff, "%s %s >%s", macroname, infname, prepfname);
486: if( sys(buff) )
487: {
488: rmf(prepfname);
489: erred = YES;
490: break;
491: }
492: infname = prepfname;
493: }
494:
495: if(c == 'e')
496: sprintf(buff, "efl %s %s >%s", eflags, infname, fortfile);
497: else
498: sprintf(buff, "ratfor %s %s >%s", rflags, infname, fortfile);
499: status = sys(buff);
500: if(macroflag)
501: rmf(infname);
502: if(status)
503: {
504: erred = YES;
505: rmf(fortfile);
506: break;
507: }
508:
509: if( ! fortonly )
510: {
511: infname = argv[i] = lastfield(argv[i]);
512: *lastchar(infname) = 'f';
513:
514: if( dofort(argv[i]) )
515: erred = YES;
516: else {
517: if( nodup(t = setdoto(argv[i])) )
518: *loadp++ = t;
519: rmf(fortfile);
520: }
521: }
522: break;
523:
524: case 'F': /* C preprocessor -> Fortran file */
525: if( unreadable(argv[i]) )
526: {
527: erred = YES;
528: break;
529: }
530: s = fortfile;
531: t = lastfield(argv[i]);
532: while( *s++ = *t++)
533: ;
534: s[-2] = 'f';
535: sprintf(buff,"%s %s %s >%s", cppname, cppflags, infname, fortfile);
536: status = sys(buff);
537: if(status)
538: {
539: erred = YES;
540: rmf(fortfile);
541: break;
542: }
543:
544: if( ! fortonly )
545: {
546: infname = argv[i] = lastfield(argv[i]);
547: *lastchar(infname) = 'f';
548:
549: if ( dofort(argv[i]) )
550: erred = YES;
551: else {
552: if (nodup(t = setdoto(argv[i])) )
553: *loadp++ = t;
554: rmf(fortfile);
555: }
556: }
557: break;
558:
559: case 'f': /* Fortran file */
560: if( unreadable(argv[i]) )
561: erred = YES;
562: else if( dofort(argv[i]) )
563: erred = YES;
564: else if( nodup(t=setdoto(argv[i])) )
565: *loadp++ = t;
566: break;
567:
568: case 'c': /* C file */
569: case 's': /* Assembler file */
570: if( unreadable(argv[i]) )
571: {
572: erred = YES;
573: break;
574: }
575: #if HERE==PDP11 || HERE==VAX
576: if( namesflag == YES )
577: fprintf(diagfile, "%s:\n", argv[i]);
578: #endif
579: sprintf(buff, "cc %s %s", cflags, argv[i] );
580: if( sys(buff) )
581: erred = YES;
582: else
583: if( nodup(t = setdoto(argv[i])) )
584: *loadp++ = t;
585: break;
586:
587: case 'o':
588: if( nodup(argv[i]) )
589: *loadp++ = argv[i];
590: break;
591:
592: default:
593: if( ! strcmp(argv[i], "-o") ) {
594: aoutname = argv[++i];
595: new_aoutname = YES;
596: if( loadflag == NO ){
597: fprintf(diagfile, "-c prevents loading, -o %s ignored\n", aoutname);
598: new_aoutname = NO;
599: }
600: } else
601: *loadp++ = argv[i];
602: break;
603: }
604:
605: if( loadflag && stupid(aoutname) )
606: erred = YES;
607: if(loadflag && !erred)
608: doload(loadargs, loadp);
609: done(erred);
610: }
611:
612:
613:
614: /*
615: * argvtos() copies a list of arguments contained in an array of character
616: * strings to a single dynamically allocated string. Each argument is
617: * separated by one blank space. Returns a pointer to the string or null
618: * if out of memory.
619: */
620: #define SBUFINCR 1024
621: #define SBUFMAX 10240
622:
623: char *
624: argvtos(argc, argv)
625: char **argv;
626: int argc;
627: {
628: register char *s; /* string pointer */
629: register int i; /* string buffer pointer */
630: char *malloc(); /* memory allocator */
631: char *realloc(); /* increase size of storage */
632: char *sbuf; /* string buffer */
633: int nbytes; /* bytes of memory required */
634: int nu; /* no. of SBUFINCR units required */
635: int sbufsize; /* current size of sbuf */
636: int strlen(); /* string length */
637:
638: sbufsize = SBUFINCR;
639: if ((sbuf = malloc((unsigned)sbufsize)) == NULL)
640: {
641: fatal("out of memory (argvtos)");
642: /* NOTREACHED */
643: }
644:
645: for (i = 0; argc-- > 0; ++argv)
646: {
647: if ((nbytes = (i+strlen(*argv)+1-sbufsize)) > 0)
648: {
649: nu = (nbytes+SBUFINCR-1)/SBUFINCR;
650: sbufsize += nu * SBUFINCR;
651: if (sbufsize > SBUFMAX)
652: {
653: fatal("argument length exceeded (argvtos)");
654: /* NOTREACHED */
655: }
656: if ((sbuf = realloc(sbuf, (unsigned)sbufsize)) == NULL)
657: {
658: fatal("out of memory (argvtos)");
659: /* NOTREACHED */
660: }
661: }
662: for (s = *argv; *s != '\0'; i++, s++)
663: sbuf[i] = *s;
664: sbuf[i++] = ' ';
665: }
666: sbuf[--i] = '\0';
667: return(sbuf);
668: }
669:
670: dofort(s)
671: char *s;
672: {
673: int retcode;
674: char buff[200];
675:
676: infname = s;
677: sprintf(buff, "%s %s %s %s %s %s",
678: pass1name, fflags, s, asmfname, initfname, textfname);
679: switch( sys(buff) )
680: {
681: case 1:
682: goto error;
683: case 0:
684: break;
685: default:
686: goto comperror;
687: }
688:
689: if( dopass2() )
690: goto comperror;
691: doasm(s);
692: retcode = 0;
693:
694: ret:
695: rmf(asmfname);
696: rmf(initfname);
697: rmf(textfname);
698: return(retcode);
699:
700: error:
701: fprintf(diagfile, "\nError. No assembly.\n");
702: retcode = 1;
703: goto ret;
704:
705: comperror:
706: fprintf(diagfile, "\ncompiler error.\n");
707: retcode = 2;
708: goto ret;
709: }
710:
711:
712:
713:
714: dopass2()
715: {
716: char buff[100];
717:
718: if(verbose)
719: fprintf(diagfile, "PASS2.");
720:
721: #if FAMILY==DMR
722: sprintf(buff, "%s %s - %s", pass2name, textfname, asmpass2);
723: return( sys(buff) );
724: #endif
725:
726:
727: #if FAMILY == PCC
728: # if TARGET==INTERDATA
729: sprintf(buff, "%s -A%s <%s >%s", pass2name, setfname, textfname, asmpass2);
730: # else
731: sprintf(buff, "%s %s %s >%s",
732: pass2name, f2flags, textfname, asmpass2);
733: # endif
734: return( sys(buff) );
735: #endif
736: }
737:
738:
739:
740:
741: doasm(s)
742: char *s;
743: {
744: register char *lastc;
745: char *obj;
746: char buff[200];
747: char *lastchar(), *setdoto();
748:
749: if(*s == '\0')
750: s = objfdefault;
751: lastc = lastchar(s);
752: obj = setdoto(s);
753:
754: #if TARGET==PDP11 || TARGET==VAX
755: # ifdef PASS2OPT
756: if(optimflag)
757: {
758: sprintf(buff, "%s -f %s %s", pass2opt, asmpass2, optzfname);
759: if( sys(buff) )
760: rmf(optzfname);
761: else
762: {
763: sprintf(buff,"mv %s %s", optzfname, asmpass2);
764: if( sys(buff) )
765: fatal("can't rename optimizer output file");
766: }
767: }
768: # endif
769: #endif
770:
771: if(saveasmflag)
772: {
773: *lastc = 's';
774: #if TARGET == INTERDATA
775: sprintf(buff, "%s %s %s %s %s >%s", CATNAME, asmfname, initfname,
776: setfname, asmpass2, obj);
777: #else
778: #if TARGET == VAX
779: if (sdbflag)
780: sprintf(buff, "%s %s %s %s >%s",
781: CATNAME, asmfname, asmpass2, initfname, obj);
782: else
783: sprintf(buff, "%s %s %s %s >%s",
784: CATNAME, asmfname, initfname, asmpass2, obj);
785: #else
786: sprintf(buff, "%s %s %s %s >%s",
787: CATNAME, asmfname, initfname, asmpass2, obj);
788: #endif
789: #endif
790: if( sys(buff) )
791: fatal("can't concatenate assembly files");
792: *lastc = 'o';
793: }
794: else
795: {
796: if(verbose)
797: fprintf(diagfile, " ASM.");
798: #if TARGET == INTERDATA
799: sprintf(buff, "%s -o %s %s %s %s %s", asmname, obj, asmfname,
800: initfname, setfname, asmpass2);
801: #endif
802:
803: #if TARGET == VAX
804: /* vax assembler currently accepts only one input file */
805: if (sdbflag)
806: sprintf(buff, "%s %s %s >>%s",
807: CATNAME, asmpass2, initfname, asmfname);
808: else
809: sprintf(buff, "%s %s %s >>%s",
810: CATNAME, initfname, asmpass2, asmfname);
811: if( sys(buff) )
812: fatal("can't concatenate assembly files");
813: #ifdef UCBVAXASM
814: sprintf(buff, "%s -J -o %s %s", asmname, obj, asmfname);
815: #else
816: sprintf(buff, "%s -o %s %s", asmname, obj, asmfname);
817: #endif
818: #endif
819:
820: #if TARGET == PDP11
821: sprintf(buff, "%s -u -o %s %s %s", asmname, obj, asmfname, asmpass2);
822: #endif
823:
824: #if TARGET!=INTERDATA && TARGET!=PDP11 && TARGET!=VAX
825: sprintf(buff, "%s -o %s %s %s", asmname, obj, asmfname, asmpass2);
826: #endif
827:
828: if( sys(buff) )
829: fatal("assembler error");
830: if(verbose)
831: fprintf(diagfile, "\n");
832: #if HERE==PDP11 && TARGET!=PDP11
833: rmf(obj);
834: #endif
835: }
836:
837: rmf(asmpass2);
838: }
839:
840:
841:
842: doload(v0, v)
843: register char *v0[], *v[];
844: {
845: char **p;
846: int waitpid;
847:
848: if(sdbflag)
849: *v++ = "-lg";
850: if (profileflag)
851: {
852: for(p = p_liblist ; *p ; *v++ = *p++)
853: ;
854: }
855: else {
856: for(p = liblist ; *p ; *v++ = *p++)
857: ;
858: }
859:
860: *v++ = "-o";
861: *v++ = aoutname;
862: *v = NULL;
863:
864: if(verbose)
865: fprintf(diagfile, "LOAD.");
866: if(debugflag)
867: {
868: for(p = v0 ; p<v ; ++p)
869: fprintf(diagfile, "%s ", *p);
870: fprintf(diagfile, "\n");
871: }
872:
873: #if HERE==PDP11 || HERE==INTERDATA || HERE==VAX
874: if( (waitpid = fork()) == 0)
875: {
876: enbint(SIG_DFL);
877: execv(ldname, v0);
878: fatalstr("couldn't load %s", ldname);
879: }
880: if( await(waitpid) )
881: erred = YES;
882: #endif
883:
884: #if HERE==INTERDATA
885: if(optimflag)
886: {
887: char buff1[100], buff2[100];
888: sprintf(buff1, "nopt %s -o junk.%d", aoutname, pid);
889: sprintf(buff2, "mv junk.%d %s", pid, aoutname);
890: if( sys(buff1) || sys(buff2) )
891: err("bad optimization");
892: }
893: #endif
894:
895: if(verbose)
896: fprintf(diagfile, "\n");
897: }
898:
899: /* Process control and Shell-simulating routines */
900:
901: sys(str)
902: char *str;
903: {
904: register char *s, *t;
905: char *argv[100], path[100];
906: char *inname, *outname;
907: int append;
908: int waitpid;
909: int argc;
910:
911:
912: if(debugflag)
913: fprintf(diagfile, "%s\n", str);
914: inname = NULL;
915: outname = NULL;
916: argv[0] = shellname;
917: argc = 1;
918:
919: t = str;
920: while( isspace(*t) )
921: ++t;
922: while(*t)
923: {
924: if(*t == '<')
925: inname = t+1;
926: else if(*t == '>')
927: {
928: if(t[1] == '>')
929: {
930: append = YES;
931: outname = t+2;
932: }
933: else {
934: append = NO;
935: outname = t+1;
936: }
937: }
938: else
939: argv[argc++] = t;
940: while( !isspace(*t) && *t!='\0' )
941: ++t;
942: if(*t)
943: {
944: *t++ = '\0';
945: while( isspace(*t) )
946: ++t;
947: }
948: }
949:
950: if(argc == 1) /* no command */
951: return(-1);
952: argv[argc] = 0;
953:
954: s = path;
955: t = "/usr/bin/";
956: while(*t)
957: *s++ = *t++;
958: for(t = argv[1] ; *s++ = *t++ ; )
959: ;
960: if((waitpid = fork()) == 0)
961: {
962: if(inname)
963: if(freopen(inname, "r", stdin) == NULL)
964: fatalstr("Cannot open %s", inname);
965: if(outname)
966: if(freopen(outname, (append ? "a" : "w"), stdout) == NULL)
967: fatalstr("Cannot open %s", outname);
968: enbint(SIG_DFL);
969:
970: texec(path+9, argv); /* command */
971: texec(path+4, argv); /* /bin/command */
972: texec(path , argv); /* /usr/bin/command */
973:
974: fatalstr("Cannot load %s",path+9);
975: }
976:
977: return( await(waitpid) );
978: }
979:
980:
981:
982:
983:
984: #include "errno.h"
985:
986: /* modified version from the Shell */
987: texec(f, av)
988: char *f;
989: char **av;
990: {
991: extern int errno;
992:
993: execv(f, av+1);
994:
995: if (errno==ENOEXEC)
996: {
997: av[1] = f;
998: execv(shellname, av);
999: fatal("No shell!");
1000: }
1001: if (errno==ENOMEM)
1002: fatalstr("%s: too large", f);
1003: }
1004:
1005:
1006:
1007:
1008:
1009:
1010: done(k)
1011: int k;
1012: {
1013: static int recurs = NO;
1014:
1015: if(recurs == NO)
1016: {
1017: recurs = YES;
1018: rmfiles();
1019: }
1020: exit(k);
1021: }
1022:
1023:
1024:
1025:
1026:
1027:
1028: enbint(k)
1029: int (*k)();
1030: {
1031: if(sigivalue == 0)
1032: (void) signal(SIGINT,k);
1033: if(sigqvalue == 0)
1034: (void) signal(SIGQUIT,k);
1035: if(sighvalue == 0)
1036: (void) signal(SIGHUP,k);
1037: if(sigtvalue == 0)
1038: (void) signal(SIGTERM,k);
1039: }
1040:
1041:
1042:
1043:
1044: intrupt()
1045: {
1046: done(2);
1047: }
1048:
1049:
1050: #ifdef PSIGNAL
1051: /*
1052: * Fancy 4.2 BSD signal printing stuff.
1053: */
1054: char harmless[NSIG] = { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1055: #endif
1056:
1057:
1058: await(waitpid)
1059: int waitpid;
1060: {
1061:
1062: #ifdef PSIGNAL
1063: extern char *sys_siglist[];
1064: union wait status;
1065: #else PSIGNAL
1066: int status;
1067: #endif PSIGNAL
1068:
1069: int w;
1070:
1071: enbint(SIG_IGN);
1072: while ( (w = wait(&status)) != waitpid)
1073: if(w == -1)
1074: fatal("bad wait code");
1075: enbint(intrupt);
1076:
1077: #ifdef PSIGNAL
1078: if(status.w_termsig)
1079: {
1080: debugflag = 0; /* Prevent us from dumping core ourselves */
1081: if(status.w_termsig != SIGINT && status.w_termsig < NSIG)
1082: fprintf(diagfile, "%s%s\n", sys_siglist[status.w_termsig],
1083: status.w_coredump ? " -- core dumped" : "");
1084: if(status.w_termsig < NSIG && ! harmless[status.w_termsig])
1085: fatal("see a system manager");
1086: else
1087: done(3);
1088: }
1089: return(status.w_retcode);
1090: #else PSIGNAL
1091: if(status & 0377)
1092: {
1093: if(status != SIGINT)
1094: fprintf(diagfile, "Termination code %d\n", status);
1095: done(3);
1096: }
1097: return(status>>8);
1098: #endif PSIGNAL
1099: }
1100:
1101: /* File Name and File Manipulation Routines */
1102:
1103: unreadable(s)
1104: register char *s;
1105: {
1106: register FILE *fp;
1107:
1108: if(fp = fopen(s, "r"))
1109: {
1110: fclose(fp);
1111: return(NO);
1112: }
1113:
1114: else
1115: {
1116: fprintf(diagfile, "Error: Cannot read file %s\n", s);
1117: return(YES);
1118: }
1119: }
1120:
1121:
1122:
1123: stupid(s)
1124: char *s;
1125: {
1126: char c;
1127: extern char *index();
1128:
1129: if( (c = dotchar(s))
1130: && index("focsreF", c)
1131: && access(s, 0) == 0 )
1132: {
1133: fprintf(diagfile, "Loading on %s would destroy it\n", s);
1134: return(YES);
1135: }
1136: return(NO);
1137: }
1138:
1139:
1140:
1141: clf(p)
1142: FILEP *p;
1143: {
1144: if(p!=NULL && *p!=NULL && *p!=stdout)
1145: {
1146: if(ferror(*p))
1147: fatal("writing error");
1148: fclose(*p);
1149: }
1150: *p = NULL;
1151: }
1152:
1153: rmfiles()
1154: {
1155: rmf(textfname);
1156: rmf(asmfname);
1157: rmf(initfname);
1158: rmf(asmpass2);
1159: #if TARGET == INTERDATA
1160: rmf(setfname);
1161: #endif
1162: }
1163:
1164:
1165:
1166:
1167:
1168:
1169:
1170:
1171: /* return -1 if file does not exist, 0 if it is of zero length
1172: and 1 if of positive length
1173: */
1174: content(filename)
1175: char *filename;
1176: {
1177: #ifdef VERSION6
1178: struct stat
1179: {
1180: char cjunk[9];
1181: char size0;
1182: int size1;
1183: int ijunk[12];
1184: } buf;
1185: #else
1186: struct stat buf;
1187: #endif
1188:
1189: if(stat(filename,&buf) < 0)
1190: return(-1);
1191: #ifdef VERSION6
1192: return(buf.size0 || buf.size1);
1193: #else
1194: return( buf.st_size > 0 );
1195: #endif
1196: }
1197:
1198:
1199:
1200:
1201: crfnames()
1202: {
1203: fname(textfname, "x");
1204: fname(asmfname, "s");
1205: fname(asmpass2, "a");
1206: fname(initfname, "d");
1207: fname(sortfname, "S");
1208: fname(objfdefault, "o");
1209: fname(prepfname, "p");
1210: fname(optzfname, "z");
1211: fname(setfname, "A");
1212: }
1213:
1214:
1215:
1216:
1217: rmf(fn)
1218: register char *fn;
1219: {
1220: /* if(!debugflag && fn!=NULL && *fn!='\0') */
1221:
1222: if(fn!=NULL && *fn!='\0')
1223: unlink(fn);
1224: }
1225:
1226:
1227:
1228:
1229:
1230: LOCAL fname(name, suff)
1231: char *name, *suff;
1232: {
1233: sprintf(name, "/tmp/%s%d.%s", temppref, pid, suff);
1234: }
1235:
1236:
1237:
1238:
1239: dotchar(s)
1240: register char *s;
1241: {
1242: for( ; *s ; ++s)
1243: if(s[0]=='.' && s[1]!='\0' && s[2]=='\0')
1244: return( s[1] );
1245: return(NO);
1246: }
1247:
1248:
1249:
1250: char *lastfield(s)
1251: register char *s;
1252: {
1253: register char *t;
1254: for(t = s; *s ; ++s)
1255: if(*s == '/')
1256: t = s+1;
1257: return(t);
1258: }
1259:
1260:
1261:
1262: char *lastchar(s)
1263: register char *s;
1264: {
1265: while(*s)
1266: ++s;
1267: return(s-1);
1268: }
1269:
1270: char *setdoto(s)
1271: register char *s;
1272: {
1273: *lastchar(s) = 'o';
1274: return( lastfield(s) );
1275: }
1276:
1277:
1278:
1279: badfile(s)
1280: char *s;
1281: {
1282: fatalstr("cannot open intermediate file %s", s);
1283: }
1284:
1285:
1286:
1287: ptr ckalloc(n)
1288: int n;
1289: {
1290: ptr p;
1291: extern char *calloc();
1292:
1293: if( p = (ptr) calloc(1, (unsigned) n) )
1294: return(p);
1295:
1296: fatal("out of memory");
1297: /* NOTREACHED */
1298: }
1299:
1300:
1301:
1302:
1303:
1304: char *copyn(n, s)
1305: register int n;
1306: register char *s;
1307: {
1308: register char *p, *q;
1309:
1310: p = q = (char *) ckalloc(n);
1311: while(n-- > 0)
1312: *q++ = *s++;
1313: return(p);
1314: }
1315:
1316:
1317:
1318: char *copys(s)
1319: char *s;
1320: {
1321: return( copyn( strlen(s)+1 , s) );
1322: }
1323:
1324:
1325:
1326:
1327:
1328: oneof(c,s)
1329: register c;
1330: register char *s;
1331: {
1332: while( *s )
1333: if(*s++ == c)
1334: return(YES);
1335: return(NO);
1336: }
1337:
1338:
1339:
1340: nodup(s)
1341: char *s;
1342: {
1343: register char **p;
1344:
1345: for(p = loadargs ; p < loadp ; ++p)
1346: if( !strcmp(*p, s) )
1347: return(NO);
1348:
1349: return(YES);
1350: }
1351:
1352:
1353:
1354: static fatal(t)
1355: char *t;
1356: {
1357: fprintf(diagfile, "Compiler error in file %s: %s\n", infname, t);
1358: if(debugflag)
1359: abort();
1360: done(1);
1361: exit(1);
1362: }
1363:
1364:
1365:
1366:
1367: static fatali(t,d)
1368: char *t;
1369: int d;
1370: {
1371: char buff[100];
1372: sprintf(buff, t, d);
1373: fatal(buff);
1374: }
1375:
1376:
1377:
1378:
1379: static fatalstr(t, s)
1380: char *t, *s;
1381: {
1382: char buff[100];
1383: sprintf(buff, t, s);
1384: fatal(buff);
1385: }
1386: err(s)
1387: char *s;
1388: {
1389: fprintf(diagfile, "Error in file %s: %s\n", infname, s);
1390: }