diff options
author | Werner Koch <wk@gnupg.org> | 2020-03-02 16:53:20 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2020-03-02 16:53:20 +0100 |
commit | d3661d81e9aafae75680164ede7322cf3d7b6804 (patch) | |
tree | 0384134cc8b8b4741ae294d231753fe674b8c451 | |
parent | 2d1969ab465bad62f73a7c24ddc8bb490ff9fd40 (diff) | |
download | libgpg-error-d3661d81e9aafae75680164ede7322cf3d7b6804.tar.gz |
core: Allow returning of attributes from gpgrt_argparser.
* src/gpg-error.h.in (ARGPARSE_FLAG_WITHATTR): New.
(ARGPARSE_ATTR_FORCE): New.
(ARGPARSE_ATTR_IGNORE): New.
(ARGPARSE_TYPE_MASK): Moved from argparse.c to here.
* src/argparse.c: Always use macros for constants.
(_gpgrt_argparse): Handle ARGPARSE_FLAG_WITHATTR.
(arg_parse): Ditto.
* tests/t-argparse.c (main): Add commented test case.
--
This is a ABI compatible hack to allow the ignore and force attributes
as well as to return which option has been ignored in a user file or
on the command line.
Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | src/argparse.c | 67 | ||||
-rw-r--r-- | src/gpg-error.h.in | 13 | ||||
-rw-r--r-- | tests/t-argparse.c | 12 |
4 files changed, 75 insertions, 21 deletions
@@ -11,9 +11,13 @@ Noteworthy changes in version 1.38 (unreleased) [C28/A28/R_] ARGPARSE_FLAG_USER NEW. ARGPARSE_FLAG_VERBOSE NEW. ARGPARSE_FLAG_USERVERS NEW. + ARGPARSE_FLAG_WITHATTR NEW. ARGPARSE_NO_CONFFILE NEW. ARGPARSE_CONFFILE NEW. ARGPARSE_OPT_CONFFILE NEW. + ARGPARSE_ATTR_FORCE NEW. + ARGPARSE_ATTR_IGNORE NEW. + ARGPARSE_TYPE_MASK NEW. ARGPARSE_PERMISSION_ERROR NEW. ARGPARSE_INVALID_META NEW. ARGPARSE_UNKNOWN_META NEW. diff --git a/src/argparse.c b/src/argparse.c index 03e033a..e1ff85e 100644 --- a/src/argparse.c +++ b/src/argparse.c @@ -64,8 +64,6 @@ static struct #define ARGPARSE_SHORTOPT_WARRANTY 32770 #define ARGPARSE_SHORTOPT_DUMP_OPTIONS 32771 -/* A mask for the types. */ -#define ARGPARSE_TYPE_MASK 7 /* Mask for the type values. */ /* The states for the gpgrt_argparser machinery. */ enum argparser_states @@ -938,6 +936,8 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig) } else /* Known option */ { + int set_ignore = 0; + if (arg->internal->in_sysconf) { /* Set the current forced and ignored attributes. */ @@ -960,19 +960,37 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig) opts[idx].long_opt, opts[idx].forced? " forced":"", opts[idx].ignore? " ignore":""); - state = Ainit; - i = 0; - goto nextstate; /* Ignore this one. */ + if ((arg->flags & ARGPARSE_FLAG_WITHATTR)) + set_ignore = 1; + else + { + 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. */ + arg->r_type = ARGPARSE_TYPE_NONE; /* Does not take an arg. */ else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL) ) - arg->r_type = 0; /* Arg is optional. */ + arg->r_type = ARGPARSE_TYPE_NONE; /* Arg is optional. */ else arg->r_opt = ARGPARSE_MISSING_ARG; + + /* If the caller wants us to return the attributes or + * ignored options, or the flags in. */ + if ((arg->flags & ARGPARSE_FLAG_WITHATTR)) + { + if (opts[idx].ignore) + arg->r_type |= ARGPARSE_ATTR_IGNORE; + if (opts[idx].forced) + arg->r_type |= ARGPARSE_ATTR_FORCE; + if (set_ignore) + arg->r_type |= ARGPARSE_OPT_IGNORE; + } + goto leave; } } /* (end state Akeyword_eol/Akeyword_spc) */ @@ -1030,9 +1048,9 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig) if (in_alias) arg->r_opt = ARGPARSE_MISSING_ARG; else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK)) - arg->r_type = 0; /* Does not take an arg. */ + arg->r_type = ARGPARSE_TYPE_NONE; /* Does not take an arg. */ else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL)) - arg->r_type = 0; /* No optional argument. */ + arg->r_type = ARGPARSE_TYPE_NONE; /* No optional argument. */ else arg->r_opt = ARGPARSE_MISSING_ARG; @@ -1420,7 +1438,7 @@ _gpgrt_argparser (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, if ((arg->internal->opt_flags & ARGPARSE_OPT_CONFFILE)) { arg->internal->explicit_confopt = 1; - if (arg->r_type == ARGPARSE_TYPE_STRING + if ((arg->r_type & ARGPARSE_TYPE_MASK) == ARGPARSE_TYPE_STRING && !arg->internal->explicit_conffile) { /* Store the first conffile name. All further @@ -1431,7 +1449,8 @@ _gpgrt_argparser (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, return (arg->r_opt = ARGPARSE_OUT_OF_CORE); } - else if (arg->r_type == ARGPARSE_TYPE_NONE) + else if ((arg->r_type & ARGPARSE_TYPE_MASK) + == ARGPARSE_TYPE_NONE) any_no_conffile = 1; } } @@ -1779,7 +1798,7 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig, int no_init) if (arg->internal->stopped && (arg->flags & ARGPARSE_FLAG_ALL)) { arg->r_opt = ARGPARSE_IS_ARG; /* Not an option but an argument. */ - arg->r_type = 2; + arg->r_type = ARGPARSE_TYPE_STRING; arg->r.ret_str = s; argc--; argv++; idx++; /* set to next one */ } @@ -1891,7 +1910,7 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig, int no_init) else { arg->internal->opt_flags = opts[i].flags; - arg->r_type = 0; + arg->r_type = ARGPARSE_TYPE_NONE; } } argc--; argv++; idx++; /* Set to next one. */ @@ -1988,7 +2007,7 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig, int no_init) else if ( arg->flags & ARGPARSE_FLAG_MIXED ) { arg->r_opt = ARGPARSE_IS_ARG; - arg->r_type = 2; + arg->r_type = ARGPARSE_TYPE_STRING; arg->r.ret_str = s; argc--; argv++; idx++; /* Set to next one. */ } @@ -2001,10 +2020,22 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig, int no_init) 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. */ + + if ((arg->flags & ARGPARSE_FLAG_WITHATTR)) + { + if (opts[i].ignore) + arg->r_type |= ARGPARSE_ATTR_IGNORE; + if (opts[i].forced) + arg->r_type |= ARGPARSE_ATTR_FORCE; + arg->r_type |= ARGPARSE_OPT_IGNORE; + } + else + { + _gpgrt_log_info (_("Note: ignoring option \"--%s\"" + " due to global config\n"), + opts[i].long_opt); + goto next_one; /* Skip ignored/forced option. */ + } } leave: diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index 165881b..5643bdf 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -1185,6 +1185,7 @@ typedef struct #define ARGPARSE_FLAG_USER 2048 /* Use user config file. */ #define ARGPARSE_FLAG_VERBOSE 4096 /* Print additional argparser info. */ #define ARGPARSE_FLAG_USERVERS 8192 /* Try version-ed user config files. */ +#define ARGPARSE_FLAG_WITHATTR 16384 /* Return attribute bits. */ /* Constants for (gpgrt_argparse_t).err. */ #define ARGPARSE_PRINT_WARNING 1 /* Print a diagnostic. */ @@ -1210,8 +1211,14 @@ typedef struct #define ARGPARSE_UNKNOWN_META (-17) #define ARGPARSE_UNEXPECTED_META (-18) -/* Flags for the option descriptor (gpgrt_opt_t)->flags. Note that - * a TYPE constant may be or-ed with the OPT constants. */ +/* Flags for the option descriptor (gpgrt_opt_t)->flags. Note that a + * TYPE constant may be or-ed with the OPT constants but when used as + * return value in r_type these OPT constants are normally not + * included. However with ARGPARSE_FLAG_WITHATTR used and an option + * would normally not be returned, it is returned but + * ARGPARSE_OPT_IGNORE is then set; further ARPARSE_ATTR_* are set. + */ +#define ARGPARSE_TYPE_MASK 0x0007 /* Mask for the type bits. */ #define ARGPARSE_TYPE_NONE 0 /* Does not take an argument. */ #define ARGPARSE_TYPE_INT 1 /* Takes an int argument. */ #define ARGPARSE_TYPE_STRING 2 /* Takes a string argument. */ @@ -1222,6 +1229,8 @@ typedef struct #define ARGPARSE_OPT_IGNORE (1<<6) /* Ignore command or option. */ #define ARGPARSE_OPT_COMMAND (1<<7) /* The argument is a command. */ #define ARGPARSE_OPT_CONFFILE (1<<8) /* The value is a conffile. */ +#define ARGPARSE_ATTR_FORCE (1<<14)/* Attribute force is set. */ +#define ARGPARSE_ATTR_IGNORE (1<<15)/* Attribute ignore is set. */ /* A set of macros to make option definitions easier to read. */ #define ARGPARSE_x(s,l,t,f,d) \ diff --git a/tests/t-argparse.c b/tests/t-argparse.c index 46b7258..80da5ac 100644 --- a/tests/t-argparse.c +++ b/tests/t-argparse.c @@ -86,6 +86,7 @@ main (int argc, char **argv) | ARGPARSE_FLAG_SYS | ARGPARSE_FLAG_USER /* | ARGPARSE_FLAG_VERBOSE */ + /* | ARGPARSE_FLAG_WITHATTR */ ) }; int i; const char *srcdir; @@ -104,7 +105,16 @@ main (int argc, char **argv) while (gpgrt_argparser (&pargs, opts, PGM".conf")) { - /* printf ("got option %d\n", pargs.r_opt); */ + /* printf ("got option %3d type %0x04x\n", pargs.r_opt, pargs.r_type); */ + /* if (pargs.r_type & (ARGPARSE_ATTR_IGNORE|ARGPARSE_ATTR_FORCE)) */ + /* printf ("attributes:%s%s\n", */ + /* (pargs.r_type & ARGPARSE_ATTR_IGNORE)? " ignore":"", */ + /* (pargs.r_type & ARGPARSE_ATTR_FORCE)? " force":""); */ + /* if (pargs.r_type & ARGPARSE_OPT_IGNORE) */ + /* { */ + /* printf ("ignored\n"); */ + /* continue; */ + /* } */ switch (pargs.r_opt) { case ARGPARSE_CONFFILE: |