Re: getopt.m4 test

2012-06-26 Thread Bruno Haible
Paul Eggert wrote:
  getopt-posix: No longer guarantee that option processing is resettable.
 
 That looks good to me, and thanks.

Thanks for the review. Eric was silent. So I'm applying this change, together
with a note in the NEWS file.

Bruno



DateModules Changes

2012-06-26  getopt-posixThis module no longer guarantees that option
processing is resettable.  If your code uses
'optreset' or 'optind = 0;', rewrite it to make
only one pass over the argument array.




Re: getopt.m4 test

2012-06-23 Thread Bruno Haible
Hi Paul, Eric,

I wrote:
 It seems to me that
   - musl's getopt is POSIX compliant (at least it passes the 3 parts of
 the test when run individually).
   - The getopt.m4 test fails only because musl does not support one of
 the 3 known ways to reset option processing. Does it support another
 method, or none at all?
   - coreutils does not rely on resetting option processing with getopt(),
 only with getopt_long() (in coreutils/src/{env.c,nice.c,stty.c}).
   - The use of OPTIND_MIN in getopt.m4 exists purely to run a single
 test program rather than 3 test programs in sequence.
 
 Paul, I would suggest to split out the 3 tests into a sequence of 3 test
 programs, and then remove the determination of gl_optind_min - since
 nothing else uses it.

Here is a proposed patch to do this. Its effect is that on HP-UX, IRIX,
OSF/1, Solaris 9, and likely also musl libc the line

  checking whether getopt is POSIX compatible... no

becomes

  checking whether getopt is POSIX compatible... yes

What this change also does is to stop guaranteeing that either 'optreset'
or setting 'optind = 0;' will reset the option processing. The rationale
is that no program I've seen actually needs this: Normal programs use getopt
to loop over their arguments just once.

Also, I couldn't reproduce the described problem with mingw and leading
'+' sign (with mingw of 2009), so let's drop this from the documentation.

Here's the proposed patch. Tested to not introduce regressions in a testdir
for 'getopt-posix', nor in a testdir for 'getopt-gnu'.


2012-06-23  Bruno Haible  br...@clisp.org

getopt-posix: No longer guarantee that option processing is resettable.
* doc/posix-functions/getopt.texi: Drop description of problem with
internal state. Fix info about mingw and msvc9.
* m4/getopt.m4 (gl_GETOPT_CHECK_HEADERS): Don't require a resettable
option processing by getopt(). Run three test programs instead of one.
Simplify cross-compilation guess.
Reported by Rich Felker dal...@aerifal.cx.

--- doc/posix-functions/getopt.texi.origSat Jun 23 17:21:27 2012
+++ doc/posix-functions/getopt.texi Sat Jun 23 17:09:50 2012
@@ -13,21 +13,17 @@
 Portability problems fixed by either Gnulib module @code{getopt-posix} or 
@code{getopt-gnu}:
 @itemize
 @item
-The @code{getopt} function keeps some internal state that cannot be explicitly
-reset on some platforms:
-mingw.
+This function is missing on some platforms:
+MSVC 9.
 @item
 The value of @code{optind} after a missing required argument is wrong
 on some platforms:
-Mac OS X 10.5, AIX 7.1.
+Mac OS X 10.5, AIX 7.1, mingw.
 @end itemize
 
 Portability problems fixed by Gnulib module @code{getopt-gnu}:
 @itemize
 @item
-This function is missing on some platforms:
-MSVC 9.
-@item
 The function @code{getopt} does not support the @samp{+} flag in the options
 string on some platforms:
 Mac OS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11 2010-11.
--- m4/getopt.m4.orig   Sat Jun 23 17:21:27 2012
+++ m4/getopt.m4Sat Jun 23 17:12:49 2012
@@ -1,4 +1,4 @@
-# getopt.m4 serial 42
+# getopt.m4 serial 43
 dnl Copyright (C) 2002-2006, 2008-2012 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -74,11 +74,6 @@
 AC_CHECK_FUNCS([getopt_long_only], [], [gl_replace_getopt=yes])
   fi
 
-  dnl mingw's getopt (in libmingwex.a) does weird things when the options
-  dnl strings starts with '+' and it's not the first call.  Some internal state
-  dnl is left over from earlier calls, and neither setting optind = 0 nor
-  dnl setting optreset = 1 get rid of this internal state.
-  dnl POSIX is silent on optind vs. optreset, so we allow either behavior.
   dnl POSIX 2008 does not specify leading '+' behavior, but see
   dnl http://austingroupbugs.net/view.php?id=191 for a recommendation on
   dnl the next version of POSIX.  For now, we only guarantee leading '+'
