Merge branch 'js/parseopt-abbrev-fix'

* js/parseopt-abbrev-fix:
  parse-options: abbreviation engine fix.
This commit is contained in:
Junio C Hamano 2007-11-11 15:12:06 -08:00
commit 91febfba6f
3 changed files with 35 additions and 12 deletions

View File

@ -119,8 +119,8 @@ static int parse_long_opt(struct optparse_t *p, const char *arg,
const struct option *options)
{
const char *arg_end = strchr(arg, '=');
const struct option *abbrev_option = NULL;
int abbrev_flags = 0;
const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
int abbrev_flags = 0, ambiguous_flags = 0;
if (!arg_end)
arg_end = arg + strlen(arg);
@ -137,16 +137,16 @@ static int parse_long_opt(struct optparse_t *p, const char *arg,
/* abbreviated? */
if (!strncmp(options->long_name, arg, arg_end - arg)) {
is_abbreviated:
if (abbrev_option)
return error("Ambiguous option: %s "
"(could be --%s%s or --%s%s)",
arg,
(flags & OPT_UNSET) ?
"no-" : "",
options->long_name,
(abbrev_flags & OPT_UNSET) ?
"no-" : "",
abbrev_option->long_name);
if (abbrev_option) {
/*
* If this is abbreviated, it is
* ambiguous. So when there is no
* exact match later, we need to
* error out.
*/
ambiguous_option = abbrev_option;
ambiguous_flags = abbrev_flags;
}
if (!(flags & OPT_UNSET) && *arg_end)
p->opt = arg_end + 1;
abbrev_option = options;
@ -176,6 +176,15 @@ is_abbreviated:
}
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)
return get_value(p, abbrev_option, abbrev_flags);
return error("unknown option `%s'", arg);

View File

@ -18,6 +18,7 @@ string options
-s, --string <string>
get a string
--string2 <str> get another string
--st <st> get another string (pervert ordering)
EOF
@ -90,4 +91,16 @@ test_expect_failure 'ambiguously abbreviated option' '
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

View File

@ -18,6 +18,7 @@ int main(int argc, const char **argv)
OPT_GROUP("string options"),
OPT_STRING('s', "string", &string, "string", "get a string"),
OPT_STRING(0, "string2", &string, "str", "get another string"),
OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"),
OPT_END(),
};
int i;