file reorg, pathnames.h, paths.h
[unix-history] / usr / src / usr.bin / f77 / f77.vax / f77.c
CommitLineData
0b02dad2
DS
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
dc0e9d50 8static char sccsid[] = "@(#)f77.c 5.5 (Berkeley) %G%";
0b02dad2
DS
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 $
87338294
DS
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 *
c466b5d7
DS
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 *
0b02dad2
DS
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
b4e1441f 83char *xxxvers = "\n@(#) F77 DRIVER, VERSION 4.2, 1984 JULY 28\n";
0b02dad2
DS
84#include <sys/types.h>
85#include <sys/stat.h>
dc0e9d50 86#include <sys/signal.h>
0b02dad2 87#include <ctype.h>
dc0e9d50 88#include <stdio.h>
0b02dad2
DS
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"
dc0e9d50 103#include "pathnames.h"
0b02dad2
DS
104#include "version.h"
105
106static FILEP diagfile = {stderr} ;
107static int pid;
108static int sigivalue = 0;
109static int sigqvalue = 0;
110static int sighvalue = 0;
111static int sigtvalue = 0;
112
113static char *pass1name = PASS1NAME ;
114static char *pass2name = PASS2NAME ;
115static char *pass2opt = PASS2OPT ;
116static char *asmname = ASMNAME ;
117static char *ldname = LDNAME ;
118static char *footname = FOOTNAME;
119static char *proffoot = PROFFOOT;
120static char *macroname = "m4";
dc0e9d50
KB
121static char *shellname = _PATH_BSHELL;
122static char *cppname = _PATH_CPP;
0b02dad2
DS
123static char *aoutname = "a.out" ;
124static char *temppref = TEMPPREF;
125
126static char *infname;
127static char textfname[44];
128static char asmfname[44];
129static char asmpass2[44];
130static char initfname[44];
131static char sortfname[44];
132static char prepfname[44];
133static char objfdefault[44];
134static char optzfname[44];
135static char setfname[44];
136
137static char fflags[50] = "-";
138static char f2flags[50];
139static 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
145static char rflags[30] = "";
146static char lflag[3] = "-x";
147static char *fflagp = fflags+1;
148static char *f2flagp = f2flags;
0b02dad2
DS
149static char *eflagp = eflags+12;
150static char *rflagp = rflags;
151static char *cppflags = "";
152static char **cppargs;
153static char **loadargs;
154static char **loadp;
155
156static flag erred = NO;
157static flag loadflag = YES;
158static flag saveasmflag = NO;
159static flag profileflag = NO;
160static flag optimflag = NO;
161static flag debugflag = NO;
162static flag verbose = NO;
0b02dad2
DS
163static flag fortonly = NO;
164static flag macroflag = NO;
165static flag sdbflag = NO;
166static flag namesflag = YES;
167
87338294
DS
168#if TARGET == PDP11
169static flag nofloating = NO;
170#endif
171
0b02dad2
DS
172static int ncpp;
173
174\f
175main(argc, argv)
176int argc;
177char **argv;
178{
87338294
DS
179register int i, n;
180int c, status;
0b02dad2
DS
181char *setdoto(), *lastchar(), *lastfield(), *copys(), *argvtos();
182ptr ckalloc();
87338294 183char *strcat();
0b02dad2
DS
184register char *s;
185char fortfile[20], *t;
87338294 186char *buff;
0b02dad2
DS
187int intrupt();
188int new_aoutname = NO;
189
190sigivalue = signal(SIGINT, SIG_IGN) == SIG_IGN;
191sigqvalue = signal(SIGQUIT,SIG_IGN) == SIG_IGN;
192sighvalue = signal(SIGHUP, SIG_IGN) == SIG_IGN;
193sigtvalue = signal(SIGTERM,SIG_IGN) == SIG_IGN;
194enbint(intrupt);
195
196pid = getpid();
197crfnames();
198
199cppargs = (char **) ckalloc( argc * sizeof(*cppargs) );
200loadargs = (char **) ckalloc( (argc+20) * sizeof(*loadargs) );
201loadargs[1] = "-X";
202loadargs[2] = "-u";
203#if HERE==PDP11 || HERE==VAX
204 loadargs[3] = "_MAIN_";
205#endif
206#if HERE == INTERDATA
207 loadargs[3] = "main";
208#endif
209loadp = loadargs + 4;
210
211--argc;
212++argv;
213
87338294
DS
214for (i = 0, n = 50; i < argc; ++i)
215 n += strlen(argv[i]) + 1;
216buff = (char *) ckalloc(n);
217
0b02dad2
DS
218while(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
c466b5d7 246#ifdef ONLY66
0b02dad2
DS
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 }
c466b5d7 257#endif
0b02dad2
DS
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':
87338294 311 (void) strcat(cflags, " -S");
0b02dad2
DS
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 }
87338294 347 (void) strcat(cflags," -g");
0b02dad2
DS
348 sdbflag = YES;
349 goto copyfflag;
350
351 case 'p':
352 profileflag = YES;
87338294 353 (void) strcat(cflags," -p");
0b02dad2
DS
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
c466b5d7
DS
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
0b02dad2
DS
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 }
439endfor:
440 --argc;
441 ++argv;
442 }
443
444#ifdef NOCORE
445if(!debugflag)
446 {
447 struct rlimit r;
448
449 r.rlim_cur = r.rlim_max = 0;
87338294 450 (void) setrlimit(RLIMIT_CORE, &r);
0b02dad2
DS
451 }
452#endif NOCORE
453
454*fflagp = '\0';
455
456if (ncpp > 0)
457 cppflags = argvtos (ncpp,cppargs);
458
459loadargs[0] = ldname;
460#if TARGET == PDP11
461 if(nofloating)
462 *loadp++ = (profileflag ? NOFLPROF : NOFLFOOT);
463 else
464#endif
465*loadp++ = (profileflag ? proffoot : footname);
466
467for(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
605if( loadflag && stupid(aoutname) )
606 erred = YES;
607if(loadflag && !erred)
608 doload(loadargs, loadp);
609done(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
623char *
624argvtos(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\f
670dofort(s)
671char *s;
672{
673int retcode;
674char buff[200];
675
676infname = s;
677sprintf(buff, "%s %s %s %s %s %s",
678 pass1name, fflags, s, asmfname, initfname, textfname);
679switch( sys(buff) )
680 {
681 case 1:
682 goto error;
683 case 0:
684 break;
685 default:
686 goto comperror;
687 }
688
689if( dopass2() )
690 goto comperror;
691doasm(s);
692retcode = 0;
693
694ret:
695 rmf(asmfname);
696 rmf(initfname);
697 rmf(textfname);
698 return(retcode);
699
700error:
701 fprintf(diagfile, "\nError. No assembly.\n");
702 retcode = 1;
703 goto ret;
704
705comperror:
706 fprintf(diagfile, "\ncompiler error.\n");
707 retcode = 2;
708 goto ret;
709}
710
711
712
713
714dopass2()
715{
716char buff[100];
717
718if(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
741doasm(s)
742char *s;
743{
744register char *lastc;
745char *obj;
746char buff[200];
747char *lastchar(), *setdoto();
748
749if(*s == '\0')
750 s = objfdefault;
751lastc = lastchar(s);
752obj = 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);
87338294
DS
764 if( sys(buff) )
765 fatal("can't rename optimizer output file");
0b02dad2
DS
766 }
767 }
768# endif
769#endif
770
771if(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
87338294
DS
790 if( sys(buff) )
791 fatal("can't concatenate assembly files");
0b02dad2
DS
792 *lastc = 'o';
793 }
794else
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);
87338294
DS
811 if( sys(buff) )
812 fatal("can't concatenate assembly files");
0b02dad2
DS
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
837rmf(asmpass2);
838}
839
840
841
842doload(v0, v)
843register char *v0[], *v[];
844{
845char **p;
846int waitpid;
847
848if(sdbflag)
849 *v++ = "-lg";
850if (profileflag)
851 {
852 for(p = p_liblist ; *p ; *v++ = *p++)
853 ;
854 }
855else {
856 for(p = liblist ; *p ; *v++ = *p++)
857 ;
858 }
859
860*v++ = "-o";
861*v++ = aoutname;
862*v = NULL;
863
864if(verbose)
865 fprintf(diagfile, "LOAD.");
866if(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 }
87338294
DS
880 if( await(waitpid) )
881 erred = YES;
0b02dad2
DS
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
895if(verbose)
896 fprintf(diagfile, "\n");
897}
898\f
899/* Process control and Shell-simulating routines */
900
901sys(str)
902char *str;
903{
904register char *s, *t;
dc0e9d50 905char *argv[100];
0b02dad2
DS
906char *inname, *outname;
907int append;
908int waitpid;
909int argc;
910
911
912if(debugflag)
913 fprintf(diagfile, "%s\n", str);
914inname = NULL;
915outname = NULL;
916argv[0] = shellname;
917argc = 1;
918
919t = str;
920while( isspace(*t) )
921 ++t;
922while(*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
950if(argc == 1) /* no command */
951 return(-1);
952argv[argc] = 0;
953
0b02dad2
DS
954if((waitpid = fork()) == 0)
955 {
956 if(inname)
87338294
DS
957 if(freopen(inname, "r", stdin) == NULL)
958 fatalstr("Cannot open %s", inname);
0b02dad2 959 if(outname)
87338294
DS
960 if(freopen(outname, (append ? "a" : "w"), stdout) == NULL)
961 fatalstr("Cannot open %s", outname);
0b02dad2
DS
962 enbint(SIG_DFL);
963
dc0e9d50 964 texec(argv[1], argv);
0b02dad2 965
dc0e9d50 966 fatalstr("Cannot load %s", argv[1]);
0b02dad2
DS
967 }
968
969return( await(waitpid) );
970}
971
972
973
974
975
976#include "errno.h"
977
978/* modified version from the Shell */
979texec(f, av)
980char *f;
981char **av;
982{
983extern int errno;
984
985execv(f, av+1);
986
987if (errno==ENOEXEC)
988 {
989 av[1] = f;
990 execv(shellname, av);
991 fatal("No shell!");
992 }
993if (errno==ENOMEM)
994 fatalstr("%s: too large", f);
995}
996
997
998
999
1000
1001
1002done(k)
1003int k;
1004{
1005static int recurs = NO;
1006
1007if(recurs == NO)
1008 {
1009 recurs = YES;
1010 rmfiles();
1011 }
1012exit(k);
1013}
1014
1015
1016
1017
1018
1019
1020enbint(k)
1021int (*k)();
1022{
1023if(sigivalue == 0)
87338294 1024 (void) signal(SIGINT,k);
0b02dad2 1025if(sigqvalue == 0)
87338294 1026 (void) signal(SIGQUIT,k);
0b02dad2 1027if(sighvalue == 0)
87338294 1028 (void) signal(SIGHUP,k);
0b02dad2 1029if(sigtvalue == 0)
87338294 1030 (void) signal(SIGTERM,k);
0b02dad2
DS
1031}
1032
1033
1034
1035
1036intrupt()
1037{
1038done(2);
1039}
1040
1041
1042#ifdef PSIGNAL
1043/*
1044 * Fancy 4.2 BSD signal printing stuff.
1045 */
1046char harmless[NSIG] = { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1047#endif
1048
1049
1050await(waitpid)
1051int waitpid;
1052{
1053
1054#ifdef PSIGNAL
1055extern char *sys_siglist[];
1056union wait status;
1057#else PSIGNAL
1058int status;
1059#endif PSIGNAL
1060
1061int w;
1062
1063enbint(SIG_IGN);
1064while ( (w = wait(&status)) != waitpid)
1065 if(w == -1)
1066 fatal("bad wait code");
1067enbint(intrupt);
1068
1069#ifdef PSIGNAL
1070if(status.w_termsig)
1071 {
1072 debugflag = 0; /* Prevent us from dumping core ourselves */
1073 if(status.w_termsig != SIGINT && status.w_termsig < NSIG)
1074 fprintf(diagfile, "%s%s\n", sys_siglist[status.w_termsig],
1075 status.w_coredump ? " -- core dumped" : "");
1076 if(status.w_termsig < NSIG && ! harmless[status.w_termsig])
1077 fatal("see a system manager");
1078 else
1079 done(3);
1080 }
1081return(status.w_retcode);
1082#else PSIGNAL
1083if(status & 0377)
1084 {
1085 if(status != SIGINT)
1086 fprintf(diagfile, "Termination code %d\n", status);
1087 done(3);
1088 }
1089return(status>>8);
1090#endif PSIGNAL
1091}
1092\f
1093/* File Name and File Manipulation Routines */
1094
1095unreadable(s)
1096register char *s;
1097{
1098register FILE *fp;
1099
1100if(fp = fopen(s, "r"))
1101 {
1102 fclose(fp);
1103 return(NO);
1104 }
1105
1106else
1107 {
1108 fprintf(diagfile, "Error: Cannot read file %s\n", s);
1109 return(YES);
1110 }
1111}
1112
1113
1114
1115stupid(s)
1116char *s;
1117{
1118char c;
87338294 1119extern char *index();
0b02dad2
DS
1120
1121if( (c = dotchar(s))
1122 && index("focsreF", c)
1123 && access(s, 0) == 0 )
1124 {
1125 fprintf(diagfile, "Loading on %s would destroy it\n", s);
1126 return(YES);
1127 }
1128return(NO);
1129}
1130
1131
1132
1133clf(p)
1134FILEP *p;
1135{
1136if(p!=NULL && *p!=NULL && *p!=stdout)
1137 {
1138 if(ferror(*p))
1139 fatal("writing error");
1140 fclose(*p);
1141 }
1142*p = NULL;
1143}
1144
1145rmfiles()
1146{
1147rmf(textfname);
1148rmf(asmfname);
1149rmf(initfname);
1150rmf(asmpass2);
1151#if TARGET == INTERDATA
1152 rmf(setfname);
1153#endif
1154}
1155
1156
1157
1158
1159
1160
1161
1162
1163/* return -1 if file does not exist, 0 if it is of zero length
1164 and 1 if of positive length
1165*/
1166content(filename)
1167char *filename;
1168{
1169#ifdef VERSION6
1170 struct stat
1171 {
1172 char cjunk[9];
1173 char size0;
1174 int size1;
1175 int ijunk[12];
1176 } buf;
1177#else
1178 struct stat buf;
1179#endif
1180
1181if(stat(filename,&buf) < 0)
1182 return(-1);
1183#ifdef VERSION6
1184 return(buf.size0 || buf.size1);
1185#else
1186 return( buf.st_size > 0 );
1187#endif
1188}
1189
1190
1191
1192
1193crfnames()
1194{
1195fname(textfname, "x");
1196fname(asmfname, "s");
1197fname(asmpass2, "a");
1198fname(initfname, "d");
1199fname(sortfname, "S");
1200fname(objfdefault, "o");
1201fname(prepfname, "p");
1202fname(optzfname, "z");
1203fname(setfname, "A");
1204}
1205
1206
1207
1208
1209rmf(fn)
1210register char *fn;
1211{
1212/* if(!debugflag && fn!=NULL && *fn!='\0') */
1213
1214if(fn!=NULL && *fn!='\0')
1215 unlink(fn);
1216}
1217
1218
1219
1220
1221
1222LOCAL fname(name, suff)
1223char *name, *suff;
1224{
dc0e9d50 1225sprintf(name, "%s/%s%d.%s", _PATH_TMP, temppref, pid, suff);
0b02dad2
DS
1226}
1227
1228
1229
1230
1231dotchar(s)
1232register char *s;
1233{
1234for( ; *s ; ++s)
1235 if(s[0]=='.' && s[1]!='\0' && s[2]=='\0')
1236 return( s[1] );
1237return(NO);
1238}
1239
1240
1241
1242char *lastfield(s)
1243register char *s;
1244{
1245register char *t;
1246for(t = s; *s ; ++s)
1247 if(*s == '/')
1248 t = s+1;
1249return(t);
1250}
1251
1252
1253
1254char *lastchar(s)
1255register char *s;
1256{
1257while(*s)
1258 ++s;
1259return(s-1);
1260}
1261
1262char *setdoto(s)
1263register char *s;
1264{
1265*lastchar(s) = 'o';
1266return( lastfield(s) );
1267}
1268
1269
1270
1271badfile(s)
1272char *s;
1273{
1274fatalstr("cannot open intermediate file %s", s);
1275}
1276
1277
1278
1279ptr ckalloc(n)
1280int n;
1281{
87338294
DS
1282ptr p;
1283extern char *calloc();
0b02dad2 1284
87338294 1285if( p = (ptr) calloc(1, (unsigned) n) )
0b02dad2
DS
1286 return(p);
1287
1288fatal("out of memory");
1289/* NOTREACHED */
1290}
1291
1292
1293
1294
1295
1296char *copyn(n, s)
1297register int n;
1298register char *s;
1299{
1300register char *p, *q;
1301
1302p = q = (char *) ckalloc(n);
1303while(n-- > 0)
1304 *q++ = *s++;
1305return(p);
1306}
1307
1308
1309
1310char *copys(s)
1311char *s;
1312{
1313return( copyn( strlen(s)+1 , s) );
1314}
1315
1316
1317
1318
1319
1320oneof(c,s)
1321register c;
1322register char *s;
1323{
1324while( *s )
1325 if(*s++ == c)
1326 return(YES);
1327return(NO);
1328}
1329
1330
1331
1332nodup(s)
1333char *s;
1334{
1335register char **p;
1336
1337for(p = loadargs ; p < loadp ; ++p)
1338 if( !strcmp(*p, s) )
1339 return(NO);
1340
1341return(YES);
1342}
1343
1344
1345
1346static fatal(t)
1347char *t;
1348{
1349fprintf(diagfile, "Compiler error in file %s: %s\n", infname, t);
1350if(debugflag)
1351 abort();
1352done(1);
1353exit(1);
1354}
1355
1356
1357
1358
1359static fatali(t,d)
1360char *t;
1361int d;
1362{
1363char buff[100];
1364sprintf(buff, t, d);
1365fatal(buff);
1366}
1367
1368
1369
1370
1371static fatalstr(t, s)
1372char *t, *s;
1373{
1374char buff[100];
1375sprintf(buff, t, s);
1376fatal(buff);
1377}
1378err(s)
1379char *s;
1380{
1381fprintf(diagfile, "Error in file %s: %s\n", infname, s);
1382}
1383