/* -*-c-*- -------------- mixvm.c :
 * Main function for mixvm, the mix vm simulator
 * ------------------------------------------------------------------
 * Copyright (C) 2000 Free Software Foundation, Inc.
 *  
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *  
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *  
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *  
 */



#include <mixlib/mix.h>
#include <mixlib/mix_vm.h>
#include <mixlib/mix_vm_dump.h>

#include <stdlib.h>
#include <stdio.h>

#ifdef HAVE_GETOPT_LONG
#  include <getopt.h>
#else
#  include <lib/getopt.h>
#endif /* HAVE_GETOPT_LONG */

extern void
mix_vmloop (int argc, char *argv[], const gchar *code_file, gboolean use_emacs);

extern void
mix_vmrun (const gchar *code_file, gboolean dump);

enum {
  VER_OPT = 'v',
  HELP_OPT = 'h',
  USAGE_OPT = 'u',
  RUN_OPT = 'r',
  DUMP_OPT = 'd',
  EMACS_OPT = 'e',	/* used by mixvm-gud only */
};

static const char *options_ = "vhurd"; /* no short opt for --emacs */

static struct option long_options_[] =
{
  {"version", no_argument, 0, VER_OPT},
  {"help", no_argument, 0, HELP_OPT},
  {"usage", no_argument, 0, USAGE_OPT},
  {"run", required_argument, 0, RUN_OPT},
  {"dump", no_argument, 0, DUMP_OPT},
  /* pek: yo! */
  {"emacs", no_argument, 0, EMACS_OPT},
  {0, 0, 0, 0}
};

static const gchar *USAGE_ = 
N_("Usage: %s [-vhurd] [--version] [--help] [--usage] [--run] [--dump] [MIX_FILE]\n");

int
main (int argc, char **argv)
{
  int c;
  const char *prog_name = argv[0];
  const char *in = NULL;
  gboolean run = FALSE;
  gboolean dump = FALSE;
  gboolean emacs = FALSE;
      
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  while (1)
    {
      c = getopt_long (argc, argv, options_, long_options_, (int*)0);
     
      /* Detect the end of the options. */
      if (c == -1)
	break;
     
      switch (c)
	{
	case HELP_OPT: case USAGE_OPT:
	  fprintf (stderr, _(USAGE_), prog_name);
	  return EXIT_SUCCESS;
     	case VER_OPT:
	  fprintf (stderr, _("%s %s, MIX Virtual Machine.\n"), 
		   prog_name, VERSION);
	  fprintf (stderr, MIX_GPL_LICENSE);
	  return EXIT_SUCCESS;
	case RUN_OPT:
	  in = optarg;
	  run = TRUE;
	  break;
	case DUMP_OPT:
	  dump = TRUE;
	  break;
     	case '?':
	  /* getopt already handles the output of a warning message */
	  fprintf (stderr, _("(Try: %s -h)\n"), prog_name);
	  return EXIT_FAILURE;
	case EMACS_OPT:
	  emacs = TRUE;
	  break;
	default:
	  g_assert_not_reached ();
	}
    }
   
  if ( optind < argc-1 )
    {
      fprintf (stderr, _("*** Error: Too many input files.\n"));
      return EXIT_FAILURE;
    }
  
  if (!in)  in = argv[optind];
  
  mix_init_lib ();
  
  if (run) mix_vmrun(in, dump);
  else mix_vmloop (argc, argv, in, emacs);

  mix_release_lib ();
  
  return EXIT_SUCCESS;
  
}