This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch, master, updated. glibc-2.13-187-gbd25564
- From: drepper at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 15 May 2011 17:35:59 -0000
- Subject: GNU C Library master sources branch, master, updated. glibc-2.13-187-gbd25564
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".
The branch, master has been updated
via bd25564e1e98910ed69043ed6a6f884ce60e5780 (commit)
from bac102db9293f3f619c319312e05dfeb7051a7ad (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=bd25564e1e98910ed69043ed6a6f884ce60e5780
commit bd25564e1e98910ed69043ed6a6f884ce60e5780
Author: Ulrich Drepper <drepper@gmail.com>
Date: Sun May 15 13:35:09 2011 -0400
Provide more helpful error message in getopt
If provide with an ambiguous long option we now show all the possibilities.
diff --git a/ChangeLog b/ChangeLog
index 47ca10d..0c0aa6a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2011-05-15 Ulrich Drepper <drepper@gmail.com>
+ [BZ #7101]
+ * posix/getopt.c (_getopt_internal_r): List all ambigious possibilities
+ when an incomplete long option is used.
+ * posix/tst-getopt_long1.c: New file.
+ * posix/Makefile (tests): Add tst-getopt_long1.
+
[BZ #10138]
* scripts/config.guess: Update from autoconf-2.68.
* scripts/config.sub: Likewise.
diff --git a/NEWS b/NEWS
index 43c3a6c..7100e1d 100644
--- a/NEWS
+++ b/NEWS
@@ -9,13 +9,13 @@ Version 2.14
* The following bugs are resolved with this release:
- 386, 9730, 9732, 9809, 10138, 10149, 10157, 11257, 11258, 11487, 11532,
- 11578, 11653, 11668, 11724, 11901, 11945, 11947, 11952, 12052, 12083,
- 12158, 12178, 12200, 12346, 12393, 12420, 12432, 12445, 12449, 12453,
- 12454, 12460, 12469, 12489, 12509, 12510, 12511, 12518, 12527, 12541,
- 12545, 12551, 12582, 12583, 12587, 12597, 12601, 12611, 12625, 12626,
- 12631, 12650, 12653, 12655, 12660, 12681, 12685, 12711, 12713, 12714,
- 12717, 12723, 12724, 12734, 12738
+ 386, 7101, 9730, 9732, 9809, 10138, 10149, 10157, 11257, 11258, 11487,
+ 11532, 11578, 11653, 11668, 11724, 11901, 11945, 11947, 11952, 12052,
+ 12083, 12158, 12178, 12200, 12346, 12393, 12420, 12432, 12445, 12449,
+ 12453, 12454, 12460, 12469, 12489, 12509, 12510, 12511, 12518, 12527,
+ 12541, 12545, 12551, 12582, 12583, 12587, 12597, 12601, 12611, 12625,
+ 12626, 12631, 12650, 12653, 12655, 12660, 12681, 12685, 12711, 12713,
+ 12714, 12717, 12723, 12724, 12734, 12738
* The RPC implementation in libc is obsoleted. Old programs keep working
but new programs cannot be linked with the routines in libc anymore.
diff --git a/posix/Makefile b/posix/Makefile
index 373e50b..e89f21e 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-1999, 2000-2007, 2009, 2010 Free Software Foundation, Inc.
+# Copyright (C) 1991-2007, 2009, 2010, 2011 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -94,7 +94,7 @@ tests := tstgetopt testfnm runtests runptests \
tst-rfc3484-3 \
tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
- bug-getopt5
+ bug-getopt5 tst-getopt_long1
xtests := bug-ga2
ifeq (yes,$(build-shared))
test-srcs := globtest
diff --git a/posix/getopt.c b/posix/getopt.c
index 2746364..db89abf 100644
--- a/posix/getopt.c
+++ b/posix/getopt.c
@@ -2,7 +2,7 @@
NOTE: getopt is part of the C library, so if you don't know what
"Keep this file name-space clean" means, talk to drepper@gnu.org
before changing it!
- Copyright (C) 1987-1996,1998-2004,2008,2009,2010
+ Copyright (C) 1987-1996,1998-2004,2008,2009,2010,2011
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -526,23 +526,28 @@ _getopt_internal_r (int argc, char *const *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;
int option_index;
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;
@@ -560,35 +565,71 @@ _getopt_internal_r (int argc, char *const *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)
{
+ 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);
diff --git a/posix/tst-getopt_long1.c b/posix/tst-getopt_long1.c
new file mode 100644
index 0000000..e0ecd12
--- /dev/null
+++ b/posix/tst-getopt_long1.c
@@ -0,0 +1,62 @@
+static void do_prepare (void);
+#define PREPARE(argc, argv) do_prepare ()
+static int do_test (void);
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+
+static char *fname;
+
+
+static void
+do_prepare (void)
+{
+ if (create_temp_file ("tst-getopt_long1", &fname) < 0)
+ {
+ printf ("cannot create temp file: %m\n");
+ exit (1);
+ }
+}
+
+
+static const struct option opts[] =
+ {
+ { "one", no_argument, NULL, '1' },
+ { "two", no_argument, NULL, '2' },
+ { "one-one", no_argument, NULL, '3' },
+ { "four", no_argument, NULL, '4' },
+ { "onto", no_argument, NULL, '5' },
+ { NULL, 0, NULL, 0 }
+ };
+
+
+static int
+do_test (void)
+{
+ if (freopen (fname, "w+", stderr) == NULL)
+ {
+ printf ("freopen failed: %m\n");
+ return 1;
+ }
+
+ char *argv[] = { "program", "--on" };
+ int argc = 2;
+
+ int c = getopt_long (argc, argv, "12345", opts, NULL);
+ printf ("return value: %c\n", c);
+
+ rewind (stderr);
+ char *line = NULL;
+ size_t len = 0;
+ if (getline (&line, &len, stderr) < 0)
+ {
+ printf ("cannot read stderr redirect: %m\n");
+ return 1;
+ }
+ printf ("message = \"%s\"\n", line);
+
+ static const char expected[] = "\
+program: option '--on' is ambiguous; possibilities: '--one' '--onto' '--one-one'\n";
+
+ return c != '?' || strcmp (line, expected) != 0;
+}
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 6 +++
NEWS | 14 ++++----
posix/Makefile | 4 +-
posix/getopt.c | 79 +++++++++++++++++++++++++++++++++++-----------
posix/tst-getopt_long1.c | 62 ++++++++++++++++++++++++++++++++++++
5 files changed, 137 insertions(+), 28 deletions(-)
create mode 100644 posix/tst-getopt_long1.c
hooks/post-receive
--
GNU C Library master sources