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