]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
getopt: merge from gnulib: function prototype adjustments
authorZack Weinberg <zackw@panix.com>
Sat, 1 Apr 2017 16:11:33 +0000 (12:11 -0400)
committerZack Weinberg <zackw@panix.com>
Fri, 7 Apr 2017 11:50:06 +0000 (07:50 -0400)
For standards compliance, getopt, getopt_long, and getopt_long_only in
glibc have to take 'char *const *argv' even though they can mutate the
array.  gnulib has tried to clean this up as much as possible: all the
internal functions use 'char **argv', and when used standalone, so do
getopt_long and getopt_long_only.

Also brought over are __nonnull annotations, corrections to documentation,
and apparently it is no longer necessary to worry about conflicting
prototypes for getopt.  The macroification of the definitions of
getopt and __posix_getopt goes beyond what is currently in gnulib.

At this point getopt1.c and getopt_int.h are identical to their gnulib
versions.

* posix/getopt.h: Add backup definition of __nonnull for
consistency with gnulib.  Define __getopt_argv_const to const
if not already defined.
(getopt): Update doc comment from gnulib.  Prototype
unconditionally.  Add __nonnull annotation.
(__posix_getopt): Add __nonnull annotation.
(getopt_long, getopt_long_only): Use __getopt_argv_const in
prototypes for consistency with gnulib.  Add __nonnull
annotations.
* posix/getopt.c (_getopt_initialize, _getopt_internal_r)
(getopt_internal): Change 'argv' argument to type 'char **'.
Remove now-unnecessary casts.
(getopt, __posix_getopt): Eliminate repetition with a macro.
Cast 'argv' to 'char **' when calling _getopt_internal.
* posix/getopt1.c (getopt_long, getopt_long_only):
Use __getopt_argv_const for consistency with gnulib.
Cast 'argv' to 'char **' when calling _getopt_internal.
(_getopt_long_r, _getopt_long_only_r):
Change 'argv' argument to type 'char **'.
(main): Constify 'long_options'.
* posix/getopt_int.h (getopt_internal, _getopt_internal_r)
(_getopt_long_r, _getopt_long_only_r):
Change 'argv' argument to type 'char **'.

ChangeLog
posix/getopt.c
posix/getopt.h
posix/getopt1.c
posix/getopt_int.h

index d45be5fedd01a2786bea297cd0827a821f82bb26..e2587267b77b70898ed75a081dbce7a5a29a3867 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
 2017-04-07  Zack Weinberg  <zackw@panix.com>
 
+       * posix/getopt.h: Add backup definition of __nonnull for
+       consistency with gnulib.  Define __getopt_argv_const to const
+       if not already defined.
+       (getopt): Update doc comment from gnulib.  Prototype
+       unconditionally.  Add __nonnull annotation.
+       (__posix_getopt): Add __nonnull annotation.
+       (getopt_long, getopt_long_only): Use __getopt_argv_const in
+       prototypes for consistency with gnulib.  Add __nonnull
+       annotations.
+       * posix/getopt.c (_getopt_initialize, _getopt_internal_r)
+       (getopt_internal): Change 'argv' argument to type 'char **'.
+       Remove now-unnecessary casts.
+       (getopt, __posix_getopt): Eliminate repetition with a macro.
+       Cast 'argv' to 'char **' when calling _getopt_internal.
+       * posix/getopt1.c (getopt_long, getopt_long_only):
+       Use __getopt_argv_const for consistency with gnulib.
+       Cast 'argv' to 'char **' when calling _getopt_internal.
+       (_getopt_long_r, _getopt_long_only_r):
+       Change 'argv' argument to type 'char **'.
+       (main): Constify 'long_options'.
+       * posix/getopt_int.h (getopt_internal, _getopt_internal_r)
+       (_getopt_long_r, _getopt_long_only_r):
+       Change 'argv' argument to type 'char **'.
+
        * stdio-common/fxprintf.c (__fxprintf_nocancel): New function.
        (locked_vfxprintf): New helper function. Handle arbitrary
        multibyte strings, not just ASCII.
index 248fe5b03a4f26e6323b6b3898e67e507a340614..f54bc2d1cfe3971d7b7753616f49704e042e769b 100644 (file)
@@ -182,7 +182,7 @@ exchange (char **argv, struct _getopt_data *d)
 /* Initialize the internal data when the first call is made.  */
 
 static const char *
