bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

new modules getopt-posix, getopt-gnu


From: Bruno Haible
Subject: new modules getopt-posix, getopt-gnu
Date: Thu, 13 Aug 2009 01:24:13 +0200
User-agent: KMail/1.9.9

There is quite some confusion in the getopt module about which functionality
requires which replacement. For example, while mingw fails to provide a working
POSIX compliant getopt() function, systems like MacOS X, Cygwin, HP-UX, Solaris
provide this but fail in the GNU compatibility section. So a package which only
needs a POSIX compliant one compiles the GNU one on most Unix platforms without
need.

The situation is made even more confusing through POSIX incompatibilities
in the glibc implementation of getopt(). Additionally, the POSIX compliance
bugs on mingw come from a wrongly implemented attempt at imitating glibc's
incompatibilities...

To make all this clearer, I'm introducing 'getopt-posix' and 'getopt-gnu'
modules, in the same way as we did for 'fnmatch'. Ultimately 'getopt-posix'
should be renamed to 'getopt', but this cannot be done after a sufficiently
long time of deprecation of the 'getopt' module.


2009-08-12  Bruno Haible  <address@hidden>

        New modules 'getopt-posix', 'getopt-gnu'.
        * modules/getopt-gnu: New file, renamed from modules/getopt.
        * modules/getopt-posix: New file.
        * modules/getopt: Turn into an obsolete alias for getopt-gnu.
        * m4/getopt.m4 (gl_FUNC_GETOPT_POSIX, gl_FUNC_GETOPT_GNU): New macros.
        (gl_GETOPT): Remove macro.
        (gl_GETOPT_CHECK_HEADERS): Do some checks only for gl_FUNC_GETOPT_GNU.
        Disable the test against BSD systems that declare optreset. Test
        against mingw bug. Test against lack of support of optional arguments
        on many platforms.
        * doc/glibc-headers/getopt.texi: Update module name and list of
        relevant platforms.
        * doc/posix-functions/getopt.texi: Mention modules 'getopt-posix' and
        'getopt-gnu' and more portability problems.
        * NEWS: Mention the changes.

*** NEWS.orig   2009-08-13 01:13:48.000000000 +0200
--- NEWS        2009-08-13 01:10:36.000000000 +0200
***************
*** 6,11 ****
--- 6,16 ----
  
  Date        Modules         Changes
  
+ 2009-08-12  getopt          This module is deprecated. Please choose among
+                             getopt-posix and getopt-gnu. getopt-gnu provides
+                             "long options" and "options with optional
+                             arguments", getopt-posix doesn't.
+ 
  2009-06-25  fpurge          The include file is changed from "fpurge.h" to
                              <stdio.h>.
  
*** /dev/null   2008-06-06 22:36:48.000000000 +0200
--- modules/getopt-posix        2009-08-12 21:13:05.000000000 +0200
***************
*** 0 ****
--- 1,38 ----
+ Description:
+ getopt() function: process command line arguments.
+ 
+ Files:
+ lib/getopt.in.h
+ lib/getopt.c
+ lib/getopt1.c
+ lib/getopt_int.h
+ m4/getopt.m4
+ 
+ Depends-on:
+ gettext-h
+ unistd
+ extensions
+ 
+ configure.ac:
+ gl_FUNC_GETOPT_POSIX
+ 
+ Makefile.am:
+ BUILT_SOURCES += $(GETOPT_H)
+ 
+ # We need the following in order to create <getopt.h> when the system
+ # doesn't have one that works with the given compiler.
+ getopt.h: getopt.in.h
+       { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+         cat $(srcdir)/getopt.in.h; \
+       } > address@hidden
+       mv -f address@hidden $@
+ MOSTLYCLEANFILES += getopt.h getopt.h-t
+ 
+ Include:
+ <unistd.h>
+ 
+ License:
+ LGPL
+ 
+ Maintainer:
+ all, glibc
*** /dev/null   2008-06-06 22:36:48.000000000 +0200
--- modules/getopt-gnu  2009-08-12 18:52:15.000000000 +0200
***************
*** 0 ****
--- 1,23 ----
+ Description:
+ GNU-like getopt() function, getopt_long() function, getopt_long_only() 
function:
+ process command line arguments.
+ 
+ Files:
+ 
+ Depends-on:
+ getopt-posix
+ 
+ configure.ac:
+ gl_FUNC_GETOPT_GNU
+ gl_MODULE_INDICATOR([getopt-gnu])
+ 
+ Makefile.am:
+ 
+ Include:
+ <getopt.h>
+ 
+ License:
+ LGPL
+ 
+ Maintainer:
+ all, glibc
*** modules/getopt.orig 2009-08-13 01:13:48.000000000 +0200
--- modules/getopt      2009-08-13 01:11:24.000000000 +0200
***************
*** 1,32 ****
  Description:
  Process command line arguments.
  
  Files:
