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

Defined functions

argvtos defined in line 623; used 2 times
await defined in line 1058; used 2 times
badfile defined in line 1279; never used
ckalloc defined in line 1287; used 5 times
clf defined in line 1141; never used
content defined in line 1174; never used
copyn defined in line 1304; used 1 times
copys defined in line 1318; used 2 times
crfnames defined in line 1201; used 1 times
doasm defined in line 741; used 1 times
dofort defined in line 670; used 3 times
doload defined in line 842; used 1 times
done defined in line 1010; used 8 times
dopass2 defined in line 714; used 1 times
dotchar defined in line 1239; used 2 times
enbint defined in line 1028; used 5 times
err defined in line 1386; used 1 times
fatal defined in line 1354; used 14 times
fatali defined in line 1367; used 1 times
fatalstr defined in line 1379; used 6 times
fname defined in line 1230; used 9 times
intrupt defined in line 1044; used 3 times
lastchar defined in line 1262; used 6 times
lastfield defined in line 1250; used 6 times
main defined in line 175; never used
nodup defined in line 1340; used 5 times
oneof defined in line 1328; used 1 times
rmf defined in line 1217; used 17 times
rmfiles defined in line 1153; used 1 times
setdoto defined in line 1270; used 7 times
stupid defined in line 1123; used 1 times
sys defined in line 901; used 14 times
texec defined in line 987; used 3 times
unreadable defined in line 1103; used 4 times

Defined variables

aoutname defined in line 123; used 9 times
asmfname defined in line 128; used 15 times
asmname defined in line 116; used 6 times
asmpass2 defined in line 129; used 17 times
cflags defined in line 139; used 4 times
cppargs defined in line 152; used 4 times
cppflags defined in line 151; used 2 times
cppname defined in line 122; used 1 times
eflagp defined in line 149; used 2 times
eflags defined in line 143; used 2 times
f2flagp defined in line 148; used 3 times
f2flags defined in line 138; used 2 times
fflagp defined in line 147; used 17 times
fflags defined in line 137; used 2 times
footname defined in line 118; used 2 times
harmless defined in line 1054; used 1 times
infname defined in line 126; used 14 times
initfname defined in line 130; used 11 times
ldname defined in line 117; used 4 times
lflag defined in line 146; used 2 times
loadargs defined in line 153; used 10 times
loadp defined in line 154; used 17 times
macroname defined in line 120; used 2 times
ncpp defined in line 172; used 3 times
objfdefault defined in line 133; used 2 times
optzfname defined in line 134; used 4 times
pass1name defined in line 113; used 2 times
pass2name defined in line 114; used 5 times
pass2opt defined in line 115; used 2 times
pid defined in line 107; used 4 times
prepfname defined in line 132; used 4 times
proffoot defined in line 119; used 2 times
rflagp defined in line 150; used 2 times
rflags defined in line 145; used 2 times
sccsid defined in line 8; never used
setfname defined in line 135; used 5 times
shellname defined in line 121; used 2 times
sighvalue defined in line 110; used 2 times
sigivalue defined in line 108; used 2 times
sigqvalue defined in line 109; used 2 times
sigtvalue defined in line 111; used 2 times
sortfname defined in line 131; used 1 times
temppref defined in line 124; used 2 times
textfname defined in line 127; used 7 times
xxxvers defined in line 83; never used

Defined struct's

stat defined in line 1178; used 2 times

Defined macros

NOCORE defined in line 96; used 1 times
PSIGNAL defined in line 98; used 5 times
SBUFINCR defined in line 620; used 4 times
SBUFMAX defined in line 621; used 1 times
Last modified: 1986-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4023
Valid CSS Valid XHTML 1.0 Strict