Skip to content

Commit 3ebbe28

Browse files
pcloudsgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f41179f commit 3ebbe28

File tree

5 files changed

+51
-22
lines changed

5 files changed

+51
-22
lines changed

builtin/merge.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,13 @@ static int option_parse_message(const struct option *opt,
114114

115115
static enum parse_opt_result option_read_message(struct parse_opt_ctx_t *ctx,
116116
const struct option *opt,
117+
const char *arg_not_used,
117118
int unset)
118119
{
119120
struct strbuf *buf = opt->value;
120121
const char *arg;
121122

123+
BUG_ON_OPT_ARG(arg_not_used);
122124
if (unset)
123125
BUG("-F cannot be negated");
124126

builtin/update-index.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -848,13 +848,15 @@ static int parse_new_style_cacheinfo(const char *arg,
848848
}
849849

850850
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)
852853
{
853854
struct object_id oid;
854855
unsigned int mode;
855856
const char *path;
856857

857858
BUG_ON_OPT_NEG(unset);
859+
BUG_ON_OPT_ARG(arg);
858860

859861
if (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) {
860862
if (add_cacheinfo(mode, &oid, path, 0))
@@ -874,11 +876,13 @@ static enum parse_opt_result cacheinfo_callback(
874876
}
875877

876878
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)
878881
{
879882
int *nul_term_line = opt->value;
880883

881884
BUG_ON_OPT_NEG(unset);
885+
BUG_ON_OPT_ARG(arg);
882886

883887
if (ctx->argc != 1)
884888
return error("option '%s' must be the last argument", opt->long_name);
@@ -888,11 +892,13 @@ static enum parse_opt_result stdin_cacheinfo_callback(
888892
}
889893

890894
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)
892897
{
893898
int *read_from_stdin = opt->value;
894899

895900
BUG_ON_OPT_NEG(unset);
901+
BUG_ON_OPT_ARG(arg);
896902

897903
if (ctx->argc != 1)
898904
return error("option '%s' must be the last argument", opt->long_name);
@@ -901,12 +907,14 @@ static enum parse_opt_result stdin_callback(
901907
}
902908

903909
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)
905912
{
906913
int *has_errors = opt->value;
907914
const char *prefix = startup_info->prefix;
908915

909916
BUG_ON_OPT_NEG(unset);
917+
BUG_ON_OPT_ARG(arg);
910918

911919
/* consume remaining arguments. */
912920
*has_errors = do_unresolve(ctx->argc, ctx->argv,
@@ -920,12 +928,14 @@ static enum parse_opt_result unresolve_callback(
920928
}
921929

922930
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)
924933
{
925934
int *has_errors = opt->value;
926935
const char *prefix = startup_info->prefix;
927936

928937
BUG_ON_OPT_NEG(unset);
938+
BUG_ON_OPT_ARG(arg);
929939

930940
/* consume remaining arguments. */
931941
setup_work_tree();

parse-options-cb.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,10 @@ int parse_opt_noop_cb(const struct option *opt, const char *arg, int unset)
171171
* parse_options().
172172
*/
173173
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)
175176
{
177+
BUG_ON_OPT_ARG(arg);
176178
return PARSE_OPT_UNKNOWN;
177179
}
178180

parse-options.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
9595

9696
switch (opt->type) {
9797
case OPTION_LOWLEVEL_CALLBACK:
98-
return opt->ll_callback(p, opt, unset);
98+
return opt->ll_callback(p, opt, NULL, unset);
9999

100100
case OPTION_BIT:
101101
if (unset)
@@ -161,16 +161,27 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
161161
return err;
162162

163163
case OPTION_CALLBACK:
164+
{
165+
const char *p_arg = NULL;
166+
int p_unset;
167+
164168
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))
171175
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+
}
174185
case OPTION_INTEGER:
175186
if (unset) {
176187
*(int *)opt->value = 0;
@@ -238,7 +249,10 @@ static enum parse_opt_result parse_short_opt(struct parse_opt_ctx_t *p,
238249
len++;
239250
arg = xmemdupz(p->opt, len);
240251
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);
242256
free(arg);
243257
return rc;
244258
}
@@ -414,10 +428,10 @@ static void parse_options_check(const struct option *opts)
414428
err |= optbug(opts, "should not accept an argument");
415429
break;
416430
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");
421435
break;
422436
case OPTION_LOWLEVEL_CALLBACK:
423437
if (!opts->ll_callback)

parse-options.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
5050

5151
struct parse_opt_ctx_t;
5252
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);
5455

5556
/*
5657
* `type`::
@@ -267,7 +268,7 @@ int parse_opt_commits(const struct option *, const char *, int);
267268
int parse_opt_tertiary(const struct option *, const char *, int);
268269
int parse_opt_string_list(const struct option *, const char *, int);
269270
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);
271272
int parse_opt_passthru(const struct option *, const char *, int);
272273
int parse_opt_passthru_argv(const struct option *, const char *, int);
273274

0 commit comments

Comments
 (0)