1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-15 17:00:26 +00:00

(const): Move outside !HAVE_CONFIG_H conditional.

(libintl.h): Include this if _LIBC.  Otherwise include gettext.h.
(wchar.h): Include, maybe.
(attribute_hidden): Define if not defind.
(__getopt_initialized): Use attribute_hidden.
(__libc_argc, __libc_argv): Renamed from original_argc, etc.
(__getopt_nonoption_flags, nonoption_flags_max_len, nonoption_flags_len):
Conditional on USE_NONOPTION_FLAGS.
(SWAP_FLAGS): New definitions.
(exchange): Test USE_NONOPTION_FLAGS.
(_getopt_initialize): Test USE_NONOPTION_FLAGS.
(_getopt_internal): Error if argc < 1.  New local var print_errors.
Improve test for ambiguous long option.
Add LIBIO support for error message output.
(NONOPTION_P): Test USE_NONOPTION_FLAGS.
This commit is contained in:
Richard M. Stallman 2002-12-04 11:17:43 +00:00
parent e1e86c97c5
commit 554ed1ff28

View File

@ -1,22 +1,23 @@
/* Getopt for GNU. /* Getopt for GNU.
NOTE: The canonical source of this file is maintained with the GNU NOTE: getopt is now part of the C library, so if you don't know what
C Library. Bugs can be reported to bug-glibc@gnu.org. "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, 96, 97, 98, 99 Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002
Free Software Foundation, Inc. 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 This program is free software; you can redistribute it and/or modify
under the terms of the GNU General Public License as published by the it under the terms of the GNU General Public License as published by
Free Software Foundation; either version 2, or (at your option) any the Free Software Foundation; either version 2, or (at your option)
later version. any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License along
along with this program; if not, write to the Free Software Foundation, with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
@ -27,13 +28,13 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#else #endif
# if !defined __STDC__ || !__STDC__
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems /* This is a separate conditional since some stdc systems
reject `defined (const)'. */ reject `defined (const)'. */
# ifndef const # ifndef const
# define const # define const
# endif
# endif # endif
#endif #endif
@ -74,15 +75,20 @@
# endif # endif
#endif #endif
#ifndef _ #ifdef _LIBC
/* This is for other GNU distributions with internationalized messages. # include <libintl.h>
When compiling libc, the _ macro is predefined. */ #else
# ifdef HAVE_LIBINTL_H /* This is for other GNU distributions with internationalized messages. */
# include <libintl.h> # include "gettext.h"
# define _(msgid) gettext (msgid) #endif
# else #define _(msgid) gettext (msgid)
# define _(msgid) (msgid)
# endif #if defined _LIBC && defined USE_IN_LIBIO
# include <wchar.h>
#endif
#ifndef attribute_hidden
# define attribute_hidden
#endif #endif
/* This version of `getopt' appears to the caller like standard Unix `getopt' /* This version of `getopt' appears to the caller like standard Unix `getopt'
@ -128,7 +134,7 @@ int optind = 1;
causes problems with re-calling getopt as programs generally don't causes problems with re-calling getopt as programs generally don't
know that. */ know that. */
int __getopt_initialized; int __getopt_initialized attribute_hidden;
/* The next char to be scanned in the option-element /* The next char to be scanned in the option-element
in which the last option character we returned was found. in which the last option character we returned was found.
@ -247,41 +253,34 @@ static int first_nonopt;
static int last_nonopt; static int last_nonopt;
#ifdef _LIBC #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 /* Bash 2.0 gives us an environment variable containing flags
indicating ARGV elements that should not be considered arguments. */ indicating ARGV elements that should not be considered arguments. */
# ifdef USE_NONOPTION_FLAGS
/* Defined in getopt_init.c */ /* Defined in getopt_init.c */
extern char *__getopt_nonoption_flags; extern char *__getopt_nonoption_flags;
static int nonoption_flags_max_len; static int nonoption_flags_max_len;
static int nonoption_flags_len; static int nonoption_flags_len;
# endif
static int original_argc; # ifdef USE_NONOPTION_FLAGS
static char *const *original_argv; # define SWAP_FLAGS(ch1, ch2) \
/* Make sure the environment variable bash 2.0 puts in the environment
is valid for the getopt call we must make sure that the ARGV passed
to getopt is that one passed to the process. */
static void
__attribute__ ((unused))
store_args_and_env (int argc, char *const *argv)
{
/* 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). */
original_argc = argc;
original_argv = argv;
}
# ifdef text_set_element
text_set_element (__libc_subinit, store_args_and_env);
# endif /* text_set_element */
# define SWAP_FLAGS(ch1, ch2) \
if (nonoption_flags_len > 0) \ if (nonoption_flags_len > 0) \
{ \ { \
char __tmp = __getopt_nonoption_flags[ch1]; \ char __tmp = __getopt_nonoption_flags[ch1]; \
__getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
__getopt_nonoption_flags[ch2] = __tmp; \ __getopt_nonoption_flags[ch2] = __tmp; \
} }
# else
# define SWAP_FLAGS(ch1, ch2)
# endif
#else /* !_LIBC */ #else /* !_LIBC */
# define SWAP_FLAGS(ch1, ch2) # define SWAP_FLAGS(ch1, ch2)
#endif /* _LIBC */ #endif /* _LIBC */
@ -313,7 +312,7 @@ exchange (argv)
It leaves the longer segment in the right place overall, It leaves the longer segment in the right place overall,
but it consists of two parts that need to be swapped next. */ but it consists of two parts that need to be swapped next. */
#ifdef _LIBC #if defined _LIBC && defined USE_NONOPTION_FLAGS
/* First make sure the handling of the `__getopt_nonoption_flags' /* First make sure the handling of the `__getopt_nonoption_flags'
string can work normally. Our top argument must be in the range string can work normally. Our top argument must be in the range
of the string. */ of the string. */
@ -417,9 +416,9 @@ _getopt_initialize (argc, argv, optstring)
else else
ordering = PERMUTE; ordering = PERMUTE;
#ifdef _LIBC #if defined _LIBC && defined USE_NONOPTION_FLAGS
if (posixly_correct == NULL if (posixly_correct == NULL
&& argc == original_argc && argv == original_argv) && argc == __libc_argc && argv == __libc_argv)
{ {
if (nonoption_flags_max_len == 0) if (nonoption_flags_max_len == 0)
{ {
@ -515,6 +514,13 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
int *longind; int *longind;
int long_only; int long_only;
{ {
int print_errors = opterr;
if (optstring[0] == ':')
print_errors = 0;
if (argc < 1)
return -1;
optarg = NULL; optarg = NULL;
if (optind == 0 || !__getopt_initialized) if (optind == 0 || !__getopt_initialized)
@ -529,7 +535,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
Either it does not have option syntax, or there is an environment flag Either it does not have option syntax, or there is an environment flag
from the shell indicating it is not an option. The later information from the shell indicating it is not an option. The later information
is only used when the used in the GNU libc. */ is only used when the used in the GNU libc. */
#ifdef _LIBC #if defined _LIBC && defined USE_NONOPTION_FLAGS
# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
|| (optind < nonoption_flags_len \ || (optind < nonoption_flags_len \
&& __getopt_nonoption_flags[optind] == '1')) && __getopt_nonoption_flags[optind] == '1'))
@ -664,16 +670,37 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
pfound = p; pfound = p;
indfound = option_index; 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. */ /* Second or later nonexact match found. */
ambig = 1; ambig = 1;
} }
if (ambig && !exact) if (ambig && !exact)
{ {
if (opterr) if (print_errors)
fprintf (stderr, _("%s: option `%s' is ambiguous\n"), {
argv[0], argv[optind]); #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); nextchar += strlen (nextchar);
optind++; optind++;
optopt = 0; optopt = 0;
@ -692,18 +719,52 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
optarg = nameend + 1; optarg = nameend + 1;
else else
{ {
if (opterr) if (print_errors)
{ {
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
int n;
#endif
if (argv[optind - 1][1] == '-') if (argv[optind - 1][1] == '-')
/* --option */ {
fprintf (stderr, /* --option */
_("%s: option `--%s' doesn't allow an argument\n"), #if defined _LIBC && defined USE_IN_LIBIO
argv[0], pfound->name); 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 else
/* +option or -option */ {
fprintf (stderr, /* +option or -option */
_("%s: option `%c%s' doesn't allow an argument\n"), #if defined _LIBC && defined USE_IN_LIBIO
argv[0], argv[optind - 1][0], pfound->name); 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); nextchar += strlen (nextchar);
@ -718,10 +779,28 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
optarg = argv[optind++]; optarg = argv[optind++];
else else
{ {
if (opterr) if (print_errors)
fprintf (stderr, {
_("%s: option `%s' requires an argument\n"), #if defined _LIBC && defined USE_IN_LIBIO
argv[0], argv[optind - 1]); 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); nextchar += strlen (nextchar);
optopt = pfound->val; optopt = pfound->val;
return optstring[0] == ':' ? ':' : '?'; return optstring[0] == ':' ? ':' : '?';
@ -745,16 +824,47 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
if (!long_only || argv[optind][1] == '-' if (!long_only || argv[optind][1] == '-'
|| my_index (optstring, *nextchar) == NULL) || 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] == '-') if (argv[optind][1] == '-')
/* --option */ {
fprintf (stderr, _("%s: unrecognized option `--%s'\n"), /* --option */
argv[0], nextchar); #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 else
/* +option or -option */ {
fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), /* +option or -option */
argv[0], argv[optind][0], nextchar); #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 *) ""; nextchar = (char *) "";
optind++; optind++;
@ -775,15 +885,44 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
if (temp == NULL || c == ':') if (temp == NULL || c == ':')
{ {
if (opterr) if (print_errors)
{ {
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
int n;
#endif
if (posixly_correct) if (posixly_correct)
/* 1003.2 specifies the format of this message. */ {
fprintf (stderr, _("%s: illegal option -- %c\n"), /* 1003.2 specifies the format of this message. */
argv[0], c); #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 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; optopt = c;
return '?'; return '?';
@ -809,11 +948,27 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
} }
else if (optind == argc) else if (optind == argc)
{ {
if (opterr) if (print_errors)
{ {
/* 1003.2 specifies the format of this message. */ /* 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"), fprintf (stderr, _("%s: option requires an argument -- %c\n"),
argv[0], c); argv[0], c);
#endif
} }
optopt = c; optopt = c;
if (optstring[0] == ':') if (optstring[0] == ':')
@ -858,9 +1013,26 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
} }
if (ambig && !exact) if (ambig && !exact)
{ {
if (opterr) if (print_errors)
fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), {
argv[0], argv[optind]); #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); nextchar += strlen (nextchar);
optind++; optind++;
return '?'; return '?';
@ -876,10 +1048,28 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
optarg = nameend + 1; optarg = nameend + 1;
else else
{ {
if (opterr) if (print_errors)
fprintf (stderr, _("\ {
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
if (__asprintf (&buf, _("\
%s: option `-W %s' doesn't allow an argument\n"), %s: option `-W %s' doesn't allow an argument\n"),
argv[0], pfound->name); 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); nextchar += strlen (nextchar);
return '?'; return '?';
@ -891,10 +1081,28 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
optarg = argv[optind++]; optarg = argv[optind++];
else else
{ {
if (opterr) if (print_errors)
fprintf (stderr, {
_("%s: option `%s' requires an argument\n"), #if defined _LIBC && defined USE_IN_LIBIO
argv[0], argv[optind - 1]); 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); nextchar += strlen (nextchar);
return optstring[0] == ':' ? ':' : '?'; return optstring[0] == ':' ? ':' : '?';
} }
@ -938,12 +1146,28 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
} }
else if (optind == argc) else if (optind == argc)
{ {
if (opterr) if (print_errors)
{ {
/* 1003.2 specifies the format of this message. */ /* 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, fprintf (stderr,
_("%s: option requires an argument -- %c\n"), _("%s: option requires an argument -- %c\n"),
argv[0], c); argv[0], c);
#endif
} }
optopt = c; optopt = c;
if (optstring[0] == ':') if (optstring[0] == ':')