summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2020-02-27 12:32:01 +0100
committerWerner Koch <wk@gnupg.org>2020-02-27 14:33:45 +0100
commit2d1969ab465bad62f73a7c24ddc8bb490ff9fd40 (patch)
tree1abee93d70cd7ebbae54eb12512258dee5771430
parentffa21bf5b7066f7fa437119ce6b508b324ea2611 (diff)
downloadlibgpg-error-2d1969ab465bad62f73a7c24ddc8bb490ff9fd40.tar.gz
core: Implement meta commands for the argparser.
* src/argparse.c (opttable_t): Add new flags forced, ignore, and explicit_ignore. (struct _gpgrt_argparse_internal_s): Change flags to bitflags. Add several flags to support meta commands. (initialize): Clear them. (handle_meta_user): Use the new verbose flag. (handle_meta_force): Implement. (handle_meta_ignore): Implement. (handle_meta_echo): Support "-echo". (handle_meta_verbose): New. (handle_metacmd): New meta command verbose. Add always flag and move the detection of unexpected meta commands to here. (_gpgrt_argparse): Make use of the ignore and forced meta commands. (finish_read_sys): New. (_gpgrt_argparser): Support the verbose flag. Call finish_read_sys. (arg_parse): Ignore non-explicit ignored and all forced options. * tests/t-argparse.c (main): Fix printing of the ARGPARSE_CONFFILE case. New option 'M'. * tests/t-argparse.conf, tests/etc/t-argparse.conf: Various changes to test the new meta commands. -- For the command line we print a diagnostic if an ignored or forced options is used. However, we do not ignore options which are only set via [ignore-all]. The rationale for the latter is that an administrator can't be be required to unignore all options used by all modes, of say gpgme. Documentation of the meta commands will for now be added to GnuPG. GnuPG-bug-id: 4788 Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r--NEWS2
-rw-r--r--src/argparse.c257
-rw-r--r--tests/etc/t-argparse.conf14
-rw-r--r--tests/t-argparse.c4
-rw-r--r--tests/t-argparse.conf5
5 files changed, 207 insertions, 75 deletions
diff --git a/NEWS b/NEWS
index d212f39..51c2c89 100644
--- a/NEWS
+++ b/NEWS
@@ -23,7 +23,7 @@ Noteworthy changes in version 1.38 (unreleased) [C28/A28/R_]
GPGRT_CONFDIR_USER NEW.
GPGRT_CONFDIR_SYS NEW.
- Release-info: https://dev.gnupg.org/T
+ Release-info: https://dev.gnupg.org/T4859
Noteworthy changes in version 1.37 (2020-02-07) [C28/A28/R0]
diff --git a/src/argparse.c b/src/argparse.c
index 512b5d7..03e033a 100644
--- a/src/argparse.c
+++ b/src/argparse.c
@@ -90,6 +90,10 @@ typedef struct
unsigned int flags;
const char *long_opt; /* Points into the user provided table. */
const char *description; /* Points into the user provided table. */
+ unsigned int forced:1; /* Forced to use the sysconf value. */
+ unsigned int ignore:1; /* Ignore this option everywhere but in
+ * the sysconf file. */
+ unsigned int explicit_ignore:1; /* Ignore was explicitly set. */
} opttable_t;
@@ -97,13 +101,20 @@ typedef struct
struct _gpgrt_argparse_internal_s
{
int idx; /* Note that this is saved and restored in _gpgrt_argparser. */
- int inarg;
- int stopped;
- int insysconfig; /* Processing global config file. */
- int explicit_confopt; /* A conffile option has been given. */
- char *explicit_conffile; /* Malloced name of an explicit conffile. */
- unsigned int opt_flags; /* Current option flags. */
- enum argparser_states state; /* of gpgrt_argparser. */
+ int inarg; /* (index into args) */
+ unsigned int verbose:1; /* Print diagnostics. */
+ unsigned int stopped:1; /* Option processing has stopped. */
+ 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 ignore_all_seen:1; /* [ignore-all] has been seen. */
+ unsigned int explicit_confopt:1; /* A conffile option has been given. */
+ char *explicit_conffile; /* Malloced name of an explicit
+ * conffile. */
+ unsigned int opt_flags; /* Current option flags. */
+ enum argparser_states state; /* State of the gpgrt_argparser. */
const char *last;
void *aliases;
const void *cur_alias;
@@ -294,7 +305,11 @@ initialize (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, estream_t fp)
arg->internal->last = NULL;
arg->internal->inarg = 0;
arg->internal->stopped = 0;
- arg->internal->insysconfig = 0;
+ arg->internal->in_sysconf = 0;
+ arg->internal->mark_forced = 0;
+ arg->internal->mark_ignore = 0;
+ arg->internal->explicit_ignore = 0;
+ arg->internal->ignore_all_seen = 0;
arg->internal->explicit_confopt = 0;
arg->internal->explicit_conffile = NULL;
arg->internal->opt_flags = 0;
@@ -631,9 +646,10 @@ handle_meta_user (gpgrt_argparse_t *arg, unsigned int alternate, char *args)
{
(void)args;
- _gpgrt_log_info ("%s:%u: meta command %s is not yet supported\n",
- arg->internal->confname, arg->lineno,
- alternate? "group":"user");
+ if (arg->internal->verbose)
+ _gpgrt_log_info ("%s:%u: meta command %s is not yet supported\n",
+ arg->internal->confname, arg->lineno,
+ alternate? "group":"user");
return 0;
}
@@ -645,38 +661,66 @@ handle_meta_user (gpgrt_argparse_t *arg, unsigned int alternate, char *args)
static int
handle_meta_force (gpgrt_argparse_t *arg, unsigned int alternate, char *args)
{
- (void)arg;
- (void)alternate;
(void)args;
+ arg->internal->mark_forced = alternate? 0 : 1;
+
return 0;
}
/* Implementation of the "ignore" command. ARG is the context. A
* value of 0 for ALTERNATE is a plain "ignore", a value of 1 request
- * an "unignore, a value of 3 requests an "ignore-all". ARGS is the
+ * an "unignore, a value of 2 requests an "ignore-all". ARGS is the
* empty string and not used. */
static int
handle_meta_ignore (gpgrt_argparse_t *arg, unsigned int alternate, char *args)
{
- (void)arg;
- (void)alternate;
(void)args;
+ if (!alternate)
+ {
+ arg->internal->mark_ignore = 1;
+ arg->internal->explicit_ignore = 1;
+ }
+ else if (alternate == 1)
+ {
+ arg->internal->mark_ignore = 0;
+ arg->internal->explicit_ignore = 1;
+ }
+ else
+ arg->internal->ignore_all_seen = 1;
+
return 0;
}
-/* Implementation of the "ignore" command. ARG is the context.
- * ALTERNATE is not used. ARGS is the string to log. */
+/* Implementation of the "ignore" command. ARG is the context. If
+ * ALTERNATE is true the filename is not printed. ARGS is the string
+ * to log. */
static int
handle_meta_echo (gpgrt_argparse_t *arg, unsigned int alternate, char *args)
{
- (void)alternate;
+ if (alternate)
+ _gpgrt_log_info ("%s\n", args);
+ else
+ _gpgrt_log_info ("%s:%u: %s\n",
+ arg->internal->confname, arg->lineno, args);
+ return 0;
+}
+
+
+/* Implementation of the "verbose" command. ARG is the context. If
+ * ALTERNATE is true the verbosity is disabled. ARGS is not used. */
+static int
+handle_meta_verbose (gpgrt_argparse_t *arg, unsigned int alternate, char *args)
+{
+ (void)args;
- _gpgrt_log_info ("%s:%u: %s\n",
- arg->internal->confname, arg->lineno, args);
+ if (alternate)
+ arg->internal->verbose = 0;
+ else
+ arg->internal->verbose = 1;
return 0;
}
@@ -688,29 +732,32 @@ static int
handle_metacmd (gpgrt_argparse_t *arg, char *keyword)
{
static struct {
- const char *name; /* Name of the command. */
+ const char *name; /* Name of the command. */
unsigned short alternate; /* Use alternate version of the command. */
- unsigned short needarg; /* Command requires an argument. */
+ unsigned short needarg:1; /* Command requires an argument. */
+ unsigned short always:1; /* Command allowed in all conf files. */
int (*func)(gpgrt_argparse_t *arg,
unsigned int alternate, char *args); /*handler*/
} cmds[] =
- {{ "user", 0, 1, handle_meta_user },
- { "group", 1, 1, handle_meta_user },
- { "force", 0, 0, handle_meta_force },
- { "+force", 0, 0, handle_meta_force },
- { "-force", 1, 0, handle_meta_force },
- { "ignore", 0, 0, handle_meta_ignore },
- { "+ignore", 0, 0, handle_meta_ignore },
- { "-ignore", 1, 0, handle_meta_ignore },
- { "ignore-all", 2, 0, handle_meta_ignore },
- { "+ignore-all", 2, 0, handle_meta_ignore },
- { "echo", 0, 1, handle_meta_echo }
+ {{ "user", 0, 1, 0, handle_meta_user },
+ { "group", 1, 1, 0, handle_meta_user },
+ { "force", 0, 0, 0, handle_meta_force },
+ { "+force", 0, 0, 0, handle_meta_force },
+ { "-force", 1, 0, 0, handle_meta_force },
+ { "ignore", 0, 0, 0, handle_meta_ignore },
+ { "+ignore", 0, 0, 0, handle_meta_ignore },
+ { "-ignore", 1, 0, 0, handle_meta_ignore },
+ { "ignore-all", 2, 0, 0, handle_meta_ignore },
+ { "+ignore-all", 2, 0, 0, handle_meta_ignore },
+ { "verbose", 0, 0, 1, handle_meta_verbose },
+ { "+verbose", 0, 0, 1, handle_meta_verbose },
+ { "-verbose", 1, 0, 1, handle_meta_verbose },
+ { "echo", 0, 1, 1, handle_meta_echo },
+ { "-echo", 1, 1, 1, handle_meta_echo }
};
char *rest;
int i;
- _gpgrt_log_debug ("Handle meta command '%s'\n", keyword);
-
for (rest = keyword; *rest && !(isascii (*rest) && isspace (*rest)); rest++)
;
if (*rest)
@@ -728,6 +775,9 @@ handle_metacmd (gpgrt_argparse_t *arg, char *keyword)
return ARGPARSE_MISSING_ARG;
if (!cmds[i].needarg && *rest)
return ARGPARSE_UNEXPECTED_ARG;
+ if (!arg->internal->in_sysconf && !cmds[i].always)
+ return ARGPARSE_UNEXPECTED_META;
+
return cmds[i].func (arg, cmds[i].alternate, rest);
}
@@ -819,24 +869,21 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
/* Before scanning the next char handle the keyword seen states. */
if (state == Akeyword_eol || state == Akeyword_spc)
{
+ /* We are either at the end of a line or right after a
+ * keyword. In the latter case we need to find the keyword
+ * so that we can decide whether an argument is required. */
+
/* Check the keyword. */
- for (i=0; i < nopts; i++ )
+ for (idx=0; idx < nopts; idx++ )
{
- if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword))
+ if (opts[idx].long_opt && !strcmp (opts[idx].long_opt, keyword))
break;
}
- idx = i;
arg->r_opt = opts[idx].short_opt;
- if ((opts[idx].flags & ARGPARSE_OPT_IGNORE))
- {
- /* Option is configured to be ignored. Start from
- * scratch (new line) or process like a comment. */
- state = state == Akeyword_eol? Ainit : Acomment;
- i = 0;
- }
- else if (!(i < nopts))
+ if (!(idx < nopts))
{
- /* The option is not known - check for internal keywords. */
+ /* The option (keyword) is not known - check for
+ * internal keywords before returning an error. */
if (state == Akeyword_spc && !strcmp (keyword, "alias"))
{
in_alias = 1;
@@ -847,7 +894,7 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
/* We might have keywords as argument - add them to
* the list of ignored keywords. Note that we
* ignore empty argument lists and thus do not to
- * call the function in the Akeyword_eol stae. */
+ * call the function in the Akeyword_eol state. */
if (state == Akeyword_spc)
{
if (ignore_invalid_option_add (arg, fp))
@@ -872,9 +919,9 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
? ARGPARSE_INVALID_COMMAND
: ARGPARSE_INVALID_OPTION);
if (state == Akeyword_spc)
- {
- state = Askipandleave;
- }
+ state = Askipandleave;
+ else
+ goto leave;
}
}
else if (state == Akeyword_spc)
@@ -882,9 +929,44 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
/* Known option but need to scan for args. */
state = Awaitarg;
}
- else
+ else if ((opts[idx].flags & ARGPARSE_OPT_IGNORE))
+ {
+ /* Known option is configured to be ignored. Start from
+ * scratch (new line) or process like a comment. */
+ state = state == Akeyword_eol? Ainit : Acomment;
+ i = 0;
+ }
+ else /* Known option */
{
- /* Known option and at end of line - return option. */
+ if (arg->internal->in_sysconf)
+ {
+ /* Set the current forced and ignored attributes. */
+ if (arg->internal->mark_forced)
+ opts[idx].forced = 1;
+ if (arg->internal->mark_ignore)
+ opts[idx].ignore = 1;
+ if (arg->internal->explicit_ignore)
+ opts[idx].explicit_ignore = 1;
+ }
+ else /* Non-sysconf file */
+ { /* Act upon the forced and ignored attributes. */
+ if (opts[idx].ignore || opts[idx].forced)
+ {
+ if (arg->internal->verbose)
+ _gpgrt_log_info ("%s:%u: ignoring option \"--%s\""
+ " due to attributes:%s%s\n",
+ arg->internal->confname,
+ arg->lineno,
+ opts[idx].long_opt,
+ opts[idx].forced? " forced":"",
+ opts[idx].ignore? " ignore":"");
+ state = Ainit;
+ i = 0;
+ goto nextstate; /* Ignore this one. */
+ }
+ }
+
+ arg->r_opt = opts[idx].short_opt;
if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
arg->r_type = 0; /* Does not take an arg. */
else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL) )
@@ -896,6 +978,7 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
} /* (end state Akeyword_eol/Akeyword_spc) */
else if (state == Ametacmd)
{
+ /* We are at the end of a line. */
gpgrt_assert (*keyword == '[');
trim_spaces (keyword+1);
if (!keyword[1])
@@ -903,11 +986,6 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
arg->r_opt = ARGPARSE_INVALID_META; /* Empty. */
goto leave;
}
- if (!arg->internal->insysconfig)
- {
- arg->r_opt = ARGPARSE_UNEXPECTED_META;
- goto leave;
- }
c = handle_metacmd (arg, keyword+1);
if (c)
{
@@ -1198,7 +1276,6 @@ is_twopartfname (const char *fname)
}
-
/* Try to use a version-ed config file name. A version-ed config file
* name is one which has the packages version number appended. For
* example if the standard config file name is "foo.conf" and the
@@ -1251,6 +1328,34 @@ try_versioned_conffile (const char *configname)
}
+/* This function is called after a sysconf file has been read. */
+static void
+finish_read_sys (gpgrt_argparse_t *arg)
+{
+ opttable_t *opts = arg->internal->opts;
+ unsigned int nopts = arg->internal->nopts;
+ int i;
+
+ if (arg->internal->ignore_all_seen)
+ {
+ /* [ignore-all] was used: Set all options which have not
+ * explictly been set as ignore or not ignore to ignore. */
+ for (i = 0; i < nopts; i++)
+ {
+ if (!opts[i].explicit_ignore)
+ opts[i].ignore = 1;
+ }
+ }
+
+ /* Reset all flags which pertain only to sysconf files. */
+ arg->internal->in_sysconf = 0;
+ arg->internal->mark_forced = 0;
+ arg->internal->mark_ignore = 0;
+ arg->internal->explicit_ignore = 0;
+ arg->internal->ignore_all_seen = 0;
+}
+
+
/* The full arg parser which handles option files and command line
* arguments. The behaviour depends on the combinations of CONFNAME
* and the ARGPARSE_FLAG_xxx values:
@@ -1382,13 +1487,14 @@ _gpgrt_argparser (gpgrt_argparse_t *arg, gpgrt_opt_t *opts,
}
arg->lineno = 0;
arg->internal->idx = 0;
+ arg->internal->verbose = 0;
arg->internal->stopped = 0;
arg->internal->inarg = 0;
_gpgrt_fclose (arg->internal->conffp);
arg->internal->conffp = _gpgrt_fopen (arg->internal->confname, "r");
if (!arg->internal->conffp)
{
- if ((arg->flags & ARGPARSE_FLAG_VERBOSE))
+ if ((arg->flags & ARGPARSE_FLAG_VERBOSE) || arg->internal->verbose)
_gpgrt_log_info (_("Note: no default option file '%s'\n"),
arg->internal->confname);
if ((arg->flags & ARGPARSE_FLAG_USER))
@@ -1398,11 +1504,11 @@ _gpgrt_argparser (gpgrt_argparse_t *arg, gpgrt_opt_t *opts,
goto next_state;
}
- if ((arg->flags & ARGPARSE_FLAG_VERBOSE))
+ if ((arg->flags & ARGPARSE_FLAG_VERBOSE) || arg->internal->verbose)
_gpgrt_log_info (_("reading options from '%s'\n"),
arg->internal->confname);
arg->internal->state = STATE_read_sys;
- arg->internal->insysconfig = 1;
+ arg->internal->in_sysconf = 1;
arg->r.ret_str = xtrystrdup (arg->internal->confname);
if (!arg->r.ret_str)
arg->r_opt = ARGPARSE_OUT_OF_CORE;
@@ -1465,9 +1571,10 @@ _gpgrt_argparser (gpgrt_argparse_t *arg, gpgrt_opt_t *opts,
}
arg->lineno = 0;
arg->internal->idx = 0;
+ arg->internal->verbose = 0;
arg->internal->stopped = 0;
arg->internal->inarg = 0;
- arg->internal->insysconfig = 0;
+ arg->internal->in_sysconf = 0;
_gpgrt_fclose (arg->internal->conffp);
arg->internal->conffp = _gpgrt_fopen (arg->internal->confname, "r");
if (!arg->internal->conffp)
@@ -1481,14 +1588,15 @@ _gpgrt_argparser (gpgrt_argparse_t *arg, gpgrt_opt_t *opts,
}
else
{
- if ((arg->flags & ARGPARSE_FLAG_VERBOSE))
+ if ((arg->flags & ARGPARSE_FLAG_VERBOSE)
+ || arg->internal->verbose)
_gpgrt_log_info (_("Note: no default option file '%s'\n"),
arg->internal->confname);
goto next_state;
}
}
- if ((arg->flags & ARGPARSE_FLAG_VERBOSE))
+ if ((arg->flags & ARGPARSE_FLAG_VERBOSE) || arg->internal->verbose)
_gpgrt_log_info (_("reading options from '%s'\n"),
arg->internal->confname);
arg->internal->state = STATE_read_user;
@@ -1509,9 +1617,10 @@ _gpgrt_argparser (gpgrt_argparse_t *arg, gpgrt_opt_t *opts,
xfree (arg->internal->confname);
arg->internal->confname = NULL;
arg->internal->idx = 0;
+ arg->internal->verbose = 0;
arg->internal->stopped = 0;
arg->internal->inarg = 0;
- arg->internal->insysconfig = 0;
+ arg->internal->in_sysconf = 0;
if (!arg->argc || !arg->argv || !*arg->argv)
{
/* No or empty argument vector - don't bother to parse things. */
@@ -1528,6 +1637,7 @@ _gpgrt_argparser (gpgrt_argparse_t *arg, gpgrt_opt_t *opts,
arg->r_opt = _gpgrt_argparse (arg->internal->conffp, arg, opts);
if (!arg->r_opt)
{
+ finish_read_sys (arg);
arg->internal->state = STATE_open_user;
goto next_state;
}
@@ -1734,6 +1844,7 @@ 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 )
;
else if ( (opts[i].flags & ARGPARSE_TYPE_MASK) )
@@ -1746,6 +1857,7 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig, int no_init)
}
else
s2 = argv[1];
+
if ( !s2 && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
{
arg->r_type = ARGPARSE_TYPE_NONE; /* Argument is optional. */
@@ -1795,7 +1907,7 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig, int no_init)
arg->internal->inarg++;
if ( (arg->flags & ARGPARSE_FLAG_ONEDASH) )
{
- for (i=0; opts[i].short_opt; i++ )
+ for (i=0; i < nopts; i++ )
if ( opts[i].long_opt && !strcmp (opts[i].long_opt, s+1))
{
dash_kludge = 1;
@@ -1886,6 +1998,15 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig, int no_init)
goto next_one;
}
+ if (arg->r_opt > 0 && i >= 0 && i < nopts
+ && ((opts[i].ignore && opts[i].explicit_ignore) || opts[i].forced))
+ {
+ _gpgrt_log_info (_("Note: ignoring option \"--%s\""
+ " due to global config\n"),
+ opts[i].long_opt);
+ goto next_one; /* Skip ignored/forced option. */
+ }
+
leave:
*arg->argc = argc;
*arg->argv = argv;
diff --git a/tests/etc/t-argparse.conf b/tests/etc/t-argparse.conf
index c556466..90b9935 100644
--- a/tests/etc/t-argparse.conf
+++ b/tests/etc/t-argparse.conf
@@ -3,12 +3,12 @@
# Options applied to all user's config files
#verbose
-[echo Begin global config]
-
+[-echo Begin global config]
+[verbose]
[group :staff]
# These option are applied to all users of the group staff up until
# the next [group] or [user] statement.
-
+[-verbose]
[+force]
# All following option are forced and thus ignored when set in user
# config files. Valid until the next [user] statement. Take care
@@ -21,11 +21,14 @@
# The compliance is set immutable for these users
verbose
+[-force]
+not-my-option
+
# The next shall raise an error due to the garpage at the end.
#<off>[+ignore] fooo
-#[+ignore-all]
+[+ignore-all]
# All options are ignored.
@@ -55,4 +58,5 @@ my-option 42
# The default algorithm for new keys is set to this.
a-long-option
-[echo End global config]
+
+[-echo End global config]
diff --git a/tests/t-argparse.c b/tests/t-argparse.c
index 4719819..46b7258 100644
--- a/tests/t-argparse.c
+++ b/tests/t-argparse.c
@@ -74,6 +74,7 @@ main (int argc, char **argv)
/* Note that on a non-utf8 terminal the ß might garble the output. */
ARGPARSE_s_n('s', "street","|Straße|set the name of the street to Straße"),
ARGPARSE_o_i('m', "my-option", 0),
+ ARGPARSE_o_i('M', "not-my-option", 0),
ARGPARSE_s_n(500, "a-long-option", 0 ),
ARGPARSE_conffile(501, "options", "|FILE|read options from FILE"),
ARGPARSE_noconffile(502, "no-options", "Ignore conf files"),
@@ -108,7 +109,7 @@ main (int argc, char **argv)
{
case ARGPARSE_CONFFILE:
printf ("current conffile='%s'\n",
- pargs.r.ret_str? pargs.r.ret_str: "[cmdline]");
+ pargs.r_type? pargs.r.ret_str: "[cmdline]");
break;
case ARGPARSE_IS_ARG :
printf ("arg='%s'\n", pargs.r.ret_str);
@@ -120,6 +121,7 @@ main (int argc, char **argv)
case 'o': opt.outfile = pargs.r.ret_str; break;
case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break;
case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break;
+ case 'M': opt.myopt = 0; break;
case 500: opt.a_long_one++; break;
default : pargs.err = ARGPARSE_PRINT_WARNING; any_warn = 1; break;
}
diff --git a/tests/t-argparse.conf b/tests/t-argparse.conf
index e2c96e2..c689a63 100644
--- a/tests/t-argparse.conf
+++ b/tests/t-argparse.conf
@@ -1,5 +1,7 @@
# User test config file for t-argparse
+[-echo begin of user config]
+[+verbose]
# Options applied to all user's config files
echo
@@ -8,4 +10,7 @@ echo
my-option 4711
+not-my-option
+
verbose
+[-echo end of user config] \ No newline at end of file