From 1dff1a67c56bb2c61eaf9b074392b0d4593b3278 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 13 Aug 2009 01:23:35 +0200 Subject: [PATCH] New modules 'getopt-posix', 'getopt-gnu'. --- ChangeLog | 18 ++++ NEWS | 5 + doc/glibc-headers/getopt.texi | 7 +- doc/posix-functions/getopt.texi | 34 +++++-- m4/getopt.m4 | 196 ++++++++++++++++++++++++++++++++++------ modules/getopt | 26 ++---- modules/getopt-gnu | 23 +++++ modules/getopt-posix | 38 ++++++++ 8 files changed, 290 insertions(+), 57 deletions(-) create mode 100644 modules/getopt-gnu create mode 100644 modules/getopt-posix diff --git a/ChangeLog b/ChangeLog index 530999b13..3131d2545 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,23 @@ 2009-08-12 Bruno Haible + 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. + +2009-08-12 Bruno Haible + Ensure that optarg etc. get declared by . * m4/getopt.m4 (gl_GETOPT_CHECK_HEADERS): Require AC_USE_SYSTEM_EXTENSIONS. diff --git a/NEWS b/NEWS index 5989bd91d..c4722c08a 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,11 @@ User visible incompatible changes 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 . diff --git a/doc/glibc-headers/getopt.texi b/doc/glibc-headers/getopt.texi index b112ab6f5..199c44937 100644 --- a/doc/glibc-headers/getopt.texi +++ b/doc/glibc-headers/getopt.texi @@ -18,7 +18,7 @@ Documentation: @uref{http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html,,man getopt}. @end itemize -Gnulib module: getopt +Gnulib module: getopt-gnu Portability problems fixed by Gnulib: @itemize @@ -26,8 +26,11 @@ Portability problems fixed by Gnulib: 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, mingw. +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. diff --git a/doc/posix-functions/getopt.texi b/doc/posix-functions/getopt.texi index 6bc123027..778e3b45c 100644 --- a/doc/posix-functions/getopt.texi +++ b/doc/posix-functions/getopt.texi @@ -4,10 +4,33 @@ POSIX specification: @url{http://www.opengroup.org/onlinepubs/9699919799/functions/getopt.html} -Gnulib module: --- +Gnulib module: getopt-posix or getopt-gnu -Portability problems fixed by Gnulib: +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{} 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,8 +41,7 @@ mixing option and non-option arguments on the command line in any order. 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 - -Gnulib provides a module @code{getopt} that has support for ``long options''. -Compared to POSIX, it adds a header file @code{} and functions -@code{getopt_long} and @code{getopt_long_only}. diff --git a/m4/getopt.m4 b/m4/getopt.m4 index 7fefef744..346afb63f 100644 --- a/m4/getopt.m4 +++ b/m4/getopt.m4 @@ -1,20 +1,28 @@ -# getopt.m4 serial 20 +# 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. -# The getopt module assume you want GNU getopt, with getopt_long etc, -# rather than vanilla POSIX getopt. This means your code should -# always include for the getopt prototypes. - -# This is gnulib's entry-point. -AC_DEFUN([gl_GETOPT], +# 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,47 +49,175 @@ AC_DEFUN([gl_GETOPT_IFELSE], # 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 to declare optarg, optind, opterr, optopt. AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) gl_replace_getopt= - if test -z "$gl_replace_getopt"; then + + dnl Test whether is available. + if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then AC_CHECK_HEADERS([getopt.h], [], [gl_replace_getopt=yes]) fi - if test -z "$gl_replace_getopt"; then + 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 and (as of 2004-10-15) mishandles optional option-arguments. - if test -z "$gl_replace_getopt"; then + 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 ]) fi - dnl Solaris 10 getopt doesn't handle `+' as a leading character in an - dnl option string (as of 2005-05-05). + 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([for working GNU getopt function], [gl_cv_func_gnu_getopt], + 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 +#include +#include + +/* 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 ]], + [AC_LANG_PROGRAM([[#include + #include + #include ]], [[ - char *myargv[3]; - myargv[0] = "conftest"; - myargv[1] = "-+"; - myargv[2] = 0; - return getopt (2, myargv, "+a") != '?'; + /* 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_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 ])])]) - if test "$gl_cv_func_gnu_getopt" = "no"; then + [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 diff --git a/modules/getopt b/modules/getopt index bad6de2c7..402e6765f 100644 --- a/modules/getopt +++ b/modules/getopt @@ -1,32 +1,20 @@ Description: Process command line arguments. +Status: +obsolete + +Notice: +This module is obsolete. Use the module 'getopt-posix' or 'getopt-gnu' instead. + Files: -lib/getopt.in.h -lib/getopt.c -lib/getopt1.c -lib/getopt_int.h -m4/getopt.m4 Depends-on: -gettext-h -unistd -extensions +getopt-gnu configure.ac: -gl_GETOPT Makefile.am: -BUILT_SOURCES += $(GETOPT_H) - -# We need the following in order to create 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; \ - } > $@-t - mv -f $@-t $@ -MOSTLYCLEANFILES += getopt.h getopt.h-t Include: diff --git a/modules/getopt-gnu b/modules/getopt-gnu new file mode 100644 index 000000000..34aea2df8 --- /dev/null +++ b/modules/getopt-gnu @@ -0,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: + + +License: +LGPL + +Maintainer: +all, glibc diff --git a/modules/getopt-posix b/modules/getopt-posix new file mode 100644 index 000000000..b36ed1e33 --- /dev/null +++ b/modules/getopt-posix @@ -0,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 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; \ + } > $@-t + mv -f $@-t $@ +MOSTLYCLEANFILES += getopt.h getopt.h-t + +Include: + + +License: +LGPL + +Maintainer: +all, glibc -- 2.11.0