xref: /netbsd-src/external/gpl2/texinfo/dist/lib/getopt.c (revision d3737e9cfd8cdb680cae0994d1d5f26b365d6d47)
1*d3737e9cSchristos /*	$NetBSD: getopt.c,v 1.2 2016/01/14 00:34:53 christos Exp $	*/
229619d2aSchristos 
329619d2aSchristos /* Getopt for GNU.
429619d2aSchristos    NOTE: getopt is now part of the C library, so if you don't know what
529619d2aSchristos    "Keep this file name-space clean" means, talk to drepper@gnu.org
629619d2aSchristos    before changing it!
729619d2aSchristos    Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004
829619d2aSchristos    	Free Software Foundation, Inc.
929619d2aSchristos    This file is part of the GNU C Library.
1029619d2aSchristos 
1129619d2aSchristos    This program is free software; you can redistribute it and/or modify
1229619d2aSchristos    it under the terms of the GNU General Public License as published by
1329619d2aSchristos    the Free Software Foundation; either version 2, or (at your option)
1429619d2aSchristos    any later version.
1529619d2aSchristos 
1629619d2aSchristos    This program is distributed in the hope that it will be useful,
1729619d2aSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
1829619d2aSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1929619d2aSchristos    GNU General Public License for more details.
2029619d2aSchristos 
2129619d2aSchristos    You should have received a copy of the GNU General Public License along
2229619d2aSchristos    with this program; if not, write to the Free Software Foundation,
2329619d2aSchristos    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2429619d2aSchristos 
2529619d2aSchristos /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
2629619d2aSchristos    Ditto for AIX 3.2 and <stdlib.h>.  */
2729619d2aSchristos #ifndef _NO_PROTO
2829619d2aSchristos # define _NO_PROTO
2929619d2aSchristos #endif
3029619d2aSchristos 
3129619d2aSchristos #ifdef HAVE_CONFIG_H
3229619d2aSchristos # include <config.h>
3329619d2aSchristos #endif
3429619d2aSchristos 
3529619d2aSchristos #include <stdio.h>
3629619d2aSchristos 
3729619d2aSchristos /* This needs to come after some library #include
3829619d2aSchristos    to get __GNU_LIBRARY__ defined.  */
3929619d2aSchristos #ifdef	__GNU_LIBRARY__
4029619d2aSchristos /* Don't include stdlib.h for non-GNU C libraries because some of them
4129619d2aSchristos    contain conflicting prototypes for getopt.  */
4229619d2aSchristos # include <stdlib.h>
4329619d2aSchristos # include <unistd.h>
4429619d2aSchristos #endif	/* GNU C library.  */
4529619d2aSchristos 
4629619d2aSchristos #include <string.h>
4729619d2aSchristos 
4829619d2aSchristos #ifdef VMS
4929619d2aSchristos # include <unixlib.h>
5029619d2aSchristos #endif
5129619d2aSchristos 
5229619d2aSchristos #ifdef _LIBC
5329619d2aSchristos # include <libintl.h>
5429619d2aSchristos #else
5529619d2aSchristos # include "gettext.h"
5629619d2aSchristos # define _(msgid) gettext (msgid)
5729619d2aSchristos #endif
5829619d2aSchristos 
5929619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
6029619d2aSchristos # include <wchar.h>
6129619d2aSchristos #endif
6229619d2aSchristos 
6329619d2aSchristos #ifndef attribute_hidden
6429619d2aSchristos # define attribute_hidden
6529619d2aSchristos #endif
6629619d2aSchristos 
6729619d2aSchristos /* This version of `getopt' appears to the caller like standard Unix `getopt'
6829619d2aSchristos    but it behaves differently for the user, since it allows the user
6929619d2aSchristos    to intersperse the options with the other arguments.
7029619d2aSchristos 
7129619d2aSchristos    As `getopt' works, it permutes the elements of ARGV so that,
7229619d2aSchristos    when it is done, all the options precede everything else.  Thus
7329619d2aSchristos    all application programs are extended to handle flexible argument order.
7429619d2aSchristos 
7529619d2aSchristos    Setting the environment variable POSIXLY_CORRECT disables permutation.
7629619d2aSchristos    Then the behavior is completely standard.
7729619d2aSchristos 
7829619d2aSchristos    GNU application programs can use a third alternative mode in which
7929619d2aSchristos    they can distinguish the relative order of options and other arguments.  */
8029619d2aSchristos 
8129619d2aSchristos #include "getopt.h"
8229619d2aSchristos #include "getopt_int.h"
8329619d2aSchristos 
8429619d2aSchristos /* For communication from `getopt' to the caller.
8529619d2aSchristos    When `getopt' finds an option that takes an argument,
8629619d2aSchristos    the argument value is returned here.
8729619d2aSchristos    Also, when `ordering' is RETURN_IN_ORDER,
8829619d2aSchristos    each non-option ARGV-element is returned here.  */
8929619d2aSchristos 
9029619d2aSchristos char *optarg;
9129619d2aSchristos 
9229619d2aSchristos /* Index in ARGV of the next element to be scanned.
9329619d2aSchristos    This is used for communication to and from the caller
9429619d2aSchristos    and for communication between successive calls to `getopt'.
9529619d2aSchristos 
9629619d2aSchristos    On entry to `getopt', zero means this is the first call; initialize.
9729619d2aSchristos 
9829619d2aSchristos    When `getopt' returns -1, this is the index of the first of the
9929619d2aSchristos    non-option elements that the caller should itself scan.
10029619d2aSchristos 
10129619d2aSchristos    Otherwise, `optind' communicates from one call to the next
10229619d2aSchristos    how much of ARGV has been scanned so far.  */
10329619d2aSchristos 
10429619d2aSchristos /* 1003.2 says this must be 1 before any call.  */
10529619d2aSchristos int optind = 1;
10629619d2aSchristos 
10729619d2aSchristos /* Callers store zero here to inhibit the error message
10829619d2aSchristos    for unrecognized options.  */
10929619d2aSchristos 
11029619d2aSchristos int opterr = 1;
11129619d2aSchristos 
11229619d2aSchristos /* Set to an option character which was unrecognized.
11329619d2aSchristos    This must be initialized on some systems to avoid linking in the
11429619d2aSchristos    system's own getopt implementation.  */
11529619d2aSchristos 
11629619d2aSchristos int optopt = '?';
11729619d2aSchristos 
11829619d2aSchristos /* Keep a global copy of all internal members of getopt_data.  */
11929619d2aSchristos 
12029619d2aSchristos static struct _getopt_data getopt_data;
12129619d2aSchristos 
12229619d2aSchristos 
12329619d2aSchristos #ifndef __GNU_LIBRARY__
12429619d2aSchristos 
12529619d2aSchristos /* Avoid depending on library functions or files
12629619d2aSchristos    whose names are inconsistent.  */
12729619d2aSchristos 
12829619d2aSchristos #ifndef getenv
12929619d2aSchristos extern char *getenv ();
13029619d2aSchristos #endif
13129619d2aSchristos 
13229619d2aSchristos #endif /* not __GNU_LIBRARY__ */
13329619d2aSchristos 
13429619d2aSchristos #ifdef _LIBC
13529619d2aSchristos /* Stored original parameters.
13629619d2aSchristos    XXX This is no good solution.  We should rather copy the args so
13729619d2aSchristos    that we can compare them later.  But we must not use malloc(3).  */
13829619d2aSchristos extern int __libc_argc;
13929619d2aSchristos extern char **__libc_argv;
14029619d2aSchristos 
14129619d2aSchristos /* Bash 2.0 gives us an environment variable containing flags
14229619d2aSchristos    indicating ARGV elements that should not be considered arguments.  */
14329619d2aSchristos 
14429619d2aSchristos # ifdef USE_NONOPTION_FLAGS
14529619d2aSchristos /* Defined in getopt_init.c  */
14629619d2aSchristos extern char *__getopt_nonoption_flags;
14729619d2aSchristos # endif
14829619d2aSchristos 
14929619d2aSchristos # ifdef USE_NONOPTION_FLAGS
15029619d2aSchristos #  define SWAP_FLAGS(ch1, ch2) \
15129619d2aSchristos   if (d->__nonoption_flags_len > 0)					      \
15229619d2aSchristos     {									      \
15329619d2aSchristos       char __tmp = __getopt_nonoption_flags[ch1];			      \
15429619d2aSchristos       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];	      \
15529619d2aSchristos       __getopt_nonoption_flags[ch2] = __tmp;				      \
15629619d2aSchristos     }
15729619d2aSchristos # else
15829619d2aSchristos #  define SWAP_FLAGS(ch1, ch2)
15929619d2aSchristos # endif
16029619d2aSchristos #else	/* !_LIBC */
16129619d2aSchristos # define SWAP_FLAGS(ch1, ch2)
16229619d2aSchristos #endif	/* _LIBC */
16329619d2aSchristos 
16429619d2aSchristos /* Exchange two adjacent subsequences of ARGV.
16529619d2aSchristos    One subsequence is elements [first_nonopt,last_nonopt)
16629619d2aSchristos    which contains all the non-options that have been skipped so far.
16729619d2aSchristos    The other is elements [last_nonopt,optind), which contains all
16829619d2aSchristos    the options processed since those non-options were skipped.
16929619d2aSchristos 
17029619d2aSchristos    `first_nonopt' and `last_nonopt' are relocated so that they describe
17129619d2aSchristos    the new indices of the non-options in ARGV after they are moved.  */
17229619d2aSchristos 
17329619d2aSchristos static void
exchange(char ** argv,struct _getopt_data * d)17429619d2aSchristos exchange (char **argv, struct _getopt_data *d)
17529619d2aSchristos {
17629619d2aSchristos   int bottom = d->__first_nonopt;
17729619d2aSchristos   int middle = d->__last_nonopt;
17829619d2aSchristos   int top = d->optind;
17929619d2aSchristos   char *tem;
18029619d2aSchristos 
18129619d2aSchristos   /* Exchange the shorter segment with the far end of the longer segment.
18229619d2aSchristos      That puts the shorter segment into the right place.
18329619d2aSchristos      It leaves the longer segment in the right place overall,
18429619d2aSchristos      but it consists of two parts that need to be swapped next.  */
18529619d2aSchristos 
18629619d2aSchristos #if defined _LIBC && defined USE_NONOPTION_FLAGS
18729619d2aSchristos   /* First make sure the handling of the `__getopt_nonoption_flags'
18829619d2aSchristos      string can work normally.  Our top argument must be in the range
18929619d2aSchristos      of the string.  */
19029619d2aSchristos   if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
19129619d2aSchristos     {
19229619d2aSchristos       /* We must extend the array.  The user plays games with us and
19329619d2aSchristos 	 presents new arguments.  */
19429619d2aSchristos       char *new_str = malloc (top + 1);
19529619d2aSchristos       if (new_str == NULL)
19629619d2aSchristos 	d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
19729619d2aSchristos       else
19829619d2aSchristos 	{
19929619d2aSchristos 	  memset (__mempcpy (new_str, __getopt_nonoption_flags,
20029619d2aSchristos 			     d->__nonoption_flags_max_len),
20129619d2aSchristos 		  '\0', top + 1 - d->__nonoption_flags_max_len);
20229619d2aSchristos 	  d->__nonoption_flags_max_len = top + 1;
20329619d2aSchristos 	  __getopt_nonoption_flags = new_str;
20429619d2aSchristos 	}
20529619d2aSchristos     }
20629619d2aSchristos #endif
20729619d2aSchristos 
20829619d2aSchristos   while (top > middle && middle > bottom)
20929619d2aSchristos     {
21029619d2aSchristos       if (top - middle > middle - bottom)
21129619d2aSchristos 	{
21229619d2aSchristos 	  /* Bottom segment is the short one.  */
21329619d2aSchristos 	  int len = middle - bottom;
21429619d2aSchristos 	  register int i;
21529619d2aSchristos 
21629619d2aSchristos 	  /* Swap it with the top part of the top segment.  */
21729619d2aSchristos 	  for (i = 0; i < len; i++)
21829619d2aSchristos 	    {
21929619d2aSchristos 	      tem = argv[bottom + i];
22029619d2aSchristos 	      argv[bottom + i] = argv[top - (middle - bottom) + i];
22129619d2aSchristos 	      argv[top - (middle - bottom) + i] = tem;
22229619d2aSchristos 	      SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
22329619d2aSchristos 	    }
22429619d2aSchristos 	  /* Exclude the moved bottom segment from further swapping.  */
22529619d2aSchristos 	  top -= len;
22629619d2aSchristos 	}
22729619d2aSchristos       else
22829619d2aSchristos 	{
22929619d2aSchristos 	  /* Top segment is the short one.  */
23029619d2aSchristos 	  int len = top - middle;
23129619d2aSchristos 	  register int i;
23229619d2aSchristos 
23329619d2aSchristos 	  /* Swap it with the bottom part of the bottom segment.  */
23429619d2aSchristos 	  for (i = 0; i < len; i++)
23529619d2aSchristos 	    {
23629619d2aSchristos 	      tem = argv[bottom + i];
23729619d2aSchristos 	      argv[bottom + i] = argv[middle + i];
23829619d2aSchristos 	      argv[middle + i] = tem;
23929619d2aSchristos 	      SWAP_FLAGS (bottom + i, middle + i);
24029619d2aSchristos 	    }
24129619d2aSchristos 	  /* Exclude the moved top segment from further swapping.  */
24229619d2aSchristos 	  bottom += len;
24329619d2aSchristos 	}
24429619d2aSchristos     }
24529619d2aSchristos 
24629619d2aSchristos   /* Update records for the slots the non-options now occupy.  */
24729619d2aSchristos 
24829619d2aSchristos   d->__first_nonopt += (d->optind - d->__last_nonopt);
24929619d2aSchristos   d->__last_nonopt = d->optind;
25029619d2aSchristos }
25129619d2aSchristos 
25229619d2aSchristos /* Initialize the internal data when the first call is made.  */
25329619d2aSchristos 
25429619d2aSchristos static const char *
_getopt_initialize(int argc,char * const * argv,const char * optstring,struct _getopt_data * d)25529619d2aSchristos _getopt_initialize (int argc, char *const *argv, const char *optstring,
25629619d2aSchristos 		    struct _getopt_data *d)
25729619d2aSchristos {
25829619d2aSchristos   /* Start processing options with ARGV-element 1 (since ARGV-element 0
25929619d2aSchristos      is the program name); the sequence of previously skipped
26029619d2aSchristos      non-option ARGV-elements is empty.  */
26129619d2aSchristos 
26229619d2aSchristos   d->__first_nonopt = d->__last_nonopt = d->optind;
26329619d2aSchristos 
26429619d2aSchristos   d->__nextchar = NULL;
26529619d2aSchristos 
26629619d2aSchristos   d->__posixly_correct = !!getenv ("POSIXLY_CORRECT");
26729619d2aSchristos 
26829619d2aSchristos   /* Determine how to handle the ordering of options and nonoptions.  */
26929619d2aSchristos 
27029619d2aSchristos   if (optstring[0] == '-')
27129619d2aSchristos     {
27229619d2aSchristos       d->__ordering = RETURN_IN_ORDER;
27329619d2aSchristos       ++optstring;
27429619d2aSchristos     }
27529619d2aSchristos   else if (optstring[0] == '+')
27629619d2aSchristos     {
27729619d2aSchristos       d->__ordering = REQUIRE_ORDER;
27829619d2aSchristos       ++optstring;
27929619d2aSchristos     }
28029619d2aSchristos   else if (d->__posixly_correct)
28129619d2aSchristos     d->__ordering = REQUIRE_ORDER;
28229619d2aSchristos   else
28329619d2aSchristos     d->__ordering = PERMUTE;
28429619d2aSchristos 
28529619d2aSchristos #if defined _LIBC && defined USE_NONOPTION_FLAGS
28629619d2aSchristos   if (!d->__posixly_correct
28729619d2aSchristos       && argc == __libc_argc && argv == __libc_argv)
28829619d2aSchristos     {
28929619d2aSchristos       if (d->__nonoption_flags_max_len == 0)
29029619d2aSchristos 	{
29129619d2aSchristos 	  if (__getopt_nonoption_flags == NULL
29229619d2aSchristos 	      || __getopt_nonoption_flags[0] == '\0')
29329619d2aSchristos 	    d->__nonoption_flags_max_len = -1;
29429619d2aSchristos 	  else
29529619d2aSchristos 	    {
29629619d2aSchristos 	      const char *orig_str = __getopt_nonoption_flags;
29729619d2aSchristos 	      int len = d->__nonoption_flags_max_len = strlen (orig_str);
29829619d2aSchristos 	      if (d->__nonoption_flags_max_len < argc)
29929619d2aSchristos 		d->__nonoption_flags_max_len = argc;
30029619d2aSchristos 	      __getopt_nonoption_flags =
30129619d2aSchristos 		(char *) malloc (d->__nonoption_flags_max_len);
30229619d2aSchristos 	      if (__getopt_nonoption_flags == NULL)
30329619d2aSchristos 		d->__nonoption_flags_max_len = -1;
30429619d2aSchristos 	      else
30529619d2aSchristos 		memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
30629619d2aSchristos 			'\0', d->__nonoption_flags_max_len - len);
30729619d2aSchristos 	    }
30829619d2aSchristos 	}
30929619d2aSchristos       d->__nonoption_flags_len = d->__nonoption_flags_max_len;
31029619d2aSchristos     }
31129619d2aSchristos   else
31229619d2aSchristos     d->__nonoption_flags_len = 0;
31329619d2aSchristos #endif
31429619d2aSchristos 
31529619d2aSchristos   return optstring;
31629619d2aSchristos }
31729619d2aSchristos 
31829619d2aSchristos /* Scan elements of ARGV (whose length is ARGC) for option characters
31929619d2aSchristos    given in OPTSTRING.
32029619d2aSchristos 
32129619d2aSchristos    If an element of ARGV starts with '-', and is not exactly "-" or "--",
32229619d2aSchristos    then it is an option element.  The characters of this element
32329619d2aSchristos    (aside from the initial '-') are option characters.  If `getopt'
32429619d2aSchristos    is called repeatedly, it returns successively each of the option characters
32529619d2aSchristos    from each of the option elements.
32629619d2aSchristos 
32729619d2aSchristos    If `getopt' finds another option character, it returns that character,
32829619d2aSchristos    updating `optind' and `nextchar' so that the next call to `getopt' can
32929619d2aSchristos    resume the scan with the following option character or ARGV-element.
33029619d2aSchristos 
33129619d2aSchristos    If there are no more option characters, `getopt' returns -1.
33229619d2aSchristos    Then `optind' is the index in ARGV of the first ARGV-element
33329619d2aSchristos    that is not an option.  (The ARGV-elements have been permuted
33429619d2aSchristos    so that those that are not options now come last.)
33529619d2aSchristos 
33629619d2aSchristos    OPTSTRING is a string containing the legitimate option characters.
33729619d2aSchristos    If an option character is seen that is not listed in OPTSTRING,
33829619d2aSchristos    return '?' after printing an error message.  If you set `opterr' to
33929619d2aSchristos    zero, the error message is suppressed but we still return '?'.
34029619d2aSchristos 
34129619d2aSchristos    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
34229619d2aSchristos    so the following text in the same ARGV-element, or the text of the following
34329619d2aSchristos    ARGV-element, is returned in `optarg'.  Two colons mean an option that
34429619d2aSchristos    wants an optional arg; if there is text in the current ARGV-element,
34529619d2aSchristos    it is returned in `optarg', otherwise `optarg' is set to zero.
34629619d2aSchristos 
34729619d2aSchristos    If OPTSTRING starts with `-' or `+', it requests different methods of
34829619d2aSchristos    handling the non-option ARGV-elements.
34929619d2aSchristos    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
35029619d2aSchristos 
35129619d2aSchristos    Long-named options begin with `--' instead of `-'.
35229619d2aSchristos    Their names may be abbreviated as long as the abbreviation is unique
35329619d2aSchristos    or is an exact match for some defined option.  If they have an
35429619d2aSchristos    argument, it follows the option name in the same ARGV-element, separated
35529619d2aSchristos    from the option name by a `=', or else the in next ARGV-element.
35629619d2aSchristos    When `getopt' finds a long-named option, it returns 0 if that option's
35729619d2aSchristos    `flag' field is nonzero, the value of the option's `val' field
35829619d2aSchristos    if the `flag' field is zero.
35929619d2aSchristos 
36029619d2aSchristos    The elements of ARGV aren't really const, because we permute them.
36129619d2aSchristos    But we pretend they're const in the prototype to be compatible
36229619d2aSchristos    with other systems.
36329619d2aSchristos 
36429619d2aSchristos    LONGOPTS is a vector of `struct option' terminated by an
36529619d2aSchristos    element containing a name which is zero.
36629619d2aSchristos 
36729619d2aSchristos    LONGIND returns the index in LONGOPT of the long-named option found.
36829619d2aSchristos    It is only valid when a long-named option has been found by the most
36929619d2aSchristos    recent call.
37029619d2aSchristos 
37129619d2aSchristos    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
37229619d2aSchristos    long-named options.  */
37329619d2aSchristos 
37429619d2aSchristos int
_getopt_internal_r(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,int long_only,struct _getopt_data * d)37529619d2aSchristos _getopt_internal_r (int argc, char *const *argv, const char *optstring,
37629619d2aSchristos 		    const struct option *longopts, int *longind,
37729619d2aSchristos 		    int long_only, struct _getopt_data *d)
37829619d2aSchristos {
37929619d2aSchristos   int print_errors = d->opterr;
38029619d2aSchristos   if (optstring[0] == ':')
38129619d2aSchristos     print_errors = 0;
38229619d2aSchristos 
38329619d2aSchristos   if (argc < 1)
38429619d2aSchristos     return -1;
38529619d2aSchristos 
38629619d2aSchristos   d->optarg = NULL;
38729619d2aSchristos 
38829619d2aSchristos   if (d->optind == 0 || !d->__initialized)
38929619d2aSchristos     {
39029619d2aSchristos       if (d->optind == 0)
39129619d2aSchristos 	d->optind = 1;	/* Don't scan ARGV[0], the program name.  */
39229619d2aSchristos       optstring = _getopt_initialize (argc, argv, optstring, d);
39329619d2aSchristos       d->__initialized = 1;
39429619d2aSchristos     }
39529619d2aSchristos 
39629619d2aSchristos   /* Test whether ARGV[optind] points to a non-option argument.
39729619d2aSchristos      Either it does not have option syntax, or there is an environment flag
39829619d2aSchristos      from the shell indicating it is not an option.  The later information
39929619d2aSchristos      is only used when the used in the GNU libc.  */
40029619d2aSchristos #if defined _LIBC && defined USE_NONOPTION_FLAGS
40129619d2aSchristos # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \
40229619d2aSchristos 		      || (d->optind < d->__nonoption_flags_len		      \
40329619d2aSchristos 			  && __getopt_nonoption_flags[d->optind] == '1'))
40429619d2aSchristos #else
40529619d2aSchristos # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
40629619d2aSchristos #endif
40729619d2aSchristos 
40829619d2aSchristos   if (d->__nextchar == NULL || *d->__nextchar == '\0')
40929619d2aSchristos     {
41029619d2aSchristos       /* Advance to the next ARGV-element.  */
41129619d2aSchristos 
41229619d2aSchristos       /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
41329619d2aSchristos 	 moved back by the user (who may also have changed the arguments).  */
41429619d2aSchristos       if (d->__last_nonopt > d->optind)
41529619d2aSchristos 	d->__last_nonopt = d->optind;
41629619d2aSchristos       if (d->__first_nonopt > d->optind)
41729619d2aSchristos 	d->__first_nonopt = d->optind;
41829619d2aSchristos 
41929619d2aSchristos       if (d->__ordering == PERMUTE)
42029619d2aSchristos 	{
42129619d2aSchristos 	  /* If we have just processed some options following some non-options,
42229619d2aSchristos 	     exchange them so that the options come first.  */
42329619d2aSchristos 
42429619d2aSchristos 	  if (d->__first_nonopt != d->__last_nonopt
42529619d2aSchristos 	      && d->__last_nonopt != d->optind)
42629619d2aSchristos 	    exchange ((char **) argv, d);
42729619d2aSchristos 	  else if (d->__last_nonopt != d->optind)
42829619d2aSchristos 	    d->__first_nonopt = d->optind;
42929619d2aSchristos 
43029619d2aSchristos 	  /* Skip any additional non-options
43129619d2aSchristos 	     and extend the range of non-options previously skipped.  */
43229619d2aSchristos 
43329619d2aSchristos 	  while (d->optind < argc && NONOPTION_P)
43429619d2aSchristos 	    d->optind++;
43529619d2aSchristos 	  d->__last_nonopt = d->optind;
43629619d2aSchristos 	}
43729619d2aSchristos 
43829619d2aSchristos       /* The special ARGV-element `--' means premature end of options.
43929619d2aSchristos 	 Skip it like a null option,
44029619d2aSchristos 	 then exchange with previous non-options as if it were an option,
44129619d2aSchristos 	 then skip everything else like a non-option.  */
44229619d2aSchristos 
44329619d2aSchristos       if (d->optind != argc && !strcmp (argv[d->optind], "--"))
44429619d2aSchristos 	{
44529619d2aSchristos 	  d->optind++;
44629619d2aSchristos 
44729619d2aSchristos 	  if (d->__first_nonopt != d->__last_nonopt
44829619d2aSchristos 	      && d->__last_nonopt != d->optind)
44929619d2aSchristos 	    exchange ((char **) argv, d);
45029619d2aSchristos 	  else if (d->__first_nonopt == d->__last_nonopt)
45129619d2aSchristos 	    d->__first_nonopt = d->optind;
45229619d2aSchristos 	  d->__last_nonopt = argc;
45329619d2aSchristos 
45429619d2aSchristos 	  d->optind = argc;
45529619d2aSchristos 	}
45629619d2aSchristos 
45729619d2aSchristos       /* If we have done all the ARGV-elements, stop the scan
45829619d2aSchristos 	 and back over any non-options that we skipped and permuted.  */
45929619d2aSchristos 
46029619d2aSchristos       if (d->optind == argc)
46129619d2aSchristos 	{
46229619d2aSchristos 	  /* Set the next-arg-index to point at the non-options
46329619d2aSchristos 	     that we previously skipped, so the caller will digest them.  */
46429619d2aSchristos 	  if (d->__first_nonopt != d->__last_nonopt)
46529619d2aSchristos 	    d->optind = d->__first_nonopt;
46629619d2aSchristos 	  return -1;
46729619d2aSchristos 	}
46829619d2aSchristos 
46929619d2aSchristos       /* If we have come to a non-option and did not permute it,
47029619d2aSchristos 	 either stop the scan or describe it to the caller and pass it by.  */
47129619d2aSchristos 
47229619d2aSchristos       if (NONOPTION_P)
47329619d2aSchristos 	{
47429619d2aSchristos 	  if (d->__ordering == REQUIRE_ORDER)
47529619d2aSchristos 	    return -1;
47629619d2aSchristos 	  d->optarg = argv[d->optind++];
47729619d2aSchristos 	  return 1;
47829619d2aSchristos 	}
47929619d2aSchristos 
48029619d2aSchristos       /* We have found another option-ARGV-element.
48129619d2aSchristos 	 Skip the initial punctuation.  */
48229619d2aSchristos 
48329619d2aSchristos       d->__nextchar = (argv[d->optind] + 1
48429619d2aSchristos 		  + (longopts != NULL && argv[d->optind][1] == '-'));
48529619d2aSchristos     }
48629619d2aSchristos 
48729619d2aSchristos   /* Decode the current option-ARGV-element.  */
48829619d2aSchristos 
48929619d2aSchristos   /* Check whether the ARGV-element is a long option.
49029619d2aSchristos 
49129619d2aSchristos      If long_only and the ARGV-element has the form "-f", where f is
49229619d2aSchristos      a valid short option, don't consider it an abbreviated form of
49329619d2aSchristos      a long option that starts with f.  Otherwise there would be no
49429619d2aSchristos      way to give the -f short option.
49529619d2aSchristos 
49629619d2aSchristos      On the other hand, if there's a long option "fubar" and
49729619d2aSchristos      the ARGV-element is "-fu", do consider that an abbreviation of
49829619d2aSchristos      the long option, just like "--fu", and not "-f" with arg "u".
49929619d2aSchristos 
50029619d2aSchristos      This distinction seems to be the most useful approach.  */
50129619d2aSchristos 
50229619d2aSchristos   if (longopts != NULL
50329619d2aSchristos       && (argv[d->optind][1] == '-'
50429619d2aSchristos 	  || (long_only && (argv[d->optind][2]
50529619d2aSchristos 			    || !strchr (optstring, argv[d->optind][1])))))
50629619d2aSchristos     {
50729619d2aSchristos       char *nameend;
50829619d2aSchristos       const struct option *p;
50929619d2aSchristos       const struct option *pfound = NULL;
51029619d2aSchristos       int exact = 0;
51129619d2aSchristos       int ambig = 0;
51229619d2aSchristos       int indfound = -1;
51329619d2aSchristos       int option_index;
51429619d2aSchristos 
51529619d2aSchristos       for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
51629619d2aSchristos 	/* Do nothing.  */ ;
51729619d2aSchristos 
51829619d2aSchristos       /* Test all long options for either exact match
51929619d2aSchristos 	 or abbreviated matches.  */
52029619d2aSchristos       for (p = longopts, option_index = 0; p->name; p++, option_index++)
52129619d2aSchristos 	if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
52229619d2aSchristos 	  {
52329619d2aSchristos 	    if ((unsigned int) (nameend - d->__nextchar)
52429619d2aSchristos 		== (unsigned int) strlen (p->name))
52529619d2aSchristos 	      {
52629619d2aSchristos 		/* Exact match found.  */
52729619d2aSchristos 		pfound = p;
52829619d2aSchristos 		indfound = option_index;
52929619d2aSchristos 		exact = 1;
53029619d2aSchristos 		break;
53129619d2aSchristos 	      }
53229619d2aSchristos 	    else if (pfound == NULL)
53329619d2aSchristos 	      {
53429619d2aSchristos 		/* First nonexact match found.  */
53529619d2aSchristos 		pfound = p;
53629619d2aSchristos 		indfound = option_index;
53729619d2aSchristos 	      }
53829619d2aSchristos 	    else if (long_only
53929619d2aSchristos 		     || pfound->has_arg != p->has_arg
54029619d2aSchristos 		     || pfound->flag != p->flag
54129619d2aSchristos 		     || pfound->val != p->val)
54229619d2aSchristos 	      /* Second or later nonexact match found.  */
54329619d2aSchristos 	      ambig = 1;
54429619d2aSchristos 	  }
54529619d2aSchristos 
54629619d2aSchristos       if (ambig && !exact)
54729619d2aSchristos 	{
54829619d2aSchristos 	  if (print_errors)
54929619d2aSchristos 	    {
55029619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
55129619d2aSchristos 	      char *buf;
55229619d2aSchristos 
55329619d2aSchristos 	      if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
55429619d2aSchristos 			      argv[0], argv[d->optind]) >= 0)
55529619d2aSchristos 		{
55629619d2aSchristos 		  _IO_flockfile (stderr);
55729619d2aSchristos 
55829619d2aSchristos 		  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
55929619d2aSchristos 		  ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
56029619d2aSchristos 
56129619d2aSchristos 		  if (_IO_fwide (stderr, 0) > 0)
56229619d2aSchristos 		    __fwprintf (stderr, L"%s", buf);
56329619d2aSchristos 		  else
56429619d2aSchristos 		    fputs (buf, stderr);
56529619d2aSchristos 
56629619d2aSchristos 		  ((_IO_FILE *) stderr)->_flags2 = old_flags2;
56729619d2aSchristos 		  _IO_funlockfile (stderr);
56829619d2aSchristos 
56929619d2aSchristos 		  free (buf);
57029619d2aSchristos 		}
57129619d2aSchristos #else
57229619d2aSchristos 	      fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
57329619d2aSchristos 		       argv[0], argv[d->optind]);
57429619d2aSchristos #endif
57529619d2aSchristos 	    }
57629619d2aSchristos 	  d->__nextchar += strlen (d->__nextchar);
57729619d2aSchristos 	  d->optind++;
57829619d2aSchristos 	  d->optopt = 0;
57929619d2aSchristos 	  return '?';
58029619d2aSchristos 	}
58129619d2aSchristos 
58229619d2aSchristos       if (pfound != NULL)
58329619d2aSchristos 	{
58429619d2aSchristos 	  option_index = indfound;
58529619d2aSchristos 	  d->optind++;
58629619d2aSchristos 	  if (*nameend)
58729619d2aSchristos 	    {
58829619d2aSchristos 	      /* Don't test has_arg with >, because some C compilers don't
58929619d2aSchristos 		 allow it to be used on enums.  */
59029619d2aSchristos 	      if (pfound->has_arg)
59129619d2aSchristos 		d->optarg = nameend + 1;
59229619d2aSchristos 	      else
59329619d2aSchristos 		{
59429619d2aSchristos 		  if (print_errors)
59529619d2aSchristos 		    {
59629619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
59729619d2aSchristos 		      char *buf;
59829619d2aSchristos 		      int n;
59929619d2aSchristos #endif
60029619d2aSchristos 
60129619d2aSchristos 		      if (argv[d->optind - 1][1] == '-')
60229619d2aSchristos 			{
60329619d2aSchristos 			  /* --option */
60429619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
60529619d2aSchristos 			  n = __asprintf (&buf, _("\
60629619d2aSchristos %s: option `--%s' doesn't allow an argument\n"),
60729619d2aSchristos 					  argv[0], pfound->name);
60829619d2aSchristos #else
60929619d2aSchristos 			  fprintf (stderr, _("\
61029619d2aSchristos %s: option `--%s' doesn't allow an argument\n"),
61129619d2aSchristos 				   argv[0], pfound->name);
61229619d2aSchristos #endif
61329619d2aSchristos 			}
61429619d2aSchristos 		      else
61529619d2aSchristos 			{
61629619d2aSchristos 			  /* +option or -option */
61729619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
61829619d2aSchristos 			  n = __asprintf (&buf, _("\
61929619d2aSchristos %s: option `%c%s' doesn't allow an argument\n"),
62029619d2aSchristos 					  argv[0], argv[d->optind - 1][0],
62129619d2aSchristos 					  pfound->name);
62229619d2aSchristos #else
62329619d2aSchristos 			  fprintf (stderr, _("\
62429619d2aSchristos %s: option `%c%s' doesn't allow an argument\n"),
62529619d2aSchristos 				   argv[0], argv[d->optind - 1][0],
62629619d2aSchristos 				   pfound->name);
62729619d2aSchristos #endif
62829619d2aSchristos 			}
62929619d2aSchristos 
63029619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
63129619d2aSchristos 		      if (n >= 0)
63229619d2aSchristos 			{
63329619d2aSchristos 			  _IO_flockfile (stderr);
63429619d2aSchristos 
63529619d2aSchristos 			  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
63629619d2aSchristos 			  ((_IO_FILE *) stderr)->_flags2
63729619d2aSchristos 			    |= _IO_FLAGS2_NOTCANCEL;
63829619d2aSchristos 
63929619d2aSchristos 			  if (_IO_fwide (stderr, 0) > 0)
64029619d2aSchristos 			    __fwprintf (stderr, L"%s", buf);
64129619d2aSchristos 			  else
64229619d2aSchristos 			    fputs (buf, stderr);
64329619d2aSchristos 
64429619d2aSchristos 			  ((_IO_FILE *) stderr)->_flags2 = old_flags2;
64529619d2aSchristos 			  _IO_funlockfile (stderr);
64629619d2aSchristos 
64729619d2aSchristos 			  free (buf);
64829619d2aSchristos 			}
64929619d2aSchristos #endif
65029619d2aSchristos 		    }
65129619d2aSchristos 
65229619d2aSchristos 		  d->__nextchar += strlen (d->__nextchar);
65329619d2aSchristos 
65429619d2aSchristos 		  d->optopt = pfound->val;
65529619d2aSchristos 		  return '?';
65629619d2aSchristos 		}
65729619d2aSchristos 	    }
65829619d2aSchristos 	  else if (pfound->has_arg == 1)
65929619d2aSchristos 	    {
66029619d2aSchristos 	      if (d->optind < argc)
66129619d2aSchristos 		d->optarg = argv[d->optind++];
66229619d2aSchristos 	      else
66329619d2aSchristos 		{
66429619d2aSchristos 		  if (print_errors)
66529619d2aSchristos 		    {
66629619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
66729619d2aSchristos 		      char *buf;
66829619d2aSchristos 
66929619d2aSchristos 		      if (__asprintf (&buf, _("\
67029619d2aSchristos %s: option `%s' requires an argument\n"),
67129619d2aSchristos 				      argv[0], argv[d->optind - 1]) >= 0)
67229619d2aSchristos 			{
67329619d2aSchristos 			  _IO_flockfile (stderr);
67429619d2aSchristos 
67529619d2aSchristos 			  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
67629619d2aSchristos 			  ((_IO_FILE *) stderr)->_flags2
67729619d2aSchristos 			    |= _IO_FLAGS2_NOTCANCEL;
67829619d2aSchristos 
67929619d2aSchristos 			  if (_IO_fwide (stderr, 0) > 0)
68029619d2aSchristos 			    __fwprintf (stderr, L"%s", buf);
68129619d2aSchristos 			  else
68229619d2aSchristos 			    fputs (buf, stderr);
68329619d2aSchristos 
68429619d2aSchristos 			  ((_IO_FILE *) stderr)->_flags2 = old_flags2;
68529619d2aSchristos 			  _IO_funlockfile (stderr);
68629619d2aSchristos 
68729619d2aSchristos 			  free (buf);
68829619d2aSchristos 			}
68929619d2aSchristos #else
69029619d2aSchristos 		      fprintf (stderr,
69129619d2aSchristos 			       _("%s: option `%s' requires an argument\n"),
69229619d2aSchristos 			       argv[0], argv[d->optind - 1]);
69329619d2aSchristos #endif
69429619d2aSchristos 		    }
69529619d2aSchristos 		  d->__nextchar += strlen (d->__nextchar);
69629619d2aSchristos 		  d->optopt = pfound->val;
69729619d2aSchristos 		  return optstring[0] == ':' ? ':' : '?';
69829619d2aSchristos 		}
69929619d2aSchristos 	    }
70029619d2aSchristos 	  d->__nextchar += strlen (d->__nextchar);
70129619d2aSchristos 	  if (longind != NULL)
70229619d2aSchristos 	    *longind = option_index;
70329619d2aSchristos 	  if (pfound->flag)
70429619d2aSchristos 	    {
70529619d2aSchristos 	      *(pfound->flag) = pfound->val;
70629619d2aSchristos 	      return 0;
70729619d2aSchristos 	    }
70829619d2aSchristos 	  return pfound->val;
70929619d2aSchristos 	}
71029619d2aSchristos 
71129619d2aSchristos       /* Can't find it as a long option.  If this is not getopt_long_only,
71229619d2aSchristos 	 or the option starts with '--' or is not a valid short
71329619d2aSchristos 	 option, then it's an error.
71429619d2aSchristos 	 Otherwise interpret it as a short option.  */
71529619d2aSchristos       if (!long_only || argv[d->optind][1] == '-'
71629619d2aSchristos 	  || strchr (optstring, *d->__nextchar) == NULL)
71729619d2aSchristos 	{
71829619d2aSchristos 	  if (print_errors)
71929619d2aSchristos 	    {
72029619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
72129619d2aSchristos 	      char *buf;
72229619d2aSchristos 	      int n;
72329619d2aSchristos #endif
72429619d2aSchristos 
72529619d2aSchristos 	      if (argv[d->optind][1] == '-')
72629619d2aSchristos 		{
72729619d2aSchristos 		  /* --option */
72829619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
72929619d2aSchristos 		  n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
73029619d2aSchristos 				  argv[0], d->__nextchar);
73129619d2aSchristos #else
73229619d2aSchristos 		  fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
73329619d2aSchristos 			   argv[0], d->__nextchar);
73429619d2aSchristos #endif
73529619d2aSchristos 		}
73629619d2aSchristos 	      else
73729619d2aSchristos 		{
73829619d2aSchristos 		  /* +option or -option */
73929619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
74029619d2aSchristos 		  n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
74129619d2aSchristos 				  argv[0], argv[d->optind][0], d->__nextchar);
74229619d2aSchristos #else
74329619d2aSchristos 		  fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
74429619d2aSchristos 			   argv[0], argv[d->optind][0], d->__nextchar);
74529619d2aSchristos #endif
74629619d2aSchristos 		}
74729619d2aSchristos 
74829619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
74929619d2aSchristos 	      if (n >= 0)
75029619d2aSchristos 		{
75129619d2aSchristos 		  _IO_flockfile (stderr);
75229619d2aSchristos 
75329619d2aSchristos 		  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
75429619d2aSchristos 		  ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
75529619d2aSchristos 
75629619d2aSchristos 		  if (_IO_fwide (stderr, 0) > 0)
75729619d2aSchristos 		    __fwprintf (stderr, L"%s", buf);
75829619d2aSchristos 		  else
75929619d2aSchristos 		    fputs (buf, stderr);
76029619d2aSchristos 
76129619d2aSchristos 		  ((_IO_FILE *) stderr)->_flags2 = old_flags2;
76229619d2aSchristos 		  _IO_funlockfile (stderr);
76329619d2aSchristos 
76429619d2aSchristos 		  free (buf);
76529619d2aSchristos 		}
76629619d2aSchristos #endif
76729619d2aSchristos 	    }
76829619d2aSchristos 	  d->__nextchar = (char *) "";
76929619d2aSchristos 	  d->optind++;
77029619d2aSchristos 	  d->optopt = 0;
77129619d2aSchristos 	  return '?';
77229619d2aSchristos 	}
77329619d2aSchristos     }
77429619d2aSchristos 
77529619d2aSchristos   /* Look at and handle the next short option-character.  */
77629619d2aSchristos 
77729619d2aSchristos   {
77829619d2aSchristos     char c = *d->__nextchar++;
77929619d2aSchristos     char *temp = strchr (optstring, c);
78029619d2aSchristos 
78129619d2aSchristos     /* Increment `optind' when we start to process its last character.  */
78229619d2aSchristos     if (*d->__nextchar == '\0')
78329619d2aSchristos       ++d->optind;
78429619d2aSchristos 
78529619d2aSchristos     if (temp == NULL || c == ':')
78629619d2aSchristos       {
78729619d2aSchristos 	if (print_errors)
78829619d2aSchristos 	  {
78929619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
79029619d2aSchristos 	      char *buf;
79129619d2aSchristos 	      int n;
79229619d2aSchristos #endif
79329619d2aSchristos 
79429619d2aSchristos 	    if (d->__posixly_correct)
79529619d2aSchristos 	      {
79629619d2aSchristos 		/* 1003.2 specifies the format of this message.  */
79729619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
79829619d2aSchristos 		n = __asprintf (&buf, _("%s: illegal option -- %c\n"),
79929619d2aSchristos 				argv[0], c);
80029619d2aSchristos #else
80129619d2aSchristos 		fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
80229619d2aSchristos #endif
80329619d2aSchristos 	      }
80429619d2aSchristos 	    else
80529619d2aSchristos 	      {
80629619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
80729619d2aSchristos 		n = __asprintf (&buf, _("%s: invalid option -- %c\n"),
80829619d2aSchristos 				argv[0], c);
80929619d2aSchristos #else
81029619d2aSchristos 		fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
81129619d2aSchristos #endif
81229619d2aSchristos 	      }
81329619d2aSchristos 
81429619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
81529619d2aSchristos 	    if (n >= 0)
81629619d2aSchristos 	      {
81729619d2aSchristos 		_IO_flockfile (stderr);
81829619d2aSchristos 
81929619d2aSchristos 		int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
82029619d2aSchristos 		((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
82129619d2aSchristos 
82229619d2aSchristos 		if (_IO_fwide (stderr, 0) > 0)
82329619d2aSchristos 		  __fwprintf (stderr, L"%s", buf);
82429619d2aSchristos 		else
82529619d2aSchristos 		  fputs (buf, stderr);
82629619d2aSchristos 
82729619d2aSchristos 		((_IO_FILE *) stderr)->_flags2 = old_flags2;
82829619d2aSchristos 		_IO_funlockfile (stderr);
82929619d2aSchristos 
83029619d2aSchristos 		free (buf);
83129619d2aSchristos 	      }
83229619d2aSchristos #endif
83329619d2aSchristos 	  }
83429619d2aSchristos 	d->optopt = c;
83529619d2aSchristos 	return '?';
83629619d2aSchristos       }
83729619d2aSchristos     /* Convenience. Treat POSIX -W foo same as long option --foo */
83829619d2aSchristos     if (temp[0] == 'W' && temp[1] == ';')
83929619d2aSchristos       {
84029619d2aSchristos 	char *nameend;
84129619d2aSchristos 	const struct option *p;
84229619d2aSchristos 	const struct option *pfound = NULL;
84329619d2aSchristos 	int exact = 0;
84429619d2aSchristos 	int ambig = 0;
84529619d2aSchristos 	int indfound = 0;
84629619d2aSchristos 	int option_index;
84729619d2aSchristos 
84829619d2aSchristos 	/* This is an option that requires an argument.  */
84929619d2aSchristos 	if (*d->__nextchar != '\0')
85029619d2aSchristos 	  {
85129619d2aSchristos 	    d->optarg = d->__nextchar;
85229619d2aSchristos 	    /* If we end this ARGV-element by taking the rest as an arg,
85329619d2aSchristos 	       we must advance to the next element now.  */
85429619d2aSchristos 	    d->optind++;
85529619d2aSchristos 	  }
85629619d2aSchristos 	else if (d->optind == argc)
85729619d2aSchristos 	  {
85829619d2aSchristos 	    if (print_errors)
85929619d2aSchristos 	      {
86029619d2aSchristos 		/* 1003.2 specifies the format of this message.  */
86129619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
86229619d2aSchristos 		char *buf;
86329619d2aSchristos 
86429619d2aSchristos 		if (__asprintf (&buf,
86529619d2aSchristos 				_("%s: option requires an argument -- %c\n"),
86629619d2aSchristos 				argv[0], c) >= 0)
86729619d2aSchristos 		  {
86829619d2aSchristos 		    _IO_flockfile (stderr);
86929619d2aSchristos 
87029619d2aSchristos 		    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
87129619d2aSchristos 		    ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
87229619d2aSchristos 
87329619d2aSchristos 		    if (_IO_fwide (stderr, 0) > 0)
87429619d2aSchristos 		      __fwprintf (stderr, L"%s", buf);
87529619d2aSchristos 		    else
87629619d2aSchristos 		      fputs (buf, stderr);
87729619d2aSchristos 
87829619d2aSchristos 		    ((_IO_FILE *) stderr)->_flags2 = old_flags2;
87929619d2aSchristos 		    _IO_funlockfile (stderr);
88029619d2aSchristos 
88129619d2aSchristos 		    free (buf);
88229619d2aSchristos 		  }
88329619d2aSchristos #else
88429619d2aSchristos 		fprintf (stderr, _("%s: option requires an argument -- %c\n"),
88529619d2aSchristos 			 argv[0], c);
88629619d2aSchristos #endif
88729619d2aSchristos 	      }
88829619d2aSchristos 	    d->optopt = c;
88929619d2aSchristos 	    if (optstring[0] == ':')
89029619d2aSchristos 	      c = ':';
89129619d2aSchristos 	    else
89229619d2aSchristos 	      c = '?';
89329619d2aSchristos 	    return c;
89429619d2aSchristos 	  }
89529619d2aSchristos 	else
89629619d2aSchristos 	  /* We already incremented `d->optind' once;
89729619d2aSchristos 	     increment it again when taking next ARGV-elt as argument.  */
89829619d2aSchristos 	  d->optarg = argv[d->optind++];
89929619d2aSchristos 
90029619d2aSchristos 	/* optarg is now the argument, see if it's in the
90129619d2aSchristos 	   table of longopts.  */
90229619d2aSchristos 
90329619d2aSchristos 	for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
90429619d2aSchristos 	     nameend++)
90529619d2aSchristos 	  /* Do nothing.  */ ;
90629619d2aSchristos 
90729619d2aSchristos 	/* Test all long options for either exact match
90829619d2aSchristos 	   or abbreviated matches.  */
90929619d2aSchristos 	for (p = longopts, option_index = 0; p->name; p++, option_index++)
91029619d2aSchristos 	  if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
91129619d2aSchristos 	    {
91229619d2aSchristos 	      if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
91329619d2aSchristos 		{
91429619d2aSchristos 		  /* Exact match found.  */
91529619d2aSchristos 		  pfound = p;
91629619d2aSchristos 		  indfound = option_index;
91729619d2aSchristos 		  exact = 1;
91829619d2aSchristos 		  break;
91929619d2aSchristos 		}
92029619d2aSchristos 	      else if (pfound == NULL)
92129619d2aSchristos 		{
92229619d2aSchristos 		  /* First nonexact match found.  */
92329619d2aSchristos 		  pfound = p;
92429619d2aSchristos 		  indfound = option_index;
92529619d2aSchristos 		}
92629619d2aSchristos 	      else
92729619d2aSchristos 		/* Second or later nonexact match found.  */
92829619d2aSchristos 		ambig = 1;
92929619d2aSchristos 	    }
93029619d2aSchristos 	if (ambig && !exact)
93129619d2aSchristos 	  {
93229619d2aSchristos 	    if (print_errors)
93329619d2aSchristos 	      {
93429619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
93529619d2aSchristos 		char *buf;
93629619d2aSchristos 
93729619d2aSchristos 		if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
93829619d2aSchristos 				argv[0], argv[d->optind]) >= 0)
93929619d2aSchristos 		  {
94029619d2aSchristos 		    _IO_flockfile (stderr);
94129619d2aSchristos 
94229619d2aSchristos 		    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
94329619d2aSchristos 		    ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
94429619d2aSchristos 
94529619d2aSchristos 		    if (_IO_fwide (stderr, 0) > 0)
94629619d2aSchristos 		      __fwprintf (stderr, L"%s", buf);
94729619d2aSchristos 		    else
94829619d2aSchristos 		      fputs (buf, stderr);
94929619d2aSchristos 
95029619d2aSchristos 		    ((_IO_FILE *) stderr)->_flags2 = old_flags2;
95129619d2aSchristos 		    _IO_funlockfile (stderr);
95229619d2aSchristos 
95329619d2aSchristos 		    free (buf);
95429619d2aSchristos 		  }
95529619d2aSchristos #else
95629619d2aSchristos 		fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
95729619d2aSchristos 			 argv[0], argv[d->optind]);
95829619d2aSchristos #endif
95929619d2aSchristos 	      }
96029619d2aSchristos 	    d->__nextchar += strlen (d->__nextchar);
96129619d2aSchristos 	    d->optind++;
96229619d2aSchristos 	    return '?';
96329619d2aSchristos 	  }
96429619d2aSchristos 	if (pfound != NULL)
96529619d2aSchristos 	  {
96629619d2aSchristos 	    option_index = indfound;
96729619d2aSchristos 	    if (*nameend)
96829619d2aSchristos 	      {
96929619d2aSchristos 		/* Don't test has_arg with >, because some C compilers don't
97029619d2aSchristos 		   allow it to be used on enums.  */
97129619d2aSchristos 		if (pfound->has_arg)
97229619d2aSchristos 		  d->optarg = nameend + 1;
97329619d2aSchristos 		else
97429619d2aSchristos 		  {
97529619d2aSchristos 		    if (print_errors)
97629619d2aSchristos 		      {
97729619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
97829619d2aSchristos 			char *buf;
97929619d2aSchristos 
98029619d2aSchristos 			if (__asprintf (&buf, _("\
98129619d2aSchristos %s: option `-W %s' doesn't allow an argument\n"),
98229619d2aSchristos 					argv[0], pfound->name) >= 0)
98329619d2aSchristos 			  {
98429619d2aSchristos 			    _IO_flockfile (stderr);
98529619d2aSchristos 
98629619d2aSchristos 			    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
98729619d2aSchristos 			    ((_IO_FILE *) stderr)->_flags2
98829619d2aSchristos 			      |= _IO_FLAGS2_NOTCANCEL;
98929619d2aSchristos 
99029619d2aSchristos 			    if (_IO_fwide (stderr, 0) > 0)
99129619d2aSchristos 			      __fwprintf (stderr, L"%s", buf);
99229619d2aSchristos 			    else
99329619d2aSchristos 			      fputs (buf, stderr);
99429619d2aSchristos 
99529619d2aSchristos 			    ((_IO_FILE *) stderr)->_flags2 = old_flags2;
99629619d2aSchristos 			    _IO_funlockfile (stderr);
99729619d2aSchristos 
99829619d2aSchristos 			    free (buf);
99929619d2aSchristos 			  }
100029619d2aSchristos #else
100129619d2aSchristos 			fprintf (stderr, _("\
100229619d2aSchristos %s: option `-W %s' doesn't allow an argument\n"),
100329619d2aSchristos 				 argv[0], pfound->name);
100429619d2aSchristos #endif
100529619d2aSchristos 		      }
100629619d2aSchristos 
100729619d2aSchristos 		    d->__nextchar += strlen (d->__nextchar);
100829619d2aSchristos 		    return '?';
100929619d2aSchristos 		  }
101029619d2aSchristos 	      }
101129619d2aSchristos 	    else if (pfound->has_arg == 1)
101229619d2aSchristos 	      {
101329619d2aSchristos 		if (d->optind < argc)
101429619d2aSchristos 		  d->optarg = argv[d->optind++];
101529619d2aSchristos 		else
101629619d2aSchristos 		  {
101729619d2aSchristos 		    if (print_errors)
101829619d2aSchristos 		      {
101929619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
102029619d2aSchristos 			char *buf;
102129619d2aSchristos 
102229619d2aSchristos 			if (__asprintf (&buf, _("\
102329619d2aSchristos %s: option `%s' requires an argument\n"),
102429619d2aSchristos 					argv[0], argv[d->optind - 1]) >= 0)
102529619d2aSchristos 			  {
102629619d2aSchristos 			    _IO_flockfile (stderr);
102729619d2aSchristos 
102829619d2aSchristos 			    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
102929619d2aSchristos 			    ((_IO_FILE *) stderr)->_flags2
103029619d2aSchristos 			      |= _IO_FLAGS2_NOTCANCEL;
103129619d2aSchristos 
103229619d2aSchristos 			    if (_IO_fwide (stderr, 0) > 0)
103329619d2aSchristos 			      __fwprintf (stderr, L"%s", buf);
103429619d2aSchristos 			    else
103529619d2aSchristos 			      fputs (buf, stderr);
103629619d2aSchristos 
103729619d2aSchristos 			    ((_IO_FILE *) stderr)->_flags2 = old_flags2;
103829619d2aSchristos 			    _IO_funlockfile (stderr);
103929619d2aSchristos 
104029619d2aSchristos 			    free (buf);
104129619d2aSchristos 			  }
104229619d2aSchristos #else
104329619d2aSchristos 			fprintf (stderr,
104429619d2aSchristos 				 _("%s: option `%s' requires an argument\n"),
104529619d2aSchristos 				 argv[0], argv[d->optind - 1]);
104629619d2aSchristos #endif
104729619d2aSchristos 		      }
104829619d2aSchristos 		    d->__nextchar += strlen (d->__nextchar);
104929619d2aSchristos 		    return optstring[0] == ':' ? ':' : '?';
105029619d2aSchristos 		  }
105129619d2aSchristos 	      }
105229619d2aSchristos 	    d->__nextchar += strlen (d->__nextchar);
105329619d2aSchristos 	    if (longind != NULL)
105429619d2aSchristos 	      *longind = option_index;
105529619d2aSchristos 	    if (pfound->flag)
105629619d2aSchristos 	      {
105729619d2aSchristos 		*(pfound->flag) = pfound->val;
105829619d2aSchristos 		return 0;
105929619d2aSchristos 	      }
106029619d2aSchristos 	    return pfound->val;
106129619d2aSchristos 	  }
106229619d2aSchristos 	  d->__nextchar = NULL;
106329619d2aSchristos 	  return 'W';	/* Let the application handle it.   */
106429619d2aSchristos       }
106529619d2aSchristos     if (temp[1] == ':')
106629619d2aSchristos       {
106729619d2aSchristos 	if (temp[2] == ':')
106829619d2aSchristos 	  {
106929619d2aSchristos 	    /* This is an option that accepts an argument optionally.  */
107029619d2aSchristos 	    if (*d->__nextchar != '\0')
107129619d2aSchristos 	      {
107229619d2aSchristos 		d->optarg = d->__nextchar;
107329619d2aSchristos 		d->optind++;
107429619d2aSchristos 	      }
107529619d2aSchristos 	    else
107629619d2aSchristos 	      d->optarg = NULL;
107729619d2aSchristos 	    d->__nextchar = NULL;
107829619d2aSchristos 	  }
107929619d2aSchristos 	else
108029619d2aSchristos 	  {
108129619d2aSchristos 	    /* This is an option that requires an argument.  */
108229619d2aSchristos 	    if (*d->__nextchar != '\0')
108329619d2aSchristos 	      {
108429619d2aSchristos 		d->optarg = d->__nextchar;
108529619d2aSchristos 		/* If we end this ARGV-element by taking the rest as an arg,
108629619d2aSchristos 		   we must advance to the next element now.  */
108729619d2aSchristos 		d->optind++;
108829619d2aSchristos 	      }
108929619d2aSchristos 	    else if (d->optind == argc)
109029619d2aSchristos 	      {
109129619d2aSchristos 		if (print_errors)
109229619d2aSchristos 		  {
109329619d2aSchristos 		    /* 1003.2 specifies the format of this message.  */
109429619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
109529619d2aSchristos 		    char *buf;
109629619d2aSchristos 
109729619d2aSchristos 		    if (__asprintf (&buf, _("\
109829619d2aSchristos %s: option requires an argument -- %c\n"),
109929619d2aSchristos 				    argv[0], c) >= 0)
110029619d2aSchristos 		      {
110129619d2aSchristos 			_IO_flockfile (stderr);
110229619d2aSchristos 
110329619d2aSchristos 			int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
110429619d2aSchristos 			((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
110529619d2aSchristos 
110629619d2aSchristos 			if (_IO_fwide (stderr, 0) > 0)
110729619d2aSchristos 			  __fwprintf (stderr, L"%s", buf);
110829619d2aSchristos 			else
110929619d2aSchristos 			  fputs (buf, stderr);
111029619d2aSchristos 
111129619d2aSchristos 			((_IO_FILE *) stderr)->_flags2 = old_flags2;
111229619d2aSchristos 			_IO_funlockfile (stderr);
111329619d2aSchristos 
111429619d2aSchristos 			free (buf);
111529619d2aSchristos 		      }
111629619d2aSchristos #else
111729619d2aSchristos 		    fprintf (stderr,
111829619d2aSchristos 			     _("%s: option requires an argument -- %c\n"),
111929619d2aSchristos 			     argv[0], c);
112029619d2aSchristos #endif
112129619d2aSchristos 		  }
112229619d2aSchristos 		d->optopt = c;
112329619d2aSchristos 		if (optstring[0] == ':')
112429619d2aSchristos 		  c = ':';
112529619d2aSchristos 		else
112629619d2aSchristos 		  c = '?';
112729619d2aSchristos 	      }
112829619d2aSchristos 	    else
112929619d2aSchristos 	      /* We already incremented `optind' once;
113029619d2aSchristos 		 increment it again when taking next ARGV-elt as argument.  */
113129619d2aSchristos 	      d->optarg = argv[d->optind++];
113229619d2aSchristos 	    d->__nextchar = NULL;
113329619d2aSchristos 	  }
113429619d2aSchristos       }
113529619d2aSchristos     return c;
113629619d2aSchristos   }
113729619d2aSchristos }
113829619d2aSchristos 
113929619d2aSchristos int
_getopt_internal(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,int long_only)114029619d2aSchristos _getopt_internal (int argc, char *const *argv, const char *optstring,
114129619d2aSchristos 		  const struct option *longopts, int *longind, int long_only)
114229619d2aSchristos {
114329619d2aSchristos   int result;
114429619d2aSchristos 
114529619d2aSchristos   getopt_data.optind = optind;
114629619d2aSchristos   getopt_data.opterr = opterr;
114729619d2aSchristos 
114829619d2aSchristos   result = _getopt_internal_r (argc, argv, optstring, longopts,
114929619d2aSchristos 			       longind, long_only, &getopt_data);
115029619d2aSchristos 
115129619d2aSchristos   optind = getopt_data.optind;
115229619d2aSchristos   optarg = getopt_data.optarg;
115329619d2aSchristos   optopt = getopt_data.optopt;
115429619d2aSchristos 
115529619d2aSchristos   return result;
115629619d2aSchristos }
115729619d2aSchristos 
115829619d2aSchristos int
getopt(int argc,char * const * argv,const char * optstring)115929619d2aSchristos getopt (int argc, char *const *argv, const char *optstring)
116029619d2aSchristos {
116129619d2aSchristos   return _getopt_internal (argc, argv, optstring,
116229619d2aSchristos 			   (const struct option *) 0,
116329619d2aSchristos 			   (int *) 0,
116429619d2aSchristos 			   0);
116529619d2aSchristos }
116629619d2aSchristos 
116729619d2aSchristos 
116829619d2aSchristos #ifdef TEST
116929619d2aSchristos 
117029619d2aSchristos /* Compile with -DTEST to make an executable for use in testing
117129619d2aSchristos    the above definition of `getopt'.  */
117229619d2aSchristos 
117329619d2aSchristos int
main(int argc,char ** argv)117429619d2aSchristos main (int argc, char **argv)
117529619d2aSchristos {
117629619d2aSchristos   int c;
117729619d2aSchristos   int digit_optind = 0;
117829619d2aSchristos 
117929619d2aSchristos   while (1)
118029619d2aSchristos     {
118129619d2aSchristos       int this_option_optind = optind ? optind : 1;
118229619d2aSchristos 
118329619d2aSchristos       c = getopt (argc, argv, "abc:d:0123456789");
118429619d2aSchristos       if (c == -1)
118529619d2aSchristos 	break;
118629619d2aSchristos 
118729619d2aSchristos       switch (c)
118829619d2aSchristos 	{
118929619d2aSchristos 	case '0':
119029619d2aSchristos 	case '1':
119129619d2aSchristos 	case '2':
119229619d2aSchristos 	case '3':
119329619d2aSchristos 	case '4':
119429619d2aSchristos 	case '5':
119529619d2aSchristos 	case '6':
119629619d2aSchristos 	case '7':
119729619d2aSchristos 	case '8':
119829619d2aSchristos 	case '9':
119929619d2aSchristos 	  if (digit_optind != 0 && digit_optind != this_option_optind)
120029619d2aSchristos 	    printf ("digits occur in two different argv-elements.\n");
120129619d2aSchristos 	  digit_optind = this_option_optind;
120229619d2aSchristos 	  printf ("option %c\n", c);
120329619d2aSchristos 	  break;
120429619d2aSchristos 
120529619d2aSchristos 	case 'a':
120629619d2aSchristos 	  printf ("option a\n");
120729619d2aSchristos 	  break;
120829619d2aSchristos 
120929619d2aSchristos 	case 'b':
121029619d2aSchristos 	  printf ("option b\n");
121129619d2aSchristos 	  break;
121229619d2aSchristos 
121329619d2aSchristos 	case 'c':
121429619d2aSchristos 	  printf ("option c with value `%s'\n", optarg);
121529619d2aSchristos 	  break;
121629619d2aSchristos 
121729619d2aSchristos 	case '?':
121829619d2aSchristos 	  break;
121929619d2aSchristos 
122029619d2aSchristos 	default:
122129619d2aSchristos 	  printf ("?? getopt returned character code 0%o ??\n", c);
122229619d2aSchristos 	}
122329619d2aSchristos     }
122429619d2aSchristos 
122529619d2aSchristos   if (optind < argc)
122629619d2aSchristos     {
122729619d2aSchristos       printf ("non-option ARGV-elements: ");
122829619d2aSchristos       while (optind < argc)
122929619d2aSchristos 	printf ("%s ", argv[optind++]);
123029619d2aSchristos       printf ("\n");
123129619d2aSchristos     }
123229619d2aSchristos 
123329619d2aSchristos   exit (0);
123429619d2aSchristos }
123529619d2aSchristos 
123629619d2aSchristos #endif /* TEST */
1237