Update.
authorUlrich Drepper <drepper@redhat.com>
Tue, 9 Mar 2004 10:36:53 +0000 (10:36 +0000)
committerUlrich Drepper <drepper@redhat.com>
Tue, 9 Mar 2004 10:36:53 +0000 (10:36 +0000)
2004-03-08  Paul Eggert  <eggert@cs.ucla.edu>

Merge from gnulib.  We now assume C89 or better.
* posix/getopt1.c (const): Remove.
* posix/getopt.c (const): Likewise.
* posix/getopt1.c (getopt_long, _getopt_long_r, getopt_long_only,
_getopt_long_only_r, main): Use prototypes, not old-style definitions.
* posix/getopt.c (exchange, _getopt_initialize, _getopt_internal_r,
_getopt_internal, getopt, main): Likewise.
* posix/getopt.h (getopt, getopt_long, getopt_long_only): Likewise.
* posix/getopt.c [!defined VMS || !HAVE_STRING_H]:
Include <string.h> regardless.  No need for <strings.h>.
[!defined _LIBC]: Include "gettext.h" rather than rolling it ourselves.
(_): Define to gettext always.
(my_index): Remove: all uses changed to strchr.
(strlen): Remove declaration.
* posix/getopt.h (struct option.name): Always const char *.

2004-03-08  Marcus Brinkmann  <marcus@gnu.org>

* posix/getopt.h (_getopt_internal): Move to ...
* posix/getopt_int.h: ... here.  New file.
* include/getopt_int.h: New file.
* include/getopt.h: Remove libc_hidden_proto for getopt_long
and getopt_long_only.
* posix/getopt1.c: Include "getopt_int.h".  Remove
libc_hidden_def for getopt_long and getopt_long_only.
(_getopt_long_r, _getopt_long_only_r): New functions.
* posix/getopt.c: Include "getopt_int.h".
(__getopt_initialized): Variable removed.
(nextchar, ordering, posixly_correct, first_nonopt, last_nonopt):
Static variables removed.
(nonoption_flags_max_len, nonoption_flags_len) [_LIBC &&
USE_NONOPTION_FLAGS]: Static variables removed.
(getopt_data): New static variable.
(SWAP_FLAGS): Use d->__nonoption_flags_len instead
nonoption_flags_len.
(exchange): Add new argument D of type struct getopt_data *.
Replace optind with d->optind, optarg with d->optarg, opterr with
d->opterr, optopt with d->optopt, nextchar with d->__nextchar,
first_nonopt with d->__first_nonopt, last_nonopt with
d->__last_nonopt, d->ordering with d->__ordering,
d->posixly_correct with d->__posixly_correct (which is now an
int instead a string, so fix users), nonoption_flags_len
with d->__nonoption_flags_len, nonoption_flags_max_len with
d->__nonoption_flags_max_len.
(_getopt_initialize): Likewise.
(_getopt_internal): Rename to ...
(_getopt_internal_r): ... this.  Also add new argument D of type
struct getopt_data * and use of members of D rather than global or
static variables as described for exchange() above.  Add new argument
to invocations of _getopt_initialize and exchange.
(_getopt_internal): Reimplement in terms of _getopt_internal_r.
* argp/argp-parse.c: Include <getopt_int.h>.
[_LIBC]: Do not include <bits/libc-lock.h>.
[!_LIBC && HAVE_CTHREADS_H]: Do not include <cthreads.h>.
[!_LIBC] (_argp_hang): Make static.
(getopt_lock, LOCK_GETOPT, UNLOCK_GETOPT): Remove.
(_argp_unlock_xxx): Remove.
(parser_init): Do not use LOCK_GETOPT.
(parser_finalize): Do not use UNLOCK_GETOPT.
(struct parser): New member OPT_DATA.
(parser_init): Initialize parser->opt_data.  Use
parser->opt_data.opterr instead of opterr.
(parser_parse_opt): Use parser->opt_data.optarg instead optarg.
(parser_parse_next): Likewise.  Use parser->opt_data.optind
instead optind.  Use parser->opt_data.optopt instead of optopt.
Call _getopt_long_only_r and _getopt_long_r instead of
getopt_long_only and getopt_long, and pass the extra argument.

ChangeLog
argp/argp-parse.c
include/getopt.h
include/getopt_int.h [new file with mode: 0644]
posix/getopt.c
posix/getopt.h
posix/getopt1.c
posix/getopt_int.h [new file with mode: 0644]

