diff options
author | Junio C Hamano <gitster@pobox.com> | 2016-08-10 11:55:23 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-08-10 11:55:24 -0700 |
commit | 60b84ba26c588c09759b90b96e072cceb862a859 (patch) | |
tree | 90b7431765568e56ad10815a9a005682d54a5a95 | |
parent | dbc5276fedbe5ac86951a054e6e8ae610f073d9d (diff) | |
parent | 023ff39b2994804e4a7b2274b22336bdb37d4a54 (diff) | |
download | git-60b84ba26c588c09759b90b96e072cceb862a859.tar.gz git-60b84ba26c588c09759b90b96e072cceb862a859.tar.xz |
Merge branch 'jk/parse-options-concat' into maint
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
-rw-r--r-- | builtin/revert.c | 13 | ||||
-rw-r--r-- | parse-options-cb.c | 29 | ||||
-rw-r--r-- | parse-options.h | 2 |
3 files changed, 22 insertions, 22 deletions
diff --git a/builtin/revert.c b/builtin/revert.c index 56a2c3666..4e693808b 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -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'), @@ -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[] = { @@ -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, diff --git a/parse-options-cb.c b/parse-options-cb.c index 239898d94..2d875202c 100644 --- a/parse-options-cb.c +++ b/parse-options-cb.c @@ -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) diff --git a/parse-options.h b/parse-options.h index ea4af92a5..78f8384c5 100644 --- a/parse-options.h +++ b/parse-options.h @@ -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); |