Subject: RFC: getopt_long(3) change
To: None <tech-userlevel@NetBSD.org>
From: Brian Ginsbach <ginsbach@NetBSD.org>
List: tech-userlevel
Date: 06/21/2007 20:50:11
I'd like to make the following change to getopt_long(3). The
current NetBSD version of getopt_long(3) does not match the behavior
of GNU getopt_long(3) when dealing with potentially abmiguous
arguments. I first noticed this while trying to create a package
for trueprint. It is also why I wrote the regression test for
getopt_long(3).
Anyone see any problems with making this change? Does it require
cranking the library version?
Index: lib/libc/stdlib/getopt_long.c
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/getopt_long.c,v
retrieving revision 1.20
diff -u -r1.20 getopt_long.c
--- lib/libc/stdlib/getopt_long.c 4 Oct 2006 17:29:42 -0000 1.20
+++ lib/libc/stdlib/getopt_long.c 17 Jan 2007 20:17:59 -0000
@@ -371,10 +371,11 @@
if (retval == -2) {
char *current_argv, *has_equal;
size_t current_argv_len;
- int i, match;
+ int i, ambiguous, match;
current_argv = __UNCONST(place);
match = -1;
+ ambiguous = 0;
optind++;
place = EMSG;
@@ -409,18 +410,25 @@
(unsigned)current_argv_len) {
/* exact match */
match = i;
+ ambiguous = 0;
break;
}
+#define lopts long_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 (!(lopts[i].has_arg == lopts[match].has_arg &&
+ lopts[i].flag == lopts[match].flag &&
+ lopts[i].val == lopts[match].val))
+ ambiguous = 1;
+#undef lopts
+ }
+ 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
Index: regress/lib/libc/stdlib/getopt_long/opttest
===================================================================
RCS file: /cvsroot/src/regress/lib/libc/stdlib/getopt_long/opttest,v
retrieving revision 1.1
diff -u -r1.1 opttest
--- regress/lib/libc/stdlib/getopt_long/opttest 18 Jan 2007 16:29:21 -0000 1.1
+++ regress/lib/libc/stdlib/getopt_long/opttest 19 Jun 2007 20:46:13 -0000
@@ -19,9 +19,9 @@
# This is promblematic
args: foo --col
# GNU libc 2.1.3 this fails with ambiguous
-result: !?|0
+#result: !?|0
# GNU libc 2.2 >= this works
-#result: color|0
+result: color|0
#
args: foo --colour
result: -colour|0
@@ -30,6 +30,6 @@
args: foo -a -b -cfoobar --required foobar --optional=bazbug --none random \
--col --color --colour
# GNU libc 2.1.3 this fails with ambiguous
-result: a,b,c=foobar,-required=foobar,-optional=bazbug,-none,!?,-color,-colour|1
+#result: a,b,c=foobar,-required=foobar,-optional=bazbug,-none,!?,-color,-colour|1
# GNU libc 2.2 >= this works
-#result: a,b,c=foobar,-required=foobar,-optional=bazbug,-none,-color,-color,-colour|1
+result: a,b,c=foobar,-required=foobar,-optional=bazbug,-none,-color,-color,-colour|1