From 7f71f9c1d6735e713de193faf03edb37c4bcb563 Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Fri, 31 Mar 2017 07:58:07 -0400 Subject: [PATCH] getopt: merge straightforward changes from gnulib This covers changes with little or no consequences when the code is used in glibc. * posix/getopt_int.h: Include getopt.h. Use impl-namespace names for all arguments to _getopt_internal and _getopt_internal_r. Declare __ordering enum outside the struct. Harmonize comments with gnulib. * posix/getopt1.c: Simplify #ifdeffage at top of file. Remove ELIDE_CODE logic entirely. Move inclusion of stdlib.h to #ifdef TEST block and make unconditional. Do not define NULL. * posix/getopt.c: Partial merge from gnulib, covering the initial includes and global declarations, commentary, and a couple of semantically-neutral code changes. --- ChangeLog | 12 +++++ posix/getopt.c | 122 +++++++++++++++------------------------------ posix/getopt1.c | 43 ++-------------- posix/getopt_int.h | 73 +++++++++++++-------------- 4 files changed, 92 insertions(+), 158 deletions(-) diff --git a/ChangeLog b/ChangeLog index c53c80ec6f..ba702c0efd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2017-04-07 Zack Weinberg + * posix/getopt_int.h: Include getopt.h. + Use impl-namespace names for all arguments to _getopt_internal and + _getopt_internal_r. + Declare __ordering enum outside the struct. + Harmonize comments with gnulib. + * posix/getopt1.c: Simplify #ifdeffage at top of file. Remove + ELIDE_CODE logic entirely. Move inclusion of stdlib.h to + #ifdef TEST block and make unconditional. Do not define NULL. + * posix/getopt.c: Partial merge from gnulib, covering the + initial includes and global declarations, commentary, and + a couple of semantically-neutral code changes. + * posix/getopt.c, posix/getopt.h, posix/getopt1.c, posix/getopt_int.h: Use '...' instead of `...' for quotation marks inside comments and strings. diff --git a/posix/getopt.c b/posix/getopt.c index ac2b0cfa93..f1fa0166d8 100644 --- a/posix/getopt.c +++ b/posix/getopt.c @@ -19,52 +19,17 @@ License along with the GNU C Library; if not, see . */ -/* This tells Alpha OSF/1 not to define a getopt prototype in . - Ditto for AIX 3.2 and . */ -#ifndef _NO_PROTO -# define _NO_PROTO -#endif - -#ifdef HAVE_CONFIG_H +#ifndef _LIBC # include #endif -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand 'configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#define GETOPT_INTERFACE_VERSION 2 -#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 -# include -# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION -# define ELIDE_CODE -# endif -#endif - -#ifndef ELIDE_CODE - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ -# include -# include -#endif /* GNU C library. */ +#include "getopt.h" +#include +#include +#include #include -#ifdef VMS -# include -#endif - #ifdef _LIBC # include #else @@ -72,29 +37,28 @@ # define _(msgid) gettext (msgid) #endif -#if defined _LIBC -# include -#endif - -#ifndef attribute_hidden -# define attribute_hidden -#endif - -/* This version of 'getopt' appears to the caller like standard Unix 'getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As 'getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. +/* This implementation of 'getopt' has three modes for handling + options interspersed with non-option arguments. It can stop + scanning for options at the first non-option argument encountered, + as POSIX specifies. It can continue scanning for options after the + first non-option argument, but permute 'argv' as it goes so that, + after 'getopt' is done, all the options precede all the non-option + arguments and 'optind' points to the first non-option argument. + Or, it can report non-option arguments as if they were arguments to + the option character '\x01'. + + The default behavior of 'getopt_long' is to permute the argument list. + When this implementation is used standalone, the default behavior of + 'getopt' is to stop at the first non-option argument, but when it is + used as part of GNU libc it also permutes the argument list. In both + cases, setting the environment variable POSIXLY_CORRECT to any value + disables permutation. + + If the first character of the OPTSTRING argument to 'getopt' or + 'getopt_long' is '+', both functions will stop at the first + non-option argument. If it is '-', both functions will report + non-option arguments as arguments to the option character '\x01'. */ - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "getopt.h" #include "getopt_int.h" /* For communication from 'getopt' to the caller. @@ -135,17 +99,6 @@ int optopt = '?'; static struct _getopt_data getopt_data; - -#ifndef __GNU_LIBRARY__ - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -#ifndef getenv -extern char *getenv (); -#endif - -#endif /* not __GNU_LIBRARY__ */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) @@ -225,7 +178,7 @@ _getopt_initialize (int argc, char *const *argv, const char *optstring, d->__nextchar = NULL; - d->__posixly_correct = posixly_correct | !!getenv ("POSIXLY_CORRECT"); + d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ @@ -731,7 +684,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, { char c = *d->__nextchar++; - char *temp = strchr (optstring, c); + const char *temp = strchr (optstring, c); /* Increment 'optind' when we start to process its last character. */ if (*d->__nextchar == '\0') @@ -776,9 +729,6 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { - if (longopts == NULL) - goto no_longs; - char *nameend; const struct option *p; const struct option *pfound = NULL; @@ -787,6 +737,9 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, int indfound = 0; int option_index; + if (longopts == NULL) + goto no_longs; + /* This is an option that requires an argument. */ if (*d->__nextchar != '\0') { @@ -997,7 +950,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, no_longs: d->__nextchar = NULL; - return 'W'; /* Let the application handle it. */ + return 'W'; /* Let the application handle it. */ } if (temp[1] == ':') { @@ -1090,13 +1043,21 @@ _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, 0); + 0, POSIXLY_CORRECT); } #ifdef _LIBC @@ -1110,7 +1071,6 @@ __posix_getopt (int argc, char *const *argv, const char *optstring) } #endif -#endif /* Not ELIDE_CODE. */ #ifdef TEST diff --git a/posix/getopt1.c b/posix/getopt1.c index b9a853804a..b4ae6e48f2 100644 --- a/posix/getopt1.c +++ b/posix/getopt1.c @@ -16,48 +16,13 @@ License along with the GNU C Library; if not, see . */ -#ifdef HAVE_CONFIG_H -#include +#ifndef _LIBC +#include "config.h" #endif -#ifdef _LIBC -# include -#else -# include "getopt.h" -#endif +#include "getopt.h" #include "getopt_int.h" -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand 'configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#define GETOPT_INTERFACE_VERSION 2 -#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 -#include -#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION -#define ELIDE_CODE -#endif -#endif - -#ifndef ELIDE_CODE - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#endif - -#ifndef NULL -#define NULL 0 -#endif - int getopt_long (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index) @@ -95,11 +60,11 @@ _getopt_long_only_r (int argc, char *const *argv, const char *options, 1, d, 0); } -#endif /* Not ELIDE_CODE. */ #ifdef TEST #include +#include int main (int argc, char **argv) diff --git a/posix/getopt_int.h b/posix/getopt_int.h index ac6ddefac3..9ac03bdaaf 100644 --- a/posix/getopt_int.h +++ b/posix/getopt_int.h @@ -19,15 +19,43 @@ #ifndef _GETOPT_INT_H #define _GETOPT_INT_H 1 +#include + extern int _getopt_internal (int ___argc, char *const *___argv, const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only, int posixly_correct); + const struct option *__longopts, int *__longind, + int __long_only, int __posixly_correct); /* Reentrant versions which can handle parsing multiple argument vectors at the same time. */ +/* Describe how to deal with options that follow non-option ARGV-elements. + + REQUIRE_ORDER means don't recognize them as options; stop option + processing when the first non-option is seen. This is what POSIX + specifies should happen. + + PERMUTE means permute the contents of ARGV as we scan, so that + eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written + to expect this. + + RETURN_IN_ORDER is an option available to programs that were + written to expect options and other ARGV-elements in any order + and that care about the ordering of the two. We describe each + non-option ARGV-element as if it were the argument of an option + with character code 1. + + The special argument '--' forces an end of option-scanning regardless + of the value of 'ordering'. In the case of RETURN_IN_ORDER, only + '--' can cause 'getopt' to return -1 with 'optind' != ARGC. */ + +enum __ord + { + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER + }; + /* Data type for reentrant functions. */ struct _getopt_data { @@ -52,41 +80,10 @@ struct _getopt_data by advancing to the next ARGV-element. */ char *__nextchar; - /* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using '+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we - scan, so that eventually all the non-options are at the end. - This allows options to be given in any order, even with programs - that were not written to expect this. - - RETURN_IN_ORDER is an option available to programs that were - written to expect options and other ARGV-elements in any order - and that care about the ordering of the two. We describe each - non-option ARGV-element as if it were the argument of an option - with character code 1. Using '-' as the first character of the - list of option characters selects this mode of operation. - - The special argument '--' forces an end of option-scanning regardless - of the value of 'ordering'. In the case of RETURN_IN_ORDER, only - '--' can cause 'getopt' to return -1 with 'optind' != ARGC. */ - - enum - { - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER - } __ordering; - - /* If the POSIXLY_CORRECT environment variable is set. */ + /* See __ord above. */ + enum __ord __ordering; + + /* True if behaving strictly as specified by POSIX. */ int __posixly_correct; @@ -108,7 +105,7 @@ extern int _getopt_internal_r (int ___argc, char *const *___argv, const char *__shortopts, const struct option *__longopts, int *__longind, int __long_only, struct _getopt_data *__data, - int posixly_correct); + int __posixly_correct); extern int _getopt_long_r (int ___argc, char *const *___argv, const char *__shortopts, -- 2.43.5