index 0ed4144..5fed959 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,73 @@
+2004-03-08  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Merge from gnulib.  We now assume C89 or better.
+       * posix/getopt1.c (const): Remove.
+       * posix/getopt.c (const): Likewise.
+       * posix/getopt1.c (getopt_long, _getopt_long_r, getopt_long_only,
+       _getopt_long_only_r, main): Use prototypes, not old-style definitions.
+       * posix/getopt.c (exchange, _getopt_initialize, _getopt_internal_r,
+       _getopt_internal, getopt, main): Likewise.
+       * posix/getopt.h (getopt, getopt_long, getopt_long_only): Likewise.
+       * posix/getopt.c [!defined VMS || !HAVE_STRING_H]:
+       Include <string.h> regardless.  No need for <strings.h>.
+       [!defined _LIBC]: Include "gettext.h" rather than rolling it ourselves.
+       (_): Define to gettext always.
+       (my_index): Remove: all uses changed to strchr.
+       (strlen): Remove declaration.
+       * posix/getopt.h (struct option.name): Always const char *.
+
+2004-03-08  Marcus Brinkmann  <marcus@gnu.org>
+
+       * posix/getopt.h (_getopt_internal): Move to ...
+       * posix/getopt_int.h: ... here.  New file.
+       * include/getopt_int.h: New file.
+       * include/getopt.h: Remove libc_hidden_proto for getopt_long
+       and getopt_long_only.
+       * posix/getopt1.c: Include "getopt_int.h".  Remove
+       libc_hidden_def for getopt_long and getopt_long_only.
+       (_getopt_long_r, _getopt_long_only_r): New functions.
+       * posix/getopt.c: Include "getopt_int.h".
+       (__getopt_initialized): Variable removed.
+       (nextchar, ordering, posixly_correct, first_nonopt, last_nonopt):
+       Static variables removed.
+       (nonoption_flags_max_len, nonoption_flags_len) [_LIBC &&
+       USE_NONOPTION_FLAGS]: Static variables removed.
+       (getopt_data): New static variable.
+       (SWAP_FLAGS): Use d->__nonoption_flags_len instead
+       nonoption_flags_len.
+       (exchange): Add new argument D of type struct getopt_data *.
+       Replace optind with d->optind, optarg with d->optarg, opterr with
+       d->opterr, optopt with d->optopt, nextchar with d->__nextchar,
+       first_nonopt with d->__first_nonopt, last_nonopt with
+       d->__last_nonopt, d->ordering with d->__ordering,
+       d->posixly_correct with d->__posixly_correct (which is now an
+       int instead a string, so fix users), nonoption_flags_len
+       with d->__nonoption_flags_len, nonoption_flags_max_len with
+       d->__nonoption_flags_max_len.
+       (_getopt_initialize): Likewise.
+       (_getopt_internal): Rename to ...
+       (_getopt_internal_r): ... this.  Also add new argument D of type
+       struct getopt_data * and use of members of D rather than global or
+       static variables as described for exchange() above.  Add new argument
+       to invocations of _getopt_initialize and exchange.
+       (_getopt_internal): Reimplement in terms of _getopt_internal_r.
+       * argp/argp-parse.c: Include <getopt_int.h>.
+       [_LIBC]: Do not include <bits/libc-lock.h>.
+       [!_LIBC && HAVE_CTHREADS_H]: Do not include <cthreads.h>.
+       [!_LIBC] (_argp_hang): Make static.
+       (getopt_lock, LOCK_GETOPT, UNLOCK_GETOPT): Remove.
+       (_argp_unlock_xxx): Remove.
+       (parser_init): Do not use LOCK_GETOPT.
+       (parser_finalize): Do not use UNLOCK_GETOPT.
+       (struct parser): New member OPT_DATA.
+       (parser_init): Initialize parser->opt_data.  Use
+       parser->opt_data.opterr instead of opterr.
+       (parser_parse_opt): Use parser->opt_data.optarg instead optarg.
+       (parser_parse_next): Likewise.  Use parser->opt_data.optind
+       instead optind.  Use parser->opt_data.optopt instead of optopt.
+       Call _getopt_long_only_r and _getopt_long_r instead of
+       getopt_long_only and getopt_long, and pass the extra argument.
+
 2004-03-09  Ulrich Drepper  <drepper@redhat.com>
 
        * iconv/gconv_db.c: Don't define lock as static.  Rename to
index 47223dc..4718ced 100644 (file)
@@ -1,5 +1,5 @@
 /* Hierarchial argument parsing, layered over getopt
-   Copyright (C) 1995-2000, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1995-2000, 2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Miles Bader <miles@gnu.ai.mit.edu>.
 
@@ -42,6 +42,7 @@ char *alloca ();
 #include <unistd.h>
 #include <limits.h>
 #include <getopt.h>
+#include <getopt_int.h>
 
 #ifndef _
 /* This is for other GNU distributions with internationalized messages.
@@ -62,14 +63,6 @@ char *alloca ();
 # define N_(msgid) (msgid)
 #endif
 
-#if _LIBC - 0
-#include <bits/libc-lock.h>
-#else
-#ifdef HAVE_CTHREADS_H
-#include <cthreads.h>
-#endif
-#endif /* _LIBC */
-
 #include "argp.h"
 #include "argp-namefrob.h"
 
@@ -97,14 +90,8 @@ char *alloca ();
 /* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep
    for one second intervals, decrementing _ARGP_HANG until it's zero.  Thus
    you can force the program to continue by attaching a debugger and setting
-   it to 0 yourself.
-
-   XXX This variable used to be exported.  But there seems to be no
-   need, at least not inside libc.  */
-#ifdef _LIBC
-static
-#endif
-volatile int _argp_hang;
+   it to 0 yourself.  */
+static volatile int _argp_hang;
 
 #define OPT_PROGNAME   -2
 #define OPT_USAGE      -3
@@ -223,42 +210,7 @@ find_long_option (struct option *long_options, const char *name)
   else
     return -1;
 }
-\f
-/* If we can, we regulate access to getopt, which is non-reentrant, with a
-   mutex.  Since the case we're trying to guard against is two different
-   threads interfering, and it's possible that someone might want to call
-   argp_parse recursively (they're careful), we use a recursive lock if
-   possible.  */
-
-#if _LIBC - 0
-
-__libc_lock_define_initialized_recursive (static, getopt_lock)
-#define LOCK_GETOPT   __libc_lock_lock_recursive (getopt_lock)
-#define UNLOCK_GETOPT __libc_lock_unlock_recursive (getopt_lock)
-
-#else /* !_LIBC */
-#ifdef HAVE_CTHREADS_H
 
-static struct mutex getopt_lock = MUTEX_INITIALIZER;
-#define LOCK_GETOPT   mutex_lock (&getopt_lock)
-#define UNLOCK_GETOPT mutex_unlock (&getopt_lock)
-
-#else /* !HAVE_CTHREADS_H */
-
-#define LOCK_GETOPT    (void)0
-#define UNLOCK_GETOPT  (void)0
-
-#endif /* HAVE_CTHREADS_H */
-#endif /* _LIBC */
-
-/* This hack to allow programs that know what's going on to call argp
-   recursively.  If someday argp is changed not to use the non-reentrant
-   getopt interface, we can get rid of this shit.  XXX */
-void
-_argp_unlock_xxx (void)
-{
-  UNLOCK_GETOPT;
-}
 \f
 /* The state of a `group' during parsing.  Each group corresponds to a
    particular argp structure from the tree of such descending from the top
@@ -320,6 +272,8 @@ struct parser
   /* LONG_OPTS is the array of getop long option structures for the union of
      all the groups of options.  */
   struct option *long_opts;
