]> Savannah Git Hosting - gnulib.git/commitdiff
getopt: split up getopt.in.h and eliminate __need_getopt
authorZack Weinberg <zackw@panix.com>
Thu, 6 Apr 2017 18:14:14 +0000 (11:14 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 6 Apr 2017 22:42:04 +0000 (15:42 -0700)
Over in glibc, all of the __need macros are being phased out in favor
of small headers that declare only the necessary components, as this
is much simpler and less prone to bugs.  As getopt is shared with
glibc, gnulib needs to do the same for __need_getopt.

__need_getopt is misnamed; what it really means is "we want only the
getopt features specified in POSIX, not the GNU extensions".  glibc
placed the "meat" of getopt.h into getopt_core.h and getopt_ext.h;
these files can be shared verbatim with gnulib.  The portability
wrapper, on the other hand, they have renounced altogether; glibc's
getopt.h will no longer be shared with gnulib at all.  In exchange,
certain glibc-specific quirks (having to do with __posix_getopt) no
longer need appear in gnulib's headers at all.

This patch merges getopt_core.h and getopt_ext.h from glibc, and
splits up the current gnulib-side portability wrapper into three
additional headers: getopt_pfx_core.h and getopt_pfx_ext.h handle
__GETOPT_PREFIX for their respective headers, getopt_cdefs.in.h
handles things like __BEGIN_DECLS and __THROW, and getopt.in.h and
unistd.in.h just use them.  All new files are clearly marked with
whether they are shared with glibc.

* lib/getopt.in.h: Eliminate __need_getopt.  Break up into ...
* lib/getopt_core.h, lib/getopt_ext.h: ... these new files shared
with glibc, and ...
* lib/getopt_cdefs.in.h, lib/getopt_pfx_core.h
* lib/getopt_pfx_ext.h: ... these new files not shared with glibc.
* lib/unistd.in.h: Include getopt_cdefs.h and getopt_pfx_core.h,
instead of defining __need_getopt and including the full getopt.h.

* m4/getopt.m4 (gl_GETOPT_SUBSTITUTE_HEADER): Check for sys/cdefs.h.
Define substitution variables GETOPT_CDEFS_H and HAVE_SYS_CDEFS_H.
* modules/getopt-posix (Files): Add new headers and sort list.
(Depends-on): No longer need snippet/arg-nonnull.
(Makefile.am): Generate getopt_cdefs.h.

ChangeLog
lib/getopt.in.h
lib/getopt_cdefs.in.h [new file with mode: 0644]
lib/getopt_core.h [new file with mode: 0644]
lib/getopt_ext.h [new file with mode: 0644]
lib/getopt_pfx_core.h [new file with mode: 0644]
lib/getopt_pfx_ext.h [new file with mode: 0644]
lib/unistd.in.h
m4/getopt.m4
modules/getopt-posix

index eb2f347a60c46efb089a2ffe85b2e3e6d4d3c8b0..436e8463264aa8ae1971163f6ef011629054401d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,44 @@
 2017-04-06  Zack Weinberg  <zackw@panix.com>
 
+       getopt: split up getopt.in.h and eliminate __need_getopt
+
+       Over in glibc, all of the __need macros are being phased out in favor
+       of small headers that declare only the necessary components, as this
+       is much simpler and less prone to bugs.  As getopt is shared with
+       glibc, gnulib needs to do the same for __need_getopt.
+
+       __need_getopt is misnamed; what it really means is "we want only the
+       getopt features specified in POSIX, not the GNU extensions".  glibc
+       placed the "meat" of getopt.h into getopt_core.h and getopt_ext.h;
+       these files can be shared verbatim with gnulib.  The portability
+       wrapper, on the other hand, they have renounced altogether; glibc's
+       getopt.h will no longer be shared with gnulib at all.  In exchange,
+       certain glibc-specific quirks (having to do with __posix_getopt) no
+       longer need appear in gnulib's headers at all.
+
+       This patch merges getopt_core.h and getopt_ext.h from glibc, and
+       splits up the current gnulib-side portability wrapper into three
+       additional headers: getopt_pfx_core.h and getopt_pfx_ext.h handle
+       __GETOPT_PREFIX for their respective headers, getopt_cdefs.in.h
+       handles things like __BEGIN_DECLS and __THROW, and getopt.in.h and
+       unistd.in.h just use them.  All new files are clearly marked with
+       whether they are shared with glibc.
+
+       * lib/getopt.in.h: Eliminate __need_getopt.  Break up into ...
+       * lib/getopt_core.h, lib/getopt_ext.h: ... these new files shared
+       with glibc, and ...
+       * lib/getopt_cdefs.in.h, lib/getopt_pfx_core.h
+       * lib/getopt_pfx_ext.h: ... these new files not shared with glibc.
+       * lib/unistd.in.h: Include getopt_cdefs.h and getopt_pfx_core.h,
+       instead of defining __need_getopt and including the full getopt.h.
+
+       * m4/getopt.m4 (gl_GETOPT_SUBSTITUTE_HEADER): Check for sys/cdefs.h.
+       Define substitution variables GETOPT_CDEFS_H and HAVE_SYS_CDEFS_H.
+       * modules/getopt-posix (Files): Add new headers and sort list.
+       (Depends-on): No longer need snippet/arg-nonnull.
+       (Makefile.am): Generate getopt_cdefs.h.
+
+
        getopt: better handling of ambiguous options
 
        glibc's getopt uses alloca to construct a linked list of possibilities
index 100840613133a44dceac2a7d54f99cc233185264..c3ffd955d0571ee7853b4de7acbd36c848dc504b 100644 (file)
@@ -1,20 +1,22 @@
 /* Declarations for getopt.
    Copyright (C) 1989-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   This file is part of gnulib.
+   Unlike most of the getopt implementation, it is NOT shared
+   with the GNU C Library, which supplies a different version of
+   this file.
+
+   gnulib is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+
+   gnulib is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
+   License along with gnulib; if not, see <http://www.gnu.org/licenses/>.  */
 
 #ifndef _@GUARD_PREFIX@_GETOPT_H
 
 # undef _GL_SYSTEM_GETOPT
 #endif
 
-#ifndef _@GUARD_PREFIX@_GETOPT_H
-
-#ifndef __need_getopt
-# define _@GUARD_PREFIX@_GETOPT_H 1
-#endif
+#define _@GUARD_PREFIX@_GETOPT_H 1
 
 /* Standalone applications should #define __GETOPT_PREFIX to an
    identifier that prefixes the external functions and variables
-   defined in this header.  When this happens, include the
-   headers that might declare getopt so that they will not cause
-   confusion if included after this file (if the system had <getopt.h>,
-   we have already included it).  Then systematically rename
-   identifiers so that they do not collide with the system functions
-   and variables.  Renaming avoids problems with some compilers and
-   linkers.  */
+   defined in getopt_core.h and getopt_ext.h.  When this happens,
+   include the headers that might declare getopt so that they will not
+   cause confusion if included after this file (if the system had
+   <getopt.h>, we have already included it).  */
 #if defined __GETOPT_PREFIX
-# if !defined __need_getopt
-#  if !@HAVE_GETOPT_H@
-#   define __need_system_stdlib_h
-#   include <stdlib.h>
-#   undef __need_system_stdlib_h
-#   include <stdio.h>
-#   include <unistd.h>
-#  endif
-#  undef __need_getopt
-# endif
-# undef __GETOPT_CONCAT
-# undef __GETOPT_XCONCAT
-# undef __GETOPT_ID
-# undef getopt
-# undef getopt_long
-# undef getopt_long_only
-# undef optarg
-# undef opterr
-# undef optind
-# undef optopt
-# undef option
-# undef _getopt_internal
-# define __GETOPT_CONCAT(x, y) x ## y
-# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
-# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
-# define getopt __GETOPT_ID (getopt)
-# define getopt_long __GETOPT_ID (getopt_long)
-# define getopt_long_only __GETOPT_ID (getopt_long_only)
-# define optarg __GETOPT_ID (optarg)
-# define opterr __GETOPT_ID (opterr)
-# define optind __GETOPT_ID (optind)
-# define optopt __GETOPT_ID (optopt)
-# define option __GETOPT_ID (option)
-# define _getopt_internal __GETOPT_ID (getopt_internal)
-#endif
-
-/* Standalone applications get correct prototypes for getopt_long and
-   getopt_long_only; they declare "char **argv".  libc uses prototypes
-   with "char *const *argv" that are incorrect because getopt_long and
-   getopt_long_only can permute argv; this is required for backward
-   compatibility (e.g., for LSB 2.0.1).
-
-   This used to be '#if defined __GETOPT_PREFIX && !defined __need_getopt',
-   but it caused redefinition warnings if both unistd.h and getopt.h were
-   included, since unistd.h includes getopt.h having previously defined
-   __need_getopt.
-
-   The only place where __getopt_argv_const is used is in definitions
-   of getopt_long and getopt_long_only below, but these are visible
-   only if __need_getopt is not defined, so it is quite safe to rewrite
-   the conditional as follows:
-*/
-#if !defined __need_getopt
-# if defined __GETOPT_PREFIX
-#  define __getopt_argv_const /* empty */
-# else
-#  define __getopt_argv_const const
-# endif
-#endif
-
-/* If __GNU_LIBRARY__ is not already defined, either we are being used
-   standalone, or this is the first header included in the source file.
-   If we are being used with glibc, we need to include <features.h>, but
-   that does not exist if we are standalone.  So: if __GNU_LIBRARY__ is
-   not defined, include <ctype.h>, which will pull in <features.h> for us
-   if it's from glibc.  (Why ctype.h?  It's guaranteed to exist and it
-   doesn't flood the namespace with stuff the way some other headers do.)  */
-#if !defined __GNU_LIBRARY__
-# include <ctype.h>
-#endif
-
-#ifndef __THROW
-# ifndef __GNUC_PREREQ
-#  define __GNUC_PREREQ(maj, min) (0)
-# endif
-# if defined __cplusplus && __GNUC_PREREQ (2,8)
-#  define __THROW       throw ()
-# else
-#  define __THROW
+# if !@HAVE_GETOPT_H@
+#  define __need_system_stdlib_h
+#  include <stdlib.h>
+#  undef __need_system_stdlib_h
+#  include <stdio.h>
+#  include <unistd.h>
 # endif
 #endif
 
-/* The definition of _GL_ARG_NONNULL is copied here.  */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* For communication from 'getopt' to the caller.
-   When 'getopt' finds an option that takes an argument,
-   the argument value is returned here.
-   Also, when 'ordering' is RETURN_IN_ORDER,
-   each non-option ARGV-element is returned here.  */
-
-extern char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
-   This is used for communication to and from the caller
-   and for communication between successive calls to 'getopt'.
-
-   On entry to 'getopt', zero means this is the first call; initialize.
-
-   When 'getopt' returns -1, this is the index of the first of the
-   non-option elements that the caller should itself scan.
-
-   Otherwise, 'optind' communicates from one call to the next
-   how much of ARGV has been scanned so far.  */
-
-extern int optind;
-
-/* Callers store zero here to inhibit the error message 'getopt' prints
-   for unrecognized options.  */
-
-extern int opterr;
-
-/* Set to an option character which was unrecognized.  */
+#include <getopt_cdefs.h>
+#include <getopt_pfx_core.h>
+#include <getopt_pfx_ext.h>
 
-extern int optopt;
-
-#ifndef __need_getopt
-/* Describe the long-named options requested by the application.
-   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
-   of 'struct option' terminated by an element containing a name which is
-   zero.
-
-   The field 'has_arg' is:
-   no_argument          (or 0) if the option does not take an argument,
-   required_argument    (or 1) if the option requires an argument,
-   optional_argument    (or 2) if the option takes an optional argument.
-
-   If the field 'flag' is not NULL, it points to a variable that is set
-   to the value given in the field 'val' when the option is found, but
-   left unchanged if the option is not found.
-
-   To have a long-named option do something other than set an 'int' to
-   a compiled-in constant, such as set a value from 'optarg', set the
-   option's 'flag' field to zero and its 'val' field to a nonzero
-   value (the equivalent single-letter option character, if there is
-   one).  For long options that have a zero 'flag' field, 'getopt'
-   returns the contents of the 'val' field.  */
-
-# if !GNULIB_defined_struct_option
-struct option
-{
-  const char *name;
-  /* has_arg can't be an enum because some compilers complain about
-     type mismatches in all the code that assumes it is an int.  */
-  int has_arg;
-  int *flag;
-  int val;
-};
-#  define GNULIB_defined_struct_option 1
-# endif
-
-/* Names for the values of the 'has_arg' field of 'struct option'.  */
-
-# define no_argument            0
-# define required_argument      1
-# define optional_argument      2
-#endif  /* need getopt */
-
-
-/* Get definitions and prototypes for functions to process the
-   arguments in ARGV (ARGC of them, minus the program name) for
-   options given in OPTS.
-
-   Return the option character from OPTS just read.  Return -1 when
-   there are no more options.  For unrecognized options, or options
-   missing arguments, 'optopt' is set to the option letter, and '?' is
-   returned.
-
-   The OPTS string is a list of characters which are recognized option
-   letters, optionally followed by colons, specifying that that letter
-   takes an argument, to be placed in 'optarg'.
-
-   If a letter in OPTS is followed by two colons, its argument is
-   optional.  This behavior is specific to the GNU 'getopt'.
-
-   The argument '--' causes premature termination of argument
-   scanning, explicitly telling 'getopt' that there are no more
-   options.
-
-   If OPTS begins with '-', then non-option arguments are treated as
-   arguments to the option '\1'.  This behavior is specific to the GNU
-   'getopt'.  If OPTS begins with '+', or POSIXLY_CORRECT is set in
-   the environment, then do not permute arguments.  */
-
-extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
-       __THROW _GL_ARG_NONNULL ((2, 3));
-
-#ifndef __GETOPT_PREFIX
-# if defined __need_getopt && defined __USE_POSIX2 \
-  && !defined __USE_POSIX_IMPLICITLY && !defined __USE_GNU
-/* The GNU getopt has more functionality than the standard version.  The
-   additional functionality can be disable at runtime.  This redirection
-   helps to also do this at runtime.  */
-#  ifdef __REDIRECT
-  extern int __REDIRECT_NTH (getopt, (int ___argc, char *const *___argv,
-                                     const char *__shortopts),
-                            __posix_getopt);
-#  else
-extern int __posix_getopt (int ___argc, char *const *___argv,
-                          const char *__shortopts)
-  __THROW _GL_ARG_NONNULL ((2, 3));
-#   define getopt __posix_getopt
-#  endif
-# endif
-#endif
-
-#ifndef __need_getopt
-extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
-                        const char *__shortopts,
-                        const struct option *__longopts, int *__longind)
-       __THROW _GL_ARG_NONNULL ((2, 3));
-extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv,
-                             const char *__shortopts,
-                             const struct option *__longopts, int *__longind)
-       __THROW _GL_ARG_NONNULL ((2, 3));
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-/* Make sure we later can get all the definitions and declarations.  */
-#undef __need_getopt
-
-#endif /* _@GUARD_PREFIX@_GETOPT_H */
 #endif /* _@GUARD_PREFIX@_GETOPT_H */