@@ -87,30 +82,16 @@
 AC_CACHE_CHECK([whether getopt is POSIX compatible],
   [gl_cv_func_getopt_posix],
   [
-dnl BSD getopt_long uses an incompatible method to reset option
-dnl processing.  Existence of the optreset variable, in and of
-dnl itself, is not a reason to replace getopt, but knowledge
-dnl of the variable is needed to determine how to reset and
-dnl whether a reset reparses the environment.  Solaris
-dnl supports neither optreset nor optind=0, but keeps no state
-dnl that needs a reset beyond setting optind=1; detect Solaris
-dnl by getopt_clip.
-AC_LINK_IFELSE(
-  [AC_LANG_PROGRAM(
- [[#include unistd.h]],
- [[int *p = optreset; return optreset;]])],
-  [gl_optind_min=1],
-  [AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM(
-[[#include getopt.h]],
-[[return 

Re: getopt.m4 test

2012-06-23 Thread Paul Eggert
On 06/23/2012 09:22 AM, Bruno Haible wrote:
   getopt-posix: No longer guarantee that option processing is resettable.

That looks good to me, and thanks.



Re: getopt.m4 test

2012-06-19 Thread Bruno Haible
Rich Felker wrote:
   3. The test for POSIX compatible getopt does not actually test for
   POSIX compatibility, but for GNU semantics which are contrary to
   POSIX. This is purely an issue of a misnamed test; if gnulib wants to
   provide a replacement getopt with GNU semantics, that's okay, but it
   should not tell the user that the host getopt is not POSIX
   compatible.

Eric Blake replied:
  We've already separated the getopt module into tests for POSIX behavior
  vs. tests for GNU extension behavior.  Which particular aspect are you
  claiming is incorrectly attributed to POSIX behavior when it should be
  treated as GNU behavior instead?  And is this occurring when the
  getopt-gnu module is in use, or is it reproducible when using just the
  getopt-posix module?  Or is this just a case of inaccurate wording but
  accurate testing?

In config.log I'm seeing that the test program is compiled with -DOPTIND_MIN=0
and then fails with exit code 1.

Here are the details:
 foo.c 
#include unistd.h
#include stdlib.h
#include string.h

int
main ()
{
  {
static char program[] = program;
static char a[] = -a;
static char foo[] = foo;
static char bar[] = bar;
char *argv[] = { program, a, foo, bar, NULL };
int c;
#ifdef OPTIND_MIN
optind = OPTIND_MIN;
opterr = 0;
#endif
c = getopt (4, argv, ab);
if (!(c == 'a'))
  return 1;
c = getopt (4, argv, ab);
if (!(c == -1))
  return 2;
if (!(optind == 2))
  return 3;
  }
  return 0;
}
===

$ musl-gcc foo.c -Wall; ./a.out; echo $?
0
$ musl-gcc foo.c -Wall -DOPTIND_MIN=0; ./a.out; echo $?
1
$ musl-gcc foo.c -Wall -DOPTIND_MIN=1; ./a.out; echo $?
0

So, musl's getopt works right when 'optind' is not initialized by the
program, or when it is initialized to 1. Like for BSD systems, but BSD
systems have 'optreset' for resetting the option processing.

It seems to me that
  - musl's getopt is POSIX compliant (at least it passes the 3 parts of
the test when run individually).
  - The getopt.m4 test fails only because musl does not support one of
the 3 known ways to reset option processing. Does it support another
method, or none at all?
  - coreutils does not rely on resetting option processing with getopt(),
only with getopt_long() (in coreutils/src/{env.c,nice.c,stty.c}).
  - The use of OPTIND_MIN in getopt.m4 exists purely to run a single
test program rather than 3 test programs in sequence.

Paul, I would suggest to split out the 3 tests into a sequence of 3 test
programs, and then remove the determination of gl_optind_min - since
nothing else uses it.

Rich Felker wrote:
 I was testing with GNU m4. The test that fails has non-option
 arguments placed before options, and tests to see if it can get the
 option with getopt.

As far as I can see, checking whether getopt is POSIX compatible
does not check this; it's the checking for working GNU getopt function
part which does it (look for the comment
This code succeeds on glibc 2.8 and fails on Cygwin 1.7.0.).

Bruno