home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 11 / CDACTUAL11.iso / cdactual / demobin / share / os2 / MST / SRC / MSTMAIN.C < prev   
Encoding:
C/C++ Source or Header  |  1995-06-26  |  24.0 KB  |  871 lines

  1. /***********************************************************************
  2.  *
  3.  *      Main Module
  4.  *
  5.  ***********************************************************************/
  6.  
  7. /***********************************************************************
  8.  *
  9.  * Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  10.  * Written by Steve Byrne.
  11.  *
  12.  * This file is part of GNU Smalltalk.
  13.  *
  14.  * GNU Smalltalk is free software; you can redistribute it and/or modify it
  15.  * under the terms of the GNU General Public License as published by the Free
  16.  * Software Foundation; either version 1, or (at your option) any later
  17.  * version.
  18.  *
  19.  * GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  20.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  21.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  22.  * more details.
  23.  *
  24.  * You should have received a copy of the GNU General Public License along with
  25.  * GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  26.  * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  27.  *
  28.  ***********************************************************************/
  29.  
  30.  
  31. /*
  32.  *    Change Log
  33.  * ============================================================================
  34.  * Author      Date       Change
  35.  * sbb       12 Sep 91    Fxied -I argument parsing code to properly gobble up
  36.  *                        the file name.
  37.  *
  38.  * sbyrne    22 May 90    Improved on Doug's mapping with macro to improve
  39.  *                        readability.
  40.  *
  41.  * sbyrne    22 May 90    Short name stuff added, thanks to Doug McCallum.
  42.  *
  43.  * sbyrne    25 Mar 90    ProcessorScheduler is too long of a name for the
  44.  *                        Atari; there are uniqueness problems.  Shortened to
  45.  *                        ProcScheduler.   Also, fixed quietExecution; wasn't
  46.  *                        set when reading from the terminal; should have been
  47.  *                        set to false (since the loading of the quiet things
  48.  *                        is over).
  49.  *
  50.  * sbyrne    15 Oct 89    Added support for creating an "installed" version of
  51.  *                        Smalltalk.  There is now an include file that the
  52.  *                        installer can customize for his site that provides
  53.  *                        default locations to be checked for the kernel .st
  54.  *                        files and the binary image file, but these can be
  55.  *                        overidden in two ways: a) by a file of the same
  56.  *                        name in the user's current directory, or b)
  57.  *                        environment variables SMALLTALK_KERNEL and
  58.  *                        SMALLTALK_IMAGE.
  59.  *
  60.  * sbyrne     4 Jul 89    Added support for user init files (in ~/.stinit),
  61.  *                        which are invoked on every startup.  Also, added
  62.  *                        support for initBlocks, which are blocks that are
  63.  *                        stored in the system and invoked on each startup
  64.  *                        (these could be used, for example, as an interim
  65.  *                        measure for declaring C callouts until the callout
  66.  *                        descriptor is converted to a Smalltalk object).
  67.  *
  68.  * sbyrne    10 Mar 89    Added support for automatically loading image file if
  69.  *                        it's newer than and of the system source files.
  70.  *
  71.  * sbyrne    27 Dec 88    Created.
  72.  *
  73.  */
  74.  
  75.  
  76. #include "mst.h"
  77. #include "mst.tab.h"
  78. #include "mstinterp.h"
  79. #include "mstcomp.h"
  80. #include "mstsave.h"
  81. #include "mstsym.h"             /* for symbol table profiling */
  82. #include "mstoop.h"             /* indirectly defines oopAt for sym tab prof */
  83. #include "mstpaths.h"
  84. #include "mstmain.h"
  85. #include <stdio.h>
  86. #include <sys/types.h>
  87. #include <sys/stat.h>
  88. #include <sys/file.h>
  89. #if defined(USG)
  90. #include <unistd.h>
  91. #endif
  92.  
  93. #ifndef MAXPATHLEN
  94. #define MAXPATHLEN              1024 /* max length of a file and path */
  95. #endif
  96.  
  97. #ifdef SHORTNAMES
  98. #define MAP_FILE(long, short)   short
  99. #else
  100. #define MAP_FILE(long, short)   long
  101. #endif
  102.  
  103.  
  104. #ifndef atarist
  105. #define INIT_FILE_NAME          ".stinit"
  106. #else
  107. #define INIT_FILE_NAME          ".tinit"
  108. #endif
  109.  
  110.  
  111. extern int              yydebug, lexDebug, numFreeOOPs;
  112. extern YYSTYPE          yylval;
  113. extern char             *getenv();
  114.  
  115. #ifdef symbol_table_profiling
  116. extern int              adds, reused, reprobes, hitsOn[];
  117. #endif /* symbol_table_profiling */
  118.  
  119. /* When true, this flag suppresses the printing of execution-related
  120.  * messages, such as the number of byte codes executed by the
  121.  * last expression, etc.
  122.  */
  123. Boolean                 quietExecution;
  124.  
  125. char                    *kernelFileDefaultPath, *imageFileDefaultPath;
  126.  
  127. /* This string contains the printed representation of the Smalltalk version
  128.  * number
  129.  */
  130. char                    versionString[50];
  131.  
  132. static Boolean          processFile(), okToLoadBinary();
  133. static void             loadStandardFiles(), loadUserInitFile(), initPaths(),
  134.                         findKernelFile(), parseArgs(), makeVersionString();
  135. static unsigned long    getFileModifyTime();
  136.  
  137.  
  138. /* Set by cmd line flag.  If true, Smalltalk is more verbose about what it's
  139.  * doing.
  140.  */
  141. static Boolean          verbose = false;
  142.  
  143. /* If true, even both kernel and user method definitions are shown as
  144.  * they are compiled.
  145.  */
  146. static Boolean          traceKernelDeclarations;
  147.  
  148. /* If true, execution tracing is performed when loading kernel method
  149.  * definitions
  150.  */
  151. static Boolean          traceKernelExecution;
  152.  
  153. /* If true, skip date checking of kernel files vs. binary image; pretend
  154.  * that binary image does not exist
  155.  */
  156. static Boolean          ignoreImage;
  157.  
  158.  
  159. /* If non-nil, this is the name of the binary image to load, and overrides
  160.  * the checking of the dates of the kernel source files against the image
  161.  * file date.
  162.  */
  163. static char             *binaryImageName = nil;
  164.  
  165.  
  166. /* Set by command line flag.  When this is true, the interpreter
  167.  * does not print out things like "execution begins" or information
  168.  * about the number of byte codes executed.
  169.  */
  170. static Boolean          runQuietly = false;
  171.  
  172.  
  173. /* The complete list of "kernel" class and method definitions.  Each of
  174.  * these files is loaded, in the order given below.  Their last modification
  175.  * dates are compared against that of the image file; if any are newer,
  176.  * the image file is ignored, these files are loaded, and a new image file
  177.  * is created.
  178.  */
  179. static char             *standardHPFSFiles[] = {
  180.   "builtins.st",
  181.   "Object.st",
  182.   "Message.st",
  183.   "Magnitude.st",
  184.   "Character.st",
  185.   "Date.st",
  186.   "Time.st",
  187.   "Number.st",
  188.   "Float.st",
  189.   "Integer.st",
  190.   "LookupKey.st",
  191.   "Association.st",
  192.   "Link.st",
  193.   "Process.st",
  194.   "Collection.st",
  195.   MAP_FILE("SequenceableCollection.st", "SeqColl.st"),
  196.   "LinkedList.st",
  197.   "Semaphore.st",
  198.   MAP_FILE("ArrayedCollection.st", "ArrColl.st"),
  199.   "Array.st",
  200.   "String.st",
  201.   "Symbol.st",
  202.   "ByteArray.st",
  203.   MAP_FILE("CompiledMethod.st", "CompileMth.st"),
  204.   "Interval.st",
  205.   MAP_FILE("OrderedCollection.st", "OrdColl.st"),
  206.   MAP_FILE("SortedCollection.st", "SortedColl.st"),
  207.   "Bag.st",
  208.   MAP_FILE("MappedCollection.st", "MappedColl.st"),
  209.   "Set.st",
  210.   "Dictionary.st",
  211.   MAP_FILE("IdentityDictionary.st", "IdentDict.st"),
  212.   MAP_FILE("SystemDictionary.st", "SysDict.st"),
  213.   "Stream.st",
  214.   MAP_FILE("PositionableStream.st", "PosStream.st"),
  215.   "ReadStream.st",
  216.   "WriteStream.st",
  217.   MAP_FILE("ReadWriteStream.st", "RWStream.st"),
  218.   "FileStream.st",
  219.   "TokenStream.st",
  220.   "Random.st",
  221.   MAP_FILE("UndefinedObject.st", "UndefObj.st"),
  222.   "Boolean.st",
  223.   "False.st",
  224.   "True.st",
  225.   "ProcessorScheduler.st",
  226.   "Delay.st",
  227.   "SharedQueue.st",
  228.   "Behavior.st",
  229.   MAP_FILE("ClassDescription.st", "ClassDescr.st"),
  230.   "Class.st",
  231.   "Metaclass.st",
  232.   MAP_FILE("MethodContext.st", "MthContext.st"),
  233.   MAP_FILE("BlockContext.st", "BlkContext.st"),
  234.   "Memory.st",
  235.   "WordMemory.st",
  236.   "ByteMemory.st",
  237.   "MethodInfo.st",
  238.   "FileSegment.st",
  239.   "SymLink.st",
  240.   "initialize.st",
  241.   "CFuncs.st",
  242.   "Autoload.st",
  243.   nil
  244. };
  245.  
  246.  
  247.  
  248. static char             *standardFATFiles[] = {
  249.   "builtins.st",
  250.   "Object.st",
  251.   "Message.st",
  252.   "Magnitud.st",
  253.   "Charact.st",
  254.   "Date.st",
  255.   "Time.st",
  256.   "Number.st",
  257.   "Float.st",
  258.   "Integer.st",
  259.   "LookKey.st",
  260.   "Assoc.st",
  261.   "Link.st",
  262.   "Process.st",
  263.   "Collect.st",
  264.   "SeqColl.st",
  265.   "LinkList.st",
  266.   "Semaph.st",
  267.   "ArrColl.st",
  268.   "Array.st",
  269.   "String.st",
  270.   "Symbol.st",
  271.   "ByteArr.st",
  272.   "CompMeth.st",
  273.   "Interval.st",
  274.   "OrdColl.st",
  275.   "Sortcoll.st",
  276.   "Bag.st",
  277.   "MappColl.st",
  278.   "Set.st",
  279.   "Diction.st",
  280.   "IdDict.st",
  281.   "SysDict.st",
  282.   "Stream.st",
  283.   "PosStrm.st",
  284.   "ReadStrm.st",
  285.   "WritStrm.st",
  286.   "RWStrm.st",
  287.   "FileStrm.st",
  288.   "TokStrm.st",
  289.   "Random.st",
  290.   "UndefObj.st",
  291.   "Boolean.st",
  292.   "False.st",
  293.   "True.st",
  294.   "ProcSchd.st",
  295.   "Delay.st",
  296.   "SharedQ.st",
  297.   "Behavior.st",
  298.   "ClsDescr.st",
  299.   "Class.st",
  300.   "Metacls.st",
  301.   "MthCont.st",
  302.   "BlkCont.st",
  303.   "Memory.st",
  304.   "WordMem.st",
  305.   "ByteMem.st",
  306.   "MethInfo.st",
  307.   "FileSeg.st",
  308.   "SymLink.st",
  309.   "init.st",
  310.   "CFuncs.st",
  311.   "Autoload.st",
  312.   nil
  313. };
  314.  
  315.  
  316. static char** standardFiles = standardFATFiles;
  317.  
  318. #ifdef atarist
  319. long _stksize = -1L;            /* what does this do? */
  320. #endif
  321. main(argc, argv)
  322. int     argc;
  323. char    **argv;
  324. {
  325.   Boolean       loadBinary, traceUserDeclarations, traceUserExecution;
  326.   int           filesProcessed;
  327.   char          *imageName;
  328.  
  329. #ifdef USE_MONCONTROL
  330.   moncontrol(0);                /* don't monitor the initial stuff */
  331. #endif /* USE_MONCONTROL */
  332.  
  333.   yydebug = 0;
  334.   traceKernelDeclarations = declareTracing = false;
  335.   traceKernelExecution = executionTracing = false;
  336.   regressionTesting = false;
  337.   ignoreImage = false;
  338.   verbose = false;
  339.  
  340.   initSignals();
  341.   initMem();
  342.   initCFuncs();
  343.   initPaths();
  344.   makeVersionString();
  345. #if defined(USG)
  346.   tzset();
  347. #endif
  348.  
  349.   parseArgs(argc, argv);
  350.  
  351.   imageName = defaultImageName;
  352.  
  353.   if (binaryImageName) {
  354.     loadBinary = true;
  355.     imageName = binaryImageName;
  356.   } else if (ignoreImage) {
  357.     loadBinary = false;
  358.   } else {
  359.     loadBinary = okToLoadBinary(defaultImageName);
  360.   }
  361.  
  362.   if (loadBinary && loadFromFile(imageName)) {
  363.     initDefaultCompilationEnvironment();
  364.     initSTDIOObjects();
  365.     initInterpreter();
  366.     gcOn();
  367.   } else {
  368.     initOOPTable();
  369.     initDictionary();
  370.     initSymbols();
  371.     initInterpreter();
  372.  
  373.     installInitialMethods();
  374.  
  375.     traceUserDeclarations = declareTracing;
  376.     traceUserExecution = executionTracing;
  377.     if (!traceKernelDeclarations) {
  378.       declareTracing = false;
  379.     }
  380.     if (!traceKernelExecution) {
  381.       executionTracing = false;
  382.     }
  383.  
  384.     gcOn();
  385.     loadStandardFiles();
  386.  
  387.     declareTracing = traceUserDeclarations;
  388.     executionTracing = traceUserExecution;
  389.  
  390. /* ***    gcOn(); *** */
  391.     saveToFile(defaultImageName);
  392.   }
  393.  
  394. #ifdef preserved /* Sun Mar 26 23:36:15 1989 */
  395. /**/#ifdef profiling
  396. /**/  monitor(0);
  397. /**/
  398. /**/  printf("results %d/%d\n", hits, misses);
  399. /**/  { int i;
  400. /**/    for (i = 0; i < 10240; i++) {
  401. /**/      if (hitsOn[i]) {
  402. /**/    printf("hitsOn[%d] = %4d\t%d\t%4x\t%8o", i, hitsOn[i],
  403. /**/           i, i, i);
  404. /**/    printObject(oopAt(i));
  405. /**/    printf("\n");
  406. /**/      }
  407. /**/    }
  408. /**/  }
  409. /**/#endif /* profiling */
  410. #endif /* preserved Sun Mar 26 23:36:15 1989 */
  411.  
  412. #ifdef USE_MONCONTROL
  413.   moncontrol(1);
  414. #endif /* USE_MONCONTROL */
  415.  
  416.   invokeInitBlocks();
  417.   loadUserInitFile();
  418.  
  419. #ifdef symbol_table_profiling
  420.   printf("%d adds, %d reused %d reprobes\n", adds, reused, reprobes);
  421.  
  422.   { int i;
  423.     for (i = 0; i < OOP_TABLE_SIZE; i++) {
  424.       if (hitsOn[i]) {
  425.         printf("hitsOn[%d] = %4d\t%d\t%4x\t%8o", i, hitsOn[i],
  426.                i, i, i);
  427.         printObject(oopAt(i));
  428.         printf("\n");
  429.       }
  430.     }
  431.   }
  432. #endif /* symbol_table_profiling */
  433.  
  434.   if (regressionTesting) {
  435.     printf("Smalltalk Ready\n\n");
  436.   } else {
  437.     printf("Smalltalk %s Ready\n\n", versionString);
  438.   }
  439.  
  440.   quietExecution = runQuietly || emacsProcess;
  441. #ifndef LEXDEBUG
  442.   for (filesProcessed = 0; *++argv; ) {
  443.     if (argv[0][0] != '-') {
  444.       processFile(argv[0], quietExecution);
  445.       filesProcessed++;
  446.     } else if (argv[0][1] == '-' || argv[0][1] == '\0') {
  447.       /* either - by itself or -- indicates standard input */
  448.       initLexer(false);
  449. #ifdef USE_READLINE
  450.       pushReadlineString();
  451. #else
  452.       pushUNIXFile(stdin, "stdin");
  453. #endif /* USE_READLINE */
  454.       yyparse();
  455.       popStream(true);
  456.     }
  457.   }
  458.  
  459.   if (filesProcessed == 0) {    /* didn't do any from cmd line, so read stdin*/
  460.     initLexer(false);
  461. #ifdef USE_READLINE
  462.     pushReadlineString();
  463. #else
  464.     pushUNIXFile(stdin, "stdin");
  465. #endif /* USE_READLINE */
  466.     yyparse();
  467.   }
  468.  
  469. #ifdef USE_MONCONTROL
  470.    moncontrol(0);
  471. #endif /* USE_MONCONTROL */
  472.  
  473. #else /* debugging the lexer */
  474.  
  475. #ifdef USE_READLINE
  476.     pushReadlineString();
  477. #else
  478.     pushUNIXFile(stdin, "stdin");
  479. #endif /* USE_READLINE */
  480.  
  481. /********* THIS IS NOT UP TO DATE ... BEWARE ************/
  482.  
  483.   lexDebug = 1;
  484.   while(!feof(infile)) {
  485.     switch (yylex()) {
  486.     case DOT:
  487.       printf("DOT\n");
  488.       break;
  489.     case BANG:
  490.       printf("BANG\n");
  491.       break;
  492.     case COLON:
  493.       printf("COLON\n");
  494.       break;
  495.     case VERTICAL_BAR:
  496.       printf("VERTICAL_BAR\n");
  497.       break;
  498.     case UPARROW:
  499.       printf("UPARROW\n");
  500.       break;
  501.     case ASSIGN:
  502.       printf("ASSIGN\n");
  503.       break;
  504.     case SHARP:
  505.       printf("SHARP\n");
  506.       break;
  507.     case SEMICOLON:
  508.       printf("SEMICOLON\n");
  509.       break;
  510.     case OPEN_PAREN:
  511.       printf("OPEN_PAREN\n");
  512.       break;
  513.     case CLOSE_PAREN:
  514.       printf("CLOSE_PAREN\n");
  515.       break;
  516.     case OPEN_BRACKET:
  517.       printf("OPEN_BRACKET\n");
  518.       break;
  519.     case CLOSE_BRACKET:
  520.       printf("CLOSE_BRACKET\n");
  521.       break;
  522.     case IDENTIFIER:
  523.       printf("IDENTIFIER: %s\n", yylval.sval);
  524.       break;
  525.     case INTEGER_LITERAL:
  526.       printf("INTEGER_LITERAL: %d\n", yylval.ival);
  527.       break;
  528.     case FLOATING_LITERAL:
  529.       printf("FLOATING_LITERAL: %g\n", yylval.fval);
  530.       break;
  531.     case CHAR_LITERAL:
  532.       printf("CHAR_LITERAL: %c\n", yylval.cval);
  533.       break;
  534.     case STRING_LITERAL:
  535.       printf("STRING_LITERAL: %s\n", yylval.sval);
  536.       break;
  537.     case BINOP:
  538.       printf("BINOP: %d\n", yylval.op);
  539.       break;
  540.     }
  541.   }
  542. #endif /* LEXDEBUG */
  543. }
  544.  
  545. /*
  546.  *      static void initPaths()
  547.  *
  548.  * Description
  549.  *
  550.  *      Sets up the paths for the kernel source directory and for where the
  551.  *      saved Smalltalk binary image lives.  Uses environment variables
  552.  *      SMALLTALK_KERNEL and SMALLTALK_IMAGE if they are set, otherwise uses
  553.  *      the paths assigned in mstpaths.h.
  554.  *
  555.  */
  556. static void initPaths()
  557. {
  558.   if ((kernelFileDefaultPath = (char *)getenv("SMALLTALK_KERNEL")) == nil) {
  559.     kernelFileDefaultPath = KERNEL_PATH;
  560.   }
  561.  
  562.   if ((imageFileDefaultPath = (char *)getenv("SMALLTALK_IMAGE")) == nil) {
  563.     imageFileDefaultPath = IMAGE_PATH;
  564.   }
  565. }
  566.  
  567. static Boolean okToLoadBinary(imageFileName)
  568. char    *imageFileName;
  569. {
  570.   unsigned long imageFileTime;
  571.   char          **fileNames, fullFileName[MAXPATHLEN],
  572.                 fullImageName[MAXPATHLEN];
  573.  
  574.   findImageFile(imageFileName, fullImageName);
  575.   imageFileTime = getFileModifyTime(fullImageName);
  576.  
  577.   if ((long)imageFileTime == -1) { /* not found */
  578.     return (false);
  579.   }
  580.  
  581.   for (fileNames = standardFiles; *fileNames; fileNames++) {
  582.     findKernelFile(*fileNames, fullFileName);
  583.     if (imageFileTime < getFileModifyTime(fullFileName)) {
  584.       return (false);
  585.     }
  586.   }
  587.  
  588.   return (true);
  589. }
  590.  
  591. static unsigned long getFileModifyTime(fileName)
  592. char    *fileName;
  593. {
  594.   struct stat   st;
  595.  
  596.   if (stat(fileName, &st) < 0) {
  597.     return ((unsigned long) -1);
  598.   } else {
  599.     return (st.st_mtime);
  600.   }
  601. }
  602.  
  603. /*
  604.  *      static void loadStandardFiles()
  605.  *
  606.  * Description
  607.  *
  608.  *      Loads the kernel Smalltalk files.  It uses a vector of file names, and
  609.  *      loads each file individually.  To provide for greater flexibility, if a
  610.  *      one of the files exists in the current directory, that is used in
  611.  *      preference to one in the default location.  The default location can be
  612.  *      overridden at runtime by setting the SMALLTALK_KERNEL environment
  613.  *      variable.
  614.  *
  615.  */
  616. static void loadStandardFiles()
  617. {
  618.   char          **fileNames, fullFileName[MAXPATHLEN];
  619.  
  620.   for (fileNames = standardFiles; *fileNames; fileNames++) {
  621.     findKernelFile(*fileNames, fullFileName);
  622.     if (!processFile(fullFileName, true)) {
  623.       fprintf(stderr,
  624.               "Can't find system file '%s', proceeding without it.\n",
  625.               fullFileName);
  626.     }
  627.   }
  628. }
  629.  
  630.  
  631. /*
  632.  *      static void findKernelFile(fileName, fullFileName)
  633.  *
  634.  * Description
  635.  *
  636.  *      Attempts to find a viable kernel Smalltalk file (.st file).  First
  637.  *      tries the current directory to allow for overriding installed kernel
  638.  *      files.  If that isn't found, the full path name of the installed kernel
  639.  *      file is stored in fullFileName.  Note that the directory part of the
  640.  *      kernel file name in this second case can be overridden by defining the
  641.  *      SMALLTALK_KERNEL environment variable to be the directory that should
  642.  *      serve as the kernel directory instead of the installed one.
  643.  *
  644.  * Inputs
  645.  *
  646.  *      fileName:
  647.  *              A simple file name, sans directory.
  648.  *      fullFileName:
  649.  *              The file name to use for the particular kernel file is returned
  650.  *              in this variable (which must be a string large enough for any
  651.  *              file name).  If there is a file in the current directory with
  652.  *              name "fileName", that is returned; otherwise the kernel path is
  653.  *              prepended to fileName (separated by a slash, of course) and
  654.  *              that is stored in the string pointed to by "fullFileName".
  655.  *
  656.  */
  657. static void findKernelFile(fileName, fullFileName)
  658. char *fileName, *fullFileName;
  659. {
  660.   if (access(fileName, R_OK) == 0) {
  661.     strcpy(fullFileName, fileName);
  662.   } else {
  663.     sprintf(fullFileName, "%s/%s", kernelFileDefaultPath, fileName);
  664.   }
  665. }
  666.  
  667.  
  668. static void loadUserInitFile()
  669. {
  670.   char          fileName[MAXPATHLEN], *home;
  671.  
  672.   if ((home = (char *)getenv("HOME")) != nil) {
  673.     sprintf(fileName, "%s/%s", home, INIT_FILE_NAME);
  674.     processFile(fileName, quietExecution);
  675.   }
  676. }
  677.  
  678. static Boolean processFile(fileName, quiet)
  679. char    *fileName;
  680. Boolean quiet;
  681. {
  682.   FILE          *file;
  683.  
  684.   file = fopen(fileName, "r");
  685.   if (file == NULL) {
  686.     return (false);
  687.   }
  688.  
  689.   if (verbose) {
  690.     printf("Processing %s\n", fileName);
  691.   }
  692.  
  693.   quietExecution = quiet;
  694.   initLexer(false);
  695.   pushUNIXFile(file, fileName);
  696.   yyparse();
  697.   popStream(true);
  698.  
  699.   return (true);
  700. }
  701.  
  702. /*
  703.  *      static void findImageFile(fileName, fullFileName)
  704.  *
  705.  * Description
  706.  *
  707.  *      Attempts to find a viable Smalltalk image file.  First
  708.  *      tries the current directory to allow for overriding installed image
  709.  *      files.  If that isn't found, the full path name of the installed image
  710.  *      file is stored in fullFileName.  Note that the directory part of the
  711.  *      image file name in this second case can be overridden by defining the
  712.  *      SMALLTALK_IMAGE environment variable to be the directory that should
  713.  *      serve as the image directory instead of the installed one.
  714.  *
  715.  * Inputs
  716.  *
  717.  *      fileName:
  718.  *              A simple file name, sans directory.
  719.  *      fullFileName:
  720.  *              The file name to use for the particular image file is returned
  721.  *              in this variable (which must be a string large enough for any
  722.  *              file name).  If there is a file in the current directory with
  723.  *              name "fileName", that is returned; otherwise the kernel path is
  724.  *              prepended to fileName (separated by a slash, of course) and
  725.  *              that is stored in the string pointed to by "fullFileName".
  726.  *
  727.  */
  728. void findImageFile(fileName, fullFileName)
  729. char *fileName, *fullFileName;
  730. {
  731.   if (access(fileName, R_OK) == 0) {
  732.     strcpy(fullFileName, fileName);
  733.   } else {
  734.     sprintf(fullFileName, "%s/%s", imageFileDefaultPath, fileName);
  735.   }
  736. }
  737.  
  738.  
  739. /*
  740.  *      static void parseArgs(argc, argv)
  741.  *
  742.  * Description
  743.  *
  744.  *      This routine scans the command line arguments, accumulating information
  745.  *      and setting flags.  This will probably be replaced by getopt in a
  746.  *      future version of Smalltalk.
  747.  *
  748.  * Inputs
  749.  *
  750.  *      argc  : The number of arguments present
  751.  *      argv  : Vector of strings that are the arguments.
  752.  *
  753.  */
  754. static void parseArgs(argc, argv)
  755. int     argc;
  756. char    **argv;
  757. {
  758.   char          **hp, **av;
  759.   char          *flags;
  760.  
  761.   static char   *helpText[] = {
  762. "GNU Smalltalk usage:",
  763. "",
  764. "    mst [ flag ... ] [ file ...]",
  765. "",
  766. "Flags can appear either as -xyz or as -x -y -z.  The currently",
  767. "defined set of flags is:",
  768. "  -c\tDump core on fatal signal",
  769. "  -d\tTrace compilation of user specified files",
  770. "  -D\tTrace compilation of kernel and user files",
  771. "  -e\tTrace execution of files specified on command line",
  772. "  -E\tTrace execution of kernel and user files",
  773. "  -H -h -?  Print this message and exit",
  774. "  -i\tIgnore the image file; rebuild it from scratch",
  775. "  -I file\tUse 'file' as the image file, instead of 'mst.im'",
  776. "  -p\tRun Smalltalk as a 'process', i.e. from within GNU Emacs",
  777. "  -q\tRun Smalltalk without printing execution information",
  778. "  -r\tRun in regression test mode (printed messages are made constant)",
  779. "  -v\tPrint the Smalltalk version number",
  780. "  -V\tEnable verbose mode",
  781. "  -y\tTurn on debugging in the parser",
  782. "  -L\tUse long HPFS filenames",
  783. "  - --\tRead input from standard input explicitly",
  784. "",
  785. "Files are loaded one after the other.  After the last one is loaded,",
  786. "Smalltalk will exit.  If no files are specified, Smalltalk reads from",
  787. "the terminal, with prompts.",
  788. NULL
  789. };
  790.  
  791.  
  792.   for ( ; *++argv; ) {
  793.     if (argv[0][0] == '-') {
  794.       for (flags = &argv[0][1]; *flags; flags++) {
  795.         switch (*flags) {
  796.         case 'c':
  797.           makeCoreFile = true;
  798.           break;
  799.         case 'D':
  800.           traceKernelDeclarations = true; /* fall thru */
  801.         case 'd':
  802.           declareTracing = true;
  803.           break;
  804.         case 'E':
  805.           traceKernelExecution = true; /* fall thru */
  806.         case 'e':
  807.           executionTracing = true;
  808.           break;
  809.         case 'h': case 'H': case '?':
  810.         default:
  811.           for (hp = helpText; *hp != NULL; hp++) {
  812.             printf("%s\n", *hp);
  813.           }
  814.           exit(0);
  815.         case 'I':
  816.           binaryImageName = argv[1];
  817.           for (av = argv+1; *av; av++) {        /* remove this argument */
  818.             *av = *(av+1);
  819.           }
  820.           break;
  821.         case 'i':
  822.           ignoreImage = true;
  823.           break;
  824.         case 'p':
  825.           emacsProcess = true;
  826.           break;
  827.         case 'q':
  828.           runQuietly = true;
  829.           break;
  830.         case 'r':
  831.           regressionTesting = true;
  832.           break;
  833.         case 'V':
  834.           verbose = true;
  835.           break;
  836.         case 'v':
  837.           printf("GNU Smalltalk version %s\n", versionString);
  838.           printf("Copyright (C) 1990, 1991 Free Software Foundation, Inc.\n");
  839.           printf("Written by Steve Byrne.\n");
  840.           printf("Using kernel path: %s\n", kernelFileDefaultPath);
  841.           printf("Using image path : %s\n", imageFileDefaultPath);
  842.           break;
  843.         case 'y':
  844.           yydebug = 1;
  845.           break;
  846.         case 'L':
  847.           standardFiles = standardHPFSFiles;
  848.         case '-':               /* this means standard input, so it's ok */
  849.           break;
  850.         }
  851.       }
  852.     }
  853.   }
  854.  
  855.   if (regressionTesting) {
  856.     traceKernelDeclarations = declareTracing = false;
  857.     traceKernelExecution = executionTracing = false;
  858.     verbose = false;
  859.   }
  860. }
  861.  
  862. static void makeVersionString()
  863. {
  864.   if (sysVersEdit != 0) {
  865.     sprintf(versionString, "%d.%d.%d", sysVersMajor, sysVersMinor,
  866.             sysVersEdit);
  867.   } else {
  868.     sprintf(versionString, "%d.%d", sysVersMajor, sysVersMinor);
  869.   }
  870. }
  871.