/*
   File: options.c
   Parses options to agfl-as

   Copyright 2006 Radboud University of Nijmegen
 
   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 Library 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.

   CVS ID: "$Id: options.c,v 1.1 2006/10/18 12:54:01 marcs Exp $"
*/

/* system includes */
#include <stdio.h>
#include <string.h>

/* libabase includes */
#include <abase_error.h>
#include <abase_dstring.h>
#include <abase_memalloc.h>

/* Local includes */
#include <options.h>

/* exported options */
static int show_version;
int generate_object;
int verbose;

/* exported file names */
char *assembler_fname;
char *object_fname;
char *basename;

static void init_options ()
	{ show_version = 0;
	  generate_object = 1;
	  verbose = 0;
	  assembler_fname = NULL;
	  object_fname = NULL;
	};

static void print_usage ()
	{ abs_message ("usage: agfl-as [flags] filename [more_flags]");
	  abs_message ("where flags and more_flags may be any of the following:");
	  abs_message ("-h:  provide this help");
	  abs_message ("-V:  show version");
	  abs_message ("-v:  verbose");
	  abs_message ("-n:  do not generate object code");
	  abs_message ("-o oname: output object code in file 'ofile'");
	  exit (4);
	};

static void syntax_error (char *syn_error)
        { abs_error (syn_error);
          print_usage ();
        };

#define streq(s1,s2) (strcmp((s1),(s2)) == 0)
static void scan_option (char *ptr, int *i, int argc, char **argv)
        { if (streq (ptr, "V")) show_version = 1;
          else if (streq (ptr, "v")) { show_version = 1; verbose = 1; }
          else if (streq (ptr, "h")) print_usage ();
          else if (streq (ptr, "n")) generate_object = 0;
          else if (streq (ptr, "o"))
            { *i = *i + 1;
              if ((*i) < argc) { object_fname = abs_new_string (argv[*i], "scan_option"); }
              else syntax_error ("missing object file name");
            }
	  else
	    { abs_error ("illegal command line option '-%s'", ptr);
	      print_usage ();
	    };
	};

#ifndef VERSION
#define VERSION "2.6"
#endif
static void try_report_version ()
        { if (!show_version) return;
          abs_message ("Agfl-as, C Version %s, Copyright 2006, Radboud University of Nijmegen.",
		       VERSION);
        };

static void set_basename (char *fname)
	{ dstring ds = abs_init_dstring (strlen (fname) + 1);
	  char *sptr;
          for (sptr = fname; (*sptr) && (*sptr != '.'); sptr++)
             abs_append_dstring_c (ds, *sptr);
          basename = abs_finish_dstring (ds);
	};

/* exported actions */
#define OBJSUFFIX "aob"
void parse_command_line (int argc, char **argv)
        { int ix;
	  init_options ();
          for (ix = 1; ix < argc; ix++)
             { char *arg = argv[ix];
               if (arg[0] == '-') scan_option (arg+1, &ix, argc, argv);
               else if (assembler_fname == NULL)
		 assembler_fname = abs_new_string (arg, "parse_command_line");
               else syntax_error ("too many source file names");
             };
          try_report_version ();

          /* Exit if no source given */
          if (assembler_fname == NULL)
            { if (!show_version)
                abs_message ("no source file name given, bailing out...");
              exit (0);
            };

	  /* Try set object fname from source file */
	  set_basename (assembler_fname);
	  if (object_fname == NULL)
	    object_fname = abs_new_fmtd_string (basename, OBJSUFFIX);
	};
