
#include "config.h"
#include "getopt.h"

#include "yodl.h"

/* Long options.  */
static const struct option long_options[] =
{
  { "define", required_argument, NULL, 'D' },
  { "definemacro", required_argument, NULL, 'd' },
  { "help", no_argument, NULL, 'h' },
  { "include", required_argument, NULL, 'I' },
  { "live-data", required_argument, NULL, 'l' },
  { "output", required_argument, NULL, 'o' },
  { "preload", required_argument, NULL, 'P' },
  { "max-pass", required_argument, NULL, 'p' },
  { "trace", no_argument, NULL, 't' },
  { "version", no_argument, NULL, 'V' },
  { "verbose", no_argument, NULL, 'v' },
  { "warranty", no_argument, NULL, 'W' },
  { "warn", no_argument, NULL, 'w' },
  { NULL, 0, NULL, 0 }
};


void
add_user_defed_macro (char *arg);


void 
parse_flags (int argc, char **argv)
{
  int opt;

  stdinclude = xstrdup (STD_INCLUDE);

  while ((opt = getopt_long (argc, argv, 
    "?hD:d:I:l:o:P:p:tVvWw", 
    long_options, NULL)) != EOF)
    switch (opt)
      {
      case 'l':
	if (!optarg || !*optarg ||
	    (sscanf (optarg, "%d", &livedata) < 1)
	  )
	  error ("-l flag needs number");
	break;

      case 'D':
	if (!optarg || !*optarg)
	  error ("-D flag lacks symbol name");
	define = strtab_add (define, &ndefine, optarg);
	break;

      case 'd':
	if (!optarg || !*optarg)
	  error ("-d flag lacks symbol name");
	add_user_defed_macro (optarg);
	break;
      case 'I':
	if (!optarg || !*optarg)
	  error ("-I flag lacks directory name");
	free (stdinclude);
	stdinclude = xstrdup (optarg);
	break;

      case 'o':
	if (!optarg || !*optarg)
	  error ("-o flag lacks output file name");
	outfname = xstrdup (optarg);
	break;

      case 'P':
	if (!optarg || !*optarg)
	  error ("-P flag lacks preload-command");
	lexer_pushstr (optarg);
	break;

      case 'p':
	if (!optarg || !*optarg)
	  error ("-p flag lacks number to specify max passes");
	if (!(maxpass = atoi (optarg)))
	  error ("bad number after -p flag");
	break;

      case 't':
	flags.trace_output = 1;
	break;

      case 'V':
	printf ("%s\n", TOPLEVEL_VERSION);
	exit (0);
	break;

      case 'v':
	verbose++;
	break;

      case 'W':
        version ();
	warranty ();
	break;

      case 'w':
	flags.warn = 1;
	break;

      case '?':
      case 'h':
      default:
	usage ();
      }

  if (argc - optind < 1)
    usage ();
}



void
add_user_defed_macro (char *arg)
{
  char s[] = "";
  char *macname = arg;
  char *eq_idx =  strchr  (arg, '=');
  char *expansion = s;
  int nargs = 0;		/* ugh */
  if (eq_idx)
    {
      *eq_idx = 0;
      expansion = eq_idx + 1;
    }

  /* ugh C&P*/
  
  if (strtab_find (userdef, nuserdef, macname) != -1)
    error_gram (builtin[idx_DEFINEMACRO], "macro %s is already defined",
		macname);

  
  userdef = strtab_add (userdef, &nuserdef, macname);
  definition = (char **) xrealloc (definition, nuserdef * sizeof (char *));
  definition[nuserdef - 1] = xstrdup (expansion);

  narg = (int *) xrealloc (narg, (nuserdef * sizeof (int)));
  narg[nuserdef - 1] = nargs;
}
