Skip to content
/ git Public
forked from git/git

Commit 2bc5414

Browse files
committed
Merge branch 'ps/parse-options-integers'
Update parse-options API to catch mistakes to pass address of an integral variable of a wrong type/size. * ps/parse-options-integers: parse-options: detect mismatches in integer signedness parse-options: introduce precision handling for `OPTION_UNSIGNED` parse-options: introduce precision handling for `OPTION_INTEGER` parse-options: rename `OPT_MAGNITUDE()` to `OPT_UNSIGNED()` parse-options: support unit factors in `OPT_INTEGER()` global: use designated initializers for options parse: fix off-by-one for minimum signed values
2 parents 68e5342 + 791aedd commit 2bc5414

37 files changed

+649
-245
lines changed

Documentation/technical/api-parse-options.adoc

+6-4
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,13 @@ There are some macros to easily define options:
211211
Use of `--no-option` will clear the list of preceding values.
212212
213213
`OPT_INTEGER(short, long, &int_var, description)`::
214-
Introduce an option with integer argument.
215-
The integer is put into `int_var`.
214+
Introduce an option with integer argument. The argument must be a
215+
integer and may include a suffix of 'k', 'm' or 'g' to
216+
scale the provided value by 1024, 1024^2 or 1024^3 respectively.
217+
The scaled value is put into `int_var`.
216218
217-
`OPT_MAGNITUDE(short, long, &unsigned_long_var, description)`::
218-
Introduce an option with a size argument. The argument must be a
219+
`OPT_UNSIGNED(short, long, &unsigned_long_var, description)`::
220+
Introduce an option with an unsigned integer argument. The argument must be a
219221
non-negative integer and may include a suffix of 'k', 'm' or 'g' to
220222
scale the provided value by 1024, 1024^2 or 1024^3 respectively.
221223
The scaled value is put into `unsigned_long_var`.

