file reorg, pathnames.h, paths.h
[unix-history] / usr / src / usr.bin / f77 / f77.tahoe / f77.c
CommitLineData
d6724028
KB
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
61char *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"
dc0e9d50 82#include "pathnames.h"
d6724028
KB
83#include "version.h"
84
85static FILEP diagfile = {stderr} ;
86static int pid;
87static int sigivalue = 0;
88static int sigqvalue = 0;
89static int sighvalue = 0;
90static int sigtvalue = 0;
91
92static char *pass1name = PASS1NAME ;
93static char *pass2name = PASS2NAME ;
94static char *pass2opt = PASS2OPT ;
95static char *asmname = ASMNAME ;
96static char *ldname = LDNAME ;
97static char *footname = FOOTNAME;
98static char *proffoot = PROFFOOT;
99static char *macroname = "m4";
dc0e9d50
KB
100static char *shellname = _PATH_BSHELL;
101static char *cppname = _PATH_CPP;
d6724028
KB
102static char *aoutname = "a.out" ;
103static char *temppref = TEMPPREF;
104
105static char *infname;
106static char textfname[44];
107static char asmfname[44];
108static char asmpass2[44];
109static char initfname[44];
110static char sortfname[44];
111static char prepfname[44];
112static char objfdefault[44];
113static char optzfname[44];
114static char setfname[44];
115
116static char fflags[50] = "-";
117static char f2flags[50];
118static 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
124static char rflags[30] = "";
125static char lflag[3] = "-x";
126static char *fflagp = fflags+1;
127static char *f2flagp = f2flags;
128static char *cflagp = cflags+2;
129static char *eflagp = eflags+12;
130static char *rflagp = rflags;
131static char *cppflags = "";
132static char **cppargs;
133static char **loadargs;
134static char **loadp;
135
136static flag erred = NO;
137static flag loadflag = YES;
138static flag saveasmflag = NO;
139static flag profileflag = NO;
140static flag optimflag = NO;
141static flag debugflag = NO;
142static flag verbose = NO;
143static flag nofloating = NO;
144static flag fortonly = NO;
145static flag macroflag = NO;
146static flag sdbflag = NO;
147static flag namesflag = YES;
148
149static int ncpp;
150
151\f
152main(argc, argv)
153int argc;
154char **argv;
155{
156int i, c, status;
157char *setdoto(), *lastchar(), *lastfield(), *copys(), *argvtos();
158ptr ckalloc();
159register char *s;
160char fortfile[20], *t;
161char buff[100];
162int intrupt();
163int new_aoutname = NO;
164
165sigivalue = signal(SIGINT, SIG_IGN) == SIG_IGN;
166sigqvalue = signal(SIGQUIT,SIG_IGN) == SIG_IGN;
167sighvalue = signal(SIGHUP, SIG_IGN) == SIG_IGN;
168sigtvalue = signal(SIGTERM,SIG_IGN) == SIG_IGN;
169enbint(intrupt);
170
171pid = getpid();
172crfnames();
173
174cppargs = (char **) ckalloc( argc * sizeof(*cppargs) );
175loadargs = (char **) ckalloc( (argc+20) * sizeof(*loadargs) );
176loadargs[1] = "-X";
177loadargs[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
184loadp = loadargs + 4;
185
186--argc;
187++argv;
188
189while(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 }
403endfor:
404 --argc;
405 ++argv;
406 }
407
408#ifdef NOCORE
409if(!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
420if (ncpp > 0)
421 cppflags = argvtos (ncpp,cppargs);
422
423loadargs[0] = ldname;
424#if TARGET == PDP11
425 if(nofloating)
426 *loadp++ = (profileflag ? NOFLPROF : NOFLFOOT);
427 else
428#endif
429*loadp++ = (profileflag ? proffoot : footname);
430
431for(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
569if( loadflag && stupid(aoutname) )
570 erred = YES;
571if(loadflag && !erred)
572 doload(loadargs, loadp);
573done(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
587char *
588argvtos(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\f
634dofort(s)
635char *s;
636{
637int retcode;
638char buff[200];
639
640infname = s;
641sprintf(buff, "%s %s %s %s %s %s",
642 pass1name, fflags, s, asmfname, initfname, textfname);
643switch( sys(buff) )
644 {
645 case 1:
646 goto error;
647 case 0:
648 break;
649 default:
650 goto comperror;
651 }
652
653if( dopass2() )
654 goto comperror;
655doasm(s);
656retcode = 0;
657
658ret:
659 rmf(asmfname);
660 rmf(initfname);
661 rmf(textfname);
662 return(retcode);
663
664error:
665 fprintf(diagfile, "\nError. No assembly.\n");
666 retcode = 1;
667 goto ret;
668
669comperror:
670 fprintf(diagfile, "\ncompiler error.\n");
671 retcode = 2;
672 goto ret;
673}
674
675
676
677
678dopass2()
679{
680char buff[100];
681
682if(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
705doasm(s)
706char *s;
707{
708register char *lastc;
709char *obj;
710char buff[200];
711char *lastchar(), *setdoto();
712
713if(*s == '\0')
714 s = objfdefault;
715lastc = lastchar(s);
716obj = 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 {
732 sprintf(buff,"mv %s %s", optzfname, asmpass2);
733 sys(buff);
734 }
735 }
736# endif
737#endif
738
739if(saveasmflag)
740 {
741 *lastc = 's';
742#if TARGET == INTERDATA
743 sprintf(buff, "%s %s %s %s %s >%s", CATNAME, asmfname, initfname,
744 setfname, asmpass2, obj);
745#else
746#if TARGET == VAX || TARGET == TAHOE
747 sprintf(buff, "%s %s %s %s >%s",
748 CATNAME, asmfname, asmpass2, initfname, obj);
749#else
750 sprintf(buff, "%s %s %s %s >%s",
751 CATNAME, asmfname, initfname, asmpass2, obj);
752#endif
753#endif
754 sys(buff);
755 *lastc = 'o';
756 }
757else
758 {
759 if(verbose)
760 fprintf(diagfile, " ASM.");
761#if TARGET == INTERDATA
762 sprintf(buff, "%s -o %s %s %s %s %s", asmname, obj, asmfname,
763 initfname, setfname, asmpass2);
764#endif
765
766#if TARGET == VAX || TARGET == TAHOE
767 /* vax assembler currently accepts only one input file */
768
769 sprintf(buff, "%s %s %s >>%s",
770 CATNAME, asmpass2, initfname, asmfname);
771 sys(buff);
772#ifdef UCBVAXASM
773 sprintf(buff, "%s -J -o %s %s", asmname, obj, asmfname);
774#else
775 sprintf(buff, "%s -o %s %s", asmname, obj, asmfname);
776#endif
777#endif
778
779#if TARGET == PDP11
780 sprintf(buff, "%s -u -o %s %s %s", asmname, obj, asmfname, asmpass2);
781#endif
782
783#if TARGET!=INTERDATA && TARGET!=PDP11 && TARGET!=VAX && TARGET!=TAHOE
784 sprintf(buff, "%s -o %s %s %s", asmname, obj, asmfname, asmpass2);
785#endif
786
787 if( sys(buff) )
788 fatal("assembler error");
789 if(verbose)
790 fprintf(diagfile, "\n");
791#if HERE==PDP11 && TARGET!=PDP11
792 rmf(obj);
793#endif
794 }
795
796rmf(asmpass2);
797}
798
799
800
801doload(v0, v)
802register char *v0[], *v[];
803{
804char **p;
805int waitpid;
806
807if(sdbflag)
808 *v++ = "-lg";
809if (profileflag)
810 {
811 for(p = p_liblist ; *p ; *v++ = *p++)
812 ;
813 }
814else {
815 for(p = liblist ; *p ; *v++ = *p++)
816 ;
817 }
818
819*v++ = "-o";
820*v++ = aoutname;
821*v = NULL;
822
823if(verbose)
824 fprintf(diagfile, "LOAD.");
825if(debugflag)
826 {
827 for(p = v0 ; p<v ; ++p)
828 fprintf(diagfile, "%s ", *p);
829 fprintf(diagfile, "\n");
830 }
831
832#if HERE==PDP11 || HERE==INTERDATA || HERE==VAX || HERE==TAHOE
833 if( (waitpid = fork()) == 0)
834 {
835 enbint(SIG_DFL);
836 execv(ldname, v0);
837 fatalstr("couldn't load %s", ldname);
838 }
839 await(waitpid);
840#endif
841
842#if HERE==INTERDATA
843 if(optimflag)
844 {
845 char buff1[100], buff2[100];
846 sprintf(buff1, "nopt %s -o junk.%d", aoutname, pid);
847 sprintf(buff2, "mv junk.%d %s", pid, aoutname);
848 if( sys(buff1) || sys(buff2) )
849 err("bad optimization");
850 }
851#endif
852
853if(verbose)
854 fprintf(diagfile, "\n");
855}
856\f
857/* Process control and Shell-simulating routines */
858
859sys(str)
860char *str;
861{
862register char *s, *t;
dc0e9d50 863char *argv[100];
d6724028
KB
864char *inname, *outname;
865int append;
866int waitpid;
867int argc;
868
869
870if(debugflag)
871 fprintf(diagfile, "%s\n", str);
872inname = NULL;
873outname = NULL;
874argv[0] = shellname;
875argc = 1;
876
877t = str;
878while( isspace(*t) )
879 ++t;
880while(*t)
881 {
882 if(*t == '<')
883 inname = t+1;
884 else if(*t == '>')
885 {
886 if(t[1] == '>')
887 {
888 append = YES;
889 outname = t+2;
890 }
891 else {
892 append = NO;
893 outname = t+1;
894 }
895 }
896 else
897 argv[argc++] = t;
898 while( !isspace(*t) && *t!='\0' )
899 ++t;
900 if(*t)
901 {
902 *t++ = '\0';
903 while( isspace(*t) )
904 ++t;
905 }
906 }
907
908if(argc == 1) /* no command */
909 return(-1);
910argv[argc] = 0;
911
d6724028
KB
912if((waitpid = fork()) == 0)
913 {
914 if(inname)
915 freopen(inname, "r", stdin);
916 if(outname)
917 freopen(outname, (append ? "a" : "w"), stdout);
918 enbint(SIG_DFL);
919
dc0e9d50 920 texec(argv[1] , argv);
d6724028 921
dc0e9d50 922 fatalstr("Cannot load %s", argv[1]);
d6724028
KB
923 }
924
925return( await(waitpid) );
926}
927
928
929
930
931
932#include "errno.h"
933
934/* modified version from the Shell */
935texec(f, av)
936char *f;
937char **av;
938{
939extern int errno;
940
941execv(f, av+1);
942
943if (errno==ENOEXEC)
944 {
945 av[1] = f;
946 execv(shellname, av);
947 fatal("No shell!");
948 }
949if (errno==ENOMEM)
950 fatalstr("%s: too large", f);
951}
952
953
954
955
956
957
958done(k)
959int k;
960{
961static int recurs = NO;
962
963if(recurs == NO)
964 {
965 recurs = YES;
966 rmfiles();
967 }
968exit(k);
969}
970
971
972
973
974
975
976enbint(k)
977int (*k)();
978{
979if(sigivalue == 0)
980 signal(SIGINT,k);
981if(sigqvalue == 0)
982 signal(SIGQUIT,k);
983if(sighvalue == 0)
984 signal(SIGHUP,k);
985if(sigtvalue == 0)
986 signal(SIGTERM,k);
987}
988
989
990
991
992intrupt()
993{
994done(2);
995}
996
997
998#ifdef PSIGNAL
999/*
1000 * Fancy 4.2 BSD signal printing stuff.
1001 */
1002char harmless[NSIG] = { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1003#endif
1004
1005
1006await(waitpid)
1007int waitpid;
1008{
1009
1010#ifdef PSIGNAL
1011extern char *sys_siglist[];
1012union wait status;
1013#else PSIGNAL
1014int status;
1015#endif PSIGNAL
1016
1017int w;
1018
1019enbint(SIG_IGN);
1020while ( (w = wait(&status)) != waitpid)
1021 if(w == -1)
1022 fatal("bad wait code");
1023enbint(intrupt);
1024
1025#ifdef PSIGNAL
1026if(status.w_termsig)
1027 {
1028 debugflag = 0; /* Prevent us from dumping core ourselves */
1029 if(status.w_termsig != SIGINT && status.w_termsig < NSIG)
1030 fprintf(diagfile, "%s%s\n", sys_siglist[status.w_termsig],
1031 status.w_coredump ? " -- core dumped" : "");
1032 if(status.w_termsig < NSIG && ! harmless[status.w_termsig])
1033 fatal("see a system manager");
1034 else
1035 done(3);
1036 }
1037return(status.w_retcode);
1038#else PSIGNAL
1039if(status & 0377)
1040 {
1041 if(status != SIGINT)
1042 fprintf(diagfile, "Termination code %d\n", status);
1043 done(3);
1044 }
1045return(status>>8);
1046#endif PSIGNAL
1047}
1048\f
1049/* File Name and File Manipulation Routines */
1050
1051unreadable(s)
1052register char *s;
1053{
1054register FILE *fp;
1055
1056if(fp = fopen(s, "r"))
1057 {
1058 fclose(fp);
1059 return(NO);
1060 }
1061
1062else
1063 {
1064 fprintf(diagfile, "Error: Cannot read file %s\n", s);
1065 return(YES);
1066 }
1067}
1068
1069
1070
1071stupid(s)
1072char *s;
1073{
1074char c;
1075
1076if( (c = dotchar(s))
1077 && index("focsreF", c)
1078 && access(s, 0) == 0 )
1079 {
1080 fprintf(diagfile, "Loading on %s would destroy it\n", s);
1081 return(YES);
1082 }
1083return(NO);
1084}
1085
1086
1087
1088clf(p)
1089FILEP *p;
1090{
1091if(p!=NULL && *p!=NULL && *p!=stdout)
1092 {
1093 if(ferror(*p))
1094 fatal("writing error");
1095 fclose(*p);
1096 }
1097*p = NULL;
1098}
1099
1100rmfiles()
1101{
1102rmf(textfname);
1103rmf(asmfname);
1104rmf(initfname);
1105rmf(asmpass2);
1106#if TARGET == INTERDATA
1107 rmf(setfname);
1108#endif
1109}
1110
1111
1112
1113
1114
1115
1116
1117
1118/* return -1 if file does not exist, 0 if it is of zero length
1119 and 1 if of positive length
1120*/
1121content(filename)
1122char *filename;
1123{
1124#ifdef VERSION6
1125 struct stat
1126 {
1127 char cjunk[9];
1128 char size0;
1129 int size1;
1130 int ijunk[12];
1131 } buf;
1132#else
1133 struct stat buf;
1134#endif
1135
1136if(stat(filename,&buf) < 0)
1137 return(-1);
1138#ifdef VERSION6
1139 return(buf.size0 || buf.size1);
1140#else
1141 return( buf.st_size > 0 );
1142#endif
1143}
1144
1145
1146
1147
1148crfnames()
1149{
1150fname(textfname, "x");
1151fname(asmfname, "s");
1152fname(asmpass2, "a");
1153fname(initfname, "d");
1154fname(sortfname, "S");
1155fname(objfdefault, "o");
1156fname(prepfname, "p");
1157fname(optzfname, "z");
1158fname(setfname, "A");
1159}
1160
1161
1162
1163
1164rmf(fn)
1165register char *fn;
1166{
1167/* if(!debugflag && fn!=NULL && *fn!='\0') */
1168
1169if(fn!=NULL && *fn!='\0')
1170 unlink(fn);
1171}
1172
1173
1174
1175
1176
1177LOCAL fname(name, suff)
1178char *name, *suff;
1179{
dc0e9d50 1180sprintf(name, "%s/%s%d.%s", _PATH_TMP, temppref, pid, suff);
d6724028
KB
1181}
1182
1183
1184
1185
1186dotchar(s)
1187register char *s;
1188{
1189for( ; *s ; ++s)
1190 if(s[0]=='.' && s[1]!='\0' && s[2]=='\0')
1191 return( s[1] );
1192return(NO);
1193}
1194
1195
1196
1197char *lastfield(s)
1198register char *s;
1199{
1200register char *t;
1201for(t = s; *s ; ++s)
1202 if(*s == '/')
1203 t = s+1;
1204return(t);
1205}
1206
1207
1208
1209char *lastchar(s)
1210register char *s;
1211{
1212while(*s)
1213 ++s;
1214return(s-1);
1215}
1216
1217char *setdoto(s)
1218register char *s;
1219{
1220*lastchar(s) = 'o';
1221return( lastfield(s) );
1222}
1223
1224
1225
1226badfile(s)
1227char *s;
1228{
1229fatalstr("cannot open intermediate file %s", s);
1230}
1231
1232
1233
1234ptr ckalloc(n)
1235int n;
1236{
1237ptr p, calloc();
1238
1239if( p = calloc(1, (unsigned) n) )
1240 return(p);
1241
1242fatal("out of memory");
1243/* NOTREACHED */
1244}
1245
1246
1247
1248
1249
1250char *copyn(n, s)
1251register int n;
1252register char *s;
1253{
1254register char *p, *q;
1255
1256p = q = (char *) ckalloc(n);
1257while(n-- > 0)
1258 *q++ = *s++;
1259return(p);
1260}
1261
1262
1263
1264char *copys(s)
1265char *s;
1266{
1267return( copyn( strlen(s)+1 , s) );
1268}
1269
1270
1271
1272
1273
1274oneof(c,s)
1275register c;
1276register char *s;
1277{
1278while( *s )
1279 if(*s++ == c)
1280 return(YES);
1281return(NO);
1282}
1283
1284
1285
1286nodup(s)
1287char *s;
1288{
1289register char **p;
1290
1291for(p = loadargs ; p < loadp ; ++p)
1292 if( !strcmp(*p, s) )
1293 return(NO);
1294
1295return(YES);
1296}
1297
1298
1299
1300static fatal(t)
1301char *t;
1302{
1303fprintf(diagfile, "Compiler error in file %s: %s\n", infname, t);
1304if(debugflag)
1305 abort();
1306done(1);
1307exit(1);
1308}
1309
1310
1311
1312
1313static fatali(t,d)
1314char *t;
1315int d;
1316{
1317char buff[100];
1318sprintf(buff, t, d);
1319fatal(buff);
1320}
1321
1322
1323
1324
1325static fatalstr(t, s)
1326char *t, *s;
1327{
1328char buff[100];
1329sprintf(buff, t, s);
1330fatal(buff);
1331}
1332err(s)
1333char *s;
1334{
1335fprintf(diagfile, "Error in file %s: %s\n", infname, s);
1336}
1337