Skip to content

Commit

Permalink
Merge branch 'jk/parse-options-concat'
Browse files Browse the repository at this point in the history
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
  • Loading branch information
gitster committed Aug 3, 2016
2 parents cf27c79 + 023ff39 commit d083d42
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 22 deletions.
13 changes: 4 additions & 9 deletions builtin/revert.c
Expand Up @@ -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 *me = action_name(opts);
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, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'),
OPT_CMDMODE(0, "abort", &cmd, N_("cancel revert or cherry-pick sequence"), 'a'),
Expand All @@ -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),
{ OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
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) {
struct option cp_extra[] = {
Expand All @@ -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_END(),
};
if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra))
die(_("program error"));
options = parse_options_concat(options, cp_extra);
}

argc = parse_options(argc, argv, NULL, options, usage_str,
Expand Down
29 changes: 17 additions & 12 deletions parse-options-cb.c
Expand Up @@ -117,19 +117,24 @@ int parse_opt_tertiary(const struct option *opt, const char *arg, int unset)
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;

for (i = 0; i < dst_size; i++)
if (dst[i].type == OPTION_END)
break;
for (j = 0; i < dst_size; i++, j++) {
dst[i] = src[j];
if (src[j].type == OPTION_END)
return 0;
}
return -1;
struct option *ret;
size_t i, a_len = 0, b_len = 0;

for (i = 0; a[i].type != OPTION_END; i++)
a_len++;
for (i = 0; b[i].type != OPTION_END; i++)
b_len++;

ALLOC_ARRAY(ret, st_add3(a_len, b_len, 1));
for (i = 0; i < a_len; i++)
ret[i] = a[i];
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)
Expand Down
2 changes: 1 addition & 1 deletion parse-options.h
Expand Up @@ -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_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 -----*/
extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
Expand Down

0 comments on commit d083d42

Please sign in to comment.