+  /* OPT_DATA is the getopt data used for the re-entrant getopt.  */
+  struct _getopt_data opt_data;
 
   /* States of the various parsing groups.  */
   struct group *groups;
@@ -531,6 +485,7 @@ parser_init (struct parser *parser, const struct argp *argp,
   error_t err = 0;
   struct group *group;
   struct parser_sizes szs;
+  struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;
 
   szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
   szs.long_len = 0;
@@ -554,6 +509,7 @@ parser_init (struct parser *parser, const struct argp *argp,
   parser->child_inputs = parser->storage + GLEN;
   parser->long_opts = parser->storage + GLEN + CLEN;
   parser->short_opts = parser->storage + GLEN + CLEN + LLEN;
+  parser->opt_data = opt_data;
 
   memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));
   parser_convert (parser, argp, flags);
@@ -597,19 +553,16 @@ parser_init (struct parser *parser, const struct argp *argp,
   if (err)
     return err;
 
-  /* Getopt is (currently) non-reentrant.  */
-  LOCK_GETOPT;
-
   if (parser->state.flags & ARGP_NO_ERRS)
     {
-      opterr = 0;
+      parser->opt_data.opterr = 0;
       if (parser->state.flags & ARGP_PARSE_ARGV0)
        /* getopt always skips ARGV[0], so we have to fake it out.  As long
           as OPTERR is 0, then it shouldn't actually try to access it.  */
        parser->state.argv--, parser->state.argc++;
     }
   else
-    opterr = 1;                /* Print error messages.  */
+    parser->opt_data.opterr = 1;       /* Print error messages.  */
 
   if (parser->state.argv == argv && argv[0])
     /* There's an argv[0]; use it for messages.  */
@@ -630,8 +583,6 @@ parser_finalize (struct parser *parser,
 {
   struct group *group;
 
-  UNLOCK_GETOPT;
-
   if (err == EBADKEY && arg_ebadkey)
     /* Suppress errors generated by unparsed arguments.  */
     err = 0;
@@ -793,7 +744,8 @@ parser_parse_opt (struct parser *parser, int opt, char *val)
        for (group = parser->groups; group < parser->egroup; group++)
          if (group->short_end > short_index)
            {
-             err = group_parse (group, &parser->state, opt, optarg);
+             err = group_parse (group, &parser->state, opt,
+                                parser->opt_data.optarg);
              break;
            }
     }
@@ -802,7 +754,8 @@ parser_parse_opt (struct parser *parser, int opt, char *val)
        the user value in order to preserve the sign.  */
     err =
       group_parse (&parser->groups[group_key - 1], &parser->state,
-                  (opt << GROUP_BITS) >> GROUP_BITS, optarg);
+                  (opt << GROUP_BITS) >> GROUP_BITS,
+                  parser->opt_data.optarg);
 
   if (err == EBADKEY)
     /* At least currently, an option not recognized is an error in the
@@ -848,15 +801,20 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey)
   if (parser->try_getopt && !parser->state.quoted)
     /* Give getopt a chance to parse this.  */
     {
-      optind = parser->state.next; /* Put it back in OPTIND for getopt.  */
-      optopt = KEY_END;        /* Distinguish KEY_ERR from a real option.  */
+      /* Put it back in OPTIND for getopt.  */
+      parser->opt_data.optind = parser->state.next;
+      /* Distinguish KEY_ERR from a real option.  */
+      parser->opt_data.optopt = KEY_END;
       if (parser->state.flags & ARGP_LONG_ONLY)
-       opt = getopt_long_only (parser->state.argc, parser->state.argv,
-                               parser->short_opts, parser->long_opts, 0);
+       opt = _getopt_long_only_r (parser->state.argc, parser->state.argv,
+                                  parser->short_opts, parser->long_opts, 0,
+                                  &parser->opt_data);
       else
-       opt = getopt_long (parser->state.argc, parser->state.argv,
-                          parser->short_opts, parser->long_opts, 0);
-      parser->state.next = optind; /* And see what getopt did.  */
+       opt = _getopt_long_r (parser->state.argc, parser->state.argv,
+                             parser->short_opts, parser->long_opts, 0,
+                             &parser->opt_data);
+      /* And see what getopt did.  */
+      parser->state.next = parser->opt_data.optind;
 
       if (opt == KEY_END)
        /* Getopt says there are no more options, so stop using
@@ -872,7 +830,7 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey)
               here, whatever happens.  */
            parser->state.quoted = parser->state.next;
        }
-      else if (opt == KEY_ERR && optopt != KEY_END)
+      else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END)
        /* KEY_ERR can have the same value as a valid user short
           option, but in the case of a real error, getopt sets OPTOPT
           to the offending character, which can never be KEY_END.  */
@@ -898,15 +856,15 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey)
        /* A non-option arg; simulate what getopt might have done.  */
        {
          opt = KEY_ARG;
-         optarg = parser->state.argv[parser->state.next++];
+         parser->opt_data.optarg = parser->state.argv[parser->state.next++];
        }
     }
 
   if (opt == KEY_ARG)
     /* A non-option argument; try each parser in turn.  */
-    err = parser_parse_arg (parser, optarg);
+    err = parser_parse_arg (parser, parser->opt_data.optarg);
   else
-    err = parser_parse_opt (parser, opt, optarg);
+    err = parser_parse_opt (parser, opt, parser->opt_data.optarg);
 
   if (err == EBADKEY)
     *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG);
index 7bef4ba..6f2693d 100644 (file)
@@ -5,9 +5,6 @@
 
 # ifdef _GETOPT_H
 
-libc_hidden_proto (getopt_long)
-libc_hidden_proto (getopt_long_only)
-
 /* Now define the internal interfaces.  */
 extern void __getopt_clean_environment (char **__env);
 
diff --git a/include/getopt_int.h b/include/getopt_int.h
new file mode 100644 (file)
index 0000000..9f7ced8
--- /dev/null
@@ -0,0 +1 @@
+#include <posix/getopt_int.h>
index 5336410..4c383a4 100644 (file)
@@ -2,7 +2,7 @@
    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 drepper@gnu.org
    before changing it!
-   Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003
+   Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004
        Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
 # include <config.h>
 #endif
 