diff --git a/lib/getopt_cdefs.in.h b/lib/getopt_cdefs.in.h
new file mode 100644 (file)
index 0000000..35a2669
--- /dev/null
@@ -0,0 +1,75 @@
+/* getopt-on-non-glibc compatibility macros.
+   Copyright (C) 1989-2017 Free Software Foundation, Inc.
+   This file is part of gnulib.
+   Unlike most of the getopt implementation, it is NOT shared
+   with the GNU C Library.
+
+   gnulib is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+
+   gnulib is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with gnulib; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GETOPT_CDEFS_H
+#define _GETOPT_CDEFS_H 1
+
+/* This header should not be used directly; include getopt.h or
+   unistd.h instead.  It does not have a protective #error, because
+   the guard macro for getopt.h in gnulib is not fixed.  */
+
+/* getopt_core.h and getopt_ext.h are shared with GNU libc, and expect
+   a number of the internal macros supplied to GNU libc's headers by
+   sys/cdefs.h.  Provide fallback definitions for all of them.  */
+#if @HAVE_SYS_CDEFS_H@
+# include <sys/cdefs.h>
+#endif
+
+#ifndef __BEGIN_DECLS
+# ifdef __cplusplus
+#  define __BEGIN_DECLS extern "C" {
+# else
+#  define __BEGIN_DECLS /* nothing */
+# endif
+#endif
+#ifndef __END_DECLS
+# ifdef __cplusplus
+#  define __END_DECLS }
+# else
+#  define __END_DECLS /* nothing */
+# endif
+#endif
+
+#ifndef __GNUC_PREREQ
+# if defined __GNUC__ && defined __GNUC_VERSION__
+# define __GNUC_PREREQ(maj, min) \
+        ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+# else
+#  define __GNUC_PREREQ(maj, min) 0
+# endif
+#endif
+
+#ifndef __THROW
+# if defined __cplusplus && __GNUC_PREREQ (2,8)
+#  define __THROW       throw ()
+# else
+#  define __THROW
+# endif
+#endif
+
+#ifndef __nonnull
+# if __GNUC_PREREQ (3,3)
+#  define __nonnull(params) __attribute__ ((__nonnull__ params))
+# else
+#  define __nonnull(params)
+# endif
+#endif
+
+#endif /* getopt_cdefs.h */
diff --git a/lib/getopt_core.h b/lib/getopt_core.h
new file mode 100644 (file)
index 0000000..1744c29
--- /dev/null
@@ -0,0 +1,96 @@
+/* Declarations for getopt (basic, portable features only).
+   Copyright (C) 1989-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library and is also part of gnulib.
+   Patches to this file should be submitted to both projects.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GETOPT_CORE_H
+#define _GETOPT_CORE_H 1
+
+/* This header should not be used directly; include getopt.h or
+   unistd.h instead.  Unlike most bits headers, it does not have
+   a protective #error, because the guard macro for getopt.h in
+   gnulib is not fixed.  */
+
+__BEGIN_DECLS
+
+/* For communication from 'getopt' to the caller.
+   When 'getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when 'ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to 'getopt'.
+
+   On entry to 'getopt', zero means this is the first call; initialize.
+
+   When 'getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, 'optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message 'getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+/* Get definitions and prototypes for functions to process the
+   arguments in ARGV (ARGC of them, minus the program name) for
+   options given in OPTS.
+
+   Return the option character from OPTS just read.  Return -1 when
+   there are no more options.  For unrecognized options, or options
+   missing arguments, 'optopt' is set to the option letter, and '?' is
+   returned.
+
+   The OPTS string is a list of characters which are recognized option
+   letters, optionally followed by colons, specifying that that letter
+   takes an argument, to be placed in 'optarg'.
+
+   If a letter in OPTS is followed by two colons, its argument is
+   optional.  This behavior is specific to the GNU 'getopt'.
+
+   The argument '--' causes premature termination of argument
+   scanning, explicitly telling 'getopt' that there are no more
+   options.
+
+   If OPTS begins with '-', then non-option arguments are treated as
+   arguments to the option '\1'.  This behavior is specific to the GNU
+   'getopt'.  If OPTS begins with '+', or POSIXLY_CORRECT is set in
+   the environment, then do not permute arguments.
+
+   For standards compliance, the 'argv' argument has the type
+   char *const *, but this is inaccurate; if argument permutation is
+   enabled, the argv array (not the strings it points to) must be
+   writable.  */
+
+extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
+       __THROW __nonnull ((2, 3));
+
+__END_DECLS
+
+#endif /* getopt_core.h */
diff --git a/lib/getopt_ext.h b/lib/getopt_ext.h
new file mode 100644 (file)
index 0000000..c1a58da
--- /dev/null
@@ -0,0 +1,77 @@
+/* Declarations for getopt (GNU extensions).
+   Copyright (C) 1989-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library and is also part of gnulib.
+   Patches to this file should be submitted to both projects.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GETOPT_EXT_H
+#define _GETOPT_EXT_H 1
+
+/* This header should not be used directly; include getopt.h instead.
+   Unlike most bits headers, it does not have a protective #error,
+   because the guard macro for getopt.h in gnulib is not fixed.  */
+
+__BEGIN_DECLS
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of 'struct option' terminated by an element containing a name which is
+   zero.
+
+   The field 'has_arg' is:
+   no_argument         (or 0) if the option does not take an argument,
+   required_argument   (or 1) if the option requires an argument,
+   optional_argument   (or 2) if the option takes an optional argument.
+
+   If the field 'flag' is not NULL, it points to a variable that is set
+   to the value given in the field 'val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an 'int' to
+   a compiled-in constant, such as set a value from 'optarg', set the
+   option's 'flag' field to zero and its 'val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero 'flag' field, 'getopt'
+   returns the contents of the 'val' field.  */
+
+struct option
+{
+  const char *name;
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the 'has_arg' field of 'struct option'.  */
+
+#define no_argument            0
+#define required_argument      1
+#define optional_argument      2
+
+extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
+                       const char *__shortopts,
+                       const struct option *__longopts, int *__longind)
+       __THROW __nonnull ((2, 3));
+extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv,
+                            const char *__shortopts,
+                            const struct option *__longopts, int *__longind)
+       __THROW __nonnull ((2, 3));
+
+__END_DECLS
+
+#endif /* getopt_ext.h */
diff --git a/lib/getopt_pfx_core.h b/lib/getopt_pfx_core.h
new file mode 100644 (file)
index 0000000..b730d2d
--- /dev/null
@@ -0,0 +1,54 @@
+/* getopt (basic, portable features) gnulib wrapper header.
+   Copyright (C) 1989-2017 Free Software Foundation, Inc.
+   This file is part of gnulib.
+   Unlike most of the getopt implementation, it is NOT shared
+   with the GNU C Library.
+
+   gnulib is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+
+   gnulib is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with gnulib; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GETOPT_PFX_CORE_H
+#define _GETOPT_PFX_CORE_H 1
+
+/* This header should not be used directly; include getopt.h or
+   unistd.h instead.  It does not have a protective #error, because
+   the guard macro for getopt.h in gnulib is not fixed.  */
+
+/* Standalone applications should #define __GETOPT_PREFIX to an
+   identifier that prefixes the external functions and variables
+   defined in getopt_core.h and getopt_ext.h.  Systematically
+   rename identifiers so that they do not collide with the system
+   functions and variables.  Renaming avoids problems with some
+   compilers and linkers.  */
+#ifdef __GETOPT_PREFIX
+# ifndef __GETOPT_ID
+#  define __GETOPT_CONCAT(x, y) x ## y
+#  define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
+#  define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
+# endif
+# undef getopt
+# undef optarg
+# undef opterr
+# undef optind
+# undef optopt
+# define getopt __GETOPT_ID (getopt)
+# define optarg __GETOPT_ID (optarg)
+# define opterr __GETOPT_ID (opterr)
+# define optind __GETOPT_ID (optind)
+# define optopt __GETOPT_ID (optopt)
+#endif
+
+#include <getopt_core.h>
+
+#endif /* getopt_pfx_core.h */
diff --git a/lib/getopt_pfx_ext.h b/lib/getopt_pfx_ext.h
new file mode 100644 (file)
index 0000000..8c1691a
--- /dev/null
@@ -0,0 +1,64 @@
+/* getopt (GNU extensions) gnulib wrapper header.
+   Copyright (C) 1989-2017 Free Software Foundation, Inc.
+   This file is part of gnulib.
+   Unlike most of the getopt implementation, it is NOT shared
+   with the GNU C Library.
+
+   gnulib is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+
+   gnulib is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with gnulib; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GETOPT_PFX_EXT_H
+#define _GETOPT_PFX_EXT_H 1
+
+/* This header should not be used directly; include getopt.h instead.
+   It does not have a protective #error, because the guard macro for
+   getopt.h in gnulib is not fixed.  */
+
+/* Standalone applications should #define __GETOPT_PREFIX to an
+   identifier that prefixes the external functions and variables
+   defined in getopt_core.h and getopt_ext.h.  Systematically
+   rename identifiers so that they do not collide with the system
+   functions and variables.  Renaming avoids problems with some
+   compilers and linkers.  */
+#ifdef __GETOPT_PREFIX
+# ifndef __GETOPT_ID
+#  define __GETOPT_CONCAT(x, y) x ## y
+#  define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
+#  define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
+# endif
+# undef getopt_long
+# undef getopt_long_only
+# undef option
+# define getopt_long __GETOPT_ID (getopt_long)
+# define getopt_long_only __GETOPT_ID (getopt_long_only)
+# define option __GETOPT_ID (option)
+#endif
+
+/* Standalone applications get correct prototypes for getopt_long and
+   getopt_long_only; they declare "char **argv".  For backward
+   compatibility with old applications, if __GETOPT_PREFIX is not
+   defined, we supply GNU-libc-compatible, but incorrect, prototypes
+   using "char *const *argv".  (GNU libc is stuck with the incorrect
+   prototypes, as they are baked into older versions of LSB.)  */
+#ifndef __getopt_argv_const
+# if defined __GETOPT_PREFIX
+#  define __getopt_argv_const /* empty */
+# else
+#  define __getopt_argv_const const
+# endif
+#endif
+
+#include <getopt_ext.h>
+
+#endif /* getopt_pfx_ext.h */
index 29706524ae14d89c69c671fe915acfa665970eef..38a0f0a9fc0b94c54c5ee8d94688c2e65707a747 100644 (file)
 /* Get getopt(), optarg, optind, opterr, optopt.
    But avoid namespace pollution on glibc systems.  */
 #if @GNULIB_UNISTD_H_GETOPT@ && !defined __GLIBC__ && !defined _GL_SYSTEM_GETOPT
