This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]