-#if !defined __STDC__ || !__STDC__
-/* This is a separate conditional since some stdc systems
-   reject `defined (const)'.  */
-# ifndef const
-#  define const
-# endif
-#endif
-
 #include <stdio.h>
 
 /* Comment out all this code if we are using the GNU C Library, and are not
 # include <unistd.h>
 #endif /* GNU C library.  */
 
+#include <string.h>
+
 #ifdef VMS
 # include <unixlib.h>
-# if HAVE_STRING_H - 0
-#  include <string.h>
-# endif
 #endif
 
-#ifndef _
-/* This is for other GNU distributions with internationalized messages.  */
-# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
-#  include <libintl.h>
-#  ifndef _
-#   define _(msgid)    gettext (msgid)
-#  endif
-# else
-#  define _(msgid)     (msgid)
-# endif
-# if defined _LIBC && defined USE_IN_LIBIO
-#  include <wchar.h>
-# endif
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "gettext.h"
+#endif
+#define _(msgid) gettext (msgid)
+
+#if defined _LIBC && defined USE_IN_LIBIO
+# include <wchar.h>
 #endif
 
 #ifndef attribute_hidden
    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.
    When `getopt' finds an option that takes an argument,
@@ -134,21 +122,6 @@ char *optarg;
 /* 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.
-   This allows us to pick up the scan where we left off.
-
-   If this is zero, or a null string, it means resume the scan
-   by advancing to the next ARGV-element.  */
-
-static char *nextchar;
-
 /* Callers store zero here to inhibit the error message
    for unrecognized options.  */
 
@@ -160,57 +133,12 @@ int opterr = 1;
 
 int optopt = '?';
 
-/* 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.
+/* Keep a global copy of all internal members of getopt_data.  */
 
-   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.
+static struct _getopt_data getopt_data;
 
-   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.  */
-
-static enum
-{
-  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
-} ordering;
-
-/* Value of POSIXLY_CORRECT environment variable.  */
-static char *posixly_correct;
 \f
-#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 <string.h>
-# define my_index      strchr
-#else
-
-# if HAVE_STRING_H
-#  include <string.h>
-# else
-#  include <strings.h>
-# endif
+#ifndef __GNU_LIBRARY__
 
 /* Avoid depending on library functions or files
    whose names are inconsistent.  */
@@ -219,43 +147,8 @@ static char *posixly_correct;
 extern char *getenv ();
 #endif
 
-static char *
-my_index (str, chr)
-     const char *str;
-     int chr;
-{
-  while (*str)
-    {
-      if (*str == chr)
-       return (char *) str;
-      str++;
-    }
-  return 0;
-}
-
-/* If using GCC, we can safely declare strlen this way.
-   If not using GCC, it is ok not to declare it.  */
-#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__) && !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 /* __GNUC__ */
-
 #endif /* not __GNU_LIBRARY__ */
 \f
-/* Handle permutation of arguments.  */
-
-/* Describe the part of ARGV that contains non-options that have
-   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
-   `last_nonopt' is the index after the last of them.  */
-
-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
@@ -269,14 +162,11 @@ extern char **__libc_argv;
 # 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)                                               \
+  if (d->__nonoption_flags_len > 0)                                          \
     {                                                                        \
       char __tmp = __getopt_nonoption_flags[ch1];                            \
       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];         \
@@ -298,17 +188,12 @@ 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__
-static void exchange (char **);
-#endif
-
 static void
-exchange (argv)
-     char **argv;
+exchange (char **argv, struct _getopt_data *d)
 {
-  int bottom = first_nonopt;
-  int middle = last_nonopt;
-  int top = optind;
+  int bottom = d->__first_nonopt;
+  int middle = d->__last_nonopt;
+  int top = d->optind;
   char *tem;
 
   /* Exchange the shorter segment with the far end of the longer segment.
@@ -320,19 +205,19 @@ exchange (argv)
   /* 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)
+  if (d->__nonoption_flags_len > 0 && top >= d->__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;
+       d->__nonoption_flags_len = d->__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;
+                            d->__nonoption_flags_max_len),
+                 '\0', top + 1 - d->__nonoption_flags_max_len);
+         d->__nonoption_flags_max_len = top + 1;
          __getopt_nonoption_flags = new_str;
        }
     }
@@ -378,76 +263,71 @@ exchange (argv)
 
   /* Update records for the slots the non-options now occupy.  */
 
-  first_nonopt += (optind - last_nonopt);
-  last_nonopt = optind;
+  d->__first_nonopt += (d->optind - d->__last_nonopt);
+  d->__last_nonopt = d->optind;
 }
 
 /* Initialize the internal data when the first call is made.  */
 
-#if defined __STDC__ && __STDC__
-static const char *_getopt_initialize (int, char *const *, const char *);
-#endif
 static const char *
-_getopt_initialize (argc, argv, optstring)
-     int argc;
-     char *const *argv;
-     const char *optstring;
+_getopt_initialize (int argc, char *const *argv, const char *optstring,
+                   struct _getopt_data *d)
 {
   /* 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;
+  d->__first_nonopt = d->__last_nonopt = d->optind;
 
-  nextchar = NULL;
+  d->__nextchar = NULL;
 
-  posixly_correct = getenv ("POSIXLY_CORRECT");
+  d->__posixly_correct = !!getenv ("POSIXLY_CORRECT");
 
   /* Determine how to handle the ordering of options and nonoptions.  */
 
   if (optstring[0] == '-')
     {
-      ordering = RETURN_IN_ORDER;
+      d->__ordering = RETURN_IN_ORDER;
       ++optstring;
     }
   else if (optstring[0] == '+')
     {
-      ordering = REQUIRE_ORDER;
+      d->__ordering = REQUIRE_ORDER;
       ++optstring;
     }
-  else if (posixly_correct != NULL)
-    ordering = REQUIRE_ORDER;
+  else if (d->__posixly_correct)
+    d->__ordering = REQUIRE_ORDER;
   else
-    ordering = PERMUTE;
+    d->__ordering = PERMUTE;
 
 #if defined _LIBC && defined USE_NONOPTION_FLAGS
-  if (posixly_correct == NULL
+  if (!d->__posixly_correct
       && argc == __libc_argc && argv == __libc_argv)
     {
-      if (nonoption_flags_max_len == 0)
+      if (d->__nonoption_flags_max_len == 0)
        {
          if (__getopt_nonoption_flags == NULL
              || __getopt_nonoption_flags[0] == '\0')
-           nonoption_flags_max_len = -1;
+           d->__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;
+             int len = d->__nonoption_flags_max_len = strlen (orig_str);
+             if (d->__nonoption_flags_max_len < argc)
+               d->__nonoption_flags_max_len = argc;
              __getopt_nonoption_flags =
-               (char *) malloc (nonoption_flags_max_len);
+               (char *) malloc (d->__nonoption_flags_max_len);
              if (__getopt_nonoption_flags == NULL)
-               nonoption_flags_max_len = -1;
+               d->__nonoption_flags_max_len = -1;
              else
                memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
-                       '\0', nonoption_flags_max_len - len);
+                       '\0', d->__nonoption_flags_max_len - len);
            }
        }
-      nonoption_flags_len = nonoption_flags_max_len;
+      d->__nonoption_flags_len = d->__nonoption_flags_max_len;
     }
   else
-    nonoption_flags_len = 0;
+    d->__nonoption_flags_len = 0;
 #endif
 
   return optstring;
@@ -510,29 +390,25 @@ _getopt_initialize (argc, argv, optstring)
    long-named options.  */
 
 int
-_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
-     int argc;
-     char *const *argv;
-     const char *optstring;
-     const struct option *longopts;
-     int *longind;
-     int long_only;
+_getopt_internal_r (int argc, char *const *argv, const char *optstring,
+                   const struct option *longopts, int *longind,
+                   int long_only, struct _getopt_data *d)
 {
-  int print_errors = opterr;
+  int print_errors = d->opterr;
   if (optstring[0] == ':')
     print_errors = 0;
 
   if (argc < 1)
     return -1;
 
-  optarg = NULL;
+  d->optarg = NULL;
 
-  if (optind == 0 || !__getopt_initialized)
+  if (d->optind == 0 || !d->__initialized)
     {
-      if (optind == 0)
-       optind = 1;     /* Don't scan ARGV[0], the program name.  */
-      optstring = _getopt_initialize (argc, argv, optstring);
-      __getopt_initialized = 1;
+      if (d->optind == 0)
+       d->optind = 1;  /* Don't scan ARGV[0], the program name.  */
+      optstring = _getopt_initialize (argc, argv, optstring, d);
+      d->__initialized = 1;
     }
 
   /* Test whether ARGV[optind] points to a non-option argument.
@@ -540,40 +416,41 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
      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'))
+# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \
+                     || (d->optind < d->__nonoption_flags_len                \
+                         && __getopt_nonoption_flags[d->optind] == '1'))
 #else
-# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
 #endif
 
-  if (nextchar == NULL || *nextchar == '\0')
+  if (d->__nextchar == NULL || *d->__nextchar == '\0')
     {
       /* Advance to the next ARGV-element.  */
 
       /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
         moved back by the user (who may also have changed the arguments).  */
-      if (last_nonopt > optind)
-       last_nonopt = optind;
-      if (first_nonopt > optind)
-       first_nonopt = optind;
+      if (d->__last_nonopt > d->optind)
+       d->__last_nonopt = d->optind;
+      if (d->__first_nonopt > d->optind)
+       d->__first_nonopt = d->optind;
 
-      if (ordering == PERMUTE)
+      if (d->__ordering == PERMUTE)
        {
          /* If we have just processed some options following some non-options,
             exchange them so that the options come first.  */
 
-         if (first_nonopt != last_nonopt && last_nonopt != optind)
-           exchange ((char **) argv);
-         else if (last_nonopt != optind)
-           first_nonopt = optind;
+         if (d->__first_nonopt != d->__last_nonopt
+             && d->__last_nonopt != d->optind)
+           exchange ((char **) argv, d);
+         else if (d->__last_nonopt != d->optind)
+           d->__first_nonopt = d->optind;
 
          /* Skip any additional non-options
             and extend the range of non-options previously skipped.  */
 
-         while (optind < argc && NONOPTION_P)
-           optind++;
-         last_nonopt = optind;
+         while (d->optind < argc && NONOPTION_P)
+           d->optind++;
+         d->__last_nonopt = d->optind;
        }
 
       /* The special ARGV-element `--' means premature end of options.
@@ -581,28 +458,29 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
         then exchange with previous non-options as if it were an option,
         then skip everything else like a non-option.  */
 
-      if (optind != argc && !strcmp (argv[optind], "--"))
+      if (d->optind != argc && !strcmp (argv[d->optind], "--"))
        {
-         optind++;
+         d->optind++;
 
-         if (first_nonopt != last_nonopt && last_nonopt != optind)
-           exchange ((char **) argv);
-         else if (first_nonopt == last_nonopt)
-           first_nonopt = optind;
-         last_nonopt = argc;
+         if (d->__first_nonopt != d->__last_nonopt
+             && d->__last_nonopt != d->optind)
+           exchange ((char **) argv, d);
+         else if (d->__first_nonopt == d->__last_nonopt)
+           d->__first_nonopt = d->optind;
+         d->__last_nonopt = argc;
 
-         optind = argc;
+         d->optind = argc;
        }
 
       /* If we have done all the ARGV-elements, stop the scan
         and back over any non-options that we skipped and permuted.  */
 
-      if (optind == argc)
+      if (d->optind == argc)
        {
          /* Set the next-arg-index to point at the non-options
             that we previously skipped, so the caller will digest them.  */
-         if (first_nonopt != last_nonopt)
-           optind = first_nonopt;
+         if (d->__first_nonopt != d->__last_nonopt)
+           d->optind = d->__first_nonopt;
          return -1;
        }
 
@@ -611,17 +489,17 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 
       if (NONOPTION_P)
        {
-         if (ordering == REQUIRE_ORDER)
+         if (d->__ordering == REQUIRE_ORDER)
            return -1;
-         optarg = argv[optind++];
+         d->optarg = argv[d->optind++];
          return 1;
        }
 
       /* We have found another option-ARGV-element.
         Skip the initial punctuation.  */
 
-      nextchar = (argv[optind] + 1
-                 + (longopts != NULL && argv[optind][1] == '-'));
+      d->__nextchar = (argv[d->optind] + 1
+                 + (longopts != NULL && argv[d->optind][1] == '-'));
     }
 
   /* Decode the current option-ARGV-element.  */
