Merge branch 'js/parseopt-abbrev-fix'
* js/parseopt-abbrev-fix: parse-options: abbreviation engine fix.
This commit is contained in:
commit
91febfba6f
@ -119,8 +119,8 @@ static int parse_long_opt(struct optparse_t *p, const char *arg,
|
|||||||
const struct option *options)
|
const struct option *options)
|
||||||
{
|
{
|
||||||
const char *arg_end = strchr(arg, '=');
|
const char *arg_end = strchr(arg, '=');
|
||||||
const struct option *abbrev_option = NULL;
|
const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
|
||||||
int abbrev_flags = 0;
|
int abbrev_flags = 0, ambiguous_flags = 0;
|
||||||
|
|
||||||
if (!arg_end)
|
if (!arg_end)
|
||||||
arg_end = arg + strlen(arg);
|
arg_end = arg + strlen(arg);
|
||||||
@ -137,16 +137,16 @@ static int parse_long_opt(struct optparse_t *p, const char *arg,
|
|||||||
/* abbreviated? */
|
/* abbreviated? */
|
||||||
if (!strncmp(options->long_name, arg, arg_end - arg)) {
|
if (!strncmp(options->long_name, arg, arg_end - arg)) {
|
||||||
is_abbreviated:
|
is_abbreviated:
|
||||||
if (abbrev_option)
|
if (abbrev_option) {
|
||||||
return error("Ambiguous option: %s "
|
/*
|
||||||
"(could be --%s%s or --%s%s)",
|
* If this is abbreviated, it is
|
||||||
arg,
|
* ambiguous. So when there is no
|
||||||
(flags & OPT_UNSET) ?
|
* exact match later, we need to
|
||||||
"no-" : "",
|
* error out.
|
||||||
options->long_name,
|
*/
|
||||||
(abbrev_flags & OPT_UNSET) ?
|
ambiguous_option = abbrev_option;
|
||||||
"no-" : "",
|
ambiguous_flags = abbrev_flags;
|
||||||
abbrev_option->long_name);
|
}
|
||||||
if (!(flags & OPT_UNSET) && *arg_end)
|
if (!(flags & OPT_UNSET) && *arg_end)
|
||||||
p->opt = arg_end + 1;
|
p->opt = arg_end + 1;
|
||||||
abbrev_option = options;
|
abbrev_option = options;
|
||||||
@ -176,6 +176,15 @@ is_abbreviated:
|
|||||||
}
|
}
|
||||||
return get_value(p, options, flags);
|
return get_value(p, options, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ambiguous_option)
|
||||||
|
return error("Ambiguous option: %s "
|
||||||
|
"(could be --%s%s or --%s%s)",
|
||||||
|
arg,
|
||||||
|
(ambiguous_flags & OPT_UNSET) ? "no-" : "",
|
||||||
|
ambiguous_option->long_name,
|
||||||
|
(abbrev_flags & OPT_UNSET) ? "no-" : "",
|
||||||
|
abbrev_option->long_name);
|
||||||
if (abbrev_option)
|
if (abbrev_option)
|
||||||
return get_value(p, abbrev_option, abbrev_flags);
|
return get_value(p, abbrev_option, abbrev_flags);
|
||||||
return error("unknown option `%s'", arg);
|
return error("unknown option `%s'", arg);
|
||||||
|
@ -18,6 +18,7 @@ string options
|
|||||||
-s, --string <string>
|
-s, --string <string>
|
||||||
get a string
|
get a string
|
||||||
--string2 <str> get another string
|
--string2 <str> get another string
|
||||||
|
--st <st> get another string (pervert ordering)
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@ -90,4 +91,16 @@ test_expect_failure 'ambiguously abbreviated option' '
|
|||||||
test $? != 129
|
test $? != 129
|
||||||
'
|
'
|
||||||
|
|
||||||
|
cat > expect << EOF
|
||||||
|
boolean: 0
|
||||||
|
integer: 0
|
||||||
|
string: 123
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'non ambiguous option (after two options it abbreviates)' '
|
||||||
|
test-parse-options --st 123 > output 2> output.err &&
|
||||||
|
test ! -s output.err &&
|
||||||
|
git diff expect output
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
@ -18,6 +18,7 @@ int main(int argc, const char **argv)
|
|||||||
OPT_GROUP("string options"),
|
OPT_GROUP("string options"),
|
||||||
OPT_STRING('s', "string", &string, "string", "get a string"),
|
OPT_STRING('s', "string", &string, "string", "get a string"),
|
||||||
OPT_STRING(0, "string2", &string, "str", "get another string"),
|
OPT_STRING(0, "string2", &string, "str", "get another string"),
|
||||||
|
OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"),
|
||||||
OPT_END(),
|
OPT_END(),
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user