aboutsummaryrefslogtreecommitdiff
path: root/parse-options.c
diff options
context:
space:
mode:
Diffstat (limited to 'parse-options.c')
-rw-r--r--parse-options.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/parse-options.c b/parse-options.c
index 5224203ffe..6d9fc7bdc7 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -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;