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