2011-12-01 01:27:26 +01:00
|
|
|
#include <assert.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "error_util.h"
|
|
|
|
#include "command-line-arguments.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
Search the array of keywords for a given argument, assigning the
|
2017-10-07 10:44:04 +02:00
|
|
|
output variable to the corresponding value. Return false if nothing
|
2011-12-01 01:27:26 +01:00
|
|
|
matches.
|
|
|
|
*/
|
|
|
|
|
2017-10-07 10:44:04 +02:00
|
|
|
static bool
|
2012-06-16 12:21:42 +02:00
|
|
|
_process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
|
2011-12-01 01:27:26 +01:00
|
|
|
|
2017-10-01 22:53:20 +02:00
|
|
|
const notmuch_keyword_t *keywords;
|
2011-12-01 01:27:26 +01:00
|
|
|
|
2012-06-05 16:36:36 +02:00
|
|
|
if (next == '\0') {
|
2012-06-16 12:21:42 +02:00
|
|
|
/* No keyword given */
|
|
|
|
arg_str = "";
|
|
|
|
}
|
|
|
|
|
2017-10-01 22:53:20 +02:00
|
|
|
for (keywords = arg_desc->keywords; keywords->name; keywords++) {
|
2017-10-01 22:53:21 +02:00
|
|
|
if (strcmp (arg_str, keywords->name) != 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (arg_desc->opt_flags)
|
|
|
|
*arg_desc->opt_flags |= keywords->value;
|
|
|
|
else
|
|
|
|
*arg_desc->opt_keyword = keywords->value;
|
|
|
|
|
2017-10-07 10:44:04 +02:00
|
|
|
return true;
|
2011-12-01 01:27:26 +01:00
|
|
|
}
|
2012-06-05 16:36:36 +02:00
|
|
|
if (next != '\0')
|
|
|
|
fprintf (stderr, "Unknown keyword argument \"%s\" for option \"%s\".\n", arg_str, arg_desc->name);
|
2012-06-16 12:21:42 +02:00
|
|
|
else
|
2012-06-05 16:36:36 +02:00
|
|
|
fprintf (stderr, "Option \"%s\" needs a keyword argument.\n", arg_desc->name);
|
2017-10-07 10:44:04 +02:00
|
|
|
return false;
|
2011-12-01 01:27:26 +01:00
|
|
|
}
|
|
|
|
|
2017-10-07 10:44:04 +02:00
|
|
|
static bool
|
2012-03-10 12:05:32 +01:00
|
|
|
_process_boolean_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
|
2017-10-07 10:44:04 +02:00
|
|
|
bool value;
|
2012-03-10 12:05:32 +01:00
|
|
|
|
2017-10-01 22:53:19 +02:00
|
|
|
if (next == '\0' || strcmp (arg_str, "true") == 0) {
|
2017-10-07 10:44:04 +02:00
|
|
|
value = true;
|
2017-10-01 22:53:19 +02:00
|
|
|
} else if (strcmp (arg_str, "false") == 0) {
|
2017-10-07 10:44:04 +02:00
|
|
|
value = false;
|
2017-10-01 22:53:19 +02:00
|
|
|
} else {
|
|
|
|
fprintf (stderr, "Unknown argument \"%s\" for (boolean) option \"%s\".\n", arg_str, arg_desc->name);
|
2017-10-07 10:44:04 +02:00
|
|
|
return false;
|
2012-03-10 12:05:32 +01:00
|
|
|
}
|
2017-10-01 22:53:19 +02:00
|
|
|
|
|
|
|
*arg_desc->opt_bool = value;
|
|
|
|
|
2017-10-07 10:44:04 +02:00
|
|
|
return true;
|
2012-03-10 12:05:32 +01:00
|
|
|
}
|
|
|
|
|
2017-10-07 10:44:04 +02:00
|
|
|
static bool
|
2012-06-05 16:36:36 +02:00
|
|
|
_process_int_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
|
|
|
|
|
|
|
|
char *endptr;
|
|
|
|
if (next == '\0' || arg_str[0] == '\0') {
|
|
|
|
fprintf (stderr, "Option \"%s\" needs an integer argument.\n", arg_desc->name);
|
2017-10-07 10:44:04 +02:00
|
|
|
return false;
|
2012-06-05 16:36:36 +02:00
|
|
|
}
|
|
|
|
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
*arg_desc->opt_int = strtol (arg_str, &endptr, 10);
|
2012-06-05 16:36:36 +02:00
|
|
|
if (*endptr == '\0')
|
2017-10-07 10:44:04 +02:00
|
|
|
return true;
|
2012-06-05 16:36:36 +02:00
|
|
|
|
|
|
|
fprintf (stderr, "Unable to parse argument \"%s\" for option \"%s\" as an integer.\n",
|
|
|
|
arg_str, arg_desc->name);
|
2017-10-07 10:44:04 +02:00
|
|
|
return false;
|
2012-06-05 16:36:36 +02:00
|
|
|
}
|
|
|
|
|
2017-10-07 10:44:04 +02:00
|
|
|
static bool
|
2012-06-05 16:36:36 +02:00
|
|
|
_process_string_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
|
|
|
|
|
|
|
|
if (next == '\0') {
|
|
|
|
fprintf (stderr, "Option \"%s\" needs a string argument.\n", arg_desc->name);
|
2017-10-07 10:44:04 +02:00
|
|
|
return false;
|
2012-06-05 16:36:36 +02:00
|
|
|
}
|
|
|
|
if (arg_str[0] == '\0') {
|
|
|
|
fprintf (stderr, "String argument for option \"%s\" must be non-empty.\n", arg_desc->name);
|
2017-10-07 10:44:04 +02:00
|
|
|
return false;
|
2012-06-05 16:36:36 +02:00
|
|
|
}
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
*arg_desc->opt_string = arg_str;
|
2017-10-07 10:44:04 +02:00
|
|
|
return true;
|
2012-06-05 16:36:36 +02:00
|
|
|
}
|
|
|
|
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
/* Return number of non-NULL opt_* fields in opt_desc. */
|
|
|
|
static int _opt_set_count (const notmuch_opt_desc_t *opt_desc)
|
|
|
|
{
|
|
|
|
return
|
|
|
|
!!opt_desc->opt_inherit +
|
|
|
|
!!opt_desc->opt_bool +
|
|
|
|
!!opt_desc->opt_int +
|
|
|
|
!!opt_desc->opt_keyword +
|
|
|
|
!!opt_desc->opt_flags +
|
|
|
|
!!opt_desc->opt_string +
|
|
|
|
!!opt_desc->opt_position;
|
|
|
|
}
|
|
|
|
|
2017-10-07 10:44:04 +02:00
|
|
|
/* Return true if opt_desc is valid. */
|
|
|
|
static bool _opt_valid (const notmuch_opt_desc_t *opt_desc)
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
{
|
|
|
|
int n = _opt_set_count (opt_desc);
|
|
|
|
|
|
|
|
if (n > 1)
|
|
|
|
INTERNAL_ERROR ("more than one non-NULL opt_* field for argument \"%s\"",
|
|
|
|
opt_desc->name);
|
|
|
|
|
|
|
|
return n > 0;
|
|
|
|
}
|
|
|
|
|
2011-12-01 01:27:26 +01:00
|
|
|
/*
|
2017-10-07 10:44:04 +02:00
|
|
|
Search for the {pos_arg_index}th position argument, return false if
|
2011-12-01 01:27:26 +01:00
|
|
|
that does not exist.
|
|
|
|
*/
|
|
|
|
|
2017-10-07 10:44:04 +02:00
|
|
|
bool
|
2011-12-01 01:27:26 +01:00
|
|
|
parse_position_arg (const char *arg_str, int pos_arg_index,
|
|
|
|
const notmuch_opt_desc_t *arg_desc) {
|
|
|
|
|
|
|
|
int pos_arg_counter = 0;
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
while (_opt_valid (arg_desc)) {
|
|
|
|
if (arg_desc->opt_position) {
|
2011-12-01 01:27:26 +01:00
|
|
|
if (pos_arg_counter == pos_arg_index) {
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
*arg_desc->opt_position = arg_str;
|
2017-10-01 22:53:14 +02:00
|
|
|
if (arg_desc->present)
|
2017-10-07 10:44:04 +02:00
|
|
|
*arg_desc->present = true;
|
|
|
|
return true;
|
2011-12-01 01:27:26 +01:00
|
|
|
}
|
|
|
|
pos_arg_counter++;
|
|
|
|
}
|
|
|
|
arg_desc++;
|
|
|
|
}
|
2017-10-07 10:44:04 +02:00
|
|
|
return false;
|
2011-12-01 01:27:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Search for a non-positional (i.e. starting with --) argument matching arg,
|
|
|
|
* parse a possible value, and assign to *output_var
|
|
|
|
*/
|
|
|
|
|
2017-07-01 17:18:44 +02:00
|
|
|
int
|
|
|
|
parse_option (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_index)
|
2014-11-05 01:25:54 +01:00
|
|
|
{
|
2017-07-01 17:18:44 +02:00
|
|
|
assert(argv);
|
|
|
|
|
|
|
|
const char *_arg = argv[opt_index];
|
|
|
|
|
2014-11-05 01:25:54 +01:00
|
|
|
assert(_arg);
|
2011-12-01 01:27:26 +01:00
|
|
|
assert(options);
|
|
|
|
|
2014-11-05 01:25:54 +01:00
|
|
|
const char *arg = _arg + 2; /* _arg starts with -- */
|
2012-06-05 16:36:36 +02:00
|
|
|
const notmuch_opt_desc_t *try;
|
2017-07-01 17:18:45 +02:00
|
|
|
|
|
|
|
const char *next_arg = NULL;
|
|
|
|
if (opt_index < argc - 1 && strncmp (argv[opt_index + 1], "--", 2) != 0)
|
|
|
|
next_arg = argv[opt_index + 1];
|
|
|
|
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
for (try = options; _opt_valid (try); try++) {
|
|
|
|
if (try->opt_inherit) {
|
|
|
|
int new_index = parse_option (argc, argv, try->opt_inherit, opt_index);
|
2017-07-01 17:18:44 +02:00
|
|
|
if (new_index >= 0)
|
|
|
|
return new_index;
|
|
|
|
}
|
2014-11-05 01:25:54 +01:00
|
|
|
|
2014-02-24 22:36:58 +01:00
|
|
|
if (! try->name)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (strncmp (arg, try->name, strlen (try->name)) != 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
char next = arg[strlen (try->name)];
|
|
|
|
const char *value = arg + strlen(try->name) + 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we have not reached the end of the argument (i.e. the
|
|
|
|
* next character is not a space or delimiter) then the
|
|
|
|
* argument could still match a longer option name later in
|
|
|
|
* the option table.
|
|
|
|
*/
|
|
|
|
if (next != '=' && next != ':' && next != '\0')
|
|
|
|
continue;
|
|
|
|
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
if (next == '\0' && next_arg != NULL && ! try->opt_bool) {
|
2017-07-01 17:18:45 +02:00
|
|
|
next = ' ';
|
|
|
|
value = next_arg;
|
|
|
|
opt_index ++;
|
|
|
|
}
|
|
|
|
|
2017-10-07 10:44:04 +02:00
|
|
|
bool opt_status = false;
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
if (try->opt_keyword || try->opt_flags)
|
2017-07-01 17:18:44 +02:00
|
|
|
opt_status = _process_keyword_arg (try, next, value);
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
else if (try->opt_bool)
|
2017-07-01 17:18:44 +02:00
|
|
|
opt_status = _process_boolean_arg (try, next, value);
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
else if (try->opt_int)
|
2017-07-01 17:18:44 +02:00
|
|
|
opt_status = _process_int_arg (try, next, value);
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
else if (try->opt_string)
|
2017-07-01 17:18:44 +02:00
|
|
|
opt_status = _process_string_arg (try, next, value);
|
cli: use designated initializers for opt desc
Several changes at once, just to not have to change the same lines
several times over:
- Use designated initializers to initialize opt desc arrays.
- Only initialize the needed fields.
- Remove arg_id (short options) as unused.
- Replace opt_type and output_var with several type safe output
variables, where the output variable being non-NULL determines the
type. Introduce checks to ensure only one is set. The downside is
some waste of const space per argument; this could be saved by
retaining opt_type and using a union, but that's still pretty
verbose.
- Fix some variables due to the type safety. Mostly a good thing, but
leads to some enums being changed to ints. This is pedantically
correct, but somewhat annoying. We could also cast, but that defeats
the purpose a bit.
- Terminate the opt desc arrays using {}.
The output variable type safety and the ability to add new fields for
just some output types or arguments are the big wins. For example, if
we wanted to add a variable to set when the argument is present, we
could do so for just the arguments that need it.
Beauty is in the eye of the beholder, but I think this looks nice when
defining the arguments, and reduces some of the verbosity we have
there.
2017-10-01 22:53:11 +02:00
|
|
|
else
|
|
|
|
INTERNAL_ERROR ("unknown or unhandled option \"%s\"", try->name);
|
|
|
|
|
2017-10-01 22:53:14 +02:00
|
|
|
if (! opt_status)
|
2017-07-01 17:18:44 +02:00
|
|
|
return -1;
|
2017-10-01 22:53:14 +02:00
|
|
|
|
|
|
|
if (try->present)
|
2017-10-07 10:44:04 +02:00
|
|
|
*try->present = true;
|
2017-10-01 22:53:14 +02:00
|
|
|
|
|
|
|
return opt_index+1;
|
2011-12-01 01:27:26 +01:00
|
|
|
}
|
2017-07-01 17:18:44 +02:00
|
|
|
return -1;
|
2011-12-01 01:27:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* See command-line-arguments.h for description */
|
|
|
|
int
|
|
|
|
parse_arguments (int argc, char **argv,
|
|
|
|
const notmuch_opt_desc_t *options, int opt_index) {
|
|
|
|
|
|
|
|
int pos_arg_index = 0;
|
2017-10-07 10:44:04 +02:00
|
|
|
bool more_args = true;
|
2011-12-01 01:27:26 +01:00
|
|
|
|
|
|
|
while (more_args && opt_index < argc) {
|
|
|
|
if (strncmp (argv[opt_index],"--",2) != 0) {
|
|
|
|
|
|
|
|
more_args = parse_position_arg (argv[opt_index], pos_arg_index, options);
|
|
|
|
|
|
|
|
if (more_args) {
|
|
|
|
pos_arg_index++;
|
|
|
|
opt_index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
2017-07-01 17:18:44 +02:00
|
|
|
int prev_opt_index = opt_index;
|
2011-12-01 01:27:26 +01:00
|
|
|
|
|
|
|
if (strlen (argv[opt_index]) == 2)
|
|
|
|
return opt_index+1;
|
|
|
|
|
2017-07-01 17:18:44 +02:00
|
|
|
opt_index = parse_option (argc, argv, options, opt_index);
|
|
|
|
if (opt_index < 0) {
|
|
|
|
fprintf (stderr, "Unrecognized option: %s\n", argv[prev_opt_index]);
|
2017-10-07 10:44:04 +02:00
|
|
|
more_args = false;
|
2011-12-01 01:27:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return opt_index;
|
|
|
|
}
|