-_getopt_initialize (int argc, char *const *argv, const char *optstring,
+_getopt_initialize (int argc, char **argv, const char *optstring,
                    struct _getopt_data *d, int posixly_correct)
 {
   /* Start processing options with ARGV-element 1 (since ARGV-element 0
@@ -272,7 +272,7 @@ _getopt_initialize (int argc, char *const *argv, const char *optstring,
    long-named options.  */
 
 int
-_getopt_internal_r (int argc, char *const *argv, const char *optstring,
+_getopt_internal_r (int argc, char **argv, const char *optstring,
                    const struct option *longopts, int *longind,
                    int long_only, struct _getopt_data *d, int posixly_correct)
 {
@@ -317,7 +317,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 
          if (d->__first_nonopt != d->__last_nonopt
              && d->__last_nonopt != d->optind)
-           exchange ((char **) argv, d);
+           exchange (argv, d);
          else if (d->__last_nonopt != d->optind)
            d->__first_nonopt = d->optind;
 
@@ -340,7 +340,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 
          if (d->__first_nonopt != d->__last_nonopt
              && d->__last_nonopt != d->optind)
-           exchange ((char **) argv, d);
+           exchange (argv, d);
          else if (d->__first_nonopt == d->__last_nonopt)
            d->__first_nonopt = d->optind;
          d->__last_nonopt = argc;
@@ -766,7 +766,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring,
 }
 
 int
-_getopt_internal (int argc, char *const *argv, const char *optstring,
+_getopt_internal (int argc, char **argv, const char *optstring,
                  const struct option *longopts, int *longind, int long_only,
                  int posixly_correct)
 {
@@ -786,32 +786,23 @@ _getopt_internal (int argc, char *const *argv, const char *optstring,
   return result;
 }
 
-/* glibc gets a LSB-compliant getopt.
-   Standalone applications get a POSIX-compliant getopt.  */
-#if _LIBC
-enum { POSIXLY_CORRECT = 0 };
-#else
-enum { POSIXLY_CORRECT = 1 };
-#endif
-
-int
-getopt (int argc, char *const *argv, const char *optstring)
-{
-  return _getopt_internal (argc, argv, optstring,
-                          (const struct option *) 0,
-                          (int *) 0,
-                          0, POSIXLY_CORRECT);
-}
+/* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt.
+   Standalone applications just get a POSIX-compliant getopt.
+   POSIX and LSB both require these functions to take 'char *const *argv'
+   even though this is incorrect (because of the permutation).  */
+#define GETOPT_ENTRY(NAME, POSIXLY_CORRECT)                    \
+  int                                                          \
+  NAME (int argc, char *const *argv, const char *optstring)    \
+  {                                                            \
+    return _getopt_internal (argc, (char **)argv, optstring,   \
+                            0, 0, 0, POSIXLY_CORRECT);         \
+  }
 
 #ifdef _LIBC
-int
-__posix_getopt (int argc, char *const *argv, const char *optstring)
-{
-  return _getopt_internal (argc, argv, optstring,
-                          (const struct option *) 0,
-                          (int *) 0,
-                          0, 1);
-}
+GETOPT_ENTRY(getopt, 0)
+GETOPT_ENTRY(__posix_getopt, 1)
+#else
+GETOPT_ENTRY(getopt, 1)
 #endif
 
 \f
index c83a186bebb58125eb58b436ad762995f0139d23..fa6aa6be3837d118d423f63731c72f6489b9c698 100644 (file)
 # include <ctype.h>
 #endif
 
+#ifndef __GNUC_PREREQ
+# define __GNUC_PREREQ(maj, min) (0)
+#endif
+
 #ifndef __THROW
-# ifndef __GNUC_PREREQ
-#  define __GNUC_PREREQ(maj, min) (0)
-# endif
 # if defined __cplusplus && __GNUC_PREREQ (2,8)
 #  define __THROW      throw ()
 # else
 # endif
 #endif
 
+#ifndef __nonnull
+# if __GNUC_PREREQ (3, 3)
+#  define __nonnull(params) __attribute__ ((__nonnull__ params))
+# else
+#  define __nonnull(params)
+# endif
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -139,45 +148,55 @@ struct option
    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 '\0'.  This behavior is specific to the GNU
-   'getopt'.  */
+   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.  */
 
-#ifdef __GNU_LIBRARY__
-/* Many other libraries have conflicting prototypes for getopt, with
-   differences in the consts, in stdlib.h.  To avoid compilation
-   errors, only prototype getopt for the GNU C library.  */
 extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
-       __THROW;
+       __THROW __nonnull ((2, 3));
 
-# if defined __need_getopt && defined __USE_POSIX2 \
-  && !defined __USE_POSIX_IMPLICITLY && !defined __USE_GNU
+#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
+# ifdef __REDIRECT
   extern int __REDIRECT_NTH (getopt, (int ___argc, char *const *___argv,
                                      const char *__shortopts),
                             __posix_getopt);
-#  else
+# else
 extern int __posix_getopt (int ___argc, char *const *___argv,
-                          const char *__shortopts) __THROW;
-#   define getopt __posix_getopt
-#  endif
+                          const char *__shortopts)
+  __THROW __nonnull ((2, 3));
+#  define getopt __posix_getopt
 # endif
-#else /* not __GNU_LIBRARY__ */
-extern int getopt ();
-#endif /* __GNU_LIBRARY__ */
+#endif
 
 #ifndef __need_getopt
-extern int getopt_long (int ___argc, char *const *___argv,
+
+/* The type of the 'argv' argument to getopt_long and getopt_long_only
+   is properly 'char **', since both functions may write to the array
+   (in order to move all the options to the beginning).  However, for
+   compatibility with old versions of LSB, glibc has to use 'char *const *'
+   instead.  */
+#ifndef __getopt_argv_const
+# define __getopt_argv_const const
+#endif
+
+extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
                        const char *__shortopts,
                        const struct option *__longopts, int *__longind)
-       __THROW;
-extern int getopt_long_only (int ___argc, char *const *___argv,
+  __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;
+  __THROW __nonnull ((2, 3));
 
 #endif
 
index b4ae6e48f2bb5bc7127af4ed6e15cd9ce7de58d1..b967d24f57be12cca2b8fff84854c838da80ddbd 100644 (file)
 #include "getopt_int.h"
 
 int
-getopt_long (int argc, char *const *argv, const char *options,
+getopt_long (int argc, char *__getopt_argv_const *argv, const char *options,
             const struct option *long_options, int *opt_index)
 {
-  return _getopt_internal (argc, argv, options, long_options, opt_index, 0, 0);
+  return _getopt_internal (argc, (char **) argv, options, long_options,
+                          opt_index, 0, 0);
 }
 
 int
-_getopt_long_r (int argc, char *const *argv, const char *options,
+_getopt_long_r (int argc, char **argv, const char *options,
                const struct option *long_options, int *opt_index,
                struct _getopt_data *d)
 {
@@ -45,14 +46,16 @@ _getopt_long_r (int argc, char *const *argv, const char *options,
    instead.  */
 
 int
-getopt_long_only (int argc, char *const *argv, const char *options,
+getopt_long_only (int argc, char *__getopt_argv_const *argv,
+                 const char *options,
                  const struct option *long_options, int *opt_index)
 {
-  return _getopt_internal (argc, argv, options, long_options, opt_index, 1, 0);
+  return _getopt_internal (argc, (char **) argv, options, long_options,
+                          opt_index, 1, 0);
 }
 
 int
-_getopt_long_only_r (int argc, char *const *argv, const char *options,
+_getopt_long_only_r (int argc, char **argv, const char *options,
                     const struct option *long_options, int *opt_index,
                     struct _getopt_data *d)
 {
@@ -76,7 +79,7 @@ main (int argc, char **argv)
     {
       int this_option_optind = optind ? optind : 1;
       int option_index = 0;
-      static struct option long_options[] =
+      static const struct option long_options[] =
       {
        {"add", 1, 0, 0},
        {"append", 0, 0, 0},
index 9ac03bdaaf89a572a6f83466d36ca0dd642f37bd..762679a30598b9c8a128abf6f7abaa626886f5a4 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <getopt.h>
 
-extern int _getopt_internal (int ___argc, char *const *___argv,
+extern int _getopt_internal (int ___argc, char **___argv,
                             const char *__shortopts,
                             const struct option *__longopts, int *__longind,
                             int __long_only, int __posixly_correct);
@@ -101,18 +101,18 @@ struct _getopt_data
    default values and to clear the initialization flag.  */
 #define _GETOPT_DATA_INITIALIZER       { 1, 1 }
 
-extern int _getopt_internal_r (int ___argc, char *const *___argv,
+extern int _getopt_internal_r (int ___argc, char **___argv,
                               const char *__shortopts,
                               const struct option *__longopts, int *__longind,
                               int __long_only, struct _getopt_data *__data,
                               int __posixly_correct);
 
-extern int _getopt_long_r (int ___argc, char *const *___argv,
+extern int _getopt_long_r (int ___argc, char **___argv,
                           const char *__shortopts,
                           const struct option *__longopts, int *__longind,
                           struct _getopt_data *__data);
 
-extern int _getopt_long_only_r (int ___argc, char *const *___argv,
+extern int _getopt_long_only_r (int ___argc, char **___argv,
                                const char *__shortopts,
                                const struct option *__longopts,
                                int *__longind,