mirror of
https://github.com/git/git.git
synced 2026-03-04 14:37:35 +01:00
parseopt: check for duplicate long names and numerical options
We already check for duplicate short names. Check for and report duplicate long names and numerical options as well. Perform the slightly expensive string duplicate check only when showing the usage to keep the cost of normal invocations low. t0012-help.sh covers it. Helped-by: Jeff King <peff@peff.net> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
a5f2ff6ce8
commit
237e520d81
@@ -5,6 +5,7 @@
|
||||
#include "gettext.h"
|
||||
#include "strbuf.h"
|
||||
#include "string-list.h"
|
||||
#include "strmap.h"
|
||||
#include "utf8.h"
|
||||
|
||||
static int disallow_abbreviated_options;
|
||||
@@ -634,6 +635,7 @@ static void check_typos(const char *arg, const struct option *options)
|
||||
static void parse_options_check(const struct option *opts)
|
||||
{
|
||||
char short_opts[128];
|
||||
bool saw_number_option = false;
|
||||
void *subcommand_value = NULL;
|
||||
|
||||
memset(short_opts, '\0', sizeof(short_opts));
|
||||
@@ -648,6 +650,11 @@ static void parse_options_check(const struct option *opts)
|
||||
else if (short_opts[opts->short_name]++)
|
||||
optbug(opts, "short name already used");
|
||||
}
|
||||
if (opts->type == OPTION_NUMBER) {
|
||||
if (saw_number_option)
|
||||
optbug(opts, "duplicate numerical option");
|
||||
saw_number_option = true;
|
||||
}
|
||||
if (opts->flags & PARSE_OPT_NODASH &&
|
||||
((opts->flags & PARSE_OPT_OPTARG) ||
|
||||
!(opts->flags & PARSE_OPT_NOARG) ||
|
||||
@@ -707,6 +714,20 @@ static void parse_options_check(const struct option *opts)
|
||||
BUG_if_bug("invalid 'struct option'");
|
||||
}
|
||||
|
||||
static void parse_options_check_harder(const struct option *opts)
|
||||
{
|
||||
struct strset long_names = STRSET_INIT;
|
||||
|
||||
for (; opts->type != OPTION_END; opts++) {
|
||||
if (opts->long_name) {
|
||||
if (!strset_add(&long_names, opts->long_name))
|
||||
optbug(opts, "long name already used");
|
||||
}
|
||||
}
|
||||
BUG_if_bug("invalid 'struct option'");
|
||||
strset_clear(&long_names);
|
||||
}
|
||||
|
||||
static int has_subcommands(const struct option *options)
|
||||
{
|
||||
for (; options->type != OPTION_END; options++)
|
||||
@@ -1324,6 +1345,8 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
|
||||
const char *prefix = usage_prefix;
|
||||
int saw_empty_line = 0;
|
||||
|
||||
parse_options_check_harder(opts);
|
||||
|
||||
if (!usagestr)
|
||||
return PARSE_OPT_HELP;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user