Blame gettext-runtime/gnulib-lib/getopt.c

Packit 5b56b6
/* Getopt for GNU.
Packit 5b56b6
   NOTE: getopt is part of the C library, so if you don't know what
Packit 5b56b6
   "Keep this file name-space clean" means, talk to drepper@gnu.org
Packit 5b56b6
   before changing it!
Packit 5b56b6
   Copyright (C) 1987-1996, 1998-2004, 2006, 2008-2015 Free Software
Packit 5b56b6
   Foundation, Inc.
Packit 5b56b6
   This file is part of the GNU C Library.
Packit 5b56b6
Packit 5b56b6
   This program is free software: you can redistribute it and/or modify
Packit 5b56b6
   it under the terms of the GNU General Public License as published by
Packit 5b56b6
   the Free Software Foundation; either version 3 of the License, or
Packit 5b56b6
   (at your option) any later version.
Packit 5b56b6
Packit 5b56b6
   This program is distributed in the hope that it will be useful,
Packit 5b56b6
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 5b56b6
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 5b56b6
   GNU General Public License for more details.
Packit 5b56b6
Packit 5b56b6
   You should have received a copy of the GNU General Public License
Packit 5b56b6
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 5b56b6

Packit 5b56b6
#ifndef _LIBC
Packit 5b56b6
# include <config.h>
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6
#include "getopt.h"
Packit 5b56b6
Packit 5b56b6
#include <stdio.h>
Packit 5b56b6
#include <stdlib.h>
Packit 5b56b6
#include <string.h>
Packit 5b56b6
#include <unistd.h>
Packit 5b56b6
Packit 5b56b6
#ifdef _LIBC
Packit 5b56b6
# include <libintl.h>
Packit 5b56b6
#else
Packit 5b56b6
# include "gettext.h"
Packit 5b56b6
# define _(msgid) gettext (msgid)
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
# include <wchar.h>
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6
/* This version of 'getopt' appears to the caller like standard Unix 'getopt'
Packit 5b56b6
   but it behaves differently for the user, since it allows the user
Packit 5b56b6
   to intersperse the options with the other arguments.
Packit 5b56b6
Packit 5b56b6
   As 'getopt_long' works, it permutes the elements of ARGV so that,
Packit 5b56b6
   when it is done, all the options precede everything else.  Thus
Packit 5b56b6
   all application programs are extended to handle flexible argument order.
Packit 5b56b6
Packit 5b56b6
   Using 'getopt' or setting the environment variable POSIXLY_CORRECT
Packit 5b56b6
   disables permutation.
Packit 5b56b6
   Then the behavior is completely standard.
Packit 5b56b6
Packit 5b56b6
   GNU application programs can use a third alternative mode in which
Packit 5b56b6
   they can distinguish the relative order of options and other arguments.  */
Packit 5b56b6
Packit 5b56b6
#include "getopt_int.h"
Packit 5b56b6
Packit 5b56b6
/* For communication from 'getopt' to the caller.
Packit 5b56b6
   When 'getopt' finds an option that takes an argument,
Packit 5b56b6
   the argument value is returned here.
Packit 5b56b6
   Also, when 'ordering' is RETURN_IN_ORDER,
Packit 5b56b6
   each non-option ARGV-element is returned here.  */
Packit 5b56b6
Packit 5b56b6
char *optarg;
Packit 5b56b6
Packit 5b56b6
/* Index in ARGV of the next element to be scanned.
Packit 5b56b6
   This is used for communication to and from the caller
Packit 5b56b6
   and for communication between successive calls to 'getopt'.
Packit 5b56b6
Packit 5b56b6
   On entry to 'getopt', zero means this is the first call; initialize.
Packit 5b56b6
Packit 5b56b6
   When 'getopt' returns -1, this is the index of the first of the
Packit 5b56b6
   non-option elements that the caller should itself scan.
Packit 5b56b6
Packit 5b56b6
   Otherwise, 'optind' communicates from one call to the next
Packit 5b56b6
   how much of ARGV has been scanned so far.  */
Packit 5b56b6
Packit 5b56b6
/* 1003.2 says this must be 1 before any call.  */
Packit 5b56b6
int optind = 1;
Packit 5b56b6
Packit 5b56b6
/* Callers store zero here to inhibit the error message
Packit 5b56b6
   for unrecognized options.  */
Packit 5b56b6
Packit 5b56b6
int opterr = 1;
Packit 5b56b6
Packit 5b56b6
/* Set to an option character which was unrecognized.
Packit 5b56b6
   This must be initialized on some systems to avoid linking in the
Packit 5b56b6
   system's own getopt implementation.  */
Packit 5b56b6
Packit 5b56b6
int optopt = '?';
Packit 5b56b6
Packit 5b56b6
/* Keep a global copy of all internal members of getopt_data.  */
Packit 5b56b6
Packit 5b56b6
static struct _getopt_data getopt_data;
Packit 5b56b6
Packit 5b56b6

Packit 5b56b6
#if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV
Packit 5b56b6
extern char *getenv ();
Packit 5b56b6
#endif
Packit 5b56b6

Packit 5b56b6
#ifdef _LIBC
Packit 5b56b6
/* Stored original parameters.
Packit 5b56b6
   XXX This is no good solution.  We should rather copy the args so
Packit 5b56b6
   that we can compare them later.  But we must not use malloc(3).  */
Packit 5b56b6
extern int __libc_argc;
Packit 5b56b6
extern char **__libc_argv;
Packit 5b56b6
Packit 5b56b6
/* Bash 2.0 gives us an environment variable containing flags
Packit 5b56b6
   indicating ARGV elements that should not be considered arguments.  */
Packit 5b56b6
Packit 5b56b6
# ifdef USE_NONOPTION_FLAGS
Packit 5b56b6
/* Defined in getopt_init.c  */
Packit 5b56b6
extern char *__getopt_nonoption_flags;
Packit 5b56b6
# endif
Packit 5b56b6
Packit 5b56b6
# ifdef USE_NONOPTION_FLAGS
Packit 5b56b6
#  define SWAP_FLAGS(ch1, ch2) \
Packit 5b56b6
  if (d->__nonoption_flags_len > 0)                                           \
Packit 5b56b6
    {                                                                         \
Packit 5b56b6
      char __tmp = __getopt_nonoption_flags[ch1];                             \
Packit 5b56b6
      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];          \
Packit 5b56b6
      __getopt_nonoption_flags[ch2] = __tmp;                                  \
Packit 5b56b6
    }
Packit 5b56b6
# else
Packit 5b56b6
#  define SWAP_FLAGS(ch1, ch2)
Packit 5b56b6
# endif
Packit 5b56b6
#else   /* !_LIBC */
Packit 5b56b6
# define SWAP_FLAGS(ch1, ch2)
Packit 5b56b6
#endif  /* _LIBC */
Packit 5b56b6
Packit 5b56b6
/* Exchange two adjacent subsequences of ARGV.
Packit 5b56b6
   One subsequence is elements [first_nonopt,last_nonopt)
Packit 5b56b6
   which contains all the non-options that have been skipped so far.
Packit 5b56b6
   The other is elements [last_nonopt,optind), which contains all
Packit 5b56b6
   the options processed since those non-options were skipped.
Packit 5b56b6
Packit 5b56b6
   'first_nonopt' and 'last_nonopt' are relocated so that they describe
Packit 5b56b6
   the new indices of the non-options in ARGV after they are moved.  */
