Skip to content

Commit 023ff39

Browse files
peffgitster
authored andcommitted
parse_options: allocate a new array when concatenating
In exactly one callers (builtin/revert.c), we build up the options list dynamically from multiple arrays. We do so by manually inserting "filler" entries into one array, and then copying the other array into the allocated space. This is tedious and error-prone, as you have to adjust the filler any time the second array is modified (although we do at least check and die() when the counts do not match up). Instead, let's just allocate a new array. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0b65a8d commit 023ff39

File tree

3 files changed

+22
-22
lines changed

3 files changed

+22
-22
lines changed

builtin/revert.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
7676
const char * const * usage_str = revert_or_cherry_pick_usage(opts);
7777
const char *me = action_name(opts);
7878
int cmd = 0;
79-
struct option options[] = {
79+
struct option base_options[] = {
8080
OPT_CMDMODE(0, "quit", &cmd, N_("end revert or cherry-pick sequence"), 'q'),
8181
OPT_CMDMODE(0, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'),
8282
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)
9191
N_("option for merge strategy"), option_parse_x),
9292
{ OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
9393
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
94-
OPT_END(),
95-
OPT_END(),
96-
OPT_END(),
97-
OPT_END(),
98-
OPT_END(),
99-
OPT_END(),
94+
OPT_END()
10095
};
96+
struct option *options = base_options;
10197

10298
if (opts->action == REPLAY_PICK) {
10399
struct option cp_extra[] = {
@@ -108,8 +104,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
108104
OPT_BOOL(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")),
109105
OPT_END(),
110106
};
111-
if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra))
112-
die(_("program error"));
107+
options = parse_options_concat(options, cp_extra);
113108
}
114109

115110
argc = parse_options(argc, argv, NULL, options, usage_str,

parse-options-cb.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -117,19 +117,24 @@ int parse_opt_tertiary(const struct option *opt, const char *arg, int unset)
117117
return 0;
118118
}
119119

120-
int parse_options_concat(struct option *dst, size_t dst_size, struct option *src)
120+
struct option *parse_options_concat(struct option *a, struct option *b)
121121
{
122-
int i, j;
123-
124-
for (i = 0; i < dst_size; i++)
125-
if (dst[i].type == OPTION_END)
126-
break;
127-
for (j = 0; i < dst_size; i++, j++) {
128-
dst[i] = src[j];
129-
if (src[j].type == OPTION_END)
130-
return 0;
131-
}
132-
return -1;
122+
struct option *ret;
123+
size_t i, a_len = 0, b_len = 0;
124+
125+
for (i = 0; a[i].type != OPTION_END; i++)
126+
a_len++;
127+
for (i = 0; b[i].type != OPTION_END; i++)
128+
b_len++;
129+
130+
ALLOC_ARRAY(ret, st_add3(a_len, b_len, 1));
131+
for (i = 0; i < a_len; i++)
132+
ret[i] = a[i];
133+
for (i = 0; i < b_len; i++)
134+
ret[a_len + i] = b[i];
135+
ret[a_len + b_len] = b[b_len]; /* final OPTION_END */
136+
137+
return ret;
133138
}
134139

135140
int parse_opt_string_list(const struct option *opt, const char *arg, int unset)

parse-options.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ extern int parse_options_step(struct parse_opt_ctx_t *ctx,
215215

216216
extern int parse_options_end(struct parse_opt_ctx_t *ctx);
217217

218-
extern int parse_options_concat(struct option *dst, size_t, struct option *src);
218+
extern struct option *parse_options_concat(struct option *a, struct option *b);
219219

220220
/*----- some often used options -----*/
221221
extern int parse_opt_abbrev_cb(const struct option *, const char *, int);

0 commit comments

Comments
 (0)