aboutsummaryrefslogtreecommitdiffstats
path: root/src/argparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/argparse.c')
-rw-r--r--src/argparse.c155
1 files changed, 113 insertions, 42 deletions
diff --git a/src/argparse.c b/src/argparse.c
index 2399c43..bd44aef 100644
--- a/src/argparse.c
+++ b/src/argparse.c
@@ -117,14 +117,17 @@ struct _gpgrt_argparse_internal_s
unsigned int in_sysconf:1; /* Processing global config file. */
unsigned int mark_forced:1; /* Mark options as forced. */
unsigned int mark_ignore:1; /* Mark options as to be ignored. */
- unsigned int explicit_ignore:1; /* Option has explicitly been set
- * to ignore or unignore. */
+ unsigned int explicit_ignore:1; /* Option has explicitly been set */
+ /* to be ignored or un-ignoref. */
+ unsigned int command_seen:1; /* A command option has been seen. */
unsigned int ignore_all_seen:1; /* [ignore-all] has been seen. */
unsigned int user_seen:1; /* A [user] has been seen. */
unsigned int user_wildcard:1; /* A [user *] has been seen. */
unsigned int user_any_active:1; /* Any user section was active. */
unsigned int user_active:1; /* User section active. */
unsigned int expand:1; /* Expand vars in option values. */
+ unsigned int explicit_cmd_mode:1;/* Command mode set via config. */
+ unsigned int cmd_mode:1; /* Command mode according to config. */
unsigned int explicit_confopt:1; /* A conffile option has been given. */
char *explicit_conffile; /* Malloced name of an explicit
* conffile. */
@@ -336,6 +339,9 @@ initialize (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, estream_t fp)
arg->internal->inarg = 0;
arg->internal->stopped = 0;
arg->internal->in_sysconf = 0;
+ arg->internal->command_seen = 0;
+ arg->internal->explicit_cmd_mode = 0;
+ arg->internal->cmd_mode = 0;
arg->internal->user_seen = 0;
arg->internal->user_wildcard = 0;
arg->internal->user_any_active = 0;
@@ -425,7 +431,7 @@ initialize (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, estream_t fp)
if (!seen_help)
{
arg->internal->opts[i].short_opt = ARGPARSE_SHORTOPT_HELP;
- arg->internal->opts[i].flags = ARGPARSE_TYPE_NONE;
+ arg->internal->opts[i].flags = ARGPARSE_OPT_COMMAND;
arg->internal->opts[i].long_opt = "help";
arg->internal->opts[i].description = "@";
arg->internal->opts[i].ordinal = i;
@@ -434,7 +440,7 @@ initialize (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, estream_t fp)
if (!seen_version)
{
arg->internal->opts[i].short_opt = ARGPARSE_SHORTOPT_VERSION;
- arg->internal->opts[i].flags = ARGPARSE_TYPE_NONE;
+ arg->internal->opts[i].flags = ARGPARSE_OPT_COMMAND;
arg->internal->opts[i].long_opt = "version";
arg->internal->opts[i].description = "@";
arg->internal->opts[i].ordinal = i;
@@ -444,7 +450,7 @@ initialize (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, estream_t fp)
if (!seen_warranty)
{
arg->internal->opts[i].short_opt = ARGPARSE_SHORTOPT_WARRANTY;
- arg->internal->opts[i].flags = ARGPARSE_TYPE_NONE;
+ arg->internal->opts[i].flags = ARGPARSE_OPT_COMMAND;
arg->internal->opts[i].long_opt = "warranty";
arg->internal->opts[i].description = "@";
arg->internal->opts[i].ordinal = i;
@@ -454,7 +460,7 @@ initialize (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, estream_t fp)
if (!seen_dump_option_table)
{
arg->internal->opts[i].short_opt = ARGPARSE_SHORTOPT_DUMP_OPTTBL;
- arg->internal->opts[i].flags = ARGPARSE_TYPE_NONE;
+ arg->internal->opts[i].flags = ARGPARSE_OPT_COMMAND;
arg->internal->opts[i].long_opt = "dump-option-table";
arg->internal->opts[i].description = "@";
arg->internal->opts[i].ordinal = i;
@@ -464,7 +470,7 @@ initialize (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, estream_t fp)
if (!seen_dump_options)
{
arg->internal->opts[i].short_opt = ARGPARSE_SHORTOPT_DUMP_OPTIONS;
- arg->internal->opts[i].flags = ARGPARSE_TYPE_NONE;
+ arg->internal->opts[i].flags = ARGPARSE_OPT_COMMAND;
arg->internal->opts[i].long_opt = "dump-options";
arg->internal->opts[i].description = "@";
arg->internal->opts[i].ordinal = i;
@@ -1369,6 +1375,21 @@ handle_meta_verbose (gpgrt_argparse_t *arg, unsigned int alternate, char *args)
return 0;
}
+/* Implementation of the "command-mode" command. ARG is the context. If
+ * ALTERNATE is true the command mode is disabled. ARGS is not used. */
+static int
+handle_meta_command (gpgrt_argparse_t *arg, unsigned int alternate, char *args)
+{
+ (void)args;
+
+ arg->internal->explicit_cmd_mode = 1;
+ if (alternate)
+ arg->internal->cmd_mode = 0;
+ else
+ arg->internal->cmd_mode = 1;
+ return 0;
+}
+
/* Implementation of the "expand" command. ARG is the context. If
* ALTERNATE is true expand is reset. ARGS is not used. */
@@ -1422,6 +1443,9 @@ handle_metacmd (gpgrt_argparse_t *arg, char *keyword)
{ "verbose", 0, 0, 1, 1, handle_meta_verbose },
{ "+verbose", 0, 0, 1, 1, handle_meta_verbose },
{ "-verbose", 1, 0, 1, 1, handle_meta_verbose },
+ { "command-mode", 0,0, 1, 0, handle_meta_command },
+ { "+command-mode",0,0, 1, 0, handle_meta_command },
+ { "-command-mode",1,0, 1, 0, handle_meta_command },
{ "echo", 0, 1, 1, 1, handle_meta_echo },
{ "-echo", 1, 1, 1, 1, handle_meta_echo },
{ "info", 0, 1, 1, 0, handle_meta_echo },
@@ -2479,9 +2503,10 @@ _gpgrt_argparser (gpgrt_argparse_t *arg, gpgrt_opt_t *opts,
/* Given the list of options in ARG and a keyword, return the index of
* the long option matching KEYWORD. On error -1 is returned for not
- * found or -2 for ambigious keyword. */
+ * found or -2 for ambiguous keyword. If ONLY_COMMANDS is set only
+ * options marked as commands are considere. */
static int
-find_long_option (gpgrt_argparse_t *arg, const char *keyword)
+find_long_option (gpgrt_argparse_t *arg, const char *keyword, int only_commands)
{
int i;
size_t n;
@@ -2495,9 +2520,24 @@ find_long_option (gpgrt_argparse_t *arg, const char *keyword)
* done. */
if (!*keyword)
return -1;
- for (i=0; i < nopts; i++ )
- if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword))
- return i;
+ if (only_commands)
+ {
+ /* Note that we consider only options which have just the
+ * command flag set and ignore all option which falsely have
+ * other bits set. */
+ for (i=0; i < nopts; i++ )
+ if (opts[i].flags == ARGPARSE_OPT_COMMAND
+ && opts[i].long_opt && !strcmp (opts[i].long_opt, keyword))
+ return i;
+ return -1; /* Not found (no abbreviations in this mode). */
+ }
+ else
+ {
+ for (i=0; i < nopts; i++ )
+ if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword))
+ return i;
+ }
+
#if 0
{
ALIAS_DEF a;
@@ -2536,6 +2576,48 @@ find_long_option (gpgrt_argparse_t *arg, const char *keyword)
}
+/* Handle special commands like "help" and "version". All of these
+ * commands call exit and thus this function does not return if such a
+ * command was found at IDX. */
+static void
+handle_special_commands (gpgrt_argparse_t *arg, int idx)
+{
+ int i = idx;
+ opttable_t *opts = arg->internal->opts;
+ unsigned int nopts = arg->internal->nopts;
+
+ if (i >= 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_HELP)
+ {
+ show_help (opts, nopts, arg->flags);
+ my_exit (arg, 0);
+ }
+ else if (i >= 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_VERSION)
+ {
+ if (!(arg->flags & ARGPARSE_FLAG_NOVERSION))
+ {
+ show_version ();
+ my_exit (arg, 0);
+ }
+ }
+ else if (i >= 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_WARRANTY)
+ {
+ writestrings (0, _gpgrt_strusage (16), "\n", NULL);
+ my_exit (arg, 0);
+ }
+ else if (i >= 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_DUMP_OPTTBL)
+ dump_option_table (arg);
+ else if (i >= 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_DUMP_OPTIONS)
+ {
+ for (i=0; i < nopts; i++ )
+ {
+ if (opts[i].long_opt && !(opts[i].flags & ARGPARSE_OPT_IGNORE))
+ writestrings (0, "--", opts[i].long_opt, "\n", NULL);
+ }
+ my_exit (arg, 0);
+ }
+}
+
+
/* The option parser for command line options. */
static int
arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig, int no_init)
@@ -2606,39 +2688,11 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig, int no_init)
argpos = strchr( s+2, '=' );
if ( argpos )
*argpos = 0;
- i = find_long_option (arg, s+2);
+ i = find_long_option (arg, s+2, 0);
if ( argpos )
*argpos = '=';
- if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_HELP)
- {
- show_help (opts, nopts, arg->flags);
- my_exit (arg, 0);
- }
- else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_VERSION)
- {
- if (!(arg->flags & ARGPARSE_FLAG_NOVERSION))
- {
- show_version ();
- my_exit (arg, 0);
- }
- }
- else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_WARRANTY)
- {
- writestrings (0, _gpgrt_strusage (16), "\n", NULL);
- my_exit (arg, 0);
- }
- else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_DUMP_OPTTBL)
- dump_option_table (arg);
- else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_DUMP_OPTIONS)
- {
- for (i=0; i < nopts; i++ )
- {
- if (opts[i].long_opt && !(opts[i].flags & ARGPARSE_OPT_IGNORE))
- writestrings (0, "--", opts[i].long_opt, "\n", NULL);
- }
- my_exit (arg, 0);
- }
+ handle_special_commands (arg, i);
if ( i == -2 )
arg->r_opt = ARGPARSE_AMBIGUOUS_OPTION;
@@ -2650,6 +2704,9 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig, int no_init)
else
arg->r_opt = opts[i].short_opt;
+ if (i >= 0 && (opts[i].flags & ARGPARSE_OPT_COMMAND))
+ arg->internal->command_seen = 1;
+
if ( i < 0 )
;
else if ( (opts[i].flags & ARGPARSE_TYPE_MASK) )
@@ -2793,6 +2850,20 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig, int no_init)
argc--; argv++; idx++;
}
}
+ else if (!arg->internal->command_seen
+ && ((!arg->internal->explicit_cmd_mode
+ && arg->flags & ARGPARSE_FLAG_COMMAND)
+ || (arg->internal->explicit_cmd_mode
+ && arg->internal->cmd_mode))
+ && (i = find_long_option (arg, s, 1)) >= 0)
+ {
+ handle_special_commands (arg, i);
+ arg->internal->opt_flags = opts[i].flags;
+ arg->internal->command_seen = 1;
+ arg->r_opt = opts[i].short_opt;
+ arg->r_type = ARGPARSE_TYPE_NONE;
+ argc--; argv++; idx++; /* Set to next one. */
+ }
else if ( arg->flags & ARGPARSE_FLAG_MIXED )
{
arg->r_opt = ARGPARSE_IS_ARG;