Skip to content

Commit 6953f24

Browse files
committed
Merge branch 'rs/parse-options-duplicated-long-options'
The parse-options API learned to notice an options[] array with duplicated long options. * rs/parse-options-duplicated-long-options: parseopt: check for duplicate long names and numerical options pack-objects: remove duplicate --stdin-packs definition
2 parents f330d46 + 237e520 commit 6953f24

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

builtin/pack-objects.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4922,8 +4922,6 @@ int cmd_pack_objects(int argc,
49224922
OPT_CALLBACK_F(0, "stdin-packs", &stdin_packs, N_("mode"),
49234923
N_("read packs from stdin"),
49244924
PARSE_OPT_OPTARG, parse_stdin_packs_mode),
4925-
OPT_BOOL(0, "stdin-packs", &stdin_packs,
4926-
N_("read packs from stdin")),
49274925
OPT_BOOL(0, "stdout", &pack_to_stdout,
49284926
N_("output pack to stdout")),
49294927
OPT_BOOL(0, "include-tag", &include_tag,

parse-options.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "gettext.h"
66
#include "strbuf.h"
77
#include "string-list.h"
8+
#include "strmap.h"
89
#include "utf8.h"
910

1011
static int disallow_abbreviated_options;
@@ -641,6 +642,7 @@ static void check_typos(const char *arg, const struct option *options)
641642
static void parse_options_check(const struct option *opts)
642643
{
643644
char short_opts[128];
645+
bool saw_number_option = false;
644646
void *subcommand_value = NULL;
645647

646648
memset(short_opts, '\0', sizeof(short_opts));
@@ -655,6 +657,11 @@ static void parse_options_check(const struct option *opts)
655657
else if (short_opts[opts->short_name]++)
656658
optbug(opts, "short name already used");
657659
}
660+
if (opts->type == OPTION_NUMBER) {
661+
if (saw_number_option)
662+
optbug(opts, "duplicate numerical option");
663+
saw_number_option = true;
664+
}
658665
if (opts->flags & PARSE_OPT_NODASH &&
659666
((opts->flags & PARSE_OPT_OPTARG) ||
660667
!(opts->flags & PARSE_OPT_NOARG) ||
@@ -714,6 +721,20 @@ static void parse_options_check(const struct option *opts)
714721
BUG_if_bug("invalid 'struct option'");
715722
}
716723

724+
static void parse_options_check_harder(const struct option *opts)
725+
{
726+
struct strset long_names = STRSET_INIT;
727+
728+
for (; opts->type != OPTION_END; opts++) {
729+
if (opts->long_name) {
730+
if (!strset_add(&long_names, opts->long_name))
731+
optbug(opts, "long name already used");
732+
}
733+
}
734+
BUG_if_bug("invalid 'struct option'");
735+
strset_clear(&long_names);
736+
}
737+
717738
static int has_subcommands(const struct option *options)
718739
{
719740
for (; options->type != OPTION_END; options++)
@@ -1339,6 +1360,8 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
13391360
const char *prefix = usage_prefix;
13401361
int saw_empty_line = 0;
13411362

1363+
parse_options_check_harder(opts);
1364+
13421365
if (!usagestr)
13431366
return PARSE_OPT_HELP;
13441367

0 commit comments

Comments
 (0)