/* This file is part of GNU Dico. -*- c -*-
   Copyright (C) 1998-2000, 2008, 2010, 2012, 2016 Sergey Poznyakoff

   GNU Dico 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 3, or (at your option)
   any later version.

   GNU Dico 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 GNU Dico.  If not, see <http://www.gnu.org/licenses/>. */

#include <dicod.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <getopt.h>
#include <gettext.h>

static struct grecs_txtacc *pp_cmd_acc;

OPTIONS_BEGIN("dicod",
              [<GNU dictionary server>],
	      [<>],
	      [<gnu>],
	      [<gnupackage>],
	      [<copyright_year=2005-2016>],
	      [<copyright_holder=Free Software Foundation, Inc.>],
	      [<program_version>])

GROUP(Select program mode)
OPTION(,E,,
       [<preprocess configuration file and exit>])
BEGIN
   mode = MODE_PREPROC;
END

OPTION(lint,t,,
       [<check configuration file syntax and exit>])
BEGIN
   config_lint_option = 1;
END

OPTION(inetd, i,,
       [<inetd mode>])
BEGIN
   mode = MODE_INETD;
END

OPTION(runtest, r,,
       [<run unit tests for module; subsequent arguments are treated as module name and unit test arguments; the -- marker introduces module initialization arguments>])
BEGIN
   mode = MODE_TEST;
   log_to_stderr = 1;
   LASTOPT;
END

GROUP(Modifiers)
    
OPTION(config,,FILE,
       [<read this configuration file>])
BEGIN
   config_file = optarg;
END

OPTION(foreground, f,,
       [<operate in foreground>])
BEGIN
   foreground = 1;
END

OPTION(stderr,,,
       [<output diagnostic to stderr>])
BEGIN
   log_to_stderr = 1;
END

OPTION(syslog,,,
       [<output diagnostic to syslog (default)>])
BEGIN
   log_to_stderr = 0;
END

OPTION(single-process, s,,
       [<single-process mode>])
BEGIN
   single_process = 1;
END

OPTION(load-dir, L, DIR,
       [<prepend DIR to the module load path>])
BEGIN
   prepend_load_path = xdico_list_create();
   dico_list_set_free_item(prepend_load_path, dicod_free_item, NULL);
   xdico_list_append(prepend_load_path, xstrdup(optarg));
END

GROUP(Debugging)
    
OPTION(transcript, T,,
       [<enable session transcript>])
BEGIN
   conf->transcript = 1;
END

OPTION(no-transcript,,,
       [<disable session transcript>])
BEGIN
   conf->transcript = 0;
END

OPTION(debug, x, NUMBER,
       [<set debug verbosity level>])
BEGIN
   debug_level_str = optarg;
   debug_level = atoi(optarg);
END

OPTION(source-info,,,
       [<include source line information in the debugging output>])
BEGIN
   debug_source_info = 1;
END  

OPTION(trace-grammar,,,
       [<trace parsing of configuration file>])
BEGIN
   grecs_gram_trace(1);
END

OPTION(trace-lex,,,
       [<trace config file lexer>])
BEGIN
   grecs_lex_trace(1);
END

GROUP([<Additional help>])

OPTION(config-help,,,
       [<show configuration file summary>])
BEGIN
   config_help();
   exit(0);
END   

GROUP(Preprocessor control)
    
OPTION(preprocessor,,PROG,
       [<use PROG as a preprocessor for config file>])
BEGIN
   grecs_preprocessor = optarg;
END

OPTION(no-preprocessor,,,
       [<do not use external preprocessor>])
BEGIN
   grecs_preprocessor = NULL;
END

OPTION(include-dir,I,DIR,
       [<add the directory DIR to the list of directories to be searched for preprocessor include files>])
BEGIN
   grecs_preproc_add_include_dir(optarg); 
END

OPTION(define,D,SYMBOL[=VALUE],
       [<define a preprocessor symbol>])
BEGIN
   char *p;

   if (!pp_cmd_acc)
       pp_cmd_acc = grecs_txtacc_create();
   grecs_txtacc_grow(pp_cmd_acc, " \"-D", 4);
   for (p = optarg; *p; p++) {
       if (*p == '\\' || *p == '"')
	   grecs_txtacc_grow_char(pp_cmd_acc, '\\');
       grecs_txtacc_grow_char(pp_cmd_acc, *p);
   }
   grecs_txtacc_grow_char(pp_cmd_acc, '"');			
END


OPTIONS_END

void
get_options(int *pargc, char **pargv[], struct dicod_conf_override *conf)
{
    int i;
    int argc = *pargc;
    char **argv = *pargv;
    
    GETOPT(argc, argv, i, exit(EX_USAGE))
    if (pp_cmd_acc && grecs_preprocessor) {
	char *args, *cmd;

	grecs_txtacc_grow_char(pp_cmd_acc, 0);
	args = grecs_txtacc_finish(pp_cmd_acc, 0);
	cmd = grecs_malloc(strlen(grecs_preprocessor) +
			   strlen(args) + 1);
	strcpy(cmd, grecs_preprocessor);
	strcat(cmd, args);
	grecs_preprocessor = cmd;
    }
    grecs_txtacc_free(pp_cmd_acc);

    if (mode == MODE_TEST) {
	*pargc = argc - i;
	*pargv = argv + i;
    } else if (i < argc) {
	fprintf(stderr, "%s: unexpected arguments\n", argv[0]);
	exit(EX_USAGE);
    }
}
