Blame gnulib/getopt.c

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