2004-02-26 Marcus Brinkmann <marcus@g10code.de>

* README.gpgconf: Fix description of arguments.
	* gpgconf-comp.c (option_check_validity): Rewritten to properly
	support optional arguments in lists.
This commit is contained in:
Marcus Brinkmann 2004-02-26 18:22:02 +00:00
parent 7aa4fa9b09
commit 255d2cea04
3 changed files with 99 additions and 107 deletions

View File

@ -1,6 +1,10 @@
2004-02-26 Marcus Brinkmann <marcus@g10code.de>
* README.gpgconf (NAME): Add info about optional arg and arg type 0.
* README.gpgconf: Fix description of arguments.
* gpgconf-comp.c (option_check_validity): Rewritten to properly
support optional arguments in lists.
* README.gpgconf: Add info about optional arg and arg type 0.
* gpgconf-comp.c (gc_component_change_options): Parse list of
arg type 0 options.
(option_check_validity): Add new argument NEW_VALUE_NR. Perform

View File

@ -80,17 +80,17 @@ Some fields contain an option argument. The format of an option
argument depends on the type of the option and on some flags:
The simplest case is that the option does not take an argument at all
(TYPE is 0). Then the option argument is either empty if the option
is not set, or an unsigned number that specifies how often the option
occurs. If the LIST flag is not set, then the only valid number is 1.
Options that don't take an argument never have the "default" flag set.
(TYPE is 0). Then the option argument is an unsigned number that
specifies how often the option occurs. If the LIST flag is not set,
then the only valid number is 1. Options that don't take an argument
never have the "default" or "optional arg" flag set.
If the option takes a number argument (ALT-TYPE is 2 or 3), and it can
only occur once (LIST flag is not set), then the option argument is
either empty if the option is not set, or it is a number. A number is
a string that begins with an optional minus character, followed by one
or more digits. The number must fit into an integer variable
(unsigned or signed, depending on ALT-TYPE).
either empty (only allowed if the argument is optional), or it is a
number. A number is a string that begins with an optional minus
character, followed by one or more digits. The number must fit into
an integer variable (unsigned or signed, depending on ALT-TYPE).
If the option takes a number argument and it can occur more than once,
then the option argument is either empty, or it is a comma-separated
@ -98,19 +98,16 @@ list of numbers as described above.
If the option takes a string argument (ALT-TYPE is 1), and it can only
occur once (LIST flag is not set) then the option argument is either
empty if the option is not set, or it starts with a double quote
character (") followed by a percent-escaped string that is the
argument value. Note that there is only a leading double quote
empty (only allowed if the argument is optional), or it starts with a
double quote character (") followed by a percent-escaped string that
is the argument value. Note that there is only a leading double quote
character, no trailing one. The double quote character is only needed
to be able to differentiate between no value and the empty string as
value.
If the option takes a string argument and it can occur more than once,
then the option argument is either empty or it starts with a double
quote character (") followed by a comma-separated list of
percent-escaped strings. Obviously any commas in the individual
strings must be percent-escaped.
If the option takes a number argument and it can occur more than once,
then the option argument is either empty, or it is a comma-separated
list of string arguments as described above.
FIXME: Document the active language and active character set. Allow
to change it via the command line?

View File

@ -1223,6 +1223,8 @@ static void
option_check_validity (gc_option_t *option, unsigned long flags,
char *new_value, unsigned long *new_value_nr)
{
char *arg;
if (option->new_flags || option->new_value)
gc_error (1, 0, "option %s already changed", option->name);
@ -1231,101 +1233,89 @@ option_check_validity (gc_option_t *option, unsigned long flags,
if (*new_value)
gc_error (1, 0, "argument %s provided for deleted option %s",
new_value, option->name);
return;
}
else
/* GC_ARG_TYPE_NONE options have special list treatment. */
if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
{
/* This is even correct for GC_ARG_TYPE_NONE options, for which
GC_OPT_FLAG_ARG_OPT is never set. */
if (!(option->flags & GC_OPT_FLAG_ARG_OPT) && (*new_value == '\0'))
gc_error (1, 0, "no argument for option %s", option->name);
char *tail;
if (*new_value)
errno = 0;
*new_value_nr = strtoul (new_value, &tail, 0);
if (errno)
gc_error (1, errno, "invalid argument for option %s",
option->name);
if (*tail)
gc_error (1, 0, "garbage after argument for option %s",
option->name);
if (!(option->flags & GC_OPT_FLAG_LIST))
{
if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
{
char *tail;
errno = 0;
*new_value_nr = strtoul (new_value, &tail, 0);
if (errno)
gc_error (1, errno, "invalid argument for option %s",
option->name);
if (*tail)
gc_error (1, 0, "garbage after argument for option %s",
option->name);
if (!(option->flags & GC_OPT_FLAG_LIST))
{
if (*new_value_nr != 1)
gc_error (1, 0, "argument for non-list option %s of type 0 "
"(none) must be 1", option->name);
}
else
{
if (*new_value_nr == 0)
gc_error (1, 0, "argument for option %s of type 0 (none) "
"must be positive", option->name);
}
}
else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
{
if (*new_value != '"')
gc_error (1, 0, "string argument for option %s must begin "
"with a quote (\") character", option->name);
}
else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
{
char *tail = new_value;
while (*tail)
{
errno = 0;
(void) strtol (new_value, &tail, 0);
if (errno)
gc_error (1, errno, "invalid argument for option %s",
option->name);
if (*tail == ',')
{
if (!(option->flags & GC_OPT_FLAG_LIST))
gc_error (1, 0, "list found for non-list option %s",
option->name);
tail++;
}
else if (*tail)
gc_error (1, 0, "garbage after argument for option %s",
option->name);
}
}
else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_UINT32)
{
char *tail = new_value;
while (*tail)
{
errno = 0;
(void) strtoul (new_value, &tail, 0);
if (errno)
gc_error (1, errno, "invalid argument for option %s",
option->name);
if (*tail == ',')
{
if (!(option->flags & GC_OPT_FLAG_LIST))
gc_error (1, 0, "list found for non-list option %s",
option->name);
tail++;
}
else if (*tail)
gc_error (1, 0, "garbage after argument for option %s",
option->name);
}
}
else
assert (!"Unexpected argument type");
if (*new_value_nr != 1)
gc_error (1, 0, "argument for non-list option %s of type 0 "
"(none) must be 1", option->name);
}
else
{
if (*new_value_nr == 0)
gc_error (1, 0, "argument for option %s of type 0 (none) "
"must be positive", option->name);
}
return;
}
arg = new_value;
do
{
if (*arg == '\0' || *arg == ',')
{
if (!(option->flags & GC_OPT_FLAG_ARG_OPT))
gc_error (1, 0, "argument required for option %s", option->name);
if (*arg == ',' && !(option->flags & GC_OPT_FLAG_LIST))
gc_error (1, 0, "list found for non-list option %s", option->name);
}
else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
{
if (*arg != '"')
gc_error (1, 0, "string argument for option %s must begin "
"with a quote (\") character", option->name);
}
else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
{
errno = 0;
(void) strtol (arg, &arg, 0);
if (errno)
gc_error (1, errno, "invalid argument for option %s",
option->name);
if (*arg != '\0' && *arg != ',')
gc_error (1, 0, "garbage after argument for option %s",
option->name);
}
else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
{
errno = 0;
(void) strtoul (arg, &arg, 0);
if (errno)
gc_error (1, errno, "invalid argument for option %s",
option->name);
if (*arg != '\0' && *arg != ',')
gc_error (1, 0, "garbage after argument for option %s",
option->name);
}
arg = strchr (arg, ',');
if (arg)
arg++;
}
while (arg && *arg);
}
@ -1377,6 +1367,7 @@ change_options_program (gc_component_t component, gc_backend_t backend,
xfree (orig_filename);
orig_filename = NULL;
}
/* We now initialize the return strings, so the caller can do the
cleanup for us. */
*src_filenamep = src_filename;