apply.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -5123,8 +5123,8 @@ int apply_parse_options(int argc, const char **argv,
51235123
/* Think twice before adding "--nul" synonym to this */
51245124
OPT_SET_INT('z', NULL, &state->line_termination,
51255125
N_("paths are separated with NUL character"), '\0'),
5126-
OPT_INTEGER('C', NULL, &state->p_context,
5127-
N_("ensure at least <n> lines of context match")),
5126+
OPT_UNSIGNED('C', NULL, &state->p_context,
5127+
N_("ensure at least <n> lines of context match")),
51285128
OPT_CALLBACK(0, "whitespace", state, N_("action"),
51295129
N_("detect new or modified lines that have whitespace errors"),
51305130
apply_option_parse_whitespace),

archive.c

+26-9
Original file line numberDiff line numberDiff line change
@@ -650,20 +650,37 @@ static int parse_archive_args(int argc, const char **argv,
650650
OPT_STRING(0, "format", &format, N_("fmt"), N_("archive format")),
651651
OPT_STRING(0, "prefix", &base, N_("prefix"),
652652
N_("prepend prefix to each pathname in the archive")),
653-
{ OPTION_CALLBACK, 0, "add-file", args, N_("file"),
654-
N_("add untracked file to archive"), 0, add_file_cb,
655-
(intptr_t)&base },
656-
{ OPTION_CALLBACK, 0, "add-virtual-file", args,
657-
N_("path:content"), N_("add untracked file to archive"), 0,
658-
add_file_cb, (intptr_t)&base },
653+
{
654+
.type = OPTION_CALLBACK,
655+
.long_name = "add-file",
656+
.value = args,
657+
.argh = N_("file"),
658+
.help = N_("add untracked file to archive"),
659+
.callback = add_file_cb,
660+
.defval = (intptr_t) &base,
661+
},
662+
{
663+
.type = OPTION_CALLBACK,
664+
.long_name = "add-virtual-file",
665+
.value = args,
666+
.argh = N_("path:content"),
667+
.help = N_("add untracked file to archive"),
668+
.callback = add_file_cb,
669+
.defval = (intptr_t) &base,
670+
},
659671
OPT_STRING('o', "output", &output, N_("file"),
660672
N_("write the archive to this file")),
661673
OPT_BOOL(0, "worktree-attributes", &worktree_attributes,
662674
N_("read .gitattributes in working directory")),
663675
OPT__VERBOSE(&verbose, N_("report archived files on stderr")),
664-
{ OPTION_STRING, 0, "mtime", &mtime_option, N_("time"),
665-
N_("set modification time of archive entries"),
666-
PARSE_OPT_NONEG },
676+
{
677+
.type = OPTION_STRING,
678+
.long_name = "mtime",
679+
.value = &mtime_option,
680+
.argh = N_("time"),
681+
.help = N_("set modification time of archive entries"),
682+
.flags = PARSE_OPT_NONEG,
683+
},
667684
OPT_NUMBER_CALLBACK(&compression_level,
668685
N_("set compression level"), number_callback),
669686
OPT_GROUP(""),

builtin/am.c

+20-8
Original file line numberDiff line numberDiff line change
@@ -2400,11 +2400,16 @@ int cmd_am(int argc,
24002400
OPT_CMDMODE(0, "quit", &resume_mode,
24012401
N_("abort the patching operation but keep HEAD where it is"),
24022402
RESUME_QUIT),
2403-
{ OPTION_CALLBACK, 0, "show-current-patch", &resume_mode,
2404-
"(diff|raw)",
2405-
N_("show the patch being applied"),
2406-
PARSE_OPT_CMDMODE | PARSE_OPT_OPTARG | PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
2407-
parse_opt_show_current_patch, RESUME_SHOW_PATCH_RAW },
2403+
{
2404+
.type = OPTION_CALLBACK,
2405+
.long_name = "show-current-patch",
2406+
.value = &resume_mode,
2407+
.argh = "(diff|raw)",
2408+
.help = N_("show the patch being applied"),
2409+
.flags = PARSE_OPT_CMDMODE | PARSE_OPT_OPTARG | PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
2410+
.callback = parse_opt_show_current_patch,
2411+
.defval = RESUME_SHOW_PATCH_RAW,
2412+
},
24082413
OPT_CMDMODE(0, "retry", &resume_mode,
24092414
N_("try to apply current patch again"),
24102415
RESUME_APPLY),
@@ -2417,9 +2422,16 @@ int cmd_am(int argc,
24172422
OPT_BOOL(0, "ignore-date", &state.ignore_date,
24182423
N_("use current timestamp for author date")),
24192424
OPT_RERERE_AUTOUPDATE(&state.allow_rerere_autoupdate),
2420-
{ OPTION_STRING, 'S', "gpg-sign", &state.sign_commit, N_("key-id"),
2421-
N_("GPG-sign commits"),
2422-
PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
2425+
{
2426+
.type = OPTION_STRING,
2427+
.short_name = 'S',
2428+
.long_name = "gpg-sign",
2429+
.value = &state.sign_commit,
2430+
.argh = N_("key-id"),
2431+
.help = N_("GPG-sign commits"),
2432+
.flags = PARSE_OPT_OPTARG,
2433+
.defval = (intptr_t) "",
2434+
},
24232435
OPT_CALLBACK_F(0, "empty", &state.empty_type, "(stop|drop|keep)",
24242436
N_("how to handle empty patches"),
24252437
PARSE_OPT_NONEG, am_option_parse_empty),

builtin/backfill.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ int cmd_backfill(int argc, const char **argv, const char *prefix, struct reposit
123123
.sparse = 0,
124124
};
125125
struct option options[] = {
126-
OPT_INTEGER(0, "min-batch-size", &ctx.min_batch_size,
127-
N_("Minimum number of objects to request at a time")),
126+
OPT_UNSIGNED(0, "min-batch-size", &ctx.min_batch_size,
127+
N_("Minimum number of objects to request at a time")),
128128
OPT_BOOL(0, "sparse", &ctx.sparse,
129129
N_("Restrict the missing objects to the current sparse-checkout")),
130130
OPT_END(),

builtin/clone.c

+10-3
Original file line numberDiff line numberDiff line change
@@ -932,9 +932,16 @@ int cmd_clone(int argc,
932932
N_("don't use local hardlinks, always copy")),
933933
OPT_BOOL('s', "shared", &option_shared,
934934
N_("setup as shared repository")),
935-
{ OPTION_CALLBACK, 0, "recurse-submodules", &option_recurse_submodules,
936-
N_("pathspec"), N_("initialize submodules in the clone"),
937-
PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)"." },
935+
{
936+
.type = OPTION_CALLBACK,
937+
.long_name = "recurse-submodules",
938+
.value = &option_recurse_submodules,
939+
.argh = N_("pathspec"),
940+
.help = N_("initialize submodules in the clone"),
941+
.flags = PARSE_OPT_OPTARG,
942+
.callback = recurse_submodules_cb,
943+
.defval = (intptr_t)".",
944+
},
938945
OPT_ALIAS(0, "recursive", "recurse-submodules"),
939946
OPT_INTEGER('j', "jobs", &max_jobs,
940947
N_("number of submodules cloned in parallel")),

builtin/column.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ int cmd_column(int argc,
3131
struct option options[] = {
3232
OPT_STRING(0, "command", &real_command, N_("name"), N_("lookup config vars")),
3333
OPT_COLUMN(0, "mode", &colopts, N_("layout to use")),
34-
OPT_INTEGER(0, "raw-mode", &colopts, N_("layout to use")),
34+
OPT_UNSIGNED(0, "raw-mode", &colopts, N_("layout to use")),
3535
OPT_INTEGER(0, "width", &copts.width, N_("maximum width")),
3636
OPT_STRING(0, "indent", &copts.indent, N_("string"), N_("padding space on left border")),
3737
OPT_STRING(0, "nl", &copts.nl, N_("string"), N_("padding space on right border")),

builtin/commit-tree.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,16 @@ int cmd_commit_tree(int argc,
111111
OPT_CALLBACK_F('F', NULL, &buffer, N_("file"),
112112
N_("read commit log message from file"), PARSE_OPT_NONEG,
113113
parse_file_arg_callback),
114-
{ OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
115-
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
114+
{
115+
.type = OPTION_STRING,
116+
.short_name = 'S',
117+
.long_name = "gpg-sign",
118+
.value = &sign_commit,
119+
.argh = N_("key-id"),
120+
.help = N_("GPG sign commit"),
121+
.flags = PARSE_OPT_OPTARG,
122+
.defval = (intptr_t) "",
123+
},
116124
OPT_END()
117125
};
118126
int ret;

builtin/commit.c

+48-14
Original file line numberDiff line numberDiff line change
@@ -1542,17 +1542,34 @@ struct repository *repo UNUSED)
15421542
STATUS_FORMAT_LONG),
15431543
OPT_BOOL('z', "null", &s.null_termination,
15441544
N_("terminate entries with NUL")),
1545-
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
1546-
N_("mode"),
1547-
N_("show untracked files, optional modes: all, normal, no. (Default: all)"),
1548-
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1549-
{ OPTION_STRING, 0, "ignored", &ignored_arg,
1550-
N_("mode"),
1551-
N_("show ignored files, optional modes: traditional, matching, no. (Default: traditional)"),
1552-
PARSE_OPT_OPTARG, NULL, (intptr_t)"traditional" },
1553-
{ OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, N_("when"),
1554-
N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
1555-
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1545+
{
1546+
.type = OPTION_STRING,
1547+
.short_name = 'u',
1548+
.long_name = "untracked-files",
1549+
.value = &untracked_files_arg,
1550+
.argh = N_("mode"),
1551+
.help = N_("show untracked files, optional modes: all, normal, no. (Default: all)"),
1552+
.flags = PARSE_OPT_OPTARG,
1553+
.defval = (intptr_t)"all",
1554+
},
1555+
{
1556+
.type = OPTION_STRING,
1557+
.long_name = "ignored",
1558+
.value = &ignored_arg,
1559+
.argh = N_("mode"),
1560+
.help = N_("show ignored files, optional modes: traditional, matching, no. (Default: traditional)"),
1561+
.flags = PARSE_OPT_OPTARG,
1562+
.defval = (intptr_t)"traditional",
1563+
},
1564+
{
1565+
.type = OPTION_STRING,
1566+
.long_name = "ignore-submodules",
1567+
.value = &ignore_submodule_arg,
1568+
.argh = N_("when"),
1569+
.help = N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
1570+
.flags = PARSE_OPT_OPTARG,
1571+
.defval = (intptr_t)"all",
1572+
},
15561573
OPT_COLUMN(0, "column", &s.colopts, N_("list untracked files in columns")),
15571574
OPT_BOOL(0, "no-renames", &no_renames, N_("do not detect renames")),
15581575
OPT_CALLBACK_F('M', "find-renames", &rename_score_arg,
@@ -1688,8 +1705,16 @@ int cmd_commit(int argc,
16881705
OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")),
16891706
OPT_CLEANUP(&cleanup_arg),
16901707
OPT_BOOL(0, "status", &include_status, N_("include status in commit message template")),
1691-
{ OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
1692-
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
1708+
{
1709+
.type = OPTION_STRING,
1710+
.short_name = 'S',
1711+
.long_name = "gpg-sign",
1712+
.value = &sign_commit,
1713+
.argh = N_("key-id"),
1714+
.help = N_("GPG sign commit"),
1715+
.flags = PARSE_OPT_OPTARG,
1716+
.defval = (intptr_t) "",
1717+
},
16931718
/* end commit message options */
16941719

16951720
OPT_GROUP(N_("Commit contents options")),
@@ -1714,7 +1739,16 @@ int cmd_commit(int argc,
17141739
N_("terminate entries with NUL")),
17151740
OPT_BOOL(0, "amend", &amend, N_("amend previous commit")),
17161741
OPT_BOOL(0, "no-post-rewrite", &no_post_rewrite, N_("bypass post-rewrite hook")),
1717-
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, N_("mode"), N_("show untracked files, optional modes: all, normal, no. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1742+
{
1743+
.type = OPTION_STRING,
1744+
.short_name = 'u',
1745+
.long_name = "untracked-files",
1746+
.value = &untracked_files_arg,
1747+
.argh = N_("mode"),
1748+
.help = N_("show untracked files, optional modes: all, normal, no. (Default: all)"),
1749+
.flags = PARSE_OPT_OPTARG,
1750+
.defval = (intptr_t)"all",
1751+
},
17181752
OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
17191753
OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
17201754
/* end commit contents options */

builtin/config.c

+10-3
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,16 @@ struct config_display_options {
131131
#define TYPE_COLOR 6
132132
#define TYPE_BOOL_OR_STR 7
133133

134-
#define OPT_CALLBACK_VALUE(s, l, v, h, i) \
135-
{ OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
136-
PARSE_OPT_NONEG, option_parse_type, (i) }
134+
#define OPT_CALLBACK_VALUE(s, l, v, h, i) { \
135+
.type = OPTION_CALLBACK, \
136+
.short_name = (s), \
137+
.long_name = (l), \
138+
.value = (v), \
139+
.help = (h), \
140+
.flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG, \
141+
.callback = option_parse_type, \
142+
.defval = (i), \
143+
}
137144

138145
static int option_parse_type(const struct option *opt, const char *arg,
139146
int unset)

builtin/describe.c

+18-6
Original file line numberDiff line numberDiff line change
@@ -601,12 +601,24 @@ int cmd_describe(int argc,
601601
N_("do not consider tags matching <pattern>")),
602602
OPT_BOOL(0, "always", &always,
603603
N_("show abbreviated commit object as fallback")),
604-
{OPTION_STRING, 0, "dirty", &dirty, N_("mark"),
605-
N_("append <mark> on dirty working tree (default: \"-dirty\")"),
606-
PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"},
607-
{OPTION_STRING, 0, "broken", &broken, N_("mark"),
608-
N_("append <mark> on broken working tree (default: \"-broken\")"),
609-
PARSE_OPT_OPTARG, NULL, (intptr_t) "-broken"},
604+
{
605+
.type = OPTION_STRING,
606+
.long_name = "dirty",
607+
.value = &dirty,
608+
.argh = N_("mark"),
609+
.help = N_("append <mark> on dirty working tree (default: \"-dirty\")"),
610+
.flags = PARSE_OPT_OPTARG,
611+
.defval = (intptr_t) "-dirty",
612+
},
613+
{
614+
.type = OPTION_STRING,
615+
.long_name = "broken",
616+
.value = &broken,
617+
.argh = N_("mark"),
618+
.help = N_("append <mark> on broken working tree (default: \"-broken\")"),
619+
.flags = PARSE_OPT_OPTARG,
620+
.defval = (intptr_t) "-broken",
621+
},
610622
OPT_END(),
611623
};
612624

builtin/fetch.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -2352,8 +2352,14 @@ int cmd_fetch(int argc,
23522352
OPT_SET_INT_F(0, "refetch", &refetch,
23532353
N_("re-fetch without negotiating common commits"),
23542354
1, PARSE_OPT_NONEG),
2355-
{ OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, N_("dir"),
2356-
N_("prepend this to submodule path output"), PARSE_OPT_HIDDEN },
2355+
{
2356+
.type = OPTION_STRING,
2357+
.long_name = "submodule-prefix",
2358+
.value = &submodule_prefix,
2359+
.argh = N_("dir"),
2360+
.help = N_("prepend this to submodule path output"),
2361+
.flags = PARSE_OPT_HIDDEN,
2362+
},
23572363
OPT_CALLBACK_F(0, "recurse-submodules-default",
23582364
&recurse_submodules_default, N_("on-demand"),
23592365
N_("default for recursive fetching of submodules "

builtin/fmt-merge-msg.c

+20-7
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,26 @@ int cmd_fmt_merge_msg(int argc,
2020
char *into_name = NULL;
2121
int shortlog_len = -1;
2222
struct option options[] = {
23-
{ OPTION_INTEGER, 0, "log", &shortlog_len, N_("n"),
24-
N_("populate log with at most <n> entries from shortlog"),
25-
PARSE_OPT_OPTARG, NULL, DEFAULT_MERGE_LOG_LEN },
26-
{ OPTION_INTEGER, 0, "summary", &shortlog_len, N_("n"),
27-
N_("alias for --log (deprecated)"),
28-
PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN, NULL,
29-
DEFAULT_MERGE_LOG_LEN },
23+
{
24+
.type = OPTION_INTEGER,
25+
.long_name = "log",
26+
.value = &shortlog_len,
27+
.precision = sizeof(shortlog_len),
28+
.argh = N_("n"),
29+
.help = N_("populate log with at most <n> entries from shortlog"),
30+
.flags = PARSE_OPT_OPTARG,
31+
.defval = DEFAULT_MERGE_LOG_LEN,
32+
},
33+
{
34+
.type = OPTION_INTEGER,
35+
.long_name = "summary",
36+
.value = &shortlog_len,
37+
.precision = sizeof(shortlog_len),
38+
.argh = N_("n"),
39+
.help = N_("alias for --log (deprecated)"),
40+
.flags = PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN,
41+
.defval = DEFAULT_MERGE_LOG_LEN,
42+
},
3043
OPT_STRING('m', "message", &message, N_("text"),
3144
N_("use <text> as start of message")),
3245
OPT_STRING(0, "into-name", &into_name, N_("name"),

builtin/gc.c

+11-5
Original file line numberDiff line numberDiff line change
@@ -743,12 +743,18 @@ struct repository *repo UNUSED)
743743
int ret;
744744
struct option builtin_gc_options[] = {
745745
OPT__QUIET(&quiet, N_("suppress progress reporting")),
746-
{ OPTION_STRING, 0, "prune", &prune_expire_arg, N_("date"),
747-
N_("prune unreferenced objects"),
748-
PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire_arg },
746+
{
747+
.type = OPTION_STRING,
748+
.long_name = "prune",
749+
.value = &prune_expire_arg,
750+
.argh = N_("date"),
751+
.help = N_("prune unreferenced objects"),
752+
.flags = PARSE_OPT_OPTARG,
753+
.defval = (intptr_t)prune_expire_arg,
754+
},
749755
OPT_BOOL(0, "cruft", &cfg.cruft_packs, N_("pack unreferenced objects separately")),
750-
OPT_MAGNITUDE(0, "max-cruft-size", &cfg.max_cruft_size,
751-
N_("with --cruft, limit the size of new cruft packs")),
756+
OPT_UNSIGNED(0, "max-cruft-size", &cfg.max_cruft_size,
757+
N_("with --cruft, limit the size of new cruft packs")),
752758
OPT_BOOL(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")),
753759
OPT_BOOL_F(0, "auto", &opts.auto_flag, N_("enable auto-gc mode"),
754760
PARSE_OPT_NOCOMPLETE),

0 commit comments

Comments
 (0)