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>

Nguyễn Thái Ngọc Duy committed Jan 27, 2019 at 07:35 UTC 3ebbe289896a698b99c91b797440563272dcd716
5 files changed +51 -22
builtin/merge.c
+2
@@ -114,11 +114,13 @@ static int option_parse_message(const struct option *opt,
114
115 static enum parse_opt_result option_read_message(struct parse_opt_ctx_t *ctx,
116 const struct option *opt,
117 + const char *arg_not_used,
118 int unset)
119 {
120 struct strbuf *buf = opt->value;
121 const char *arg;
122
123 + BUG_ON_OPT_ARG(arg_not_used);
124 if (unset)
125 BUG("-F cannot be negated");
126
builtin/update-index.c
+15 -5
@@ -848,13 +848,15 @@ static int parse_new_style_cacheinfo(const char *arg,
848 }
849
850 static enum parse_opt_result cacheinfo_callback(
851 - struct parse_opt_ctx_t *ctx, const struct option *opt, int unset)
851 + struct parse_opt_ctx_t *ctx, const struct option *opt,
852 + const char *arg, int unset)
853 {
854 struct object_id oid;
855 unsigned int mode;
856 const char *path;
857
858 BUG_ON_OPT_NEG(unset);
859 + BUG_ON_OPT_ARG(arg);
860
861 if (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) {
862 if (add_cacheinfo(mode, &oid, path, 0))
@@ -874,11 +876,13 @@ static enum parse_opt_result cacheinfo_callback(
876 }
877
878 static enum parse_opt_result stdin_cacheinfo_callback(
877 - struct parse_opt_ctx_t *ctx, const struct option *opt, int unset)
879 + struct parse_opt_ctx_t *ctx, const struct option *opt,
880 + const char *arg, int unset)
881 {
882 int *nul_term_line = opt->value;
883
884 BUG_ON_OPT_NEG(unset);
885 + BUG_ON_OPT_ARG(arg);
886
887 if (ctx->argc != 1)
888 return error("option '%s' must be the last argument", opt->long_name);
@@ -888,11 +892,13 @@ static enum parse_opt_result stdin_cacheinfo_callback(
892 }
893
894 static enum parse_opt_result stdin_callback(
891 - struct parse_opt_ctx_t *ctx, const struct option *opt, int unset)
895 + struct parse_opt_ctx_t *ctx, const struct option *opt,
896 + const char *arg, int unset)
897 {
898 int *read_from_stdin = opt->value;
899
900 BUG_ON_OPT_NEG(unset);
901 + BUG_ON_OPT_ARG(arg);
902
903 if (ctx->argc != 1)
904 return error("option '%s' must be the last argument", opt->long_name);
@@ -901,12 +907,14 @@ static enum parse_opt_result stdin_callback(
907 }
908
909 static enum parse_opt_result unresolve_callback(
904 - struct parse_opt_ctx_t *ctx, const struct option *opt, int unset)
910 + struct parse_opt_ctx_t *ctx, const struct option *opt,
911 + const char *arg, int unset)
912 {
913 int *has_errors = opt->value;
914 const char *prefix = startup_info->prefix;
915
916 BUG_ON_OPT_NEG(unset);
917 + BUG_ON_OPT_ARG(arg);
918
919 /* consume remaining arguments. */
920 *has_errors = do_unresolve(ctx->argc, ctx->argv,
@@ -920,12 +928,14 @@ static enum parse_opt_result unresolve_callback(
928 }
929
930 static enum parse_opt_result reupdate_callback(
923 - struct parse_opt_ctx_t *ctx, const struct option *opt, int unset)
931 + struct parse_opt_ctx_t *ctx, const struct option *opt,
932 + const char *arg, int unset)
933 {
934 int *has_errors = opt->value;
935 const char *prefix = startup_info->prefix;
936
937 BUG_ON_OPT_NEG(unset);
938 + BUG_ON_OPT_ARG(arg);
939
940 /* consume remaining arguments. */
941 setup_work_tree();
parse-options-cb.c
+3 -1
@@ -171,8 +171,10 @@ int parse_opt_noop_cb(const struct option *opt, const char *arg, int unset)
171 * parse_options().
172 */
173 enum parse_opt_result parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx,
174 - const struct option *opt, int unset)
174 + const struct option *opt,
175 + const char *arg, int unset)
176 {
177 + BUG_ON_OPT_ARG(arg);
178 return PARSE_OPT_UNKNOWN;
179 }
180
parse-options.c
+28 -14
@@ -95,7 +95,7 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
95
96 switch (opt->type) {
97 case OPTION_LOWLEVEL_CALLBACK:
98 - return opt->ll_callback(p, opt, unset);
98 + return opt->ll_callback(p, opt, NULL, unset);
99
100 case OPTION_BIT:
101 if (unset)
@@ -161,16 +161,27 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
161 return err;
162
163 case OPTION_CALLBACK:
164 + {
165 + const char *p_arg = NULL;
166 + int p_unset;
167 +
168 if (unset)
165 - return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
166 - if (opt->flags & PARSE_OPT_NOARG)
167 - return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
168 - if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
169 - return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
170 - if (get_arg(p, opt, flags, &arg))
169 + p_unset = 1;
170 + else if (opt->flags & PARSE_OPT_NOARG)
171 + p_unset = 0;
172 + else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
173 + p_unset = 0;
174 + else if (get_arg(p, opt, flags, &arg))
175 return -1;
172 - return (*opt->callback)(opt, arg, 0) ? (-1) : 0;
173 -
176 + else {
177 + p_unset = 0;
178 + p_arg = arg;
179 + }
180 + if (opt->callback)
181 + return (*opt->callback)(opt, p_arg, p_unset) ? (-1) : 0;
182 + else
183 + return (*opt->ll_callback)(p, opt, p_arg, p_unset);
184 + }
185 case OPTION_INTEGER:
186 if (unset) {
187 *(int *)opt->value = 0;
@@ -238,7 +249,10 @@ static enum parse_opt_result parse_short_opt(struct parse_opt_ctx_t *p,
249 len++;
250 arg = xmemdupz(p->opt, len);
251 p->opt = p->opt[len] ? p->opt + len : NULL;
241 - rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0;
252 + if (numopt->callback)
253 + rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0;
254 + else
255 + rc = (*numopt->ll_callback)(p, numopt, arg, 0);
256 free(arg);
257 return rc;
258 }
@@ -414,10 +428,10 @@ static void parse_options_check(const struct option *opts)
428 err |= optbug(opts, "should not accept an argument");
429 break;
430 case OPTION_CALLBACK:
417 - if (!opts->callback)
418 - BUG("OPTION_CALLBACK needs a callback");
419 - if (opts->ll_callback)
420 - BUG("OPTION_CALLBACK needs no ll_callback");
431 + if (!opts->callback && !opts->ll_callback)
432 + BUG("OPTION_CALLBACK needs one callback");
433 + if (opts->callback && opts->ll_callback)
434 + BUG("OPTION_CALLBACK can't have two callbacks");
435 break;
436 case OPTION_LOWLEVEL_CALLBACK:
437 if (!opts->ll_callback)
parse-options.h
+3 -2
@@ -50,7 +50,8 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
50
51 struct parse_opt_ctx_t;
52 typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
53 - const struct option *opt, int unset);
53 + const struct option *opt,
54 + const char *arg, int unset);
55
56 /*
57 * `type`::
@@ -267,7 +268,7 @@ int parse_opt_commits(const struct option *, const char *, int);
268 int parse_opt_tertiary(const struct option *, const char *, int);
269 int parse_opt_string_list(const struct option *, const char *, int);
270 int parse_opt_noop_cb(const struct option *, const char *, int);
270 -int parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx, const struct option *, int);
271 +int parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx, const struct option *, const char *, int);
272 int parse_opt_passthru(const struct option *, const char *, int);
273 int parse_opt_passthru_argv(const struct option *, const char *, int);
274