home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / pascal / src / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-16  |  9.9 KB  |  471 lines

  1. /*-
  2.  * Copyright (c) 1980 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. char copyright[] =
  36. "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)main.c    5.3 (Berkeley) 4/16/91";
  42. #endif /* not lint */
  43.  
  44. #include "whoami.h"
  45. #include "0.h"
  46. #include "tree_ty.h"        /* must be included for yy.h */
  47. #include "yy.h"
  48. #include <signal.h>
  49. #include "objfmt.h"
  50. #include "config.h"
  51.  
  52. /*
  53.  * This version of pi has been in use at Berkeley since May 1977
  54.  * and is very stable. Please report any problems with the error
  55.  * recovery to the second author at the address given in the file
  56.  * READ_ME.  The second author takes full responsibility for any bugs
  57.  * in the syntactic error recovery.
  58.  */
  59.  
  60. char    piusage[]    = "pi [ -blnpstuw ] [ -i file ... ] name.p";
  61.  
  62. char    *usageis    = piusage;
  63.  
  64. #ifdef OBJ
  65.  
  66. char    pixusage[]    = "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]";
  67. char    *obj    = "obj";
  68.  
  69. #endif OBJ
  70.  
  71. #ifdef PC
  72.  
  73. char    *pcname = "pc.pc0";
  74. char    pcusage[]    = "pc [ options ] [ -o file ] [ -i file ... ] name.p";
  75. FILE    *pcstream = NULL;
  76.  
  77. #endif PC
  78. #ifdef PTREE
  79.     char    *pTreeName = "pi.pTree";
  80. #endif PTREE
  81.  
  82. int    onintr();
  83.  
  84. extern    char *lastname;
  85.  
  86. FILE    *ibuf;
  87.  
  88. /*
  89.  * these are made real variables
  90.  * so they can be changed
  91.  * if you are compiling on a smaller machine
  92.  */
  93. double    MAXINT    =  2147483647.;
  94. double    MININT    = -2147483648.;
  95.  
  96. /*
  97.  * Main program for pi.
  98.  * Process options, then call yymain
  99.  * to do all the real work.
  100.  */
  101. main(argc, argv)
  102.     int argc;
  103.     char *argv[];
  104. {
  105.     register char *cp;
  106.     register c;
  107.     FILE *fopen();
  108.     extern char *myctime();
  109.     extern long lseek();
  110.     int i;
  111.  
  112.     if (argv[0][0] == 'a')
  113.         err_file += err_pathlen , how_file += how_pathlen;
  114. #    ifdef OBJ
  115.         if (argv[0][0] == '-' && argv[0][1] == 'o') {
  116.             obj = &argv[0][2];
  117.             usageis = pixusage;
  118.             how_file[strlen(how_file)] = 'x';
  119.             ofil = 3;
  120.         } else {
  121.             ofil = creat(obj, 0755);
  122.             if (ofil < 0) {
  123.                 perror(obj);
  124.                 pexit(NOSTART);
  125.             }
  126.         }
  127. #    endif OBJ
  128.     argv++, argc--;
  129.     if (argc == 0) {
  130.         i = fork();
  131.         if (i == -1)
  132.             goto usage;
  133.         if (i == 0) {
  134.             execl("/bin/cat", "cat", how_file, 0);
  135.             goto usage;
  136.         }
  137.         while (wait(&i) != -1)
  138.             continue;
  139.         pexit(NOSTART);
  140.     }
  141. #    ifdef OBJ
  142.         opt('p') = opt('t') = opt('b') = 1;
  143. #if defined(vax) || defined(tahoe)
  144.         /* pdx is currently supported on the vax and the tahoe */
  145.         opt('g') = 1;
  146. #endif
  147.         while (argc > 0) {
  148.             cp = argv[0];
  149.             if (*cp++ != '-')
  150.                 break;
  151.             while (c = *cp++) switch (c) {
  152. #ifdef DEBUG
  153.                 case 'k':
  154.                 case 'r':
  155.                 case 'y':
  156.                     togopt(c);
  157.                     continue;
  158.                 case 'K':
  159.                     yycosts();
  160.                     pexit(NOSTART);
  161.                 case 'A':
  162.                     testtrace = TRUE;
  163.                 case 'F':
  164.                     fulltrace = TRUE;
  165.                 case 'E':
  166.                     errtrace = TRUE;
  167.                     opt('r')++;
  168.                     continue;
  169.                 case 'U':
  170.                     yyunique = FALSE;
  171.                     continue;
  172. #endif
  173.                 case 'b':
  174.                     opt('b') = 2;
  175.                     continue;
  176.                 case 'i':
  177.                     pflist = argv + 1;
  178.                     pflstc = 0;
  179.                     while (argc > 1) {
  180.                         if (dotted(argv[1], 'p'))
  181.                             break;
  182.                         pflstc++, argc--, argv++;
  183.                     }
  184.                     if (pflstc == 0)
  185.                         goto usage;
  186.                     continue;
  187.                 case 'g':
  188.                 case 'l':
  189.                 case 'n':
  190.                 case 'p':
  191.                 case 's':
  192.                 case 't':
  193.                 case 'u':
  194.                 case 'w':
  195.                     togopt(c);
  196.                     continue;
  197.                 case 'z':
  198.                     monflg = TRUE;
  199.                     continue;
  200.                 case 'L':
  201.                     togopt( 'L' );
  202.                     continue;
  203.                 default:
  204.     usage:
  205.                     Perror( "Usage", usageis);
  206.                     pexit(NOSTART);
  207.             }
  208.             argc--, argv++;
  209.         }
  210. #    endif OBJ
  211. #    ifdef PC
  212.         opt( 'b' ) = 1;
  213.         opt( 'g' ) = 0;
  214.         opt( 't' ) = 0;
  215.         opt( 'p' ) = 0;
  216.         usageis = pcusage;
  217.         while ( argc > 0 ) {
  218.         cp = argv[0];
  219.         if ( *cp++ != '-' ) {
  220.             break;
  221.         }
  222.         c = *cp++;
  223.         switch( c ) {
  224. #ifdef DEBUG
  225.             case 'k':
  226.             case 'r':
  227.             case 'y':
  228.                 togopt(c);
  229.                 break;
  230.             case 'K':
  231.                 yycosts();
  232.                 pexit(NOSTART);
  233.             case 'A':
  234.                 testtrace = TRUE;
  235.                 /* and fall through */
  236.             case 'F':
  237.                 fulltrace = TRUE;
  238.                 /* and fall through */
  239.             case 'E':
  240.                 errtrace = TRUE;
  241.                 opt('r')++;
  242.                 break;
  243.             case 'U':
  244.                 yyunique = FALSE;
  245.                 break;
  246. #endif
  247.             case 'b':
  248.                 opt('b') = 2;
  249.                 break;
  250.             case 'i':
  251.                 pflist = argv + 1;
  252.                 pflstc = 0;
  253.                 while (argc > 1) {
  254.                     if (dotted(argv[1], 'p'))
  255.                         break;
  256.                     pflstc++, argc--, argv++;
  257.                 }
  258.                 if (pflstc == 0)
  259.                     goto usage;
  260.                 break;
  261.             /*
  262.              *    output file for the first pass
  263.              */
  264.             case 'o':
  265.                 if ( argc < 2 ) {
  266.                 goto usage;
  267.                 }
  268.                 argv++;
  269.                 argc--;
  270.                 pcname = argv[0];
  271.                 break;    
  272.             case 'J':
  273.                 togopt( 'J' );
  274.                 break;
  275.             case 'C':
  276.                 /*
  277.                  * since -t is an ld switch, use -C
  278.                  * to turn on tests
  279.                  */
  280.                 togopt( 't' );
  281.                 break;
  282.             case 'g':
  283.                 /*
  284.                  *    sdb symbol table
  285.                  */
  286.                 togopt( 'g' );
  287.                 break;
  288.             case 'l':
  289.             case 's':
  290.             case 'u':
  291.             case 'w':
  292.                 togopt(c);
  293.                 break;
  294.             case 'p':
  295.                 /*
  296.                  *    -p on the command line means profile
  297.                  */
  298.                 profflag = TRUE;
  299.                 break;
  300.             case 'z':
  301.                 monflg = TRUE;
  302.                 break;
  303.             case 'L':
  304.                 togopt( 'L' );
  305.                 break;
  306.             default:
  307. usage:
  308.                 Perror( "Usage", usageis);
  309.                 pexit(NOSTART);
  310.         }
  311.         argc--;
  312.         argv++;
  313.         }
  314. #    endif PC
  315.     if (argc != 1)
  316.         goto usage;
  317.     efil = open ( err_file, 0 );
  318.     if ( efil < 0 )
  319.         perror(err_file), pexit(NOSTART);
  320.     filename = argv[0];
  321.     if (!dotted(filename, 'p')) {
  322.         Perror(filename, "Name must end in '.p'");
  323.         pexit(NOSTART);
  324.     }
  325.     close(0);
  326.     if ( ( ibuf = fopen( filename , "r" ) ) == NULL )
  327.         perror(filename), pexit(NOSTART);
  328.     ibp = ibuf;
  329. #    ifdef PC
  330.         if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) {
  331.         perror( pcname );
  332.         pexit( NOSTART );
  333.         }
  334.         stabsource( filename, TRUE );
  335. #    endif PC
  336. #    ifdef PTREE
  337. #        define    MAXpPAGES    16
  338.         if ( ! pCreate( pTreeName , MAXpPAGES ) ) {
  339.         perror( pTreeName );
  340.         pexit( NOSTART );
  341.         }
  342. #    endif PTREE
  343.     if ( signal( SIGINT , SIG_IGN ) != SIG_IGN )
  344.         (void) signal( SIGINT , onintr );
  345.     if (opt('l')) {
  346.         opt('n')++;
  347.         yysetfile(filename);
  348.         opt('n')--;
  349.     }
  350.     yymain();
  351.     /* No return */
  352. }
  353.  
  354. pchr(c)
  355.     char c;
  356. {
  357.  
  358.     putc ( c , stdout );
  359. }
  360.  
  361. #ifdef PC
  362. char    ugh[]    = "Fatal error in pc\n";
  363. #endif
  364. #ifdef OBJ
  365. char    ugh[]    = "Fatal error in pi\n";
  366. #endif
  367. /*
  368.  * Exit from the Pascal system.
  369.  * We throw in an ungraceful termination
  370.  * message if c > 1 indicating a severe
  371.  * error such as running out of memory
  372.  * or an internal inconsistency.
  373.  */
  374. pexit(c)
  375.     int c;
  376. {
  377.  
  378.     if (opt('l') && c != DIED && c != NOSTART)
  379.         while (getline() != -1)
  380.             continue;
  381.     yyflush();
  382.     switch (c) {
  383.         case DIED:
  384.             write(2, ugh, sizeof ugh);
  385.         case NOSTART:
  386.         case ERRS:
  387. #            ifdef OBJ
  388.                 if (ofil > 0)
  389.                     unlink(obj);
  390.             /*
  391.              * remove symbol table temp files
  392.              */
  393.                 removenlfile();
  394.  
  395. #            endif OBJ
  396. #            ifdef PC
  397.                 if ( pcstream != NULL ) {
  398.                 unlink( pcname );
  399.                 }
  400. #            endif PC
  401.             break;
  402.         case AOK:
  403. #            ifdef OBJ
  404.                 pflush();
  405.             /*
  406.              * copy symbol table temp files to obj file
  407.              */
  408.                 copynlfile();
  409.  
  410. #            endif OBJ
  411. #            ifdef PC
  412.                 puteof();
  413. #            endif PC
  414.             break;
  415.     }
  416.     /*
  417.      *    this to gather statistics on programs being compiled
  418.      *    taken 20 june 79     ... peter
  419.      *
  420.      *  if (fork() == 0) {
  421.      *      char *cp = "-0";
  422.      *      cp[1] += c;
  423.      *      execl("/usr/lib/gather", "gather", cp, filename, 0);
  424.      *      exit(1);
  425.      *  }
  426.      */
  427. #    ifdef PTREE
  428.         pFinish();
  429. #    endif
  430.     exit(c);
  431. }
  432.  
  433. onintr()
  434. {
  435.  
  436.     (void) signal( SIGINT , SIG_IGN );
  437.     pexit(NOSTART);
  438. }
  439.  
  440. /*
  441.  * Get an error message from the error message file
  442.  */
  443. geterr(seekpt, buf)
  444.     int seekpt;
  445.     char *buf;
  446. {
  447.  
  448.     (void) lseek(efil, (long) seekpt, 0);
  449.     if (read(efil, buf, 256) <= 0)
  450.         perror(err_file), pexit(DIED);
  451. }
  452.  
  453. header()
  454. {
  455.     extern char *version;
  456.     static char anyheaders;
  457.  
  458.     gettime( filename );
  459.     if (anyheaders && opt('n'))
  460.         putc( '\f' , stdout );
  461.     anyheaders++;
  462. #    ifdef OBJ
  463.         printf("Berkeley Pascal PI -- Version %s\n\n%s  %s\n\n",
  464.             version, myctime((int *) (&tvec)), filename);
  465. #    endif OBJ
  466. #    ifdef PC
  467.         printf("Berkeley Pascal PC -- Version %s\n\n%s  %s\n\n",
  468.             version, myctime((int *) (&tvec)), filename);
  469. #    endif PC
  470. }
  471.