Blame src/getopt.c

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