]> sourceware.org Git - newlib-cygwin.git/commitdiff
* libc/getopt.c (parse_long_options): Use fix from NetBSD's getopt
authorCorinna Vinschen <corinna@vinschen.de>
Tue, 13 Jan 2009 09:58:43 +0000 (09:58 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Tue, 13 Jan 2009 09:58:43 +0000 (09:58 +0000)
to avoid false ambiguities.

winsup/cygwin/ChangeLog
winsup/cygwin/libc/getopt.c

index 66332c54e5207291bafa628901bfeff5ede63394..9c91a0dde49fb9f81f6c164c7c57fd3d1ae88115 100644 (file)
@@ -1,3 +1,8 @@
+2009-01-13  Corinna Vinschen  <corinna@vinschen.de>
+
+       * libc/getopt.c (parse_long_options): Use fix from NetBSD's getopt
+       to avoid false ambiguities.
+
 2009-01-12  Corinna Vinschen  <corinna@vinschen.de>
 
        * syscalls.cc (enum bin_status): New type.
index 0b5a18025b5346a6c4aa89bc1fd7e86743ea2caf..ccec9b5123ba1707b85754b861f66fea4b78990f 100644 (file)
@@ -170,10 +170,16 @@ parse_long_options(char * const *nargv, const char *options,
 {
        char *current_argv, *has_equal;
        size_t current_argv_len;
-       int i, match;
+       int i, ambiguous, match;
+
+#define IDENTICAL_INTERPRETATION(_x, _y)                                \
+       (long_options[(_x)].has_arg == long_options[(_y)].has_arg &&    \
+        long_options[(_x)].flag == long_options[(_y)].flag &&          \
+        long_options[(_x)].val == long_options[(_y)].val)
 
        current_argv = place;
        match = -1;
+       ambiguous = 0;
 
        optind++;
 
@@ -193,6 +199,7 @@ parse_long_options(char * const *nargv, const char *options,
                if (strlen(long_options[i].name) == current_argv_len) {
                        /* exact match */
                        match = i;
+                       ambiguous = 0;
                        break;
                }
                /*
@@ -204,14 +211,16 @@ parse_long_options(char * const *nargv, const char *options,
 
                if (match == -1)        /* partial match */
                        match = i;
-               else {
-                       /* ambiguous abbreviation */
-                       if (PRINT_ERROR)
-                               warnx(ambig, (int)current_argv_len,
-                                    current_argv);
-                       optopt = 0;
-                       return (BADCH);
-               }
+               else if (!IDENTICAL_INTERPRETATION(i, match))
+                       ambiguous = 1;
+       }
+       if (ambiguous) {
+               /* ambiguous abbreviation */
+               if (PRINT_ERROR)
+                       warnx(ambig, (int)current_argv_len,
+                            current_argv);
+               optopt = 0;
+               return (BADCH);
        }
        if (match != -1) {              /* option found */
                if (long_options[match].has_arg == no_argument
@@ -276,6 +285,7 @@ parse_long_options(char * const *nargv, const char *options,
                return (0);
        } else
                return (long_options[match].val);
+#undef IDENTICAL_INTERPRETATION
 }
 
 /*
This page took 0.03777 seconds and 5 git commands to generate.