/*$Header: /a/rathlin/disk/src/master/edml/EDML4/fam.src/UPTODATE/RCS/fam.c,v 5.1 91/09/05 18:24:02 edml Exp $*/

#include <stdio.h>
#include <ctype.h>
#include "globdefs.h"
#include "structs.h"
#include "globvars.h"
#include "debug.h"
#include "io.h"

#ifdef CWIN
#include "cwin.h"
#endif

extern LWord *OldEnd;  /* MK-GC */

FatalError(errorText)
char *errorText;
{
#ifdef CWIN
  printf("\nFatal Error: %s\n", errorText);
#else
  fprintf(stderr, "\nFatal Error: %s\n", errorText);
  perror("");  
#endif
  exit(1); }

FILE *std_input = 0, *std_log = 0;

main(argc,argv)
int argc; char *argv[];
{  int     i;  int noisy = 1; int recon = 0; int flushing = 1;
   char *bootfile, *input_file = 0, *log_file = 0;
   char ProgArg[80];  /* It is intended that this string will eventually
                         be passed to the saved state as an argument */
    std_input = std_log = 0;
#ifdef CWIN
    strcpy(about_box_title,        "About CML");
    strcpy(about_box_description,  "CML 1.02 for Win32(s)");
    strcpy(about_box_rights_1,     "Copyright Univ. Edinburgh &&");
    strcpy(about_box_rights_2,     "A C Norman.            1994");
    cwin_pause_at_end = 1;
    cwin_report_mid("CML 1.02");
    cwin_report_right("A C Norman, 1994");
    cwin_ensure_screen();
#endif

/* for some reason there are lots of these calls for the risc_os port */
#ifdef RISC_OS
   SetupIntHandler();
#endif
   i = 1;
   while (i < argc && argv[i]!=0 && argv[i][0] == '-')
      switch (tolower(argv[i++][1])) {

      case 'h': if (i == argc) break;
                if (sscanf(argv[i++], "%d", &HeapSize) != 1  ||
                    HeapSize >= 32*1024)
                   FatalError("-h <heapsize in kbytes> expected");
                HeapSize *= 1024;
                break;
      case 'i': if (i == argc) break;
                input_file = argv[i++];
                break;
      case 'l': if (i == argc) break;
                log_file = argv[i++];
                break;
      case 's': break;               /* System builder */
      case 'q': noisy = 0; break;    /* Suppresses initial messages */
      case 'b': flushing = 0; break; /* disables effect of famflush() */
      case 'r': recon = 1; break;    /* Allows heap reconfiguration */
      case 'd': dynamicprof = 1;break; /*AJG: turns on dynamic scanning */
      /*
       * The next (-p) flag allows running down pipes to collect scripts...
       *
       * Sam Nelson, Stirling Univ., 20.1.88.
       */
      case 'p':
        faketty=1;
#ifndef CWIN
        setbuf(stdout,NULL);
#endif
        break;
#ifdef DEBUGinterp
      case 'o': strcpy(OpNameFile,argv[i++]) ; break ;
      default:
         FatalError("fam [-d] [-q] [-p] [-h n] [-o file] bootfile [args] expected") ;
#else
      default:
         FatalError("fam [-d] [-q] [-p] [-h n] bootfile [args] expected");
#endif
      }

    std_input = 0;    
    if (input_file != 0) std_input = fopen(input_file, "r");
    std_log = 0;    
    if (log_file != 0) std_log = fopen(log_file, "w");
#ifdef CWIN
/* I argue here that if there is a log file the user can see everything
 * there & does not need a pause at the end of the run. */
    if (std_log != 0) cwin_pause_at_end = 0;
#endif
#ifdef RISC_OS
   SetupIntHandler();
   SetupIntHandler();
#endif
#ifdef CWIN
#  define MY_NAME cwin_full_program_name
#endif
#ifdef DOS386
#  define MY_NAME argv[0]
#endif
   bootfile = "-";
   if (i < argc) bootfile = argv[i++];
   if (bootfile == NULL || bootfile[0] == '-' || bootfile[0] == 0)
   {
#ifdef MY_NAME
/*
 * If my executable image was aaaa.exe I look in aaaa.exp for the image file
 */
       char *p;
       strcpy(ProgArg, MY_NAME);
       p = ProgArg + strlen(ProgArg);
       if (toupper(*--p) == 'E' &&
           toupper(*--p) == 'X' &&
           toupper(*--p) == 'E' &&
           toupper(*--p) == '.')
       {   p++;
           *p++ = 'E';
           *p++ = 'X';
           *p++ = 'P';
           *p = 0;
           bootfile = (char *)malloc(strlen(ProgArg) + 1);
           if (bootfile != NULL) strcpy(bootfile, ProgArg);
       }
       else bootfile = NULL;
       if (bootfile == NULL)
#endif
           FatalError("fam [-q] [-p] [-h n] bootfile [args] expected");
   }


   ProgArg[0] = 0; if (i < argc) strcpy(ProgArg, argv[i++]);
   for (; i < argc; i++) {strcat(ProgArg, " "); strcat(ProgArg, argv[i]);}

   if (noisy)
      printf ("FAM %s started on %s \n   (version %s%s of %s)\n",
              argv[0], datestring(DateInUnix()),
              verstring(VERSION), SUBVERSION, filecreationdate(argv[0]));

   CreateInitialHeapSpace();
   CurrentState = (State *)ImportState(bootfile, noisy, recon);

   Seed = TodInS() & 0x7fff;

   SetupStreams(flushing);
#ifdef READLINE
   SetupReadline(argv[0]);
#endif
   SetupExceptions();
   ResetConstants();
   SetTopProcess();
   SetupIntHandler();

   OldEnd=EndOfASpace;
   Wall=MidOfASpace;
   SetUpResAndFree();    /* Putting these 3 lines here means that its
                            not possible to call a GC from the 
                            reconfiguration editor [MK] */

   RunState();

   exit(0);
}

