[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] getopt: for ambiguous options, enumerate the possibilities.
From: |
James Youngman |
Subject: |
[PATCH] getopt: for ambiguous options, enumerate the possibilities. |
Date: |
Tue, 24 May 2011 22:51:34 +0100 |
* 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 | 87 ++++++++++++++++++++++++++++++++++++++++++++++------------
2 files changed, 76 insertions(+), 18 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c2a67da..02809c5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-05-15 James Youngman <address@hidden>
+
+ 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 <address@hidden>
intprops-tests: new module
diff --git a/lib/getopt.c b/lib/getopt.c
index c8b3013..f0d1cf6 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,35 +519,71 @@ _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 = malloc (sizeof (*newp));
+ newp->p = p;
+ newp->next = ambig_list;
+ ambig_list = newp;
+ }
}
- if (ambig && !exact)
+ if (ambig_list != NULL && !exact)
{
if (print_errors)
{
+ struct option_list first;
+ first.p = pfound;
+ first.next = ambig_list;
+ ambig_list = &first;
+
#if defined _LIBC && defined USE_IN_LIBIO
- char *buf;
+ char *buf = NULL;
+ size_t buflen = 0;
- if (__asprintf (&buf, _("%s: option '%s' is ambiguous\n"),
- argv[0], argv[d->optind]) >= 0)
+ FILE *fp = open_memstream (&buf, &buflen);
+ if (fp != NULL)
{
- _IO_flockfile (stderr);
+ fprintf (fp,
+ _("%s: option '%s' is ambiguous; possibilities:"),
+ argv[0], argv[d->optind]);
- int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+ do
+ {
+ fprintf (fp, " '--%s'", ambig_list->p->name);
+ ambig_list = ambig_list->next;
+ }
+ while (ambig_list != NULL);
- __fxprintf (NULL, "%s", buf);
+ fputc_unlocked ('\n', fp);
- ((_IO_FILE *) stderr)->_flags2 = old_flags2;
- _IO_funlockfile (stderr);
+ if (__builtin_expect (fclose (fp) != EOF, 1))
+ {
+ _IO_flockfile (stderr);
- free (buf);
+ 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);
+ }
}
#else
- fprintf (stderr, _("%s: option '%s' is ambiguous\n"),
+ fprintf (stderr,
+ _("%s: option '%s' is ambiguous; possibilities:"),
argv[0], argv[d->optind]);
+ do
+ {
+ fprintf (stderr, " '--%s'", ambig_list->p->name);
+ ambig_list = ambig_list->next;
+ }
+ while (ambig_list != NULL);
+
+ fputc ('\n', stderr);
#endif
}
d->__nextchar += strlen (d->__nextchar);
@@ -549,7 +591,16 @@ _getopt_internal_r (int argc, char **argv, const char
*optstring,
d->optopt = 0;
return '?';
}
-
+ if (ambig_list != NULL)
+ {
+ do
+ {
+ struct option_list *pn = ambig_list->next;
+ free (ambig_list);
+ ambig_list = pn;
+ } while (ambig_list != NULL);
+ }
+
if (pfound != NULL)
{
option_index = indfound;
--
1.7.2.5
- [PATCH] getopt: for ambiguous options, enumerate the possibilities., James Youngman, 2011/05/15
- Re: [PATCH] getopt: for ambiguous options, enumerate the possibilities., Bruno Haible, 2011/05/15
- [PATCH] getopt: for ambiguous options, enumerate the possibilities.,
James Youngman <=
- Re: [PATCH] getopt: for ambiguous options, enumerate the possibilities., Bruno Haible, 2011/05/24
- [PATCH] getopt: for ambiguous options, enumerate the possibilities., James Youngman, 2011/05/25
- Re: [PATCH] getopt: for ambiguous options, enumerate the possibilities., Bruno Haible, 2011/05/26
- Re: [PATCH] getopt: for ambiguous options, enumerate the possibilities., Jim Meyering, 2011/05/26
- Re: [PATCH] getopt: for ambiguous options, enumerate the possibilities., Eric Blake, 2011/05/26