@@ -640,8 +518,9 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
      This distinction seems to be the most useful approach.  */
 
   if (longopts != NULL
-      && (argv[optind][1] == '-'
-         || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+      && (argv[d->optind][1] == '-'
+         || (long_only && (argv[d->optind][2]
+                           || !strchr (optstring, argv[d->optind][1])))))
     {
       char *nameend;
       const struct option *p;
@@ -651,15 +530,15 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
       int indfound = -1;
       int option_index;
 
-      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+      for (nameend = d->__nextchar; *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 (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
          {
-           if ((unsigned int) (nameend - nextchar)
+           if ((unsigned int) (nameend - d->__nextchar)
                == (unsigned int) strlen (p->name))
              {
                /* Exact match found.  */
@@ -690,7 +569,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
              char *buf;
 
              if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
-                             argv[0], argv[optind]) >= 0)
+                             argv[0], argv[d->optind]) >= 0)
                {
                  _IO_flockfile (stderr);
 
@@ -709,25 +588,25 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                }
 #else
              fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
-                      argv[0], argv[optind]);
+                      argv[0], argv[d->optind]);
 #endif
            }
-         nextchar += strlen (nextchar);
-         optind++;
-         optopt = 0;
+         d->__nextchar += strlen (d->__nextchar);
+         d->optind++;
+         d->optopt = 0;
          return '?';
        }
 
       if (pfound != NULL)
        {
          option_index = indfound;
-         optind++;
+         d->optind++;
          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;
+               d->optarg = nameend + 1;
              else
                {
                  if (print_errors)
@@ -737,7 +616,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                      int n;
 #endif
 
-                     if (argv[optind - 1][1] == '-')
+                     if (argv[d->optind - 1][1] == '-')
                        {
                          /* --option */
 #if defined _LIBC && defined USE_IN_LIBIO
@@ -756,12 +635,13 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 #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],
+                                         argv[0], argv[d->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);
+                                  argv[0], argv[d->optind - 1][0],
+                                  pfound->name);
 #endif
                        }
 
@@ -787,16 +667,16 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 #endif
                    }
 
-                 nextchar += strlen (nextchar);
+                 d->__nextchar += strlen (d->__nextchar);
 
-                 optopt = pfound->val;
+                 d->optopt = pfound->val;
                  return '?';
                }
            }
          else if (pfound->has_arg == 1)
            {
-             if (optind < argc)
-               optarg = argv[optind++];
+             if (d->optind < argc)
+               d->optarg = argv[d->optind++];
              else
                {
                  if (print_errors)
@@ -806,7 +686,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 
                      if (__asprintf (&buf, _("\
 %s: option `%s' requires an argument\n"),
-                                     argv[0], argv[optind - 1]) >= 0)
+                                     argv[0], argv[d->optind - 1]) >= 0)
                        {
                          _IO_flockfile (stderr);
 
@@ -827,15 +707,15 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 #else
                      fprintf (stderr,
                               _("%s: option `%s' requires an argument\n"),
-                              argv[0], argv[optind - 1]);
+                              argv[0], argv[d->optind - 1]);
 #endif
                    }
-                 nextchar += strlen (nextchar);
-                 optopt = pfound->val;
+                 d->__nextchar += strlen (d->__nextchar);
+                 d->optopt = pfound->val;
                  return optstring[0] == ':' ? ':' : '?';
                }
            }
-         nextchar += strlen (nextchar);
+         d->__nextchar += strlen (d->__nextchar);
          if (longind != NULL)
            *longind = option_index;
          if (pfound->flag)
@@ -850,8 +730,8 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
         or the option starts with '--' or is not a valid short
         option, then it's an error.
         Otherwise interpret it as a short option.  */
-      if (!long_only || argv[optind][1] == '-'
-         || my_index (optstring, *nextchar) == NULL)
+      if (!long_only || argv[d->optind][1] == '-'
+         || strchr (optstring, *d->__nextchar) == NULL)
        {
          if (print_errors)
            {
@@ -860,15 +740,15 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
              int n;
 #endif
 
-             if (argv[optind][1] == '-')
+             if (argv[d->optind][1] == '-')
                {
                  /* --option */
 #if defined _LIBC && defined USE_IN_LIBIO
                  n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
-                                 argv[0], nextchar);
+                                 argv[0], d->__nextchar);
 #else
                  fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
-                          argv[0], nextchar);
+                          argv[0], d->__nextchar);
 #endif
                }
              else
@@ -876,10 +756,10 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                  /* +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);
+                                 argv[0], argv[d->optind][0], d->__nextchar);
 #else
                  fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
-                          argv[0], argv[optind][0], nextchar);
+                          argv[0], argv[d->optind][0], d->__nextchar);
 #endif
                }
 
@@ -903,9 +783,9 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                }
 #endif
            }
-         nextchar = (char *) "";
-         optind++;
-         optopt = 0;
+         d->__nextchar = (char *) "";
+         d->optind++;
+         d->optopt = 0;
          return '?';
        }
     }
@@ -913,12 +793,12 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
   /* Look at and handle the next short option-character.  */
 
   {
-    char c = *nextchar++;
-    char *temp = my_index (optstring, c);
+    char c = *d->__nextchar++;
+    char *temp = strchr (optstring, c);
 
     /* Increment `optind' when we start to process its last character.  */
-    if (*nextchar == '\0')
-      ++optind;
+    if (*d->__nextchar == '\0')
+      ++d->optind;
 
     if (temp == NULL || c == ':')
       {
@@ -929,7 +809,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
              int n;
 #endif
 
-           if (posixly_correct)
+           if (d->__posixly_correct)
              {
                /* 1003.2 specifies the format of this message.  */
 #if defined _LIBC && defined USE_IN_LIBIO
@@ -969,7 +849,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
              }
 #endif
          }
-       optopt = c;
+       d->optopt = c;
        return '?';
       }
     /* Convenience. Treat POSIX -W foo same as long option --foo */