- lib/getopt.in.h
- lib/getopt.c
- lib/getopt1.c
- lib/getopt_int.h
- m4/getopt.m4
  
  Depends-on:
! gettext-h
! unistd
! extensions
  
  configure.ac:
- gl_GETOPT
  
  Makefile.am:
- BUILT_SOURCES += $(GETOPT_H)
- 
- # We need the following in order to create <getopt.h> when the system
- # doesn't have one that works with the given compiler.
- getopt.h: getopt.in.h
-       { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-         cat $(srcdir)/getopt.in.h; \
-       } > address@hidden
-       mv -f address@hidden $@
- MOSTLYCLEANFILES += getopt.h getopt.h-t
  
  Include:
  <getopt.h>
--- 1,20 ----
  Description:
  Process command line arguments.
  
+ Status:
+ obsolete
+ 
+ Notice:
+ This module is obsolete. Use the module 'getopt-posix' or 'getopt-gnu' 
instead.
+ 
  Files:
  
  Depends-on:
! getopt-gnu
  
  configure.ac:
  
  Makefile.am:
  
  Include:
  <getopt.h>
*** m4/getopt.m4.orig   2009-08-13 01:13:48.000000000 +0200
--- m4/getopt.m4        2009-08-13 01:11:15.000000000 +0200
***************
*** 1,20 ****
! # getopt.m4 serial 20
  dnl Copyright (C) 2002-2006, 2008-2009 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
  dnl with or without modifications, as long as this notice is preserved.
  
! # The getopt module assume you want GNU getopt, with getopt_long etc,
! # rather than vanilla POSIX getopt.  This means your code should
! # always include <getopt.h> for the getopt prototypes.
! 
! # This is gnulib's entry-point.
! AC_DEFUN([gl_GETOPT],
  [
    AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
    gl_GETOPT_IFELSE([
      gl_REPLACE_GETOPT
!   ])
  ])
  
  # Request the gnulib implementation of the getopt functions unconditionally.
--- 1,28 ----
! # getopt.m4 serial 21
  dnl Copyright (C) 2002-2006, 2008-2009 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
  dnl with or without modifications, as long as this notice is preserved.
  
! # Request a POSIX compliant getopt function.
! AC_DEFUN([gl_FUNC_GETOPT_POSIX],
  [
+   m4_divert_text([DEFAULTS], [gl_getopt_required=POSIX])
    AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
    gl_GETOPT_IFELSE([
      gl_REPLACE_GETOPT
!   ],
!   [])
! ])
! 
! # Request a POSIX compliant getopt function with GNU extensions (such as
! # options with optional arguments) and the functions getopt_long,
! # getopt_long_only.
! AC_DEFUN([gl_FUNC_GETOPT_GNU],
! [
!   m4_divert_text([INIT_PREPARE], [gl_getopt_required=GNU])
! 
!   AC_REQUIRE([gl_FUNC_GETOPT_POSIX])
  ])
  
  # Request the gnulib implementation of the getopt functions unconditionally.