Packit 5b56b6
Packit 5b56b6
static void
Packit 5b56b6
exchange (char **argv, struct _getopt_data *d)
Packit 5b56b6
{
Packit 5b56b6
  int bottom = d->__first_nonopt;
Packit 5b56b6
  int middle = d->__last_nonopt;
Packit 5b56b6
  int top = d->optind;
Packit 5b56b6
  char *tem;
Packit 5b56b6
Packit 5b56b6
  /* Exchange the shorter segment with the far end of the longer segment.
Packit 5b56b6
     That puts the shorter segment into the right place.
Packit 5b56b6
     It leaves the longer segment in the right place overall,
Packit 5b56b6
     but it consists of two parts that need to be swapped next.  */
Packit 5b56b6
Packit 5b56b6
#if defined _LIBC && defined USE_NONOPTION_FLAGS
Packit 5b56b6
  /* First make sure the handling of the '__getopt_nonoption_flags'
Packit 5b56b6
     string can work normally.  Our top argument must be in the range
Packit 5b56b6
     of the string.  */
Packit 5b56b6
  if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
Packit 5b56b6
    {
Packit 5b56b6
      /* We must extend the array.  The user plays games with us and
Packit 5b56b6
         presents new arguments.  */
Packit 5b56b6
      char *new_str = malloc (top + 1);
Packit 5b56b6
      if (new_str == NULL)
Packit 5b56b6
        d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
Packit 5b56b6
      else
Packit 5b56b6
        {
Packit 5b56b6
          memset (__mempcpy (new_str, __getopt_nonoption_flags,
Packit 5b56b6
                             d->__nonoption_flags_max_len),
Packit 5b56b6
                  '\0', top + 1 - d->__nonoption_flags_max_len);
Packit 5b56b6
          d->__nonoption_flags_max_len = top + 1;
Packit 5b56b6
          __getopt_nonoption_flags = new_str;
Packit 5b56b6
        }
Packit 5b56b6
    }
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6
  while (top > middle && middle > bottom)
Packit 5b56b6
    {
Packit 5b56b6
      if (top - middle > middle - bottom)
Packit 5b56b6
        {
Packit 5b56b6
          /* Bottom segment is the short one.  */
Packit 5b56b6
          int len = middle - bottom;
Packit 5b56b6
          register int i;
Packit 5b56b6
Packit 5b56b6
          /* Swap it with the top part of the top segment.  */
Packit 5b56b6
          for (i = 0; i < len; i++)
Packit 5b56b6
            {
Packit 5b56b6
              tem = argv[bottom + i];
Packit 5b56b6
              argv[bottom + i] = argv[top - (middle - bottom) + i];
Packit 5b56b6
              argv[top - (middle - bottom) + i] = tem;
Packit 5b56b6
              SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
Packit 5b56b6
            }
Packit 5b56b6
          /* Exclude the moved bottom segment from further swapping.  */
Packit 5b56b6
          top -= len;
Packit 5b56b6
        }
Packit 5b56b6
      else
Packit 5b56b6
        {
Packit 5b56b6
          /* Top segment is the short one.  */
Packit 5b56b6
          int len = top - middle;
Packit 5b56b6
          register int i;
Packit 5b56b6
Packit 5b56b6
          /* Swap it with the bottom part of the bottom segment.  */
Packit 5b56b6
          for (i = 0; i < len; i++)
Packit 5b56b6
            {
Packit 5b56b6
              tem = argv[bottom + i];
Packit 5b56b6
              argv[bottom + i] = argv[middle + i];
Packit 5b56b6
              argv[middle + i] = tem;
Packit 5b56b6
              SWAP_FLAGS (bottom + i, middle + i);
Packit 5b56b6
            }
Packit 5b56b6
          /* Exclude the moved top segment from further swapping.  */
Packit 5b56b6
          bottom += len;
Packit 5b56b6
        }
Packit 5b56b6
    }
Packit 5b56b6
Packit 5b56b6
  /* Update records for the slots the non-options now occupy.  */
Packit 5b56b6
Packit 5b56b6
  d->__first_nonopt += (d->optind - d->__last_nonopt);
Packit 5b56b6
  d->__last_nonopt = d->optind;
Packit 5b56b6
}
Packit 5b56b6
Packit 5b56b6
/* Initialize the internal data when the first call is made.  */
Packit 5b56b6
Packit 5b56b6
static const char *
Packit 5b56b6
_getopt_initialize (int argc _GL_UNUSED,
Packit 5b56b6
                    char **argv _GL_UNUSED, const char *optstring,
Packit 5b56b6
                    struct _getopt_data *d, int posixly_correct)
Packit 5b56b6
{
Packit 5b56b6
  /* Start processing options with ARGV-element 1 (since ARGV-element 0
Packit 5b56b6
     is the program name); the sequence of previously skipped
Packit 5b56b6
     non-option ARGV-elements is empty.  */
Packit 5b56b6
Packit 5b56b6
  d->__first_nonopt = d->__last_nonopt = d->optind;
Packit 5b56b6
Packit 5b56b6
  d->__nextchar = NULL;
Packit 5b56b6
Packit 5b56b6
  d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT");
Packit 5b56b6
Packit 5b56b6
  /* Determine how to handle the ordering of options and nonoptions.  */
Packit 5b56b6
Packit 5b56b6
  if (optstring[0] == '-')
Packit 5b56b6
    {
Packit 5b56b6
      d->__ordering = RETURN_IN_ORDER;
Packit 5b56b6
      ++optstring;
Packit 5b56b6
    }
Packit 5b56b6
  else if (optstring[0] == '+')
Packit 5b56b6
    {
Packit 5b56b6
      d->__ordering = REQUIRE_ORDER;
Packit 5b56b6
      ++optstring;
Packit 5b56b6
    }
Packit 5b56b6
  else if (d->__posixly_correct)
Packit 5b56b6
    d->__ordering = REQUIRE_ORDER;
Packit 5b56b6
  else
Packit 5b56b6
    d->__ordering = PERMUTE;
Packit 5b56b6
Packit 5b56b6
#if defined _LIBC && defined USE_NONOPTION_FLAGS
Packit 5b56b6
  if (!d->__posixly_correct
Packit 5b56b6
      && argc == __libc_argc && argv == __libc_argv)
Packit 5b56b6
    {
Packit 5b56b6
      if (d->__nonoption_flags_max_len == 0)
Packit 5b56b6
        {
Packit 5b56b6
          if (__getopt_nonoption_flags == NULL
Packit 5b56b6
              || __getopt_nonoption_flags[0] == '\0')
Packit 5b56b6
            d->__nonoption_flags_max_len = -1;
Packit 5b56b6
          else
Packit 5b56b6
            {
Packit 5b56b6
              const char *orig_str = __getopt_nonoption_flags;
Packit 5b56b6
              int len = d->__nonoption_flags_max_len = strlen (orig_str);
Packit 5b56b6
              if (d->__nonoption_flags_max_len < argc)
Packit 5b56b6
                d->__nonoption_flags_max_len = argc;
Packit 5b56b6
              __getopt_nonoption_flags =
Packit 5b56b6
                (char *) malloc (d->__nonoption_flags_max_len);
Packit 5b56b6
              if (__getopt_nonoption_flags == NULL)
Packit 5b56b6
                d->__nonoption_flags_max_len = -1;
Packit 5b56b6
              else
Packit 5b56b6
                memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
Packit 5b56b6
                        '\0', d->__nonoption_flags_max_len - len);
Packit 5b56b6
            }
Packit 5b56b6
        }
Packit 5b56b6
      d->__nonoption_flags_len = d->__nonoption_flags_max_len;
Packit 5b56b6
    }
Packit 5b56b6
  else
Packit 5b56b6
    d->__nonoption_flags_len = 0;
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6
  return optstring;
Packit 5b56b6
}
Packit 5b56b6

