summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--src/argparse.c67
-rw-r--r--src/gpg-error.h.in13
-rw-r--r--tests/t-argparse.c12
4 files changed, 75 insertions, 21 deletions
diff --git a/NEWS b/NEWS
index 51c2c89..9e32030 100644
--- a/NEWS
+++ b/NEWS
@@ -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: