diff options
author | Johannes Schindelin <Johannes.Schindelin@gmx.de> | 2007-10-14 17:54:06 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2007-10-29 21:03:30 -0700 |
commit | 7f275b91520d31bfbe43ec5a9bbaf8ac6e663ce0 (patch) | |
tree | 3e21e4a89617c56b47b7d4d1f2312198a8641de9 /parse-options.c | |
parent | 0ce865b134f8ccd60f6e584744144b0978a9fdf2 (diff) | |
download | git-7f275b91520d31bfbe43ec5a9bbaf8ac6e663ce0.tar.gz |
parse-options: Allow abbreviated options when unambiguous
When there is an option "--amend", the option parser now recognizes
"--am" for that option, provided that there is no other option beginning
with "--am".
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'parse-options.c')
-rw-r--r-- | parse-options.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/parse-options.c b/parse-options.c index 12a9f9ea68..b4a3b63e9f 100644 --- a/parse-options.c +++ b/parse-options.c @@ -113,6 +113,13 @@ static int parse_short_opt(struct optparse_t *p, const struct option *options) 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; + + if (!arg_end) + arg_end = arg + strlen(arg); + for (; options->type != OPTION_END; options++) { const char *rest; int flags = 0; @@ -122,10 +129,38 @@ static int parse_long_opt(struct optparse_t *p, const char *arg, rest = skip_prefix(arg, options->long_name); if (!rest) { + /* 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 (!(flags & OPT_UNSET) && *arg_end) + p->opt = arg_end + 1; + abbrev_option = options; + abbrev_flags = flags; + continue; + } + /* negated and abbreviated very much? */ + if (!prefixcmp("no-", arg)) { + flags |= OPT_UNSET; + goto is_abbreviated; + } + /* negated? */ if (strncmp(arg, "no-", 3)) continue; flags |= OPT_UNSET; rest = skip_prefix(arg + 3, options->long_name); + /* abbreviated and negated? */ + if (!rest && !prefixcmp(options->long_name, arg + 3)) + goto is_abbreviated; if (!rest) continue; } @@ -136,6 +171,8 @@ static int parse_long_opt(struct optparse_t *p, const char *arg, } return get_value(p, options, flags); } + if (abbrev_option) + return get_value(p, abbrev_option, abbrev_flags); return error("unknown option `%s'", arg); } |