@@ -984,14 +864,14 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
        int option_index;
 
        /* This is an option that requires an argument.  */
-       if (*nextchar != '\0')
+       if (*d->__nextchar != '\0')
          {
-           optarg = nextchar;
+           d->optarg = d->__nextchar;
            /* If we end this ARGV-element by taking the rest as an arg,
               we must advance to the next element now.  */
-           optind++;
+           d->optind++;
          }
-       else if (optind == argc)
+       else if (d->optind == argc)
          {
            if (print_errors)
              {
@@ -1023,7 +903,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                         argv[0], c);
 #endif
              }
-           optopt = c;
+           d->optopt = c;
            if (optstring[0] == ':')
              c = ':';
            else
@@ -1031,22 +911,23 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
            return c;
          }
        else
-         /* We already incremented `optind' once;
+         /* We already incremented `d->optind' once;
             increment it again when taking next ARGV-elt as argument.  */
-         optarg = argv[optind++];
+         d->optarg = argv[d->optind++];
 
        /* optarg is now the argument, see if it's in the
           table of longopts.  */
 
-       for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+       for (d->__nextchar = nameend = d->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 (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
            {
-             if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+             if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
                {
                  /* Exact match found.  */
                  pfound = p;
@@ -1072,7 +953,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                char *buf;
 
                if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
-                               argv[0], argv[optind]) >= 0)
+                               argv[0], argv[d->optind]) >= 0)
                  {
                    _IO_flockfile (stderr);
 
@@ -1091,11 +972,11 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                  }
 #else
                fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
-                        argv[0], argv[optind]);
+                        argv[0], argv[d->optind]);
 #endif
              }
-           nextchar += strlen (nextchar);
-           optind++;
+           d->__nextchar += strlen (d->__nextchar);
+           d->optind++;
            return '?';
          }
        if (pfound != NULL)
@@ -1106,7 +987,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                /* 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;
+                 d->optarg = nameend + 1;
                else
                  {
                    if (print_errors)
@@ -1141,14 +1022,14 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 #endif
                      }
 
-                   nextchar += strlen (nextchar);
+                   d->__nextchar += strlen (d->__nextchar);
                    return '?';
                  }
              }
            else if (pfound->has_arg == 1)
              {
-               if (optind < argc)
-                 optarg = argv[optind++];
+               if (d->optind < argc)
+                 d->optarg = argv[d->optind++];
                else
                  {
                    if (print_errors)
@@ -1158,7 +1039,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 
                        if (__asprintf (&buf, _("\
 %s: option `%s' requires an argument\n"),
-                                       argv[0], argv[optind - 1]) >= 0)
+                                       argv[0], argv[d->optind - 1]) >= 0)
                          {
                            _IO_flockfile (stderr);
 
@@ -1179,14 +1060,14 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 #else
                        fprintf (stderr,
                                 _("%s: option `%s' requires an argument\n"),
-                                argv[0], argv[optind - 1]);
+                                argv[0], argv[d->optind - 1]);
 #endif
                      }
-                   nextchar += strlen (nextchar);
+                   d->__nextchar += strlen (d->__nextchar);
                    return optstring[0] == ':' ? ':' : '?';
                  }
              }
-           nextchar += strlen (nextchar);
+           d->__nextchar += strlen (d->__nextchar);
            if (longind != NULL)
              *longind = option_index;
            if (pfound->flag)
@@ -1196,7 +1077,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
              }
            return pfound->val;
          }
-         nextchar = NULL;
+         d->__nextchar = NULL;
          return 'W';   /* Let the application handle it.   */
       }
     if (temp[1] == ':')
@@ -1204,26 +1085,26 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
        if (temp[2] == ':')
          {
            /* This is an option that accepts an argument optionally.  */
-           if (*nextchar != '\0')
+           if (*d->__nextchar != '\0')
              {
-               optarg = nextchar;
-               optind++;
+               d->optarg = d->__nextchar;
+               d->optind++;
              }
            else
-             optarg = NULL;
-           nextchar = NULL;
+             d->optarg = NULL;
+           d->__nextchar = NULL;
          }
        else
          {
            /* This is an option that requires an argument.  */
-           if (*nextchar != '\0')
+           if (*d->__nextchar != '\0')
              {
-               optarg = nextchar;
+               d->optarg = d->__nextchar;
                /* If we end this ARGV-element by taking the rest as an arg,
                   we must advance to the next element now.  */
-               optind++;
+               d->optind++;
              }
-           else if (optind == argc)
+           else if (d->optind == argc)
              {
                if (print_errors)
                  {
@@ -1256,7 +1137,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                             argv[0], c);
 #endif
                  }
-               optopt = c;
+               d->optopt = c;
                if (optstring[0] == ':')
                  c = ':';
                else
@@ -1265,8 +1146,8 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
            else
              /* We already incremented `optind' once;
                 increment it again when taking next ARGV-elt as argument.  */
-             optarg = argv[optind++];
-           nextchar = NULL;
+             d->optarg = argv[d->optind++];
+           d->__nextchar = NULL;
          }
       }
     return c;
@@ -1274,10 +1155,26 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 }
 
 int