Packit 5b56b6
/* Scan elements of ARGV (whose length is ARGC) for option characters
Packit 5b56b6
   given in OPTSTRING.
Packit 5b56b6
Packit 5b56b6
   If an element of ARGV starts with '-', and is not exactly "-" or "--",
Packit 5b56b6
   then it is an option element.  The characters of this element
Packit 5b56b6
   (aside from the initial '-') are option characters.  If 'getopt'
Packit 5b56b6
   is called repeatedly, it returns successively each of the option characters
Packit 5b56b6
   from each of the option elements.
Packit 5b56b6
Packit 5b56b6
   If 'getopt' finds another option character, it returns that character,
Packit 5b56b6
   updating 'optind' and 'nextchar' so that the next call to 'getopt' can
Packit 5b56b6
   resume the scan with the following option character or ARGV-element.
Packit 5b56b6
Packit 5b56b6
   If there are no more option characters, 'getopt' returns -1.
Packit 5b56b6
   Then 'optind' is the index in ARGV of the first ARGV-element
Packit 5b56b6
   that is not an option.  (The ARGV-elements have been permuted
Packit 5b56b6
   so that those that are not options now come last.)
Packit 5b56b6
Packit 5b56b6
   OPTSTRING is a string containing the legitimate option characters.
Packit 5b56b6
   If an option character is seen that is not listed in OPTSTRING,
Packit 5b56b6
   return '?' after printing an error message.  If you set 'opterr' to
Packit 5b56b6
   zero, the error message is suppressed but we still return '?'.
Packit 5b56b6
Packit 5b56b6
   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
Packit 5b56b6
   so the following text in the same ARGV-element, or the text of the following
Packit 5b56b6
   ARGV-element, is returned in 'optarg'.  Two colons mean an option that
Packit 5b56b6
   wants an optional arg; if there is text in the current ARGV-element,
Packit 5b56b6
   it is returned in 'optarg', otherwise 'optarg' is set to zero.
Packit 5b56b6
Packit 5b56b6
   If OPTSTRING starts with '-' or '+', it requests different methods of
Packit 5b56b6
   handling the non-option ARGV-elements.
Packit 5b56b6
   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
Packit 5b56b6
Packit 5b56b6
   Long-named options begin with '--' instead of '-'.
Packit 5b56b6
   Their names may be abbreviated as long as the abbreviation is unique
Packit 5b56b6
   or is an exact match for some defined option.  If they have an
Packit 5b56b6
   argument, it follows the option name in the same ARGV-element, separated
Packit 5b56b6
   from the option name by a '=', or else the in next ARGV-element.
Packit 5b56b6
   When 'getopt' finds a long-named option, it returns 0 if that option's
Packit 5b56b6
   'flag' field is nonzero, the value of the option's 'val' field
Packit 5b56b6
   if the 'flag' field is zero.
Packit 5b56b6
Packit 5b56b6
   The elements of ARGV aren't really const, because we permute them.
Packit 5b56b6
   But we pretend they're const in the prototype to be compatible
Packit 5b56b6
   with other systems.
Packit 5b56b6
Packit 5b56b6
   LONGOPTS is a vector of 'struct option' terminated by an
Packit 5b56b6
   element containing a name which is zero.
Packit 5b56b6
Packit 5b56b6
   LONGIND returns the index in LONGOPT of the long-named option found.
Packit 5b56b6
   It is only valid when a long-named option has been found by the most
Packit 5b56b6
   recent call.
Packit 5b56b6
Packit 5b56b6
   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
Packit 5b56b6
   long-named options.  */
Packit 5b56b6
Packit 5b56b6
int
Packit 5b56b6
_getopt_internal_r (int argc, char **argv, const char *optstring,
Packit 5b56b6
                    const struct option *longopts, int *longind,
Packit 5b56b6
                    int long_only, struct _getopt_data *d, int posixly_correct)
Packit 5b56b6
{
Packit 5b56b6
  int print_errors = d->opterr;
Packit 5b56b6
Packit 5b56b6
  if (argc < 1)
Packit 5b56b6
    return -1;
Packit 5b56b6
Packit 5b56b6
  d->optarg = NULL;
Packit 5b56b6
Packit 5b56b6
  if (d->optind == 0 || !d->__initialized)
Packit 5b56b6
    {
Packit 5b56b6
      if (d->optind == 0)
Packit 5b56b6
        d->optind = 1;  /* Don't scan ARGV[0], the program name.  */
Packit 5b56b6
      optstring = _getopt_initialize (argc, argv, optstring, d,
Packit 5b56b6
                                      posixly_correct);
Packit 5b56b6
      d->__initialized = 1;
Packit 5b56b6
    }
Packit 5b56b6
  else if (optstring[0] == '-' || optstring[0] == '+')
Packit 5b56b6
    optstring++;
Packit 5b56b6
  if (optstring[0] == ':')
Packit 5b56b6
    print_errors = 0;
Packit 5b56b6
Packit 5b56b6
  /* Test whether ARGV[optind] points to a non-option argument.
Packit 5b56b6
     Either it does not have option syntax, or there is an environment flag
Packit 5b56b6
     from the shell indicating it is not an option.  The later information
Packit 5b56b6
     is only used when the used in the GNU libc.  */
Packit 5b56b6
#if defined _LIBC && defined USE_NONOPTION_FLAGS
Packit 5b56b6
# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \
Packit 5b56b6
                      || (d->optind < d->__nonoption_flags_len                \
Packit 5b56b6
                          && __getopt_nonoption_flags[d->optind] == '1'))
Packit 5b56b6
#else
Packit 5b56b6
# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6
  if (d->__nextchar == NULL || *d->__nextchar == '\0')
Packit 5b56b6
    {
Packit 5b56b6
      /* Advance to the next ARGV-element.  */
Packit 5b56b6
Packit 5b56b6
      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
Packit 5b56b6
         moved back by the user (who may also have changed the arguments).  */
Packit 5b56b6
      if (d->__last_nonopt > d->optind)
Packit 5b56b6
        d->__last_nonopt = d->optind;
Packit 5b56b6
      if (d->__first_nonopt > d->optind)
Packit 5b56b6
        d->__first_nonopt = d->optind;
Packit 5b56b6
Packit 5b56b6
      if (d->__ordering == PERMUTE)
Packit 5b56b6
        {
Packit 5b56b6
          /* If we have just processed some options following some non-options,
Packit 5b56b6
             exchange them so that the options come first.  */
Packit 5b56b6
Packit 5b56b6
          if (d->__first_nonopt != d->__last_nonopt
Packit 5b56b6
              && d->__last_nonopt != d->optind)
Packit 5b56b6
            exchange ((char **) argv, d);
Packit 5b56b6
          else if (d->__last_nonopt != d->optind)
Packit 5b56b6
            d->__first_nonopt = d->optind;
Packit 5b56b6
Packit 5b56b6
          /* Skip any additional non-options
Packit 5b56b6
             and extend the range of non-options previously skipped.  */
Packit 5b56b6
Packit 5b56b6
          while (d->optind < argc && NONOPTION_P)
Packit 5b56b6
            d->optind++;
Packit 5b56b6
          d->__last_nonopt = d->optind;
Packit 5b56b6
        }
Packit 5b56b6
Packit 5b56b6
      /* The special ARGV-element '--' means premature end of options.
Packit 5b56b6
         Skip it like a null option,
Packit 5b56b6
         then exchange with previous non-options as if it were an option,
Packit 5b56b6
         then skip everything else like a non-option.  */
Packit 5b56b6
Packit 5b56b6
      if (d->optind != argc && !strcmp (argv[d->optind], "--"))
Packit 5b56b6
        {
Packit 5b56b6
          d->optind++;
Packit 5b56b6
Packit 5b56b6
          if (d->__first_nonopt != d->__last_nonopt
Packit 5b56b6
              && d->__last_nonopt != d->optind)
Packit 5b56b6
            exchange ((char **) argv, d);
Packit 5b56b6
          else if (d->__first_nonopt == d->__last_nonopt)
Packit 5b56b6
            d->__first_nonopt = d->optind;
Packit 5b56b6
          d->__last_nonopt = argc;
Packit 5b56b6
Packit 5b56b6
          d->optind = argc;
Packit 5b56b6
        }
Packit 5b56b6
Packit 5b56b6
      /* If we have done all the ARGV-elements, stop the scan
Packit 5b56b6
         and back over any non-options that we skipped and permuted.  */
Packit 5b56b6
Packit 5b56b6
      if (d->optind == argc)
Packit 5b56b6
        {
Packit 5b56b6
          /* Set the next-arg-index to point at the non-options
Packit 5b56b6
             that we previously skipped, so the caller will digest them.  */
Packit 5b56b6
          if (d->__first_nonopt != d->__last_nonopt)
Packit 5b56b6
            d->optind = d->__first_nonopt;
Packit 5b56b6
          return -1;
Packit 5b56b6
        }
Packit 5b56b6
Packit 5b56b6
      /* If we have come to a non-option and did not permute it,
Packit 5b56b6
         either stop the scan or describe it to the caller and pass it by.  */
Packit 5b56b6
Packit 5b56b6
      if (NONOPTION_P)
Packit 5b56b6
        {
Packit 5b56b6
          if (d->__ordering == REQUIRE_ORDER)
Packit 5b56b6
            return -1;
Packit 5b56b6
          d->optarg = argv[d->optind++];
Packit 5b56b6
          return 1;
Packit 5b56b6
        }
Packit 5b56b6
Packit 5b56b6
      /* We have found another option-ARGV-element.
Packit 5b56b6
         Skip the initial punctuation.  */
Packit 5b56b6
Packit 5b56b6
      d->__nextchar = (argv[d->optind] + 1
Packit 5b56b6
                  + (longopts != NULL && argv[d->optind][1] == '-'));
Packit 5b56b6
    }