***************
*** 41,87 ****
  # Determine whether to replace the entire getopt facility.
  AC_DEFUN([gl_GETOPT_CHECK_HEADERS],
  [
    dnl Persuade Solaris <unistd.h> to declare optarg, optind, opterr, optopt.
    AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
  
    gl_replace_getopt=
!   if test -z "$gl_replace_getopt"; then
      AC_CHECK_HEADERS([getopt.h], [], [gl_replace_getopt=yes])
    fi
  
!   if test -z "$gl_replace_getopt"; then
      AC_CHECK_FUNCS([getopt_long_only], [], [gl_replace_getopt=yes])
    fi
  
    dnl BSD getopt_long uses an incompatible method to reset option processing,
!   dnl and (as of 2004-10-15) mishandles optional option-arguments.
!   if test -z "$gl_replace_getopt"; then
      AC_CHECK_DECL([optreset], [gl_replace_getopt=yes], [],
        [#include <getopt.h>])
    fi
  
!   dnl Solaris 10 getopt doesn't handle `+' as a leading character in an
!   dnl option string (as of 2005-05-05).
    if test -z "$gl_replace_getopt"; then
!     AC_CACHE_CHECK([for working GNU getopt function], [gl_cv_func_gnu_getopt],
        [AC_RUN_IFELSE(
!       [AC_LANG_PROGRAM([[#include <getopt.h>]],
           [[
!            char *myargv[3];
!            myargv[0] = "conftest";
!            myargv[1] = "-+";
!            myargv[2] = 0;
!            return getopt (2, myargv, "+a") != '?';
           ]])],
!       [gl_cv_func_gnu_getopt=yes],
!       [gl_cv_func_gnu_getopt=no],
!       [dnl cross compiling - pessimistically guess based on decls
!        dnl Solaris 10 getopt doesn't handle `+' as a leading character in an
!        dnl option string (as of 2005-05-05).
!        AC_CHECK_DECL([getopt_clip],
!          [gl_cv_func_gnu_getopt=no], [gl_cv_func_gnu_getopt=yes],
!          [#include <getopt.h>])])])
!     if test "$gl_cv_func_gnu_getopt" = "no"; then
        gl_replace_getopt=yes
      fi
    fi
--- 49,223 ----
  # Determine whether to replace the entire getopt facility.
  AC_DEFUN([gl_GETOPT_CHECK_HEADERS],
  [
+   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ 
    dnl Persuade Solaris <unistd.h> to declare optarg, optind, opterr, optopt.
    AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
  
    gl_replace_getopt=
! 
!   dnl Test whether <getopt.h> is available.
!   if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then
      AC_CHECK_HEADERS([getopt.h], [], [gl_replace_getopt=yes])
    fi
  
!   dnl Test whether the function getopt_long is available.
!   if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then
      AC_CHECK_FUNCS([getopt_long_only], [], [gl_replace_getopt=yes])
    fi
  
    dnl BSD getopt_long uses an incompatible method to reset option processing,
!   dnl but the testsuite does not show a need to use this 'optreset' variable.
!   if false && test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; 
then
      AC_CHECK_DECL([optreset], [gl_replace_getopt=yes], [],
        [#include <getopt.h>])
    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.
    if test -z "$gl_replace_getopt"; then
!     AC_CACHE_CHECK([whether getopt is POSIX compatible],
!       [gl_cv_func_getopt_posix],
!       [
!         dnl This test fails on mingw and succeeds on all other platforms.
!         AC_TRY_RUN([
! #include <unistd.h>
! #include <stdlib.h>
! #include <string.h>
! 
! /* The glibc implementation of getopt supports setting optind = 0 as a means
!    of clearing the internal state, but other implementations don't.  */
! #if (__GLIBC__ >= 2)
! # define OPTIND_MIN 0
! #else
! # define OPTIND_MIN 1
! #endif
! 
! int
! main ()
! {
!   {
!     int argc = 0;
!     char *argv[10];
!     int c;
! 
!     argv[argc++] = "program";
!     argv[argc++] = "-a";
!     argv[argc++] = "foo";
!     argv[argc++] = "bar";
!     optind = OPTIND_MIN;
!     opterr = 0;
! 
!     c = getopt (argc, argv, "ab");
!     if (!(c == 'a'))
!       return 1;
!     c = getopt (argc, argv, "ab");
!     if (!(c == -1))
!       return 2;
!     if (!(optind == 2))
!       return 3;
!   }
!   /* Some internal state exists at this point.  */
!   {
!     int argc = 0;
!     char *argv[10];
!     int c;
! 
!     argv[argc++] = "program";
!     argv[argc++] = "donald";
!     argv[argc++] = "-p";
!     argv[argc++] = "billy";
!     argv[argc++] = "duck";
!     argv[argc++] = "-a";
!     argv[argc++] = "bar";
!     optind = OPTIND_MIN;
!     opterr = 0;
! 
!     c = getopt (argc, argv, "+abp:q:");
!     if (!(c == -1))
!       return 4;
!     if (!(strcmp (argv[0], "program") == 0))
!       return 5;
!     if (!(strcmp (argv[1], "donald") == 0))
!       return 6;
!     if (!(strcmp (argv[2], "-p") == 0))
!       return 7;
!     if (!(strcmp (argv[3], "billy") == 0))
!       return 8;
!     if (!(strcmp (argv[4], "duck") == 0))
!       return 9;
!     if (!(strcmp (argv[5], "-a") == 0))
!       return 10;
!     if (!(strcmp (argv[6], "bar") == 0))
!       return 11;
!     if (!(optind == 1))
!       return 12;
!   }
! 
!   return 0;
! }
! ],
!           [gl_cv_func_getopt_posix=yes], [gl_cv_func_getopt_posix=no],
!           [case "$host_os" in
!              mingw*) gl_cv_func_getopt_posix="guessing no";;
!              *)      gl_cv_func_getopt_posix="guessing yes";;
!            esac
!           ])
!       ])
!     case "$gl_cv_func_getopt_posix" in
!       *no) gl_replace_getopt=yes ;;
!     esac
!   fi
! 
!   if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then
!     AC_CACHE_CHECK([for working GNU getopt function], [gl_cv_func_getopt_gnu],
        [AC_RUN_IFELSE(
!       [AC_LANG_PROGRAM([[#include <getopt.h>
!                          #include <stddef.h>
!                          #include <string.h>]],
           [[
!              /* This code succeeds on glibc 2.8, OpenBSD 4.0, Cygwin, mingw,
!                 and fails on MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5,
!                 OSF/1 5.1, Solaris 10.  */
!              {
!                char *myargv[3];
!                myargv[0] = "conftest";
!                myargv[1] = "-+";
!                myargv[2] = 0;
!                opterr = 0;
!                if (getopt (2, myargv, "+a") != '?')
!                  return 1;
!              }
!              /* This code succeeds on glibc 2.8, mingw,
!                 and fails on MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11,
!                 IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin.  */
!              {
!                char *argv[] = { "program", "-p", "foo", "bar" };
! 
!                optind = 1;
!                if (getopt (4, argv, "p::") != 'p')
!                  return 2;
!                if (optarg != NULL)
!                  return 3;
!                if (getopt (4, argv, "p::") != -1)
!                  return 4;
!                if (optind != 2)
!                  return 5;
!              }
!              return 0;
           ]])],
!       [gl_cv_func_getopt_gnu=yes],
!       [gl_cv_func_getopt_gnu=no],
!       [dnl Cross compiling. Guess based on host and declarations.
!          case "$host_os" in
!            *-gnu* | mingw*) gl_cv_func_getopt_gnu=no;;
!            *)               gl_cv_func_getopt_gnu=yes;;
!          esac
!         ])
!       ])
!     if test "$gl_cv_func_getopt_gnu" = "no"; then
        gl_replace_getopt=yes
      fi
    fi
*** doc/glibc-headers/getopt.texi.orig  2009-08-13 01:13:48.000000000 +0200
--- doc/glibc-headers/getopt.texi       2009-08-13 01:10:36.000000000 +0200
***************
*** 18,24 ****
  
@uref{http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html,,man 
getopt}.
  @end itemize
  
! Gnulib module: getopt
  
  Portability problems fixed by Gnulib:
  @itemize
--- 18,24 ----
  
@uref{http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html,,man 
getopt}.
  @end itemize
  
! Gnulib module: getopt-gnu
  
  Portability problems fixed by Gnulib:
  @itemize
***************
*** 26,33 ****
  This header file is missing on some platforms:
  AIX 5.1, HP-UX 11, Interix 3.5.
  @item
  The function @code{getopt_long_only} is missing on some platforms:
! MacOS X 10.3, FreeBSD 5.2.1, NetBSD 3.0, IRIX 6.5, OSF/1 5.1, mingw.
  @item
  The method to reset options is incompatible on some platforms:
  FreeBSD 6.0, NetBSD 3.0(?), OpenBSD 3.8, Cygwin(?), mingw.
--- 26,36 ----
  This header file is missing on some platforms:
  AIX 5.1, HP-UX 11, Interix 3.5.
  @item
+ The function @code{getopt_long} is missing on some platforms:
+ IRIX 6.5, OSF/1 5.1, Solaris 9.
+ @item
  The function @code{getopt_long_only} is missing on some platforms:
! MacOS X 10.3, FreeBSD 5.2.1, NetBSD 3.0, IRIX 6.5, OSF/1 5.1, Solaris 9, 
mingw.
  @item
  The method to reset options is incompatible on some platforms:
  FreeBSD 6.0, NetBSD 3.0(?), OpenBSD 3.8, Cygwin(?), mingw.
*** doc/posix-functions/getopt.texi.orig        2009-08-13 01:13:48.000000000 
+0200
--- doc/posix-functions/getopt.texi     2009-08-13 01:10:36.000000000 +0200
***************
*** 4,13 ****
  
  POSIX specification: 
@url{http://www.opengroup.org/onlinepubs/9699919799/functions/getopt.html}
  
! Gnulib module: ---
  
! Portability problems fixed by Gnulib:
  @itemize
  @end itemize
  
  Portability problems not fixed by Gnulib:
--- 4,36 ----
  
  POSIX specification: 
@url{http://www.opengroup.org/onlinepubs/9699919799/functions/getopt.html}
  
! Gnulib module: getopt-posix or getopt-gnu
  
! The module @code{getopt-gnu} has support for ``long options'' and for
! ``options that take optional arguments''.  Compared to the API defined by 
POSIX,
! it adds a header file @code{<getopt.h>} and a function @code{getopt_long}.
! 
! 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.
! @end itemize
! 
! Portability problems fixed by Gnulib module @code{getopt-gnu}:
  @itemize
+ @item
+ The function @code{getopt} does not support the @samp{+} flag in the options
+ string on some platforms:
+ MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10.
+ @item
+ The function @code{getopt} does not support options with optional arguments
+ on some platforms:
+ MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 
10, Cygwin.
+ @item
+ The function @code{getopt_long} is missing on some platforms:
+ AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 9, Interix 3.5.
  @end itemize
  
  Portability problems not fixed by Gnulib:
***************
*** 18,25 ****
  Other implementations, such as the one in Cygwin, enforce strict POSIX
  compliance: they require that the option arguments precede the non-option
  arguments.  This is something to watch out in your program's testsuite.
  @end itemize
- 
- Gnulib provides a module @code{getopt} that has support for ``long options''.
- Compared to POSIX, it adds a header file @code{<getopt.h>} and functions
- @code{getopt_long} and @code{getopt_long_only}.
--- 41,47 ----
  Other implementations, such as the one in Cygwin, enforce strict POSIX
  compliance: they require that the option arguments precede the non-option
  arguments.  This is something to watch out in your program's testsuite.
+ @item
+ The function @code{getopt_long_only} is missing on some platforms:
+ MacOS X 10.3, FreeBSD 5.2.1, NetBSD 3.0, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 
5.1, Solaris 9, mingw, Interix 3.5.
  @end itemize




reply via email to

[Prev in Thread] Current Thread [Next in Thread]