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.
This commit is contained in:
Zack Weinberg 2017-03-31 07:58:07 -04:00
parent 7784135eb0
commit 7f71f9c1d6
4 changed files with 89 additions and 155 deletions

View File

@ -1,5 +1,17 @@
2017-04-07 Zack Weinberg <zackw@panix.com>
* 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.

View File

@ -19,52 +19,17 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
#ifndef _NO_PROTO
# define _NO_PROTO
#endif
#ifdef HAVE_CONFIG_H
#ifndef _LIBC
# include <config.h>
#endif
#include "getopt.h"
#include <stdio.h>
/* 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 <gnu-versions.h>
# 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 <stdlib.h>
# include <unistd.h>
#endif /* GNU C library. */
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#ifdef VMS
# include <unixlib.h>
#endif
#ifdef _LIBC
# include <libintl.h>
#else
@ -72,29 +37,28 @@
# define _(msgid) gettext (msgid)
#endif
#if defined _LIBC
# include <wchar.h>
#endif
/* 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'.
#ifndef attribute_hidden
# define attribute_hidden
#endif
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.
/* 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.
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'. */
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.
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

View File

@ -16,48 +16,13 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#ifndef _LIBC
#include "config.h"
#endif
#ifdef _LIBC
# include <getopt.h>
#else
# include "getopt.h"
#endif
#include "getopt.h"
#include "getopt_int.h"
#include <stdio.h>
/* 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 <gnu-versions.h>
#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 <stdlib.h>
#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 <stdio.h>
#include <stdlib.h>
int
main (int argc, char **argv)

View File

@ -19,15 +19,43 @@
#ifndef _GETOPT_INT_H
#define _GETOPT_INT_H 1
#include <getopt.h>
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.
/* See __ord above. */
enum __ord __ordering;
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. */
/* 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,