Packit 5b56b6
Packit 5b56b6
  /* Decode the current option-ARGV-element.  */
Packit 5b56b6
Packit 5b56b6
  /* Check whether the ARGV-element is a long option.
Packit 5b56b6
Packit 5b56b6
     If long_only and the ARGV-element has the form "-f", where f is
Packit 5b56b6
     a valid short option, don't consider it an abbreviated form of
Packit 5b56b6
     a long option that starts with f.  Otherwise there would be no
Packit 5b56b6
     way to give the -f short option.
Packit 5b56b6
Packit 5b56b6
     On the other hand, if there's a long option "fubar" and
Packit 5b56b6
     the ARGV-element is "-fu", do consider that an abbreviation of
Packit 5b56b6
     the long option, just like "--fu", and not "-f" with arg "u".
Packit 5b56b6
Packit 5b56b6
     This distinction seems to be the most useful approach.  */
Packit 5b56b6
Packit 5b56b6
  if (longopts != NULL
Packit 5b56b6
      && (argv[d->optind][1] == '-'
Packit 5b56b6
          || (long_only && (argv[d->optind][2]
Packit 5b56b6
                            || !strchr (optstring, argv[d->optind][1])))))
Packit 5b56b6
    {
Packit 5b56b6
      char *nameend;
Packit 5b56b6
      unsigned int namelen;
Packit 5b56b6
      const struct option *p;
Packit 5b56b6
      const struct option *pfound = NULL;
Packit 5b56b6
      struct option_list
Packit 5b56b6
      {
Packit 5b56b6
        const struct option *p;
Packit 5b56b6
        struct option_list *next;
Packit 5b56b6
      } *ambig_list = NULL;
Packit 5b56b6
#ifdef _LIBC
Packit 5b56b6
/* malloc() not used for _LIBC to simplify failure messages.  */
Packit 5b56b6
# define free_option_list(l)
Packit 5b56b6
#else
Packit 5b56b6
# define free_option_list(l)			\
Packit 5b56b6
      while (l != NULL)				\
Packit 5b56b6
        {					\
Packit 5b56b6
          struct option_list *pn = l->next;	\
Packit 5b56b6
          free (l);				\
Packit 5b56b6
          l = pn;				\
Packit 5b56b6
        }
Packit 5b56b6
#endif
Packit 5b56b6
      int exact = 0;
Packit 5b56b6
      int ambig = 0;
Packit 5b56b6
      int indfound = -1;
Packit 5b56b6
      int option_index;
Packit 5b56b6
Packit 5b56b6
      for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
Packit 5b56b6
        /* Do nothing.  */ ;
Packit 5b56b6
      namelen = nameend - d->__nextchar;
Packit 5b56b6
Packit 5b56b6
      /* Test all long options for either exact match
Packit 5b56b6
         or abbreviated matches.  */
Packit 5b56b6
      for (p = longopts, option_index = 0; p->name; p++, option_index++)
Packit 5b56b6
        if (!strncmp (p->name, d->__nextchar, namelen))
Packit 5b56b6
          {
Packit 5b56b6
            if (namelen == (unsigned int) strlen (p->name))
Packit 5b56b6
              {
Packit 5b56b6
                /* Exact match found.  */
Packit 5b56b6
                pfound = p;
Packit 5b56b6
                indfound = option_index;
Packit 5b56b6
                exact = 1;
Packit 5b56b6
                break;
Packit 5b56b6
              }
Packit 5b56b6
            else if (pfound == NULL)
Packit 5b56b6
              {
Packit 5b56b6
                /* First nonexact match found.  */
Packit 5b56b6
                pfound = p;
Packit 5b56b6
                indfound = option_index;
Packit 5b56b6
              }
Packit 5b56b6
            else if (ambig)
Packit 5b56b6
              ; /* Taking simpler path to handling ambiguities.  */
Packit 5b56b6
            else if (long_only
Packit 5b56b6
                     || pfound->has_arg != p->has_arg
Packit 5b56b6
                     || pfound->flag != p->flag
Packit 5b56b6
                     || pfound->val != p->val)
Packit 5b56b6
              {
Packit 5b56b6
                /* Second or later nonexact match found.  */
Packit 5b56b6
#ifdef _LIBC
Packit 5b56b6
                struct option_list *newp = alloca (sizeof (*newp));
Packit 5b56b6
#else
Packit 5b56b6
                struct option_list *newp = malloc (sizeof (*newp));
Packit 5b56b6
                if (newp == NULL)
Packit 5b56b6
                  {
Packit 5b56b6
                    free_option_list (ambig_list);
Packit 5b56b6
                    ambig_list = NULL;
Packit 5b56b6
                    ambig = 1; /* Use simpler fallback message.  */
Packit 5b56b6
                  }
Packit 5b56b6
                else
Packit 5b56b6
#endif
Packit 5b56b6
                  {
Packit 5b56b6
                    newp->p = p;
Packit 5b56b6
                    newp->next = ambig_list;
Packit 5b56b6
                    ambig_list = newp;
Packit 5b56b6
                  }
Packit 5b56b6
              }
Packit 5b56b6
          }
Packit 5b56b6
Packit 5b56b6
      if ((ambig || ambig_list) && !exact)
Packit 5b56b6
        {
Packit 5b56b6
          if (print_errors && ambig_list)
Packit 5b56b6
            {
Packit 5b56b6
              struct option_list first;
Packit 5b56b6
              first.p = pfound;
Packit 5b56b6
              first.next = ambig_list;
Packit 5b56b6
              ambig_list = &first;
Packit 5b56b6
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
              char *buf = NULL;
Packit 5b56b6
              size_t buflen = 0;
Packit 5b56b6
Packit 5b56b6
              FILE *fp = open_memstream (&buf, &buflen);
Packit 5b56b6
              if (fp != NULL)
Packit 5b56b6
                {
Packit 5b56b6
                  fprintf (fp,
Packit 5b56b6
                           _("%s: option '%s' is ambiguous; possibilities:"),
Packit 5b56b6
                           argv[0], argv[d->optind]);
Packit 5b56b6
Packit 5b56b6
                  do
Packit 5b56b6
                    {
Packit 5b56b6
                      fprintf (fp, " '--%s'", ambig_list->p->name);
Packit 5b56b6
                      ambig_list = ambig_list->next;
Packit 5b56b6
                    }
Packit 5b56b6
                  while (ambig_list != NULL);
Packit 5b56b6
Packit 5b56b6
                  fputc_unlocked ('\n', fp);
Packit 5b56b6
Packit 5b56b6
                  if (__builtin_expect (fclose (fp) != EOF, 1))
Packit 5b56b6
                    {
Packit 5b56b6
                      _IO_flockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                      int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
Packit 5b56b6
                      ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
Packit 5b56b6
Packit 5b56b6
                      __fxprintf (NULL, "%s", buf);
Packit 5b56b6
Packit 5b56b6
                      ((_IO_FILE *) stderr)->_flags2 = old_flags2;
Packit 5b56b6
                      _IO_funlockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                      free (buf);
Packit 5b56b6
                    }
Packit 5b56b6
                }
Packit 5b56b6
#else
Packit 5b56b6
              fprintf (stderr,
Packit 5b56b6
                       _("%s: option '%s' is ambiguous; possibilities:"),
Packit 5b56b6
                       argv[0], argv[d->optind]);
Packit 5b56b6
              do
Packit 5b56b6
                {
Packit 5b56b6
                  fprintf (stderr, " '--%s'", ambig_list->p->name);
Packit 5b56b6
                  ambig_list = ambig_list->next;
Packit 5b56b6
                }
Packit 5b56b6
              while (ambig_list != NULL);
Packit 5b56b6
Packit 5b56b6
              fputc ('\n', stderr);
Packit 5b56b6
#endif
Packit 5b56b6
            }
Packit 5b56b6
          else if (print_errors && ambig)
Packit 5b56b6
            {
Packit 5b56b6
              fprintf (stderr,
Packit 5b56b6
                       _("%s: option '%s' is ambiguous\n"),
Packit 5b56b6
                       argv[0], argv[d->optind]);
Packit 5b56b6
            }
Packit 5b56b6
          d->__nextchar += strlen (d->__nextchar);
Packit 5b56b6
          d->optind++;
Packit 5b56b6
          d->optopt = 0;
Packit 5b56b6
          free_option_list (ambig_list);
Packit 5b56b6
          return '?';
Packit 5b56b6
        }
Packit 5b56b6
Packit 5b56b6
      free_option_list (ambig_list);
Packit 5b56b6
Packit 5b56b6
      if (pfound != NULL)
Packit 5b56b6
        {
Packit 5b56b6
          option_index = indfound;
Packit 5b56b6
          d->optind++;
Packit 5b56b6
          if (*nameend)
Packit 5b56b6
            {
Packit 5b56b6
              /* Don't test has_arg with >, because some C compilers don't
Packit 5b56b6
                 allow it to be used on enums.  */
Packit 5b56b6
              if (pfound->has_arg)
Packit 5b56b6
                d->optarg = nameend + 1;
Packit 5b56b6
              else
Packit 5b56b6
                {
Packit 5b56b6
                  if (print_errors)
Packit 5b56b6
                    {
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
                      char *buf;
Packit 5b56b6
                      int n;
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6
                      if (argv[d->optind - 1][1] == '-')
Packit 5b56b6
                        {
Packit 5b56b6
                          /* --option */
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
                          n = __asprintf (&buf, _("\
Packit 5b56b6
%s: option '--%s' doesn't allow an argument\n"),
Packit 5b56b6
                                          argv[0], pfound->name);
Packit 5b56b6
#else
Packit 5b56b6
                          fprintf (stderr, _("\
Packit 5b56b6
%s: option '--%s' doesn't allow an argument\n"),
Packit 5b56b6
                                   argv[0], pfound->name);
Packit 5b56b6
#endif
Packit 5b56b6
                        }
Packit 5b56b6
                      else
Packit 5b56b6
                        {
Packit 5b56b6
                          /* +option or -option */
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
                          n = __asprintf (&buf, _("\
Packit 5b56b6
%s: option '%c%s' doesn't allow an argument\n"),
Packit 5b56b6
                                          argv[0], argv[d->optind - 1][0],
Packit 5b56b6
                                          pfound->name);
Packit 5b56b6
#else
Packit 5b56b6
                          fprintf (stderr, _("\
Packit 5b56b6
%s: option '%c%s' doesn't allow an argument\n"),
Packit 5b56b6
                                   argv[0], argv[d->optind - 1][0],
Packit 5b56b6
                                   pfound->name);
Packit 5b56b6
#endif
Packit 5b56b6
                        }
Packit 5b56b6
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
                      if (n >= 0)
Packit 5b56b6
                        {
Packit 5b56b6
                          _IO_flockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                          int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
Packit 5b56b6
                          ((_IO_FILE *) stderr)->_flags2
Packit 5b56b6
                            |= _IO_FLAGS2_NOTCANCEL;
Packit 5b56b6
Packit 5b56b6
                          __fxprintf (NULL, "%s", buf);
Packit 5b56b6
Packit 5b56b6
                          ((_IO_FILE *) stderr)->_flags2 = old_flags2;
Packit 5b56b6
                          _IO_funlockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                          free (buf);
Packit 5b56b6
                        }
Packit 5b56b6
#endif
Packit 5b56b6
                    }
Packit 5b56b6
Packit 5b56b6
                  d->__nextchar += strlen (d->__nextchar);
Packit 5b56b6
Packit 5b56b6
                  d->optopt = pfound->val;
Packit 5b56b6
                  return '?';
Packit 5b56b6
                }
Packit 5b56b6
            }
Packit 5b56b6
          else if (pfound->has_arg == 1)
Packit 5b56b6
            {
Packit 5b56b6
              if (d->optind < argc)
Packit 5b56b6
                d->optarg = argv[d->optind++];
Packit 5b56b6
              else
Packit 5b56b6
                {
Packit 5b56b6
                  if (print_errors)
Packit 5b56b6
                    {
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
                      char *buf;
Packit 5b56b6
Packit 5b56b6
                      if (__asprintf (&buf, _("\
Packit 5b56b6
%s: option '--%s' requires an argument\n"),
Packit 5b56b6
                                      argv[0], pfound->name) >= 0)
Packit 5b56b6
                        {
Packit 5b56b6
                          _IO_flockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                          int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
Packit 5b56b6
                          ((_IO_FILE *) stderr)->_flags2
Packit 5b56b6
                            |= _IO_FLAGS2_NOTCANCEL;
Packit 5b56b6
Packit 5b56b6
                          __fxprintf (NULL, "%s", buf);
Packit 5b56b6
Packit 5b56b6
                          ((_IO_FILE *) stderr)->_flags2 = old_flags2;
Packit 5b56b6
                          _IO_funlockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                          free (buf);
Packit 5b56b6
                        }
Packit 5b56b6
#else
Packit 5b56b6
                      fprintf (stderr,
Packit 5b56b6
                               _("%s: option '--%s' requires an argument\n"),
Packit 5b56b6
                               argv[0], pfound->name);
Packit 5b56b6
#endif
Packit 5b56b6
                    }
Packit 5b56b6
                  d->__nextchar += strlen (d->__nextchar);
Packit 5b56b6
                  d->optopt = pfound->val;
Packit 5b56b6
                  return optstring[0] == ':' ? ':' : '?';
Packit 5b56b6
                }
Packit 5b56b6
            }
Packit 5b56b6
          d->__nextchar += strlen (d->__nextchar);
Packit 5b56b6
          if (longind != NULL)
Packit 5b56b6
            *longind = option_index;
Packit 5b56b6
          if (pfound->flag)
Packit 5b56b6
            {
Packit 5b56b6
              *(pfound->flag) = pfound->val;
Packit 5b56b6
              return 0;
Packit 5b56b6
            }
Packit 5b56b6
          return pfound->val;
Packit 5b56b6
        }
Packit 5b56b6
Packit 5b56b6
      /* Can't find it as a long option.  If this is not getopt_long_only,
Packit 5b56b6
         or the option starts with '--' or is not a valid short
Packit 5b56b6
         option, then it's an error.
Packit 5b56b6
         Otherwise interpret it as a short option.  */
Packit 5b56b6
      if (!long_only || argv[d->optind][1] == '-'
Packit 5b56b6
          || strchr (optstring, *d->__nextchar) == NULL)
Packit 5b56b6
        {
Packit 5b56b6
          if (print_errors)
Packit 5b56b6
            {
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
              char *buf;
Packit 5b56b6
              int n;
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6
              if (argv[d->optind][1] == '-')
Packit 5b56b6
                {
Packit 5b56b6
                  /* --option */
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
                  n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"),
Packit 5b56b6
                                  argv[0], d->__nextchar);
Packit 5b56b6
#else
Packit 5b56b6
                  fprintf (stderr, _("%s: unrecognized option '--%s'\n"),
Packit 5b56b6
                           argv[0], d->__nextchar);
Packit 5b56b6
#endif
Packit 5b56b6
                }
Packit 5b56b6
              else
Packit 5b56b6
                {
Packit 5b56b6
                  /* +option or -option */
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
                  n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"),
Packit 5b56b6
                                  argv[0], argv[d->optind][0], d->__nextchar);
Packit 5b56b6
#else
Packit 5b56b6
                  fprintf (stderr, _("%s: unrecognized option '%c%s'\n"),
Packit 5b56b6
                           argv[0], argv[d->optind][0], d->__nextchar);
Packit 5b56b6
#endif
Packit 5b56b6
                }
Packit 5b56b6
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
              if (n >= 0)
Packit 5b56b6
                {
Packit 5b56b6
                  _IO_flockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
Packit 5b56b6
                  ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
Packit 5b56b6
Packit 5b56b6
                  __fxprintf (NULL, "%s", buf);
Packit 5b56b6
Packit 5b56b6
                  ((_IO_FILE *) stderr)->_flags2 = old_flags2;
Packit 5b56b6
                  _IO_funlockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                  free (buf);
Packit 5b56b6
                }
Packit 5b56b6
#endif
Packit 5b56b6
            }
Packit 5b56b6
          d->__nextchar = (char *) "";
Packit 5b56b6
          d->optind++;
Packit 5b56b6
          d->optopt = 0;
Packit 5b56b6
          return '?';
Packit 5b56b6
        }
Packit 5b56b6
    }
Packit 5b56b6
Packit 5b56b6
  /* Look at and handle the next short option-character.  */
Packit 5b56b6
Packit 5b56b6
  {
Packit 5b56b6
    char c = *d->__nextchar++;
Packit 5b56b6
    const char *temp = strchr (optstring, c);
Packit 5b56b6
Packit 5b56b6
    /* Increment 'optind' when we start to process its last character.  */
Packit 5b56b6
    if (*d->__nextchar == '\0')
Packit 5b56b6
      ++d->optind;
Packit 5b56b6
Packit 5b56b6
    if (temp == NULL || c == ':' || c == ';')
Packit 5b56b6
      {
Packit 5b56b6
        if (print_errors)
Packit 5b56b6
          {
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
              char *buf;
Packit 5b56b6
              int n;
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
              n = __asprintf (&buf, _("%s: invalid option -- '%c'\n"),
Packit 5b56b6
                              argv[0], c);
Packit 5b56b6
#else
Packit 5b56b6
              fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c);
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
            if (n >= 0)
Packit 5b56b6
              {
Packit 5b56b6
                _IO_flockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
Packit 5b56b6
                ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
Packit 5b56b6
Packit 5b56b6
                __fxprintf (NULL, "%s", buf);
Packit 5b56b6
Packit 5b56b6
                ((_IO_FILE *) stderr)->_flags2 = old_flags2;
Packit 5b56b6
                _IO_funlockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                free (buf);
Packit 5b56b6
              }
Packit 5b56b6
#endif
Packit 5b56b6
          }
Packit 5b56b6
        d->optopt = c;
Packit 5b56b6
        return '?';
Packit 5b56b6
      }
Packit 5b56b6
    /* Convenience. Treat POSIX -W foo same as long option --foo */
Packit 5b56b6
    if (temp[0] == 'W' && temp[1] == ';')
Packit 5b56b6
      {
Packit 5b56b6
        char *nameend;
Packit 5b56b6
        const struct option *p;
Packit 5b56b6
        const struct option *pfound = NULL;
Packit 5b56b6
        int exact = 0;
Packit 5b56b6
        int ambig = 0;
Packit 5b56b6
        int indfound = 0;
Packit 5b56b6
        int option_index;
Packit 5b56b6
Packit 5b56b6
        if (longopts == NULL)
Packit 5b56b6
          goto no_longs;
Packit 5b56b6
Packit 5b56b6
        /* This is an option that requires an argument.  */
Packit 5b56b6
        if (*d->__nextchar != '\0')
Packit 5b56b6
          {
Packit 5b56b6
            d->optarg = d->__nextchar;
Packit 5b56b6
            /* If we end this ARGV-element by taking the rest as an arg,
Packit 5b56b6
               we must advance to the next element now.  */
Packit 5b56b6
            d->optind++;
Packit 5b56b6
          }
Packit 5b56b6
        else if (d->optind == argc)
Packit 5b56b6
          {
Packit 5b56b6
            if (print_errors)
Packit 5b56b6
              {
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
                char *buf;
Packit 5b56b6
Packit 5b56b6
                if (__asprintf (&buf,
Packit 5b56b6
                                _("%s: option requires an argument -- '%c'\n"),
Packit 5b56b6
                                argv[0], c) >= 0)
Packit 5b56b6
                  {
Packit 5b56b6
                    _IO_flockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
Packit 5b56b6
                    ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
Packit 5b56b6
Packit 5b56b6
                    __fxprintf (NULL, "%s", buf);
Packit 5b56b6
Packit 5b56b6
                    ((_IO_FILE *) stderr)->_flags2 = old_flags2;
Packit 5b56b6
                    _IO_funlockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                    free (buf);
Packit 5b56b6
                  }
Packit 5b56b6
#else
Packit 5b56b6
                fprintf (stderr,
Packit 5b56b6
                         _("%s: option requires an argument -- '%c'\n"),
Packit 5b56b6
                         argv[0], c);
Packit 5b56b6
#endif
Packit 5b56b6
              }
Packit 5b56b6
            d->optopt = c;
Packit 5b56b6
            if (optstring[0] == ':')
Packit 5b56b6
              c = ':';
Packit 5b56b6
            else
Packit 5b56b6
              c = '?';
Packit 5b56b6
            return c;
Packit 5b56b6
          }
Packit 5b56b6
        else
Packit 5b56b6
          /* We already incremented 'd->optind' once;
Packit 5b56b6
             increment it again when taking next ARGV-elt as argument.  */
Packit 5b56b6
          d->optarg = argv[d->optind++];
Packit 5b56b6
Packit 5b56b6
        /* optarg is now the argument, see if it's in the
Packit 5b56b6
           table of longopts.  */
Packit 5b56b6
Packit 5b56b6
        for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
Packit 5b56b6
             nameend++)
Packit 5b56b6
          /* Do nothing.  */ ;
Packit 5b56b6
Packit 5b56b6
        /* Test all long options for either exact match
Packit 5b56b6
           or abbreviated matches.  */
Packit 5b56b6
        for (p = longopts, option_index = 0; p->name; p++, option_index++)
Packit 5b56b6
          if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
Packit 5b56b6
            {
Packit 5b56b6
              if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
Packit 5b56b6
                {
Packit 5b56b6
                  /* Exact match found.  */
Packit 5b56b6
                  pfound = p;
Packit 5b56b6
                  indfound = option_index;
Packit 5b56b6
                  exact = 1;
Packit 5b56b6
                  break;
Packit 5b56b6
                }
Packit 5b56b6
              else if (pfound == NULL)
Packit 5b56b6
                {
Packit 5b56b6
                  /* First nonexact match found.  */
Packit 5b56b6
                  pfound = p;
Packit 5b56b6
                  indfound = option_index;
Packit 5b56b6
                }
Packit 5b56b6
              else if (long_only
Packit 5b56b6
                       || pfound->has_arg != p->has_arg
Packit 5b56b6
                       || pfound->flag != p->flag
Packit 5b56b6
                       || pfound->val != p->val)
Packit 5b56b6
                /* Second or later nonexact match found.  */
Packit 5b56b6
                ambig = 1;
Packit 5b56b6
            }
Packit 5b56b6
        if (ambig && !exact)
Packit 5b56b6
          {
Packit 5b56b6
            if (print_errors)
Packit 5b56b6
              {
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
                char *buf;
Packit 5b56b6
Packit 5b56b6
                if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"),
Packit 5b56b6
                                argv[0], d->optarg) >= 0)
Packit 5b56b6
                  {
Packit 5b56b6
                    _IO_flockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
Packit 5b56b6
                    ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
Packit 5b56b6
Packit 5b56b6
                    __fxprintf (NULL, "%s", buf);
Packit 5b56b6
Packit 5b56b6
                    ((_IO_FILE *) stderr)->_flags2 = old_flags2;
Packit 5b56b6
                    _IO_funlockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                    free (buf);
Packit 5b56b6
                  }
Packit 5b56b6
#else
Packit 5b56b6
                fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"),
Packit 5b56b6
                         argv[0], d->optarg);
Packit 5b56b6
#endif
Packit 5b56b6
              }
Packit 5b56b6
            d->__nextchar += strlen (d->__nextchar);
Packit 5b56b6
            d->optind++;
Packit 5b56b6
            return '?';
Packit 5b56b6
          }
