diff options
author | Pierre Habouzit <madcoder@debian.org> | 2007-10-15 01:45:45 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2007-10-29 21:03:30 -0700 |
commit | ffe659f94d793375fca97dd296422fc10c155016 (patch) | |
tree | 8cd20e4bf38a001e60fbc1356dfa9d2ede346ea9 /parse-options.c | |
parent | f389c808b6774fb0a1fc54cf2563a7b3038dd1d4 (diff) | |
download | git-ffe659f94d793375fca97dd296422fc10c155016.tar.gz |
parse-options: make some arguments optional, add callbacks.
* add the possibility to use callbacks to parse some options, this can
help implementing new options kinds with great flexibility. struct option
gains a callback pointer and a `defval' where callbacks user can put
either integers or pointers. callbacks also can use the `value' pointer
for anything, preferably to the pointer to the final storage for the value
though.
* add a `flag' member to struct option to make explicit that this option may
have an optional argument. The semantics depends on the option type. For
INTEGERS, it means that if the switch is not used in its
--long-form=<value> form, and that there is no token after it or that the
token does not starts with a digit, then it's assumed that the switch has
no argument. For STRING or CALLBACK it works the same, except that the
condition is that the next atom starts with a dash. This is needed to
implement backward compatible behaviour with existing ways to parse the
command line. Its use for new options is discouraged.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'parse-options.c')
-rw-r--r-- | parse-options.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/parse-options.c b/parse-options.c index 89c5f52be5..c751ebf601 100644 --- a/parse-options.c +++ b/parse-options.c @@ -39,7 +39,8 @@ static int opterror(const struct option *opt, const char *reason, int flags) static int get_value(struct optparse_t *p, const struct option *opt, int flags) { - const char *s; + const char *s, *arg; + arg = p->opt ? p->opt : (p->argc > 1 ? p->argv[1] : NULL); if (p->opt && (flags & OPT_UNSET)) return opterror(opt, "takes no value", flags); @@ -59,17 +60,34 @@ static int get_value(struct optparse_t *p, *(const char **)opt->value = (const char *)NULL; return 0; } - if (!p->opt && p->argc <= 1) + if (opt->flags & PARSE_OPT_OPTARG && (!arg || *arg == '-')) { + *(const char **)opt->value = (const char *)opt->defval; + return 0; + } + if (!arg) return opterror(opt, "requires a value", flags); *(const char **)opt->value = get_arg(p); return 0; + case OPTION_CALLBACK: + if (flags & OPT_UNSET) + return (*opt->callback)(opt, NULL, 1); + if (opt->flags & PARSE_OPT_OPTARG && (!arg || *arg == '-')) + return (*opt->callback)(opt, NULL, 0); + if (!arg) + return opterror(opt, "requires a value", flags); + return (*opt->callback)(opt, get_arg(p), 0); + case OPTION_INTEGER: if (flags & OPT_UNSET) { *(int *)opt->value = 0; return 0; } - if (!p->opt && p->argc <= 1) + if (opt->flags & PARSE_OPT_OPTARG && (!arg || !isdigit(*arg))) { + *(int *)opt->value = opt->defval; + return 0; + } + if (!arg) return opterror(opt, "requires a value", flags); *(int *)opt->value = strtol(get_arg(p), (char **)&s, 10); if (*s) @@ -201,13 +219,24 @@ void usage_with_options(const char * const *usagestr, switch (opts->type) { case OPTION_INTEGER: - pos += fprintf(stderr, " <n>"); + if (opts->flags & PARSE_OPT_OPTARG) + pos += fprintf(stderr, " [<n>]"); + else + pos += fprintf(stderr, " <n>"); break; case OPTION_STRING: - if (opts->argh) - pos += fprintf(stderr, " <%s>", opts->argh); - else - pos += fprintf(stderr, " ..."); + case OPTION_CALLBACK: + if (opts->argh) { + if (opts->flags & PARSE_OPT_OPTARG) + pos += fprintf(stderr, " [<%s>]", opts->argh); + else + pos += fprintf(stderr, " <%s>", opts->argh); + } else { + if (opts->flags & PARSE_OPT_OPTARG) + pos += fprintf(stderr, " [...]"); + else + pos += fprintf(stderr, " ..."); + } break; default: break; |