Merge branch 'jc/parseopt-verify-short-name'
Add checks for a common programming mistake to assign the same short option name to two separate options to help developers. * jc/parseopt-verify-short-name: parse-options: detect attempt to add a duplicate short option name
This commit is contained in:
@ -14,8 +14,12 @@ static int parse_options_usage(struct parse_opt_ctx_t *ctx,
|
|||||||
|
|
||||||
int optbug(const struct option *opt, const char *reason)
|
int optbug(const struct option *opt, const char *reason)
|
||||||
{
|
{
|
||||||
if (opt->long_name)
|
if (opt->long_name) {
|
||||||
|
if (opt->short_name)
|
||||||
|
return error("BUG: switch '%c' (--%s) %s",
|
||||||
|
opt->short_name, opt->long_name, reason);
|
||||||
return error("BUG: option '%s' %s", opt->long_name, reason);
|
return error("BUG: option '%s' %s", opt->long_name, reason);
|
||||||
|
}
|
||||||
return error("BUG: switch '%c' %s", opt->short_name, reason);
|
return error("BUG: switch '%c' %s", opt->short_name, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,12 +351,20 @@ static void check_typos(const char *arg, const struct option *options)
|
|||||||
static void parse_options_check(const struct option *opts)
|
static void parse_options_check(const struct option *opts)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
char short_opts[128];
|
||||||
|
|
||||||
|
memset(short_opts, '\0', sizeof(short_opts));
|
||||||
for (; opts->type != OPTION_END; opts++) {
|
for (; opts->type != OPTION_END; opts++) {
|
||||||
if ((opts->flags & PARSE_OPT_LASTARG_DEFAULT) &&
|
if ((opts->flags & PARSE_OPT_LASTARG_DEFAULT) &&
|
||||||
(opts->flags & PARSE_OPT_OPTARG))
|
(opts->flags & PARSE_OPT_OPTARG))
|
||||||
err |= optbug(opts, "uses incompatible flags "
|
err |= optbug(opts, "uses incompatible flags "
|
||||||
"LASTARG_DEFAULT and OPTARG");
|
"LASTARG_DEFAULT and OPTARG");
|
||||||
|
if (opts->short_name) {
|
||||||
|
if (0x7F <= opts->short_name)
|
||||||
|
err |= optbug(opts, "invalid short name");
|
||||||
|
else if (short_opts[opts->short_name]++)
|
||||||
|
err |= optbug(opts, "short name already used");
|
||||||
|
}
|
||||||
if (opts->flags & PARSE_OPT_NODASH &&
|
if (opts->flags & PARSE_OPT_NODASH &&
|
||||||
((opts->flags & PARSE_OPT_OPTARG) ||
|
((opts->flags & PARSE_OPT_OPTARG) ||
|
||||||
!(opts->flags & PARSE_OPT_NOARG) ||
|
!(opts->flags & PARSE_OPT_NOARG) ||
|
||||||
|
@ -19,7 +19,7 @@ sed -e 's/^|//' >expect <<\END_EXPECT
|
|||||||
| -d, --data[=...] short and long option with an optional argument
|
| -d, --data[=...] short and long option with an optional argument
|
||||||
|
|
|
|
||||||
|Argument hints
|
|Argument hints
|
||||||
| -b <arg> short option required argument
|
| -B <arg> short option required argument
|
||||||
| --bar2 <arg> long option required argument
|
| --bar2 <arg> long option required argument
|
||||||
| -e, --fuz <with-space>
|
| -e, --fuz <with-space>
|
||||||
| short and long option required argument
|
| short and long option required argument
|
||||||
@ -51,7 +51,7 @@ sed -e 's/^|//' >optionspec <<\EOF
|
|||||||
|d,data? short and long option with an optional argument
|
|d,data? short and long option with an optional argument
|
||||||
|
|
|
|
||||||
| Argument hints
|
| Argument hints
|
||||||
|b=arg short option required argument
|
|B=arg short option required argument
|
||||||
|bar2=arg long option required argument
|
|bar2=arg long option required argument
|
||||||
|e,fuz=with-space short and long option required argument
|
|e,fuz=with-space short and long option required argument
|
||||||
|s?some short option optional argument
|
|s?some short option optional argument
|
||||||
|
Reference in New Issue
Block a user