Commit | Line | Data |
---|---|---|
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 | ||
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" | |
dc0e9d50 | 82 | #include "pathnames.h" |
d6724028 KB |
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"; | |
dc0e9d50 KB |
100 | static char *shellname = _PATH_BSHELL; |
101 | static char *cppname = _PATH_CPP; | |
d6724028 KB |
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 | \f | |
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 | \f | |
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 | { | |
732 | sprintf(buff,"mv %s %s", optzfname, asmpass2); | |
733 | sys(buff); | |
734 | } | |
735 | } | |
736 | # endif | |
737 | #endif | |
738 | ||
739 | if(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 | } | |
757 | else | |
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 | ||
796 | rmf(asmpass2); | |
797 | } | |
798 | ||
799 | ||
800 | ||
801 | doload(v0, v) | |
802 | register char *v0[], *v[]; | |
803 | { | |
804 | char **p; | |
805 | int waitpid; | |
806 | ||
807 | if(sdbflag) | |
808 | *v++ = "-lg"; | |
809 | if (profileflag) | |
810 | { | |
811 | for(p = p_liblist ; *p ; *v++ = *p++) | |
812 | ; | |
813 | } | |
814 | else { | |
815 | for(p = liblist ; *p ; *v++ = *p++) | |
816 | ; | |
817 | } | |
818 | ||
819 | *v++ = "-o"; | |
820 | *v++ = aoutname; | |
821 | *v = NULL; | |
822 | ||
823 | if(verbose) | |
824 | fprintf(diagfile, "LOAD."); | |
825 | if(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 | ||
853 | if(verbose) | |
854 | fprintf(diagfile, "\n"); | |
855 | } | |
856 | \f | |
857 | /* Process control and Shell-simulating routines */ | |
858 | ||
859 | sys(str) | |
860 | char *str; | |
861 | { | |
862 | register char *s, *t; | |
dc0e9d50 | 863 | char *argv[100]; |
d6724028 KB |
864 | char *inname, *outname; |
865 | int append; | |
866 | int waitpid; | |
867 | int argc; | |
868 | ||
869 | ||
870 | if(debugflag) | |
871 | fprintf(diagfile, "%s\n", str); | |
872 | inname = NULL; | |
873 | outname = NULL; | |
874 | argv[0] = shellname; | |
875 | argc = 1; | |
876 | ||
877 | t = str; | |
878 | while( isspace(*t) ) | |
879 | ++t; | |
880 | while(*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 | ||
908 | if(argc == 1) /* no command */ | |
909 | return(-1); | |
910 | argv[argc] = 0; | |
911 | ||
d6724028 KB |
912 | if((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 | ||
925 | return( await(waitpid) ); | |
926 | } | |
927 | ||
928 | ||
929 | ||
930 | ||
931 | ||
932 | #include "errno.h" | |
933 | ||
934 | /* modified version from the Shell */ | |
935 | texec(f, av) | |
936 | char *f; | |
937 | char **av; | |
938 | { | |
939 | extern int errno; | |
940 | ||
941 | execv(f, av+1); | |
942 | ||
943 | if (errno==ENOEXEC) | |
944 | { | |
945 | av[1] = f; | |
946 | execv(shellname, av); | |
947 | fatal("No shell!"); | |
948 | } | |
949 | if (errno==ENOMEM) | |
950 | fatalstr("%s: too large", f); | |
951 | } | |
952 | ||
953 | ||
954 | ||
955 | ||
956 | ||
957 | ||
958 | done(k) | |
959 | int k; | |
960 | { | |
961 | static int recurs = NO; | |
962 | ||
963 | if(recurs == NO) | |
964 | { | |
965 | recurs = YES; | |
966 | rmfiles(); | |
967 | } | |
968 | exit(k); | |
969 | } | |
970 | ||
971 | ||
972 | ||
973 | ||
974 | ||
975 | ||
976 | enbint(k) | |
977 | int (*k)(); | |
978 | { | |
979 | if(sigivalue == 0) | |
980 | signal(SIGINT,k); | |
981 | if(sigqvalue == 0) | |
982 | signal(SIGQUIT,k); | |
983 | if(sighvalue == 0) | |
984 | signal(SIGHUP,k); | |
985 | if(sigtvalue == 0) | |
986 | signal(SIGTERM,k); | |
987 | } | |
988 | ||
989 | ||
990 | ||
991 | ||
992 | intrupt() | |
993 | { | |
994 | done(2); | |
995 | } | |
996 | ||
997 | ||
998 | #ifdef PSIGNAL | |
999 | /* | |
1000 | * Fancy 4.2 BSD signal printing stuff. | |
1001 | */ | |
1002 | char harmless[NSIG] = { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 }; | |
1003 | #endif | |
1004 | ||
1005 | ||
1006 | await(waitpid) | |
1007 | int waitpid; | |
1008 | { | |
1009 | ||
1010 | #ifdef PSIGNAL | |
1011 | extern char *sys_siglist[]; | |
1012 | union wait status; | |
1013 | #else PSIGNAL | |
1014 | int status; | |
1015 | #endif PSIGNAL | |
1016 | ||
1017 | int w; | |
1018 | ||
1019 | enbint(SIG_IGN); | |
1020 | while ( (w = wait(&status)) != waitpid) | |
1021 | if(w == -1) | |
1022 | fatal("bad wait code"); | |
1023 | enbint(intrupt); | |
1024 | ||
1025 | #ifdef PSIGNAL | |
1026 | if(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 | } | |
1037 | return(status.w_retcode); | |
1038 | #else PSIGNAL | |
1039 | if(status & 0377) | |
1040 | { | |
1041 | if(status != SIGINT) | |
1042 | fprintf(diagfile, "Termination code %d\n", status); | |
1043 | done(3); | |
1044 | } | |
1045 | return(status>>8); | |
1046 | #endif PSIGNAL | |
1047 | } | |
1048 | \f | |
1049 | /* File Name and File Manipulation Routines */ | |
1050 | ||
1051 | unreadable(s) | |
1052 | register char *s; | |
1053 | { | |
1054 | register FILE *fp; | |
1055 | ||
1056 | if(fp = fopen(s, "r")) | |
1057 | { | |
1058 | fclose(fp); | |
1059 | return(NO); | |
1060 | } | |
1061 | ||
1062 | else | |
1063 | { | |
1064 | fprintf(diagfile, "Error: Cannot read file %s\n", s); | |
1065 | return(YES); | |
1066 | } | |
1067 | } | |
1068 | ||
1069 | ||
1070 | ||
1071 | stupid(s) | |
1072 | char *s; | |
1073 | { | |
1074 | char c; | |
1075 | ||
1076 | if( (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 | } | |
1083 | return(NO); | |
1084 | } | |
1085 | ||
1086 | ||
1087 | ||
1088 | clf(p) | |
1089 | FILEP *p; | |
1090 | { | |
1091 | if(p!=NULL && *p!=NULL && *p!=stdout) | |
1092 | { | |
1093 | if(ferror(*p)) | |
1094 | fatal("writing error"); | |
1095 | fclose(*p); | |
1096 | } | |
1097 | *p = NULL; | |
1098 | } | |
1099 | ||
1100 | rmfiles() | |
1101 | { | |
1102 | rmf(textfname); | |
1103 | rmf(asmfname); | |
1104 | rmf(initfname); | |
1105 | rmf(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 | */ | |
1121 | content(filename) | |
1122 | char *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 | ||
1136 | if(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 | ||
1148 | crfnames() | |
1149 | { | |
1150 | fname(textfname, "x"); | |
1151 | fname(asmfname, "s"); | |
1152 | fname(asmpass2, "a"); | |
1153 | fname(initfname, "d"); | |
1154 | fname(sortfname, "S"); | |
1155 | fname(objfdefault, "o"); | |
1156 | fname(prepfname, "p"); | |
1157 | fname(optzfname, "z"); | |
1158 | fname(setfname, "A"); | |
1159 | } | |
1160 | ||
1161 | ||
1162 | ||
1163 | ||
1164 | rmf(fn) | |
1165 | register char *fn; | |
1166 | { | |
1167 | /* if(!debugflag && fn!=NULL && *fn!='\0') */ | |
1168 | ||
1169 | if(fn!=NULL && *fn!='\0') | |
1170 | unlink(fn); | |
1171 | } | |
1172 | ||
1173 | ||
1174 | ||
1175 | ||
1176 | ||
1177 | LOCAL fname(name, suff) | |
1178 | char *name, *suff; | |
1179 | { | |
dc0e9d50 | 1180 | sprintf(name, "%s/%s%d.%s", _PATH_TMP, temppref, pid, suff); |
d6724028 KB |
1181 | } |
1182 | ||
1183 | ||
1184 | ||
1185 | ||
1186 | dotchar(s) | |
1187 | register char *s; | |
1188 | { | |
1189 | for( ; *s ; ++s) | |
1190 | if(s[0]=='.' && s[1]!='\0' && s[2]=='\0') | |
1191 | return( s[1] ); | |
1192 | return(NO); | |
1193 | } | |
1194 | ||
1195 | ||
1196 | ||
1197 | char *lastfield(s) | |
1198 | register char *s; | |
1199 | { | |
1200 | register char *t; | |
1201 | for(t = s; *s ; ++s) | |
1202 | if(*s == '/') | |
1203 | t = s+1; | |
1204 | return(t); | |
1205 | } | |
1206 | ||
1207 | ||
1208 | ||
1209 | char *lastchar(s) | |
1210 | register char *s; | |
1211 | { | |
1212 | while(*s) | |
1213 | ++s; | |
1214 | return(s-1); | |
1215 | } | |
1216 | ||
1217 | char *setdoto(s) | |
1218 | register char *s; | |
1219 | { | |
1220 | *lastchar(s) = 'o'; | |
1221 | return( lastfield(s) ); | |
1222 | } | |
1223 | ||
1224 | ||
1225 | ||
1226 | badfile(s) | |
1227 | char *s; | |
1228 | { | |
1229 | fatalstr("cannot open intermediate file %s", s); | |
1230 | } | |
1231 | ||
1232 | ||
1233 | ||
1234 | ptr ckalloc(n) | |
1235 | int n; | |
1236 | { | |
1237 | ptr p, calloc(); | |
1238 | ||
1239 | if( p = calloc(1, (unsigned) n) ) | |
1240 | return(p); | |
1241 | ||
1242 | fatal("out of memory"); | |
1243 | /* NOTREACHED */ | |
1244 | } | |
1245 | ||
1246 | ||
1247 | ||
1248 | ||
1249 | ||
1250 | char *copyn(n, s) | |
1251 | register int n; | |
1252 | register char *s; | |
1253 | { | |
1254 | register char *p, *q; | |
1255 | ||
1256 | p = q = (char *) ckalloc(n); | |
1257 | while(n-- > 0) | |
1258 | *q++ = *s++; | |
1259 | return(p); | |
1260 | } | |
1261 | ||
1262 | ||
1263 | ||
1264 | char *copys(s) | |
1265 | char *s; | |
1266 | { | |
1267 | return( copyn( strlen(s)+1 , s) ); | |
1268 | } | |
1269 | ||
1270 | ||
1271 | ||
1272 | ||
1273 | ||
1274 | oneof(c,s) | |
1275 | register c; | |
1276 | register char *s; | |
1277 | { | |
1278 | while( *s ) | |
1279 | if(*s++ == c) | |
1280 | return(YES); | |
1281 | return(NO); | |
1282 | } | |
1283 | ||
1284 | ||
1285 | ||
1286 | nodup(s) | |
1287 | char *s; | |
1288 | { | |
1289 | register char **p; | |
1290 | ||
1291 | for(p = loadargs ; p < loadp ; ++p) | |
1292 | if( !strcmp(*p, s) ) | |
1293 | return(NO); | |
1294 | ||
1295 | return(YES); | |
1296 | } | |
1297 | ||
1298 | ||
1299 | ||
1300 | static fatal(t) | |
1301 | char *t; | |
1302 | { | |
1303 | fprintf(diagfile, "Compiler error in file %s: %s\n", infname, t); | |
1304 | if(debugflag) | |
1305 | abort(); | |
1306 | done(1); | |
1307 | exit(1); | |
1308 | } | |
1309 | ||
1310 | ||
1311 | ||
1312 | ||
1313 | static fatali(t,d) | |
1314 | char *t; | |
1315 | int d; | |
1316 | { | |
1317 | char buff[100]; | |
1318 | sprintf(buff, t, d); | |
1319 | fatal(buff); | |
1320 | } | |
1321 | ||
1322 | ||
1323 | ||
1324 | ||
1325 | static fatalstr(t, s) | |
1326 | char *t, *s; | |
1327 | { | |
1328 | char buff[100]; | |
1329 | sprintf(buff, t, s); | |
1330 | fatal(buff); | |
1331 | } | |
1332 | err(s) | |
1333 | char *s; | |
1334 | { | |
1335 | fprintf(diagfile, "Error in file %s: %s\n", infname, s); | |
1336 | } | |
1337 |