diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2009-01-13 09:58:43 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2009-01-13 09:58:43 +0000 |
commit | 8c3efc4901fb372caa0831bc7745acf80587750b (patch) | |
tree | 99734e1cfd09560d4a52a87b4faee92a3a2f7bca | |
parent | d9db4e43f32feb1f24a3054e927cff2877e788b4 (diff) | |
download | cygnal-8c3efc4901fb372caa0831bc7745acf80587750b.tar.gz cygnal-8c3efc4901fb372caa0831bc7745acf80587750b.tar.bz2 cygnal-8c3efc4901fb372caa0831bc7745acf80587750b.zip |
* libc/getopt.c (parse_long_options): Use fix from NetBSD's getopt
to avoid false ambiguities.
-rw-r--r-- | winsup/cygwin/ChangeLog | 5 | ||||
-rw-r--r-- | winsup/cygwin/libc/getopt.c | 28 |
2 files changed, 24 insertions, 9 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 66332c54e..9c91a0dde 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -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. diff --git a/winsup/cygwin/libc/getopt.c b/winsup/cygwin/libc/getopt.c index 0b5a18025..ccec9b512 100644 --- a/winsup/cygwin/libc/getopt.c +++ b/winsup/cygwin/libc/getopt.c @@ -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 } /* |