From 0b946a428ca93c45247d5241c026be12a42643d1 Mon Sep 17 00:00:00 2001 From: Henning Geinitz Date: Wed, 2 Apr 2003 21:16:19 +0000 Subject: [PATCH] Update to glibc 2.3.1 version. This fixes a compilation warning. Further more, the code is now LGPLed. --- ChangeLog | 3 + include/getopt.h | 120 ++++++--- lib/getopt.c | 685 +++++++++++++++++++++++++++++++++++++++-------- lib/getopt1.c | 56 ++-- 4 files changed, 694 insertions(+), 170 deletions(-) diff --git a/ChangeLog b/ChangeLog index 115f51de9..84bb4eb24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -33,6 +33,9 @@ * TODO: Removed sm3600, artec and libusb configure switch entries. Updated v4l, sanei buffer print and html manpages entries. Added OS/2 crash entry. + * include/getopt.h lib/getopt.c lib/getopt1.c: Update to glibc + 2.3.1 version. This fixes a compilation warning. Further more, + the code is now LGPLed. 2003-03-31 Henning Meier-Geinitz diff --git a/include/getopt.h b/include/getopt.h index aa7877f86..4283c35b1 100644 --- a/include/getopt.h +++ b/include/getopt.h @@ -1,22 +1,38 @@ /* Declarations for getopt. - Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc. + Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. + 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. - This program is distributed in the hope that it will be useful, + 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 General Public License for more details. + 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 General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #ifndef _GETOPT_H -#define _GETOPT_H 1 + +#ifndef __need_getopt +# define _GETOPT_H 1 +#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 , but + that does not exist if we are standalone. So: if __GNU_LIBRARY__ is + not defined, include , which will pull in 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 +#endif #ifdef __cplusplus extern "C" { @@ -36,7 +52,7 @@ extern char *optarg; On entry to `getopt', zero means this is the first call; initialize. - When `getopt' returns EOF, this is the index of the first of the + 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 @@ -53,6 +69,7 @@ extern int opterr; 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 @@ -76,11 +93,11 @@ extern int optopt; struct option { -#if defined (__STDC__) && __STDC__ +# if (defined __STDC__ && __STDC__) || defined __cplusplus const char *name; -#else +# else char *name; -#endif +# endif /* 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; @@ -90,40 +107,75 @@ struct option /* Names for the values of the `has_arg' field of `struct option'. */ -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ -#if defined (__STDC__) && __STDC__ -#ifdef __GNU_LIBRARY__ + +/* 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 '\0'. This behavior is specific to the GNU + `getopt'. */ + +#if (defined __STDC__ && __STDC__) || defined __cplusplus +# 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); -#else /* not __GNU_LIBRARY__ */ +extern int getopt (int ___argc, char *const *___argv, const char *__shortopts); +# else /* not __GNU_LIBRARY__ */ extern int getopt (); -#endif /* __GNU_LIBRARY__ */ -extern int getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); +# endif /* __GNU_LIBRARY__ */ + +# ifndef __need_getopt +extern int getopt_long (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); +extern int getopt_long_only (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); /* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); +extern int _getopt_internal (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only); +# endif #else /* not __STDC__ */ extern int getopt (); +# ifndef __need_getopt extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); +# endif #endif /* __STDC__ */ #ifdef __cplusplus } #endif -#endif /* _GETOPT_H */ +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/lib/getopt.c b/lib/getopt.c index 04a172eca..289d137e2 100644 --- a/lib/getopt.c +++ b/lib/getopt.c @@ -1,41 +1,42 @@ /* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu + "Keep this file name-space clean" means, talk to drepper@gnu.org before changing it! - - Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 1996 + Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. + 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. - This program is distributed in the hope that it will be useful, + 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 General Public License for more details. + 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 General Public License - along with this program; if not, write to the Free Software - Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO -#define _NO_PROTO +# define _NO_PROTO #endif #ifdef HAVE_CONFIG_H -#include "../include/sane/config.h" +# include #endif -#if !defined (__STDC__) || !__STDC__ +#if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ -#ifndef const -#define const -#endif +# ifndef const +# define const +# endif #endif #include @@ -48,35 +49,50 @@ 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. */ -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) +#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__ +#ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ -#include -#if defined (_LIBC) || defined (HAVE_UNISTD_H) -#include -#endif +# include +# include #endif /* GNU C library. */ #ifdef VMS -#include -#if HAVE_STRING_H - 0 -#include -#endif -#endif - -#ifdef WIN32 -/* It's not Unix, really. See? Capital letters. */ -#include -#define getpid() GetCurrentProcessId() +# include +# if HAVE_STRING_H - 0 +# include +# endif #endif #ifndef _ -#define _(msgid) (msgid) +/* This is for other GNU distributions with internationalized messages. */ +# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +# include +# ifndef _ +# define _(msgid) gettext (msgid) +# endif +# else +# define _(msgid) (msgid) +# endif +# if defined _LIBC && defined USE_IN_LIBIO +# include +# endif +#endif + +#ifndef attribute_hidden +# define attribute_hidden #endif /* This version of `getopt' appears to the caller like standard Unix `getopt' @@ -101,7 +117,7 @@ Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ -char *optarg = NULL; +char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller @@ -109,14 +125,20 @@ char *optarg = NULL; On entry to `getopt', zero means this is the first call; initialize. - When `getopt' returns EOF, this is the index of the first of the + 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. */ -/* XXX 1003.2 says this must be 1 before any call. */ -int optind = 0; +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized attribute_hidden; /* The next char to be scanned in the option-element in which the last option character we returned was found. @@ -165,7 +187,7 @@ int optopt = '?'; 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 EOF with `optind' != ARGC. */ + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ static enum { @@ -175,19 +197,27 @@ static enum /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; -#ifdef __GNU_LIBRARY__ +#ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ -#include -#define my_index strchr +# include +# define my_index strchr #else +# if HAVE_STRING_H +# include +# else +# include +# endif + /* Avoid depending on library functions or files whose names are inconsistent. */ -char *getenv (); +#ifndef getenv +extern char *getenv (); +#endif static char * my_index (str, chr) @@ -208,11 +238,11 @@ my_index (str, chr) #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ -#if !defined (__STDC__) || !__STDC__ +# if (!defined __STDC__ || !__STDC__) && !defined strlen /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); -#endif /* not __STDC__ */ +# endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ @@ -226,11 +256,38 @@ extern int strlen (const char *); static int first_nonopt; static int last_nonopt; +#ifdef _LIBC +/* Stored original parameters. + XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ +extern int __libc_argc; +extern char **__libc_argv; + /* Bash 2.0 gives us an environment variable containing flags indicating ARGV elements that should not be considered arguments. */ -static const char *nonoption_flags; +# ifdef USE_NONOPTION_FLAGS +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; static int nonoption_flags_len; +# endif + +# ifdef USE_NONOPTION_FLAGS +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +# else +# define SWAP_FLAGS(ch1, ch2) +# endif +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) @@ -241,7 +298,7 @@ static int nonoption_flags_len; `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ -#if defined (__STDC__) && __STDC__ +#if defined __STDC__ && __STDC__ static void exchange (char **); #endif @@ -259,6 +316,28 @@ exchange (argv) It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ +#if defined _LIBC && defined USE_NONOPTION_FLAGS + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + while (top > middle && middle > bottom) { if (top - middle > middle - bottom) @@ -273,6 +352,7 @@ exchange (argv) tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); } /* Exclude the moved bottom segment from further swapping. */ top -= len; @@ -289,6 +369,7 @@ exchange (argv) tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); } /* Exclude the moved top segment from further swapping. */ bottom += len; @@ -303,18 +384,20 @@ exchange (argv) /* Initialize the internal data when the first call is made. */ -#if defined (__STDC__) && __STDC__ -static const char *_getopt_initialize (const char *); +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); #endif static const char * -_getopt_initialize (optstring) +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ - first_nonopt = last_nonopt = optind = 1; + first_nonopt = last_nonopt = optind; nextchar = NULL; @@ -337,20 +420,35 @@ _getopt_initialize (optstring) else ordering = PERMUTE; - if (posixly_correct == NULL) +#if defined _LIBC && defined USE_NONOPTION_FLAGS + if (posixly_correct == NULL + && argc == __libc_argc && argv == __libc_argv) { - /* Bash 2.0 puts a special variable in the environment for each - command it runs, specifying which ARGV elements are the results of - file name wildcard expansion and therefore should not be - considered as options. */ - char var[100]; - sprintf (var, "_%d_GNU_nonoption_argv_flags_", getpid ()); - nonoption_flags = getenv (var); - if (nonoption_flags == NULL) - nonoption_flags_len = 0; - else - nonoption_flags_len = strlen (nonoption_flags); + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; } + else + nonoption_flags_len = 0; +#endif return optstring; } @@ -368,7 +466,7 @@ _getopt_initialize (optstring) updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. - If there are no more option characters, `getopt' returns `EOF'. + If there are no more option characters, `getopt' returns -1. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) @@ -420,20 +518,34 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int *longind; int long_only; { + int print_errors = opterr; + if (optstring[0] == ':') + print_errors = 0; + + if (argc < 1) + return -1; + optarg = NULL; - if (optind == 0) + if (optind == 0 || !__getopt_initialized) { - optstring = _getopt_initialize (optstring); - optind = 1; /* Don't scan ARGV[0], the program name. */ + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; } /* Test whether ARGV[optind] points to a non-option argument. Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. */ -#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ - || (optind < nonoption_flags_len \ - && nonoption_flags[optind] == '1')) + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#if defined _LIBC && defined USE_NONOPTION_FLAGS +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif if (nextchar == NULL || *nextchar == '\0') { @@ -491,7 +603,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; - return EOF; + return -1; } /* If we have come to a non-option and did not permute it, @@ -500,7 +612,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) if (NONOPTION_P) { if (ordering == REQUIRE_ORDER) - return EOF; + return -1; optarg = argv[optind++]; return 1; } @@ -536,22 +648,19 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) const struct option *pfound = NULL; int exact = 0; int ambig = 0; - int indfound; + int indfound = -1; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; -#ifdef lint /* Suppress `used before initialized' warning. */ - indfound = 0; -#endif - /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { - if (nameend - nextchar == strlen (p->name)) + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) { /* Exact match found. */ pfound = p; @@ -565,16 +674,37 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) pfound = p; indfound = option_index; } - else + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { - if (opterr) - fprintf (stderr, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[optind]); + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]) >= 0) + { + + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); +#endif + } nextchar += strlen (nextchar); optind++; optopt = 0; @@ -593,17 +723,53 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) optarg = nameend + 1; else { - if (opterr) - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - _("%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - _("%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[optind - 1][0], pfound->name); + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif + + if (argv[optind - 1][1] == '-') + { + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("\ +%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#else + fprintf (stderr, _("\ +%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + else + { + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("\ +%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], + pfound->name); +#else + fprintf (stderr, _("\ +%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#endif + } nextchar += strlen (nextchar); @@ -617,10 +783,28 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) optarg = argv[optind++]; else { - if (opterr) - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]) >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); +#endif + } nextchar += strlen (nextchar); optopt = pfound->val; return optstring[0] == ':' ? ':' : '?'; @@ -644,16 +828,47 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { - if (opterr) + if (print_errors) { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif + if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, _("%s: unrecognized option `--%s'\n"), - argv[0], nextchar); + { + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); +#else + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); +#endif + } else - /* +option or -option */ - fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[optind][0], nextchar); + { + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); +#else + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#endif } nextchar = (char *) ""; optind++; @@ -674,19 +889,241 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) if (temp == NULL || c == ':') { - if (opterr) + if (print_errors) { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif + if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: illegal option -- %c\n"), - argv[0], c); + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: illegal option -- %c\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); +#endif + } else - fprintf (stderr, _("%s: invalid option -- %c\n"), - argv[0], c); + { +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: invalid option -- %c\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#endif } optopt = c; return '?'; } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, + _("%s: option requires an argument -- %c\n"), + argv[0], c) >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); +#endif + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]) >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); +#endif + } + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name) >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]) >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); +#endif + } + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } if (temp[1] == ':') { if (temp[2] == ':') @@ -713,12 +1150,28 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) } else if (optind == argc) { - if (opterr) + if (print_errors) { /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option requires an argument -- %c\n"), + argv[0], c) >= 0) + { + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); + } +#else fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); +#endif } optopt = c; if (optstring[0] == ':') @@ -749,7 +1202,7 @@ getopt (argc, argv, optstring) 0); } -#endif /* _LIBC or not __GNU_LIBRARY__. */ +#endif /* Not ELIDE_CODE. */ #ifdef TEST @@ -769,7 +1222,7 @@ main (argc, argv) int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); - if (c == EOF) + if (c == -1) break; switch (c) diff --git a/lib/getopt1.c b/lib/getopt1.c index 15c93d8db..ad06cc7f9 100644 --- a/lib/getopt1.c +++ b/lib/getopt1.c @@ -1,28 +1,34 @@ /* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994 - Free Software Foundation, Inc. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Free Software Foundation, Inc. + This file is part of the GNU C Library. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. + 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. - This program is distributed in the hope that it will be useful, + 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 General Public License for more details. + 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 General Public License - along with this program; if not, write to the Free Software - Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #ifdef HAVE_CONFIG_H -#include "../include/sane/config.h" +#include #endif -#include "getopt.h" +#ifdef _LIBC +# include +#else +# include "getopt.h" +#endif -#if !defined (__STDC__) || !__STDC__ +#if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const @@ -40,15 +46,21 @@ 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. */ -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) +#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 -#else -char *getenv (); #endif #ifndef NULL @@ -82,8 +94,12 @@ getopt_long_only (argc, argv, options, long_options, opt_index) return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } +# ifdef _LIBC +libc_hidden_def (getopt_long) +libc_hidden_def (getopt_long_only) +# endif -#endif /* _LIBC or not __GNU_LIBRARY__. */ +#endif /* Not ELIDE_CODE. */ #ifdef TEST @@ -114,7 +130,7 @@ main (argc, argv) c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); - if (c == EOF) + if (c == -1) break; switch (c)