Merge branch 'jk/parse-options-concat'
Users of the parse_options_concat() API function need to allocate extra slots in advance and fill them with OPT_END() when they want to decide the set of supported options dynamically, which makes the code error-prone and hard to read. This has been corrected by tweaking the API to allocate and return a new copy of "struct option" array. * jk/parse-options-concat: parse_options: allocate a new array when concatenating
This commit is contained in:
@ -76,7 +76,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
|
|||||||
const char * const * usage_str = revert_or_cherry_pick_usage(opts);
|
const char * const * usage_str = revert_or_cherry_pick_usage(opts);
|
||||||
const char *me = action_name(opts);
|
const char *me = action_name(opts);
|
||||||
int cmd = 0;
|
int cmd = 0;
|
||||||
struct option options[] = {
|
struct option base_options[] = {
|
||||||
OPT_CMDMODE(0, "quit", &cmd, N_("end revert or cherry-pick sequence"), 'q'),
|
OPT_CMDMODE(0, "quit", &cmd, N_("end revert or cherry-pick sequence"), 'q'),
|
||||||
OPT_CMDMODE(0, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'),
|
OPT_CMDMODE(0, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'),
|
||||||
OPT_CMDMODE(0, "abort", &cmd, N_("cancel revert or cherry-pick sequence"), 'a'),
|
OPT_CMDMODE(0, "abort", &cmd, N_("cancel revert or cherry-pick sequence"), 'a'),
|
||||||
@ -91,13 +91,9 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
|
|||||||
N_("option for merge strategy"), option_parse_x),
|
N_("option for merge strategy"), option_parse_x),
|
||||||
{ OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
|
{ OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
|
||||||
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
|
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
|
||||||
OPT_END(),
|
OPT_END()
|
||||||
OPT_END(),
|
|
||||||
OPT_END(),
|
|
||||||
OPT_END(),
|
|
||||||
OPT_END(),
|
|
||||||
OPT_END(),
|
|
||||||
};
|
};
|
||||||
|
struct option *options = base_options;
|
||||||
|
|
||||||
if (opts->action == REPLAY_PICK) {
|
if (opts->action == REPLAY_PICK) {
|
||||||
struct option cp_extra[] = {
|
struct option cp_extra[] = {
|
||||||
@ -108,8 +104,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
|
|||||||
OPT_BOOL(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")),
|
OPT_BOOL(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")),
|
||||||
OPT_END(),
|
OPT_END(),
|
||||||
};
|
};
|
||||||
if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra))
|
options = parse_options_concat(options, cp_extra);
|
||||||
die(_("program error"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
argc = parse_options(argc, argv, NULL, options, usage_str,
|
argc = parse_options(argc, argv, NULL, options, usage_str,
|
||||||
|
@ -117,19 +117,24 @@ int parse_opt_tertiary(const struct option *opt, const char *arg, int unset)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_options_concat(struct option *dst, size_t dst_size, struct option *src)
|
struct option *parse_options_concat(struct option *a, struct option *b)
|
||||||
{
|
{
|
||||||
int i, j;
|
struct option *ret;
|
||||||
|
size_t i, a_len = 0, b_len = 0;
|
||||||
|
|
||||||
for (i = 0; i < dst_size; i++)
|
for (i = 0; a[i].type != OPTION_END; i++)
|
||||||
if (dst[i].type == OPTION_END)
|
a_len++;
|
||||||
break;
|
for (i = 0; b[i].type != OPTION_END; i++)
|
||||||
for (j = 0; i < dst_size; i++, j++) {
|
b_len++;
|
||||||
dst[i] = src[j];
|
|
||||||
if (src[j].type == OPTION_END)
|
ALLOC_ARRAY(ret, st_add3(a_len, b_len, 1));
|
||||||
return 0;
|
for (i = 0; i < a_len; i++)
|
||||||
}
|
ret[i] = a[i];
|
||||||
return -1;
|
for (i = 0; i < b_len; i++)
|
||||||
|
ret[a_len + i] = b[i];
|
||||||
|
ret[a_len + b_len] = b[b_len]; /* final OPTION_END */
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_opt_string_list(const struct option *opt, const char *arg, int unset)
|
int parse_opt_string_list(const struct option *opt, const char *arg, int unset)
|
||||||
|
@ -215,7 +215,7 @@ extern int parse_options_step(struct parse_opt_ctx_t *ctx,
|
|||||||
|
|
||||||
extern int parse_options_end(struct parse_opt_ctx_t *ctx);
|
extern int parse_options_end(struct parse_opt_ctx_t *ctx);
|
||||||
|
|
||||||
extern int parse_options_concat(struct option *dst, size_t, struct option *src);
|
extern struct option *parse_options_concat(struct option *a, struct option *b);
|
||||||
|
|
||||||
/*----- some often used options -----*/
|
/*----- some often used options -----*/
|
||||||
extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
|
extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
|
||||||
|
Reference in New Issue
Block a user