-# define __need_getopt
-# include <getopt.h>
+# include <getopt_cdefs.h>
+# include <getopt_pfx_core.h>
 #endif
 
 #ifndef _GL_INLINE_HEADER_BEGIN
index f23d27b4144596f02714a402a67b1983d98cc087..139a814c6b7be454cac2da02c93617613a833a9d 100644 (file)
@@ -354,9 +354,19 @@ dnl is ambiguous with environment values that contain newlines.
 
 AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER],
 [
-  GETOPT_H=getopt.h
+  AC_CHECK_HEADERS_ONCE([sys/cdefs.h])
+  if test $ac_cv_header_sys_cdefs_h = yes; then
+    HAVE_SYS_CDEFS_H=1
+  else
+    HAVE_SYS_CDEFS_H=0
+  fi
+  AC_SUBST([HAVE_SYS_CDEFS_H])
+
   AC_DEFINE([__GETOPT_PREFIX], [[rpl_]],
     [Define to rpl_ if the getopt replacement functions and variables
      should be used.])
+  GETOPT_H=getopt.h
+  GETOPT_CDEFS_H=getopt_cdefs.h
   AC_SUBST([GETOPT_H])
+  AC_SUBST([GETOPT_CDEFS_H])
 ])
index 642fc56e0b8004db095f92d280f3de1910233c72..5844217ae5556f05753be941397495165f4fc02c 100644 (file)
@@ -2,17 +2,21 @@ Description:
 getopt() function: process command line arguments.
 
 Files:
