Skip to content

Commit 2a409a1

Browse files
rscharfegitster
authored andcommitted
parse-options: no --[no-]no-...
Avoid showing an optional "no-" for options that already start with a "no-" in the short help, as that double negation is confusing. Document the opposite variant on its own line with a generated help text instead, unless it's defined and documented explicitly already. Signed-off-by: René Scharfe <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 652a6b1 commit 2a409a1

File tree

3 files changed

+28
-3
lines changed

3 files changed

+28
-3
lines changed

parse-options.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1042,11 +1042,22 @@ static void usage_padding(FILE *outfile, size_t pos)
10421042
fprintf(outfile, "%*s", pad + USAGE_GAP, "");
10431043
}
10441044

1045+
static const struct option *find_option_by_long_name(const struct option *opts,
1046+
const char *long_name)
1047+
{
1048+
for (; opts->type != OPTION_END; opts++) {
1049+
if (opts->long_name && !strcmp(opts->long_name, long_name))
1050+
return opts;
1051+
}
1052+
return NULL;
1053+
}
1054+
10451055
static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t *ctx,
10461056
const char * const *usagestr,
10471057
const struct option *opts,
10481058
int full, int err)
10491059
{
1060+
const struct option *all_opts = opts;
10501061
FILE *outfile = err ? stderr : stdout;
10511062
int need_newline;
10521063

@@ -1128,6 +1139,7 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
11281139
for (; opts->type != OPTION_END; opts++) {
11291140
size_t pos;
11301141
const char *cp, *np;
1142+
const char *positive_name = NULL;
11311143

11321144
if (opts->type == OPTION_SUBCOMMAND)
11331145
continue;
@@ -1157,7 +1169,8 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
11571169
pos += fprintf(outfile, ", ");
11581170
if (opts->long_name) {
11591171
const char *long_name = opts->long_name;
1160-
if (opts->flags & PARSE_OPT_NONEG)
1172+
if ((opts->flags & PARSE_OPT_NONEG) ||
1173+
skip_prefix(long_name, "no-", &positive_name))
11611174
pos += fprintf(outfile, "--%s", long_name);
11621175
else
11631176
pos += fprintf(outfile, "--[no-]%s", long_name);
@@ -1185,6 +1198,16 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
11851198
np++;
11861199
pos = 0;
11871200
}
1201+
1202+
if (positive_name) {
1203+
if (find_option_by_long_name(all_opts, positive_name))
1204+
continue;
1205+
pos = usage_indent(outfile);
1206+
pos += fprintf(outfile, "--%s", positive_name);
1207+
usage_padding(outfile, pos);
1208+
fprintf_ln(outfile, _("opposite of --no-%s"),
1209+
positive_name);
1210+
}
11881211
}
11891212
fputc('\n', outfile);
11901213

t/t0040-parse-options.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ usage: test-tool parse-options <options>
1414
A helper function for the parse-options API.
1515
1616
--[no-]yes get a boolean
17-
-D, --[no-]no-doubt begins with 'no-'
17+
-D, --no-doubt begins with 'no-'
18+
--doubt opposite of --no-doubt
1819
-B, --no-fear be brave
1920
-b, --[no-]boolean increment by one
2021
-4, --[no-]or4 bitwise-or boolean with ...0100

t/t1502/optionspec-neg.help

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ usage: some-command [options] <args>...
44
some-command does foo and bar!
55

66
--[no-]foo can be negated
7-
--[no-]no-bar can be positivated
7+
--no-bar can be positivated
8+
--bar opposite of --no-bar
89
--positive-only cannot be negated
910
--no-negative cannot be positivated
1011

0 commit comments

Comments
 (0)