-getopt (argc, argv, optstring)
-     int argc;
-     char *const *argv;
-     const char *optstring;
+_getopt_internal (int argc, char *const *argv, const char *optstring,
+                 const struct option *longopts, int *longind, int long_only)
+{
+  int result;
+
+  getopt_data.optind = optind;
+  getopt_data.opterr = opterr;
+
+  result = _getopt_internal_r (argc, argv, optstring, longopts,
+                              longind, long_only, &getopt_data);
+
+  optind = getopt_data.optind;
+  optarg = getopt_data.optarg;
+  optopt = getopt_data.optopt;
+
+  return result;
+}
+
+int
+getopt (int argc, char *const *argv, const char *optstring)
 {
   return _getopt_internal (argc, argv, optstring,
                           (const struct option *) 0,
@@ -1293,9 +1190,7 @@ getopt (argc, argv, optstring)
    the above definition of `getopt'.  */
 
 int
-main (argc, argv)
-     int argc;
-     char **argv;
+main (int argc, char **argv)
 {
   int c;
   int digit_optind = 0;
index 675d3a7..a1de242 100644 (file)
@@ -105,11 +105,7 @@ extern int optopt;
 
 struct option
 {
-# if (defined __STDC__ && __STDC__) || defined __cplusplus
   const char *name;
-# else
-  char *name;
-# 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;
@@ -149,18 +145,17 @@ struct option
    arguments to the option '\0'.  This behavior is specific to the GNU
    `getopt'.  */
 
-#if (defined __STDC__ && __STDC__) || defined __cplusplus
-# ifdef __GNU_LIBRARY__
+#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;
-# else /* not __GNU_LIBRARY__ */
+#else /* not __GNU_LIBRARY__ */
 extern int getopt ();
-# endif /* __GNU_LIBRARY__ */
+#endif /* __GNU_LIBRARY__ */
 
-# ifndef __need_getopt
+#ifndef __need_getopt
 extern int getopt_long (int ___argc, char *const *___argv,
                        const char *__shortopts,
                        const struct option *__longopts, int *__longind)
@@ -170,21 +165,7 @@ extern int getopt_long_only (int ___argc, char *const *___argv,
                             const struct option *__longopts, int *__longind)
        __THROW;
 
-/* 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);
-# 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__ */
+#endif
 
 #ifdef __cplusplus
 }
index ad06cc7..2f75d4c 100644 (file)
@@ -1,5 +1,5 @@
 /* getopt_long and getopt_long_only entry points for GNU getopt.
-   Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+   Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004
      Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
 #else
 # include "getopt.h"
 #endif
-
-#if !defined __STDC__ || !__STDC__
-/* This is a separate conditional since some stdc systems
-   reject `defined (const)'.  */
-#ifndef const
-#define const
-#endif
-#endif
+#include "getopt_int.h"
 
 #include <stdio.h>
 
 #endif
 
 int
-getopt_long (argc, argv, options, long_options, opt_index)
-     int argc;
-     char *const *argv;
-     const char *options;
-     const struct option *long_options;
-     int *opt_index;
+getopt_long (int argc, char *const *argv, const char *options,
+            const struct option *long_options, int *opt_index)
 {
   return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
 }
 
+int
+_getopt_long_r (int argc, char *const *argv, const char *options,
+               const struct option *long_options, int *opt_index,
+               struct _getopt_data *d)
+{
+  return _getopt_internal_r (argc, argv, options, long_options, opt_index,
+                            0, d);
+}
+
 /* Like getopt_long, but '-' as well as '--' can indicate a long option.
    If an option that starts with '-' (not '--') doesn't match a long option,
    but does match a short option, it is parsed as a short option
    instead.  */
 
 int
-getopt_long_only (argc, argv, options, long_options, opt_index)
-     int argc;
-     char *const *argv;
-     const char *options;
-     const struct option *long_options;
-     int *opt_index;
+getopt_long_only (int argc, char *const *argv, const char *options,
+                 const struct option *long_options, int *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
+int
+_getopt_long_only_r (int argc, char *const *argv, const char *options,
+                    const struct option *long_options, int *opt_index,
+                    struct _getopt_data *d)
+{
+  return _getopt_internal_r (argc, argv, options, long_options, opt_index,
+                            1, d);
+}
 
 #endif /* Not ELIDE_CODE.  */
 \f
@@ -106,9 +104,7 @@ libc_hidden_def (getopt_long_only)
 #include <stdio.h>
 
 int
-main (argc, argv)
-     int argc;
-     char **argv;
+main (int argc, char **argv)
 {
   int c;
   int digit_optind = 0;
diff --git a/posix/getopt_int.h b/posix/getopt_int.h
new file mode 100644 (file)
index 0000000..d982c72
--- /dev/null
@@ -0,0 +1,130 @@
+/* Internal declarations for getopt.
+   Copyright (C) 1989-1994,1996-1999,2001,2003,2004
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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.
+
+   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
+   Lesser General Public License for more details.
+
+   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_INT_H
+#define _GETOPT_INT_H  1
+
+extern int _getopt_internal (int ___argc, char *const *___argv,
+                            const char *__shortopts,
+                            const struct option *__longopts, int *__longind,
+                            int __long_only);
+
+\f
+/* Reentrant versions which can handle parsing multiple argument
+   vectors at the same time.  */
+
+/* Data type for reentrant functions.  */
+struct _getopt_data
+{
+  /* These have exactly the same meaning as the corresponding global
+     variables, except that they are used for the reentrant
+     versions of getopt.  */
+  int optind;
+  int opterr;
+  int optopt;
+  char *optarg;
+
+  /* Internal members.  */
+
+  /* True if the internal members have been initialized.  */
+  int __initialized;
+
+  /* The next char to be scanned in the option-element
+     in which the last option character we returned was found.
+     This allows us to pick up the scan where we left off.
+
+     If this is zero, or a null string, it means resume the scan
+     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.  */
+  int __posixly_correct;
+
+
+  /* Handle permutation of arguments.  */
+
+  /* Describe the part of ARGV that contains non-options that have
+     been skipped.  `first_nonopt' is the index in ARGV of the first
+     of them; `last_nonopt' is the index after the last of them.  */
+
+  int __first_nonopt;
+  int __last_nonopt;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  int __nonoption_flags_max_len;
+  int __nonoption_flags_len;
+# endif
+};
+
+/* The initializer is necessary to set OPTIND and OPTERR to their
+   default values and to clear the initialization flag.  */
+#define _GETOPT_DATA_INITIALIZER       { 1, 1 }
+
+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);
+
+extern int _getopt_long_r (int ___argc, char *const *___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,
+                               const char *__shortopts,
+                               const struct option *__longopts,
+                               int *__longind,
+                               struct _getopt_data *__data);
+
+#endif /* getopt_int.h */