about summary refs log tree commit diff
path: root/posix/getopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'posix/getopt.c')
-rw-r--r--posix/getopt.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/posix/getopt.c b/posix/getopt.c
index a7f0b54857..2746364fc7 100644
--- a/posix/getopt.c
+++ b/posix/getopt.c
@@ -2,7 +2,8 @@
    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 Free Software Foundation, Inc.
+   Copyright (C) 1987-1996,1998-2004,2008,2009,2010
+   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
@@ -394,8 +395,6 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 		    int long_only, struct _getopt_data *d, int posixly_correct)
 {
   int print_errors = d->opterr;
-  if (optstring[0] == ':')
-    print_errors = 0;
 
   if (argc < 1)
     return -1;
@@ -410,6 +409,10 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 				      posixly_correct);
       d->__initialized = 1;
     }
+  else if (optstring[0] == '-' || optstring[0] == '+')
+    optstring++;
+  if (optstring[0] == ':')
+    print_errors = 0;
 
   /* Test whether ARGV[optind] points to a non-option argument.
      Either it does not have option syntax, or there is an environment flag
@@ -679,8 +682,8 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 		      char *buf;
 
 		      if (__asprintf (&buf, _("\
-%s: option '%s' requires an argument\n"),
-				      argv[0], argv[d->optind - 1]) >= 0)
+%s: option '--%s' requires an argument\n"),
+				      argv[0], pfound->name) >= 0)
 			{
 			  _IO_flockfile (stderr);
 
@@ -697,8 +700,8 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 			}
 #else
 		      fprintf (stderr,
-			       _("%s: option '%s' requires an argument\n"),
-			       argv[0], argv[d->optind - 1]);
+			       _("%s: option '--%s' requires an argument\n"),
+			       argv[0], pfound->name);
 #endif
 		    }
 		  d->__nextchar += strlen (d->__nextchar);
@@ -788,7 +791,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
     if (*d->__nextchar == '\0')
       ++d->optind;
 
-    if (temp == NULL || c == ':')
+    if (temp == NULL || c == ':' || c == ';')
       {
 	if (print_errors)
 	  {
@@ -910,7 +913,10 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 		  pfound = p;
 		  indfound = option_index;
 		}
-	      else
+	      else if (long_only
+		       || pfound->has_arg != p->has_arg
+		       || pfound->flag != p->flag
+		       || pfound->val != p->val)
 		/* Second or later nonexact match found.  */
 		ambig = 1;
 	    }
@@ -922,7 +928,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 		char *buf;
 
 		if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"),
-				argv[0], argv[d->optind]) >= 0)
+				argv[0], d->optarg) >= 0)
 		  {
 		    _IO_flockfile (stderr);
 
@@ -938,7 +944,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 		  }
 #else
 		fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"),
-			 argv[0], argv[d->optind]);
+			 argv[0], d->optarg);
 #endif
 	      }
 	    d->__nextchar += strlen (d->__nextchar);
@@ -1001,8 +1007,8 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 			char *buf;
 
 			if (__asprintf (&buf, _("\
-%s: option '%s' requires an argument\n"),
-					argv[0], argv[d->optind - 1]) >= 0)
+%s: option '-W %s' requires an argument\n"),
+					argv[0], pfound->name) >= 0)
 			  {
 			    _IO_flockfile (stderr);
 
@@ -1018,15 +1024,17 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 			    free (buf);
 			  }
 #else
-			fprintf (stderr,
-				 _("%s: option '%s' requires an argument\n"),
-				 argv[0], argv[d->optind - 1]);
+			fprintf (stderr, _("\
+%s: option '-W %s' requires an argument\n"),
+				 argv[0], pfound->name);
 #endif
 		      }
 		    d->__nextchar += strlen (d->__nextchar);
 		    return optstring[0] == ':' ? ':' : '?';
 		  }
 	      }
+	    else
+	      d->optarg = NULL;
 	    d->__nextchar += strlen (d->__nextchar);
 	    if (longind != NULL)
 	      *longind = option_index;