diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2019-01-27 07:35:28 +0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2019-01-27 16:28:18 -0800 |
commit | 3ebbe289896a698b99c91b797440563272dcd716 (patch) | |
tree | 09798977c8fc962c33fb6e3c95285484d9d855b2 /parse-options.c | |
parent | f41179f16ba2fc16e31be81518536008afe2e278 (diff) | |
download | git-3ebbe289896a698b99c91b797440563272dcd716.tar.gz |
parse-options: allow ll_callback with OPTION_CALLBACK
OPTION_CALLBACK is much simpler/safer to use, but parse_opt_cb does
not allow access to parse_opt_ctx_t, which sometimes is useful
(e.g. to obtain the prefix).
Extending parse_opt_cb to take parse_opt_cb could result in a lot of
changes. Instead let's just allow ll_callback to be used with
OPTION_CALLBACK. The user will have to be careful, not to change
anything in ctx, or return wrong result code. But that's the price for
ll_callback.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'parse-options.c')
-rw-r--r-- | parse-options.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/parse-options.c b/parse-options.c index 50c340474c..cec74522e5 100644 --- a/parse-options.c +++ b/parse-options.c @@ -95,7 +95,7 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p, switch (opt->type) { case OPTION_LOWLEVEL_CALLBACK: - return opt->ll_callback(p, opt, unset); + return opt->ll_callback(p, opt, NULL, unset); case OPTION_BIT: if (unset) @@ -161,16 +161,27 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p, return err; case OPTION_CALLBACK: + { + const char *p_arg = NULL; + int p_unset; + if (unset) - return (*opt->callback)(opt, NULL, 1) ? (-1) : 0; - if (opt->flags & PARSE_OPT_NOARG) - return (*opt->callback)(opt, NULL, 0) ? (-1) : 0; - if (opt->flags & PARSE_OPT_OPTARG && !p->opt) - return (*opt->callback)(opt, NULL, 0) ? (-1) : 0; - if (get_arg(p, opt, flags, &arg)) + p_unset = 1; + else if (opt->flags & PARSE_OPT_NOARG) + p_unset = 0; + else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) + p_unset = 0; + else if (get_arg(p, opt, flags, &arg)) return -1; - return (*opt->callback)(opt, arg, 0) ? (-1) : 0; - + else { + p_unset = 0; + p_arg = arg; + } + if (opt->callback) + return (*opt->callback)(opt, p_arg, p_unset) ? (-1) : 0; + else + return (*opt->ll_callback)(p, opt, p_arg, p_unset); + } case OPTION_INTEGER: if (unset) { *(int *)opt->value = 0; @@ -238,7 +249,10 @@ static enum parse_opt_result parse_short_opt(struct parse_opt_ctx_t *p, len++; arg = xmemdupz(p->opt, len); p->opt = p->opt[len] ? p->opt + len : NULL; - rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0; + if (numopt->callback) + rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0; + else + rc = (*numopt->ll_callback)(p, numopt, arg, 0); free(arg); return rc; } @@ -414,10 +428,10 @@ static void parse_options_check(const struct option *opts) err |= optbug(opts, "should not accept an argument"); break; case OPTION_CALLBACK: - if (!opts->callback) - BUG("OPTION_CALLBACK needs a callback"); - if (opts->ll_callback) - BUG("OPTION_CALLBACK needs no ll_callback"); + if (!opts->callback && !opts->ll_callback) + BUG("OPTION_CALLBACK needs one callback"); + if (opts->callback && opts->ll_callback) + BUG("OPTION_CALLBACK can't have two callbacks"); break; case OPTION_LOWLEVEL_CALLBACK: if (!opts->ll_callback) |