* lib/getopt.c (_getopt_internal_r): Merge glibc change printing the ambiguous options when an ambiguous prefix is given. This was glibc Buganizer wishlist bug 7101. --- ChangeLog | 7 +++++++ lib/getopt.c | 55 ++++++++++++++++++++++++++++++------------------------- 2 files changed, 37 insertions(+), 25 deletions(-)
diff --git a/ChangeLog b/ChangeLog index c2a67da..02809c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-05-15 James Youngman <j...@gnu.org> + + getopt: for ambiguous options, enumerate the possibilities. + * lib/getopt.c (_getopt_internal_r): Merge glibc change printing + the ambiguous options when an ambiguous prefix is given. This was + glibc Buganizer wishlist bug 7101. + 2011-05-13 Paul Eggert <egg...@cs.ucla.edu> intprops-tests: new module diff --git a/lib/getopt.c b/lib/getopt.c index c8b3013..f3dd855 100644 --- a/lib/getopt.c +++ b/lib/getopt.c @@ -479,8 +479,14 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, || !strchr (optstring, argv[d->optind][1]))))) { char *nameend; + unsigned int namelen; const struct option *p; const struct option *pfound = NULL; + struct option_list + { + const struct option *p; + struct option_list *next; + } *ambig_list = NULL; int exact = 0; int ambig = 0; int indfound = -1; @@ -488,14 +494,14 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; + namelen = nameend - d->__nextchar; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) + if (!strncmp (p->name, d->__nextchar, namelen)) { - if ((unsigned int) (nameend - d->__nextchar) - == (unsigned int) strlen (p->name)) + if (namelen == (unsigned int) strlen (p->name)) { /* Exact match found. */ pfound = p; @@ -513,36 +519,35 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; + { + /* Second or later nonexact match found. */ + struct option_list *newp = alloca (sizeof (*newp)); + newp->p = p; + newp->next = ambig_list; + ambig_list = newp; + } } - if (ambig && !exact) + if (ambig_list != NULL && !exact) { if (print_errors) { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; + struct option_list first; + first.p = pfound; + first.next = ambig_list; + ambig_list = &first; - if (__asprintf (&buf, _("%s: option '%s' is ambiguous\n"), - argv[0], argv[d->optind]) >= 0) + fprintf (stderr, + _("%s: option '%s' is ambiguous; possibilities:"), + argv[0], argv[d->optind]); + do { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); + fprintf (stderr, " '--%s'", ambig_list->p->name); + ambig_list = ambig_list->next; } -#else - fprintf (stderr, _("%s: option '%s' is ambiguous\n"), - argv[0], argv[d->optind]); -#endif + while (ambig_list != NULL); + + fputc ('\n', stderr); } d->__nextchar += strlen (d->__nextchar); d->optind++; -- 1.7.2.5