-lib/getopt.in.h
 lib/getopt.c
 lib/getopt1.c
+lib/getopt.in.h
+lib/getopt_cdefs.in.h
+lib/getopt_core.h
+lib/getopt_ext.h
 lib/getopt_int.h
+lib/getopt_pfx_core.h
+lib/getopt_pfx_ext.h
 m4/getopt.m4
 
 Depends-on:
 unistd
 extensions
 include_next
-snippet/arg-nonnull
 gettext-h       [test $REPLACE_GETOPT = 1]
 
 configure.ac:
@@ -26,11 +30,11 @@ fi
 AC_SUBST([GNULIB_${gl_include_guard_prefix}_UNISTD_H_GETOPT])
 
 Makefile.am:
-BUILT_SOURCES += $(GETOPT_H)
+BUILT_SOURCES += $(GETOPT_H) $(GETOPT_CDEFS_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 $(top_builddir)/config.status $(ARG_NONNULL_H)
+getopt.h: getopt.in.h $(top_builddir)/config.status
        $(AM_V_GEN)rm -f $@-t $@ && \
        { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
          sed -e 's|@''GUARD_PREFIX''@|${gl_include_guard_prefix}|g' \
@@ -39,11 +43,19 @@ getopt.h: getopt.in.h $(top_builddir)/config.status $(ARG_NONNULL_H)
              -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
              -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
              -e 's|@''NEXT_GETOPT_H''@|$(NEXT_GETOPT_H)|g' \
-             -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
              < $(srcdir)/getopt.in.h; \
        } > $@-t && \
        mv -f $@-t $@
-MOSTLYCLEANFILES += getopt.h getopt.h-t
+
+getopt_cdefs.h: getopt_cdefs.in.h $(top_builddir)/config.status
+       $(AM_V_GEN)rm -f $@-t $@ && \
+       { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+          sed -e 's|@''HAVE_SYS_CDEFS_H''@|$(HAVE_SYS_CDEFS_H)|g' \
+             < $(srcdir)/getopt_cdefs.in.h; \
+       } > $@-t && \
+       mv -f $@-t $@
+
+MOSTLYCLEANFILES += getopt.h getopt.h-t getopt_cdefs.h getopt_cdefs.h-t
 
 Include:
 <unistd.h>