Packit 5b56b6
        if (pfound != NULL)
Packit 5b56b6
          {
Packit 5b56b6
            option_index = indfound;
Packit 5b56b6
            if (*nameend)
Packit 5b56b6
              {
Packit 5b56b6
                /* Don't test has_arg with >, because some C compilers don't
Packit 5b56b6
                   allow it to be used on enums.  */
Packit 5b56b6
                if (pfound->has_arg)
Packit 5b56b6
                  d->optarg = nameend + 1;
Packit 5b56b6
                else
Packit 5b56b6
                  {
Packit 5b56b6
                    if (print_errors)
Packit 5b56b6
                      {
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
                        char *buf;
Packit 5b56b6
Packit 5b56b6
                        if (__asprintf (&buf, _("\
Packit 5b56b6
%s: option '-W %s' doesn't allow an argument\n"),
Packit 5b56b6
                                        argv[0], pfound->name) >= 0)
Packit 5b56b6
                          {
Packit 5b56b6
                            _IO_flockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                            int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
Packit 5b56b6
                            ((_IO_FILE *) stderr)->_flags2
Packit 5b56b6
                              |= _IO_FLAGS2_NOTCANCEL;
Packit 5b56b6
Packit 5b56b6
                            __fxprintf (NULL, "%s", buf);
Packit 5b56b6
Packit 5b56b6
                            ((_IO_FILE *) stderr)->_flags2 = old_flags2;
Packit 5b56b6
                            _IO_funlockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                            free (buf);
Packit 5b56b6
                          }
Packit 5b56b6
#else
Packit 5b56b6
                        fprintf (stderr, _("\
Packit 5b56b6
%s: option '-W %s' doesn't allow an argument\n"),
Packit 5b56b6
                                 argv[0], pfound->name);
Packit 5b56b6
#endif
Packit 5b56b6
                      }
Packit 5b56b6
Packit 5b56b6
                    d->__nextchar += strlen (d->__nextchar);
Packit 5b56b6
                    return '?';
Packit 5b56b6
                  }
Packit 5b56b6
              }
Packit 5b56b6
            else if (pfound->has_arg == 1)
Packit 5b56b6
              {
Packit 5b56b6
                if (d->optind < argc)
Packit 5b56b6
                  d->optarg = argv[d->optind++];
Packit 5b56b6
                else
Packit 5b56b6
                  {
Packit 5b56b6
                    if (print_errors)
Packit 5b56b6
                      {
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
                        char *buf;
Packit 5b56b6
Packit 5b56b6
                        if (__asprintf (&buf, _("\
Packit 5b56b6
%s: option '-W %s' requires an argument\n"),
Packit 5b56b6
                                        argv[0], pfound->name) >= 0)
Packit 5b56b6
                          {
Packit 5b56b6
                            _IO_flockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                            int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
Packit 5b56b6
                            ((_IO_FILE *) stderr)->_flags2
Packit 5b56b6
                              |= _IO_FLAGS2_NOTCANCEL;
Packit 5b56b6
Packit 5b56b6
                            __fxprintf (NULL, "%s", buf);
Packit 5b56b6
Packit 5b56b6
                            ((_IO_FILE *) stderr)->_flags2 = old_flags2;
Packit 5b56b6
                            _IO_funlockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                            free (buf);
Packit 5b56b6
                          }
Packit 5b56b6
#else
Packit 5b56b6
                        fprintf (stderr, _("\
Packit 5b56b6
%s: option '-W %s' requires an argument\n"),
Packit 5b56b6
                                 argv[0], pfound->name);
Packit 5b56b6
#endif
Packit 5b56b6
                      }
Packit 5b56b6
                    d->__nextchar += strlen (d->__nextchar);
Packit 5b56b6
                    return optstring[0] == ':' ? ':' : '?';
Packit 5b56b6
                  }
Packit 5b56b6
              }
Packit 5b56b6
            else
Packit 5b56b6
              d->optarg = NULL;
Packit 5b56b6
            d->__nextchar += strlen (d->__nextchar);
Packit 5b56b6
            if (longind != NULL)
Packit 5b56b6
              *longind = option_index;
Packit 5b56b6
            if (pfound->flag)
Packit 5b56b6
              {
Packit 5b56b6
                *(pfound->flag) = pfound->val;
Packit 5b56b6
                return 0;
Packit 5b56b6
              }
Packit 5b56b6
            return pfound->val;
Packit 5b56b6
          }
Packit 5b56b6
Packit 5b56b6
      no_longs:
Packit 5b56b6
        d->__nextchar = NULL;
Packit 5b56b6
        return 'W';   /* Let the application handle it.   */
Packit 5b56b6
      }
Packit 5b56b6
    if (temp[1] == ':')
Packit 5b56b6
      {
Packit 5b56b6
        if (temp[2] == ':')
Packit 5b56b6
          {
Packit 5b56b6
            /* This is an option that accepts an argument optionally.  */
Packit 5b56b6
            if (*d->__nextchar != '\0')
Packit 5b56b6
              {
Packit 5b56b6
                d->optarg = d->__nextchar;
Packit 5b56b6
                d->optind++;
Packit 5b56b6
              }
Packit 5b56b6
            else
Packit 5b56b6
              d->optarg = NULL;
Packit 5b56b6
            d->__nextchar = NULL;
Packit 5b56b6
          }
Packit 5b56b6
        else
Packit 5b56b6
          {
Packit 5b56b6
            /* This is an option that requires an argument.  */
Packit 5b56b6
            if (*d->__nextchar != '\0')
Packit 5b56b6
              {
Packit 5b56b6
                d->optarg = d->__nextchar;
Packit 5b56b6
                /* If we end this ARGV-element by taking the rest as an arg,
Packit 5b56b6
                   we must advance to the next element now.  */
Packit 5b56b6
                d->optind++;
Packit 5b56b6
              }
Packit 5b56b6
            else if (d->optind == argc)
Packit 5b56b6
              {
Packit 5b56b6
                if (print_errors)
Packit 5b56b6
                  {
Packit 5b56b6
#if defined _LIBC && defined USE_IN_LIBIO
Packit 5b56b6
                    char *buf;
Packit 5b56b6
Packit 5b56b6
                    if (__asprintf (&buf, _("\
Packit 5b56b6
%s: option requires an argument -- '%c'\n"),
Packit 5b56b6
                                    argv[0], c) >= 0)
Packit 5b56b6
                      {
Packit 5b56b6
                        _IO_flockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                        int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
Packit 5b56b6
                        ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
Packit 5b56b6
Packit 5b56b6
                        __fxprintf (NULL, "%s", buf);
Packit 5b56b6
Packit 5b56b6
                        ((_IO_FILE *) stderr)->_flags2 = old_flags2;
Packit 5b56b6
                        _IO_funlockfile (stderr);
Packit 5b56b6
Packit 5b56b6
                        free (buf);
Packit 5b56b6
                      }
Packit 5b56b6
#else
Packit 5b56b6
                    fprintf (stderr,
Packit 5b56b6
                             _("%s: option requires an argument -- '%c'\n"),
Packit 5b56b6
                             argv[0], c);
Packit 5b56b6
#endif
Packit 5b56b6
                  }
Packit 5b56b6
                d->optopt = c;
Packit 5b56b6
                if (optstring[0] == ':')
Packit 5b56b6
                  c = ':';
Packit 5b56b6
                else
Packit 5b56b6
                  c = '?';
Packit 5b56b6
              }
Packit 5b56b6
            else
Packit 5b56b6
              /* We already incremented 'optind' once;
Packit 5b56b6
                 increment it again when taking next ARGV-elt as argument.  */
Packit 5b56b6
              d->optarg = argv[d->optind++];
Packit 5b56b6
            d->__nextchar = NULL;
Packit 5b56b6
          }
Packit 5b56b6
      }
Packit 5b56b6
    return c;
Packit 5b56b6
  }
Packit 5b56b6
}
Packit 5b56b6
Packit 5b56b6
int
Packit 5b56b6
_getopt_internal (int argc, char **argv, const char *optstring,
Packit 5b56b6
                  const struct option *longopts, int *longind, int long_only,
Packit 5b56b6
                  int posixly_correct)
Packit 5b56b6
{
Packit 5b56b6
  int result;
Packit 5b56b6
Packit 5b56b6
  getopt_data.optind = optind;
Packit 5b56b6
  getopt_data.opterr = opterr;
Packit 5b56b6
Packit 5b56b6
  result = _getopt_internal_r (argc, argv, optstring, longopts,
Packit 5b56b6
                               longind, long_only, &getopt_data,
Packit 5b56b6
                               posixly_correct);
Packit 5b56b6
Packit 5b56b6
  optind = getopt_data.optind;
Packit 5b56b6
  optarg = getopt_data.optarg;
Packit 5b56b6
  optopt = getopt_data.optopt;
Packit 5b56b6
Packit 5b56b6
  return result;
Packit 5b56b6
}
Packit 5b56b6
Packit 5b56b6
/* glibc gets a LSB-compliant getopt.
Packit 5b56b6
   Standalone applications get a POSIX-compliant getopt.  */
Packit 5b56b6
#if _LIBC
Packit 5b56b6
enum { POSIXLY_CORRECT = 0 };
Packit 5b56b6
#else
Packit 5b56b6
enum { POSIXLY_CORRECT = 1 };
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6
int
Packit 5b56b6
getopt (int argc, char *const *argv, const char *optstring)
Packit 5b56b6
{
Packit 5b56b6
  return _getopt_internal (argc, (char **) argv, optstring,
Packit 5b56b6
                           (const struct option *) 0,
Packit 5b56b6
                           (int *) 0,
Packit 5b56b6
                           0, POSIXLY_CORRECT);
Packit 5b56b6
}
Packit 5b56b6
Packit 5b56b6
#ifdef _LIBC
Packit 5b56b6
int
Packit 5b56b6
__posix_getopt (int argc, char *const *argv, const char *optstring)
Packit 5b56b6
{
Packit 5b56b6
  return _getopt_internal (argc, argv, optstring,
Packit 5b56b6
                           (const struct option *) 0,
Packit 5b56b6
                           (int *) 0,
Packit 5b56b6
                           0, 1);
Packit 5b56b6
}
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6

Packit 5b56b6
#ifdef TEST
Packit 5b56b6
Packit 5b56b6
/* Compile with -DTEST to make an executable for use in testing
Packit 5b56b6
   the above definition of 'getopt'.  */
Packit 5b56b6
Packit 5b56b6
int
Packit 5b56b6
main (int argc, char **argv)
Packit 5b56b6
{
Packit 5b56b6
  int c;
Packit 5b56b6
  int digit_optind = 0;
Packit 5b56b6
Packit 5b56b6
  while (1)
Packit 5b56b6
    {
Packit 5b56b6
      int this_option_optind = optind ? optind : 1;
Packit 5b56b6
Packit 5b56b6
      c = getopt (argc, argv, "abc:d:0123456789");
Packit 5b56b6
      if (c == -1)
Packit 5b56b6
        break;
Packit 5b56b6
Packit 5b56b6
      switch (c)
Packit 5b56b6
        {
Packit 5b56b6
        case '0':
Packit 5b56b6
        case '1':
Packit 5b56b6
        case '2':
Packit 5b56b6
        case '3':
Packit 5b56b6
        case '4':
Packit 5b56b6
        case '5':
Packit 5b56b6
        case '6':
Packit 5b56b6
        case '7':
Packit 5b56b6
        case '8':
Packit 5b56b6
        case '9':
Packit 5b56b6
          if (digit_optind != 0 && digit_optind != this_option_optind)
Packit 5b56b6
            printf ("digits occur in two different argv-elements.\n");
Packit 5b56b6
          digit_optind = this_option_optind;
Packit 5b56b6
          printf ("option %c\n", c);
Packit 5b56b6
          break;
Packit 5b56b6
Packit 5b56b6
        case 'a':
Packit 5b56b6
          printf ("option a\n");
Packit 5b56b6
          break;
Packit 5b56b6
Packit 5b56b6
        case 'b':
Packit 5b56b6
          printf ("option b\n");
Packit 5b56b6
          break;
Packit 5b56b6
Packit 5b56b6
        case 'c':
Packit 5b56b6
          printf ("option c with value '%s'\n", optarg);
Packit 5b56b6
          break;
Packit 5b56b6
Packit 5b56b6
        case '?':
Packit 5b56b6
          break;
Packit 5b56b6
Packit 5b56b6
        default:
Packit 5b56b6
          printf ("?? getopt returned character code 0%o ??\n", c);
Packit 5b56b6
        }
Packit 5b56b6
    }
Packit 5b56b6
Packit 5b56b6
  if (optind < argc)
Packit 5b56b6
    {
Packit 5b56b6
      printf ("non-option ARGV-elements: ");
Packit 5b56b6
      while (optind < argc)
Packit 5b56b6
        printf ("%s ", argv[optind++]);
Packit 5b56b6
      printf ("\n");
Packit 5b56b6
    }
Packit 5b56b6
Packit 5b56b6
  exit (0);
Packit 5b56b6
}
Packit 5b56b6
Packit 5b56b6
#endif /* TEST */