xref: /original-bsd/usr.bin/f77/f77.vax/f77.c (revision 850c0003)
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.5 (Berkeley) 05/10/89";
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 <sys/types.h>
85 #include <sys/stat.h>
86 #include <sys/signal.h>
87 #include <ctype.h>
88 #include <stdio.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 "pathnames.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	= FOOTNAME;
119 static char *proffoot	= PROFFOOT;
120 static char *macroname	= "m4";
121 static char *shellname	= _PATH_BSHELL;
122 static char *cppname	= _PATH_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];
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 if((waitpid = fork()) == 0)
955 	{
956 	if(inname)
957 		if(freopen(inname, "r", stdin) == NULL)
958 			fatalstr("Cannot open %s", inname);
959 	if(outname)
960 		if(freopen(outname, (append ? "a" : "w"), stdout) == NULL)
961 			fatalstr("Cannot open %s", outname);
962 	enbint(SIG_DFL);
963 
964 	texec(argv[1], argv);
965 
966 	fatalstr("Cannot load %s", argv[1]);
967 	}
968 
969 return( await(waitpid) );
970 }
971 
972 
973 
974 
975 
976 #include "errno.h"
977 
978 /* modified version from the Shell */
979 texec(f, av)
980 char *f;
981 char **av;
982 {
983 extern int errno;
984 
985 execv(f, av+1);
986 
987 if (errno==ENOEXEC)
988 	{
989 	av[1] = f;
990 	execv(shellname, av);
991 	fatal("No shell!");
992 	}
993 if (errno==ENOMEM)
994 	fatalstr("%s: too large", f);
995 }
996 
997 
998 
999 
1000 
1001 
1002 done(k)
1003 int k;
1004 {
1005 static int recurs	= NO;
1006 
1007 if(recurs == NO)
1008 	{
1009 	recurs = YES;
1010 	rmfiles();
1011 	}
1012 exit(k);
1013 }
1014 
1015 
1016 
1017 
1018 
1019 
1020 enbint(k)
1021 int (*k)();
1022 {
1023 if(sigivalue == 0)
1024 	(void) signal(SIGINT,k);
1025 if(sigqvalue == 0)
1026 	(void) signal(SIGQUIT,k);
1027 if(sighvalue == 0)
1028 	(void) signal(SIGHUP,k);
1029 if(sigtvalue == 0)
1030 	(void) signal(SIGTERM,k);
1031 }
1032 
1033 
1034 
1035 
1036 intrupt()
1037 {
1038 done(2);
1039 }
1040 
1041 
1042 #ifdef PSIGNAL
1043 /*
1044  * Fancy 4.2 BSD signal printing stuff.
1045  */
1046 char harmless[NSIG] = { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
1047 #endif
1048 
1049 
1050 await(waitpid)
1051 int waitpid;
1052 {
1053 
1054 #ifdef PSIGNAL
1055 extern char *sys_siglist[];
1056 union wait status;
1057 #else PSIGNAL
1058 int status;
1059 #endif PSIGNAL
1060 
1061 int w;
1062 
1063 enbint(SIG_IGN);
1064 while ( (w = wait(&status)) != waitpid)
1065 	if(w == -1)
1066 		fatal("bad wait code");
1067 enbint(intrupt);
1068 
1069 #ifdef PSIGNAL
1070 if(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 	}
1081 return(status.w_retcode);
1082 #else PSIGNAL
1083 if(status & 0377)
1084 	{
1085 	if(status != SIGINT)
1086 		fprintf(diagfile, "Termination code %d\n", status);
1087 	done(3);
1088 	}
1089 return(status>>8);
1090 #endif PSIGNAL
1091 }
1092 
1093 /* File Name and File Manipulation Routines */
1094 
1095 unreadable(s)
1096 register char *s;
1097 {
1098 register FILE *fp;
1099 
1100 if(fp = fopen(s, "r"))
1101 	{
1102 	fclose(fp);
1103 	return(NO);
1104 	}
1105 
1106 else
1107 	{
1108 	fprintf(diagfile, "Error: Cannot read file %s\n", s);
1109 	return(YES);
1110 	}
1111 }
1112 
1113 
1114 
1115 stupid(s)
1116 char *s;
1117 {
1118 char c;
1119 extern char *index();
1120 
1121 if( (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 	}
1128 return(NO);
1129 }
1130 
1131 
1132 
1133 clf(p)
1134 FILEP *p;
1135 {
1136 if(p!=NULL && *p!=NULL && *p!=stdout)
1137 	{
1138 	if(ferror(*p))
1139 		fatal("writing error");
1140 	fclose(*p);
1141 	}
1142 *p = NULL;
1143 }
1144 
1145 rmfiles()
1146 {
1147 rmf(textfname);
1148 rmf(asmfname);
1149 rmf(initfname);
1150 rmf(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 */
1166 content(filename)
1167 char *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 
1181 if(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 
1193 crfnames()
1194 {
1195 fname(textfname, "x");
1196 fname(asmfname, "s");
1197 fname(asmpass2, "a");
1198 fname(initfname, "d");
1199 fname(sortfname, "S");
1200 fname(objfdefault, "o");
1201 fname(prepfname, "p");
1202 fname(optzfname, "z");
1203 fname(setfname, "A");
1204 }
1205 
1206 
1207 
1208 
1209 rmf(fn)
1210 register char *fn;
1211 {
1212 /* if(!debugflag && fn!=NULL && *fn!='\0') */
1213 
1214 if(fn!=NULL && *fn!='\0')
1215 	unlink(fn);
1216 }
1217 
1218 
1219 
1220 
1221 
1222 LOCAL fname(name, suff)
1223 char *name, *suff;
1224 {
1225 sprintf(name, "%s/%s%d.%s", _PATH_TMP, temppref, pid, suff);
1226 }
1227 
1228 
1229 
1230 
1231 dotchar(s)
1232 register char *s;
1233 {
1234 for( ; *s ; ++s)
1235 	if(s[0]=='.' && s[1]!='\0' && s[2]=='\0')
1236 		return( s[1] );
1237 return(NO);
1238 }
1239 
1240 
1241 
1242 char *lastfield(s)
1243 register char *s;
1244 {
1245 register char *t;
1246 for(t = s; *s ; ++s)
1247 	if(*s == '/')
1248 		t = s+1;
1249 return(t);
1250 }
1251 
1252 
1253 
1254 char *lastchar(s)
1255 register char *s;
1256 {
1257 while(*s)
1258 	++s;
1259 return(s-1);
1260 }
1261 
1262 char *setdoto(s)
1263 register char *s;
1264 {
1265 *lastchar(s) = 'o';
1266 return( lastfield(s) );
1267 }
1268 
1269 
1270 
1271 badfile(s)
1272 char *s;
1273 {
1274 fatalstr("cannot open intermediate file %s", s);
1275 }
1276 
1277 
1278 
1279 ptr ckalloc(n)
1280 int n;
1281 {
1282 ptr p;
1283 extern char *calloc();
1284 
1285 if( p = (ptr) calloc(1, (unsigned) n) )
1286 	return(p);
1287 
1288 fatal("out of memory");
1289 /* NOTREACHED */
1290 }
1291 
1292 
1293 
1294 
1295 
1296 char *copyn(n, s)
1297 register int n;
1298 register char *s;
1299 {
1300 register char *p, *q;
1301 
1302 p = q = (char *) ckalloc(n);
1303 while(n-- > 0)
1304 	*q++ = *s++;
1305 return(p);
1306 }
1307 
1308 
1309 
1310 char *copys(s)
1311 char *s;
1312 {
1313 return( copyn( strlen(s)+1 , s) );
1314 }
1315 
1316 
1317 
1318 
1319 
1320 oneof(c,s)
1321 register c;
1322 register char *s;
1323 {
1324 while( *s )
1325 	if(*s++ == c)
1326 		return(YES);
1327 return(NO);
1328 }
1329 
1330 
1331 
1332 nodup(s)
1333 char *s;
1334 {
1335 register char **p;
1336 
1337 for(p = loadargs ; p < loadp ; ++p)
1338 	if( !strcmp(*p, s) )
1339 		return(NO);
1340 
1341 return(YES);
1342 }
1343 
1344 
1345 
1346 static fatal(t)
1347 char *t;
1348 {
1349 fprintf(diagfile, "Compiler error in file %s: %s\n", infname, t);
1350 if(debugflag)
1351 	abort();
1352 done(1);
1353 exit(1);
1354 }
1355 
1356 
1357 
1358 
1359 static fatali(t,d)
1360 char *t;
1361 int d;
1362 {
1363 char buff[100];
1364 sprintf(buff, t, d);
1365 fatal(buff);
1366 }
1367 
1368 
1369 
1370 
1371 static fatalstr(t, s)
1372 char *t, *s;
1373 {
1374 char buff[100];
1375 sprintf(buff, t, s);
1376 fatal(buff);
1377 }
1378 err(s)
1379 char *s;
1380 {
1381 fprintf(diagfile, "Error in file %s: %s\n", infname, s);
1382 }
1383 
1384