xref: /openbsd-src/gnu/lib/libiberty/src/getopt.c (revision 20fce977aadac3358da45d5027d7d19cdc03b0fe)
100bf4279Sespie /* Getopt for GNU.
200bf4279Sespie    NOTE: getopt is now part of the C library, so if you don't know what
300bf4279Sespie    "Keep this file name-space clean" means, talk to drepper@gnu.org
400bf4279Sespie    before changing it!
500bf4279Sespie 
6*20fce977Smiod    Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
7*20fce977Smiod    1996, 1997, 1998, 2005 Free Software Foundation, Inc.
800bf4279Sespie 
92e0724c7Sespie    NOTE: This source is derived from an old version taken from the GNU C
102e0724c7Sespie    Library (glibc).
1100bf4279Sespie 
1200bf4279Sespie    This program is free software; you can redistribute it and/or modify it
1300bf4279Sespie    under the terms of the GNU General Public License as published by the
1400bf4279Sespie    Free Software Foundation; either version 2, or (at your option) any
1500bf4279Sespie    later version.
1600bf4279Sespie 
1700bf4279Sespie    This program is distributed in the hope that it will be useful,
1800bf4279Sespie    but WITHOUT ANY WARRANTY; without even the implied warranty of
1900bf4279Sespie    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2000bf4279Sespie    GNU General Public License for more details.
2100bf4279Sespie 
2200bf4279Sespie    You should have received a copy of the GNU General Public License
2300bf4279Sespie    along with this program; if not, write to the Free Software
24*20fce977Smiod    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
2500bf4279Sespie    USA.  */
2600bf4279Sespie 
2700bf4279Sespie /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
2800bf4279Sespie    Ditto for AIX 3.2 and <stdlib.h>.  */
2900bf4279Sespie #ifndef _NO_PROTO
3000bf4279Sespie # define _NO_PROTO
3100bf4279Sespie #endif
3200bf4279Sespie 
3300bf4279Sespie #ifdef HAVE_CONFIG_H
3400bf4279Sespie # include <config.h>
3500bf4279Sespie #endif
3600bf4279Sespie 
3700bf4279Sespie #if !defined __STDC__ || !__STDC__
3800bf4279Sespie /* This is a separate conditional since some stdc systems
3900bf4279Sespie    reject `defined (const)'.  */
4000bf4279Sespie # ifndef const
4100bf4279Sespie #  define const
4200bf4279Sespie # endif
4300bf4279Sespie #endif
4400bf4279Sespie 
45*20fce977Smiod #include "ansidecl.h"
4600bf4279Sespie #include <stdio.h>
4700bf4279Sespie 
4800bf4279Sespie /* Comment out all this code if we are using the GNU C Library, and are not
4900bf4279Sespie    actually compiling the library itself.  This code is part of the GNU C
5000bf4279Sespie    Library, but also included in many other GNU distributions.  Compiling
5100bf4279Sespie    and linking in this code is a waste when using the GNU C library
5200bf4279Sespie    (especially if it is a shared library).  Rather than having every GNU
5300bf4279Sespie    program understand `configure --with-gnu-libc' and omit the object files,
5400bf4279Sespie    it is simpler to just do this in the source for each such file.  */
5500bf4279Sespie 
5600bf4279Sespie #define GETOPT_INTERFACE_VERSION 2
5700bf4279Sespie #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
5800bf4279Sespie # include <gnu-versions.h>
5900bf4279Sespie # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
6000bf4279Sespie #  define ELIDE_CODE
6100bf4279Sespie # endif
6200bf4279Sespie #endif
6300bf4279Sespie 
6400bf4279Sespie #ifndef ELIDE_CODE
6500bf4279Sespie 
6600bf4279Sespie 
6700bf4279Sespie /* This needs to come after some library #include
6800bf4279Sespie    to get __GNU_LIBRARY__ defined.  */
6900bf4279Sespie #ifdef	__GNU_LIBRARY__
7000bf4279Sespie /* Don't include stdlib.h for non-GNU C libraries because some of them
7100bf4279Sespie    contain conflicting prototypes for getopt.  */
7200bf4279Sespie # include <stdlib.h>
7300bf4279Sespie # include <unistd.h>
7400bf4279Sespie #endif	/* GNU C library.  */
7500bf4279Sespie 
7600bf4279Sespie #ifdef VMS
7700bf4279Sespie # include <unixlib.h>
7800bf4279Sespie # if HAVE_STRING_H - 0
7900bf4279Sespie #  include <string.h>
8000bf4279Sespie # endif
8100bf4279Sespie #endif
8200bf4279Sespie 
8300bf4279Sespie #ifndef _
8400bf4279Sespie /* This is for other GNU distributions with internationalized messages.
8500bf4279Sespie    When compiling libc, the _ macro is predefined.  */
869588ddcfSespie # if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
8700bf4279Sespie #  include <libintl.h>
8800bf4279Sespie #  define _(msgid)	gettext (msgid)
8900bf4279Sespie # else
9000bf4279Sespie #  define _(msgid)	(msgid)
9100bf4279Sespie # endif
9200bf4279Sespie #endif
9300bf4279Sespie 
9400bf4279Sespie /* This version of `getopt' appears to the caller like standard Unix `getopt'
9500bf4279Sespie    but it behaves differently for the user, since it allows the user
9600bf4279Sespie    to intersperse the options with the other arguments.
9700bf4279Sespie 
9800bf4279Sespie    As `getopt' works, it permutes the elements of ARGV so that,
9900bf4279Sespie    when it is done, all the options precede everything else.  Thus
10000bf4279Sespie    all application programs are extended to handle flexible argument order.
10100bf4279Sespie 
10200bf4279Sespie    Setting the environment variable POSIXLY_CORRECT disables permutation.
10300bf4279Sespie    Then the behavior is completely standard.
10400bf4279Sespie 
10500bf4279Sespie    GNU application programs can use a third alternative mode in which
10600bf4279Sespie    they can distinguish the relative order of options and other arguments.  */
10700bf4279Sespie 
10800bf4279Sespie #include "getopt.h"
10900bf4279Sespie 
11000bf4279Sespie /* For communication from `getopt' to the caller.
11100bf4279Sespie    When `getopt' finds an option that takes an argument,
11200bf4279Sespie    the argument value is returned here.
11300bf4279Sespie    Also, when `ordering' is RETURN_IN_ORDER,
11400bf4279Sespie    each non-option ARGV-element is returned here.  */
11500bf4279Sespie 
11600bf4279Sespie char *optarg = NULL;
11700bf4279Sespie 
11800bf4279Sespie /* Index in ARGV of the next element to be scanned.
11900bf4279Sespie    This is used for communication to and from the caller
12000bf4279Sespie    and for communication between successive calls to `getopt'.
12100bf4279Sespie 
12200bf4279Sespie    On entry to `getopt', zero means this is the first call; initialize.
12300bf4279Sespie 
12400bf4279Sespie    When `getopt' returns -1, this is the index of the first of the
12500bf4279Sespie    non-option elements that the caller should itself scan.
12600bf4279Sespie 
12700bf4279Sespie    Otherwise, `optind' communicates from one call to the next
12800bf4279Sespie    how much of ARGV has been scanned so far.  */
12900bf4279Sespie 
13000bf4279Sespie /* 1003.2 says this must be 1 before any call.  */
13100bf4279Sespie int optind = 1;
13200bf4279Sespie 
13300bf4279Sespie /* Formerly, initialization of getopt depended on optind==0, which
13400bf4279Sespie    causes problems with re-calling getopt as programs generally don't
13500bf4279Sespie    know that. */
13600bf4279Sespie 
13700bf4279Sespie int __getopt_initialized = 0;
13800bf4279Sespie 
13900bf4279Sespie /* The next char to be scanned in the option-element
14000bf4279Sespie    in which the last option character we returned was found.
14100bf4279Sespie    This allows us to pick up the scan where we left off.
14200bf4279Sespie 
14300bf4279Sespie    If this is zero, or a null string, it means resume the scan
14400bf4279Sespie    by advancing to the next ARGV-element.  */
14500bf4279Sespie 
14600bf4279Sespie static char *nextchar;
14700bf4279Sespie 
14800bf4279Sespie /* Callers store zero here to inhibit the error message
14900bf4279Sespie    for unrecognized options.  */
15000bf4279Sespie 
15100bf4279Sespie int opterr = 1;
15200bf4279Sespie 
15300bf4279Sespie /* Set to an option character which was unrecognized.
15400bf4279Sespie    This must be initialized on some systems to avoid linking in the
15500bf4279Sespie    system's own getopt implementation.  */
15600bf4279Sespie 
15700bf4279Sespie int optopt = '?';
15800bf4279Sespie 
15900bf4279Sespie /* Describe how to deal with options that follow non-option ARGV-elements.
16000bf4279Sespie 
16100bf4279Sespie    If the caller did not specify anything,
16200bf4279Sespie    the default is REQUIRE_ORDER if the environment variable
16300bf4279Sespie    POSIXLY_CORRECT is defined, PERMUTE otherwise.
16400bf4279Sespie 
16500bf4279Sespie    REQUIRE_ORDER means don't recognize them as options;
16600bf4279Sespie    stop option processing when the first non-option is seen.
16700bf4279Sespie    This is what Unix does.
16800bf4279Sespie    This mode of operation is selected by either setting the environment
16900bf4279Sespie    variable POSIXLY_CORRECT, or using `+' as the first character
17000bf4279Sespie    of the list of option characters.
17100bf4279Sespie 
17200bf4279Sespie    PERMUTE is the default.  We permute the contents of ARGV as we scan,
17300bf4279Sespie    so that eventually all the non-options are at the end.  This allows options
17400bf4279Sespie    to be given in any order, even with programs that were not written to
17500bf4279Sespie    expect this.
17600bf4279Sespie 
17700bf4279Sespie    RETURN_IN_ORDER is an option available to programs that were written
17800bf4279Sespie    to expect options and other ARGV-elements in any order and that care about
17900bf4279Sespie    the ordering of the two.  We describe each non-option ARGV-element
18000bf4279Sespie    as if it were the argument of an option with character code 1.
18100bf4279Sespie    Using `-' as the first character of the list of option characters
18200bf4279Sespie    selects this mode of operation.
18300bf4279Sespie 
18400bf4279Sespie    The special argument `--' forces an end of option-scanning regardless
18500bf4279Sespie    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
18600bf4279Sespie    `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
18700bf4279Sespie 
18800bf4279Sespie static enum
18900bf4279Sespie {
19000bf4279Sespie   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
19100bf4279Sespie } ordering;
19200bf4279Sespie 
19300bf4279Sespie /* Value of POSIXLY_CORRECT environment variable.  */
19400bf4279Sespie static char *posixly_correct;
19500bf4279Sespie 
19600bf4279Sespie #ifdef	__GNU_LIBRARY__
19700bf4279Sespie /* We want to avoid inclusion of string.h with non-GNU libraries
19800bf4279Sespie    because there are many ways it can cause trouble.
19900bf4279Sespie    On some systems, it contains special magic macros that don't work
20000bf4279Sespie    in GCC.  */
20100bf4279Sespie # include <string.h>
20200bf4279Sespie # define my_index	strchr
20300bf4279Sespie #else
20400bf4279Sespie 
20500bf4279Sespie # if HAVE_STRING_H
20600bf4279Sespie #  include <string.h>
20700bf4279Sespie # else
20800bf4279Sespie #  if HAVE_STRINGS_H
20900bf4279Sespie #   include <strings.h>
21000bf4279Sespie #  endif
21100bf4279Sespie # endif
21200bf4279Sespie 
21300bf4279Sespie /* Avoid depending on library functions or files
21400bf4279Sespie    whose names are inconsistent.  */
21500bf4279Sespie 
216*20fce977Smiod #if HAVE_STDLIB_H && HAVE_DECL_GETENV
217*20fce977Smiod #  include <stdlib.h>
218*20fce977Smiod #elif !defined(getenv)
219*20fce977Smiod #  ifdef __cplusplus
220*20fce977Smiod extern "C" {
221*20fce977Smiod #  endif /* __cplusplus */
222*20fce977Smiod extern char *getenv (const char *);
223*20fce977Smiod #  ifdef __cplusplus
224*20fce977Smiod }
225*20fce977Smiod #  endif /* __cplusplus */
22600bf4279Sespie #endif
22700bf4279Sespie 
22800bf4279Sespie static char *
my_index(const char * str,int chr)229*20fce977Smiod my_index (const char *str, int chr)
23000bf4279Sespie {
23100bf4279Sespie   while (*str)
23200bf4279Sespie     {
23300bf4279Sespie       if (*str == chr)
23400bf4279Sespie 	return (char *) str;
23500bf4279Sespie       str++;
23600bf4279Sespie     }
23700bf4279Sespie   return 0;
23800bf4279Sespie }
23900bf4279Sespie 
24000bf4279Sespie /* If using GCC, we can safely declare strlen this way.
24100bf4279Sespie    If not using GCC, it is ok not to declare it.  */
24200bf4279Sespie #ifdef __GNUC__
24300bf4279Sespie /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
24400bf4279Sespie    That was relevant to code that was here before.  */
24500bf4279Sespie # if (!defined __STDC__ || !__STDC__) && !defined strlen
24600bf4279Sespie /* gcc with -traditional declares the built-in strlen to return int,
24700bf4279Sespie    and has done so at least since version 2.4.5. -- rms.  */
24800bf4279Sespie extern int strlen (const char *);
24900bf4279Sespie # endif /* not __STDC__ */
25000bf4279Sespie #endif /* __GNUC__ */
25100bf4279Sespie 
25200bf4279Sespie #endif /* not __GNU_LIBRARY__ */
25300bf4279Sespie 
25400bf4279Sespie /* Handle permutation of arguments.  */
25500bf4279Sespie 
25600bf4279Sespie /* Describe the part of ARGV that contains non-options that have
25700bf4279Sespie    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
25800bf4279Sespie    `last_nonopt' is the index after the last of them.  */
25900bf4279Sespie 
26000bf4279Sespie static int first_nonopt;
26100bf4279Sespie static int last_nonopt;
26200bf4279Sespie 
26300bf4279Sespie #ifdef _LIBC
26400bf4279Sespie /* Bash 2.0 gives us an environment variable containing flags
26500bf4279Sespie    indicating ARGV elements that should not be considered arguments.  */
26600bf4279Sespie 
26700bf4279Sespie /* Defined in getopt_init.c  */
26800bf4279Sespie extern char *__getopt_nonoption_flags;
26900bf4279Sespie 
27000bf4279Sespie static int nonoption_flags_max_len;
27100bf4279Sespie static int nonoption_flags_len;
27200bf4279Sespie 
27300bf4279Sespie static int original_argc;
27400bf4279Sespie static char *const *original_argv;
27500bf4279Sespie 
27600bf4279Sespie /* Make sure the environment variable bash 2.0 puts in the environment
27700bf4279Sespie    is valid for the getopt call we must make sure that the ARGV passed
27800bf4279Sespie    to getopt is that one passed to the process.  */
27900bf4279Sespie static void
28000bf4279Sespie __attribute__ ((unused))
store_args_and_env(int argc,char * const * argv)28100bf4279Sespie store_args_and_env (int argc, char *const *argv)
28200bf4279Sespie {
28300bf4279Sespie   /* XXX This is no good solution.  We should rather copy the args so
28400bf4279Sespie      that we can compare them later.  But we must not use malloc(3).  */
28500bf4279Sespie   original_argc = argc;
28600bf4279Sespie   original_argv = argv;
28700bf4279Sespie }
28800bf4279Sespie # ifdef text_set_element
28900bf4279Sespie text_set_element (__libc_subinit, store_args_and_env);
29000bf4279Sespie # endif /* text_set_element */
29100bf4279Sespie 
29200bf4279Sespie # define SWAP_FLAGS(ch1, ch2) \
29300bf4279Sespie   if (nonoption_flags_len > 0)						      \
29400bf4279Sespie     {									      \
29500bf4279Sespie       char __tmp = __getopt_nonoption_flags[ch1];			      \
29600bf4279Sespie       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];	      \
29700bf4279Sespie       __getopt_nonoption_flags[ch2] = __tmp;				      \
29800bf4279Sespie     }
29900bf4279Sespie #else	/* !_LIBC */
30000bf4279Sespie # define SWAP_FLAGS(ch1, ch2)
30100bf4279Sespie #endif	/* _LIBC */
30200bf4279Sespie 
30300bf4279Sespie /* Exchange two adjacent subsequences of ARGV.
30400bf4279Sespie    One subsequence is elements [first_nonopt,last_nonopt)
30500bf4279Sespie    which contains all the non-options that have been skipped so far.
30600bf4279Sespie    The other is elements [last_nonopt,optind), which contains all
30700bf4279Sespie    the options processed since those non-options were skipped.
30800bf4279Sespie 
30900bf4279Sespie    `first_nonopt' and `last_nonopt' are relocated so that they describe
31000bf4279Sespie    the new indices of the non-options in ARGV after they are moved.  */
31100bf4279Sespie 
31200bf4279Sespie #if defined __STDC__ && __STDC__
31300bf4279Sespie static void exchange (char **);
31400bf4279Sespie #endif
31500bf4279Sespie 
31600bf4279Sespie static void
exchange(char ** argv)317*20fce977Smiod exchange (char **argv)
31800bf4279Sespie {
31900bf4279Sespie   int bottom = first_nonopt;
32000bf4279Sespie   int middle = last_nonopt;
32100bf4279Sespie   int top = optind;
32200bf4279Sespie   char *tem;
32300bf4279Sespie 
32400bf4279Sespie   /* Exchange the shorter segment with the far end of the longer segment.
32500bf4279Sespie      That puts the shorter segment into the right place.
32600bf4279Sespie      It leaves the longer segment in the right place overall,
32700bf4279Sespie      but it consists of two parts that need to be swapped next.  */
32800bf4279Sespie 
32900bf4279Sespie #ifdef _LIBC
33000bf4279Sespie   /* First make sure the handling of the `__getopt_nonoption_flags'
33100bf4279Sespie      string can work normally.  Our top argument must be in the range
33200bf4279Sespie      of the string.  */
33300bf4279Sespie   if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
33400bf4279Sespie     {
33500bf4279Sespie       /* We must extend the array.  The user plays games with us and
33600bf4279Sespie 	 presents new arguments.  */
337*20fce977Smiod       char *new_str = (char *) malloc (top + 1);
33800bf4279Sespie       if (new_str == NULL)
33900bf4279Sespie 	nonoption_flags_len = nonoption_flags_max_len = 0;
34000bf4279Sespie       else
34100bf4279Sespie 	{
3429588ddcfSespie 	  memset (mempcpy (new_str, __getopt_nonoption_flags,
34300bf4279Sespie 			   nonoption_flags_max_len),
34400bf4279Sespie 		  '\0', top + 1 - nonoption_flags_max_len);
34500bf4279Sespie 	  nonoption_flags_max_len = top + 1;
34600bf4279Sespie 	  __getopt_nonoption_flags = new_str;
34700bf4279Sespie 	}
34800bf4279Sespie     }
34900bf4279Sespie #endif
35000bf4279Sespie 
35100bf4279Sespie   while (top > middle && middle > bottom)
35200bf4279Sespie     {
35300bf4279Sespie       if (top - middle > middle - bottom)
35400bf4279Sespie 	{
35500bf4279Sespie 	  /* Bottom segment is the short one.  */
35600bf4279Sespie 	  int len = middle - bottom;
35700bf4279Sespie 	  register int i;
35800bf4279Sespie 
35900bf4279Sespie 	  /* Swap it with the top part of the top segment.  */
36000bf4279Sespie 	  for (i = 0; i < len; i++)
36100bf4279Sespie 	    {
36200bf4279Sespie 	      tem = argv[bottom + i];
36300bf4279Sespie 	      argv[bottom + i] = argv[top - (middle - bottom) + i];
36400bf4279Sespie 	      argv[top - (middle - bottom) + i] = tem;
36500bf4279Sespie 	      SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
36600bf4279Sespie 	    }
36700bf4279Sespie 	  /* Exclude the moved bottom segment from further swapping.  */
36800bf4279Sespie 	  top -= len;
36900bf4279Sespie 	}
37000bf4279Sespie       else
37100bf4279Sespie 	{
37200bf4279Sespie 	  /* Top segment is the short one.  */
37300bf4279Sespie 	  int len = top - middle;
37400bf4279Sespie 	  register int i;
37500bf4279Sespie 
37600bf4279Sespie 	  /* Swap it with the bottom part of the bottom segment.  */
37700bf4279Sespie 	  for (i = 0; i < len; i++)
37800bf4279Sespie 	    {
37900bf4279Sespie 	      tem = argv[bottom + i];
38000bf4279Sespie 	      argv[bottom + i] = argv[middle + i];
38100bf4279Sespie 	      argv[middle + i] = tem;
38200bf4279Sespie 	      SWAP_FLAGS (bottom + i, middle + i);
38300bf4279Sespie 	    }
38400bf4279Sespie 	  /* Exclude the moved top segment from further swapping.  */
38500bf4279Sespie 	  bottom += len;
38600bf4279Sespie 	}
38700bf4279Sespie     }
38800bf4279Sespie 
38900bf4279Sespie   /* Update records for the slots the non-options now occupy.  */
39000bf4279Sespie 
39100bf4279Sespie   first_nonopt += (optind - last_nonopt);
39200bf4279Sespie   last_nonopt = optind;
39300bf4279Sespie }
39400bf4279Sespie 
39500bf4279Sespie /* Initialize the internal data when the first call is made.  */
39600bf4279Sespie 
39700bf4279Sespie #if defined __STDC__ && __STDC__
39800bf4279Sespie static const char *_getopt_initialize (int, char *const *, const char *);
39900bf4279Sespie #endif
40000bf4279Sespie static const char *
_getopt_initialize(int argc ATTRIBUTE_UNUSED,char * const * argv ATTRIBUTE_UNUSED,const char * optstring)401*20fce977Smiod _getopt_initialize (int argc ATTRIBUTE_UNUSED,
402*20fce977Smiod 		    char *const *argv ATTRIBUTE_UNUSED,
403*20fce977Smiod 		    const char *optstring)
40400bf4279Sespie {
40500bf4279Sespie   /* Start processing options with ARGV-element 1 (since ARGV-element 0
40600bf4279Sespie      is the program name); the sequence of previously skipped
40700bf4279Sespie      non-option ARGV-elements is empty.  */
40800bf4279Sespie 
40900bf4279Sespie   first_nonopt = last_nonopt = optind;
41000bf4279Sespie 
41100bf4279Sespie   nextchar = NULL;
41200bf4279Sespie 
41300bf4279Sespie   posixly_correct = getenv ("POSIXLY_CORRECT");
41400bf4279Sespie 
41500bf4279Sespie   /* Determine how to handle the ordering of options and nonoptions.  */
41600bf4279Sespie 
41700bf4279Sespie   if (optstring[0] == '-')
41800bf4279Sespie     {
41900bf4279Sespie       ordering = RETURN_IN_ORDER;
42000bf4279Sespie       ++optstring;
42100bf4279Sespie     }
42200bf4279Sespie   else if (optstring[0] == '+')
42300bf4279Sespie     {
42400bf4279Sespie       ordering = REQUIRE_ORDER;
42500bf4279Sespie       ++optstring;
42600bf4279Sespie     }
42700bf4279Sespie   else if (posixly_correct != NULL)
42800bf4279Sespie     ordering = REQUIRE_ORDER;
42900bf4279Sespie   else
43000bf4279Sespie     ordering = PERMUTE;
43100bf4279Sespie 
43200bf4279Sespie #ifdef _LIBC
43300bf4279Sespie   if (posixly_correct == NULL
43400bf4279Sespie       && argc == original_argc && argv == original_argv)
43500bf4279Sespie     {
43600bf4279Sespie       if (nonoption_flags_max_len == 0)
43700bf4279Sespie 	{
43800bf4279Sespie 	  if (__getopt_nonoption_flags == NULL
43900bf4279Sespie 	      || __getopt_nonoption_flags[0] == '\0')
44000bf4279Sespie 	    nonoption_flags_max_len = -1;
44100bf4279Sespie 	  else
44200bf4279Sespie 	    {
44300bf4279Sespie 	      const char *orig_str = __getopt_nonoption_flags;
44400bf4279Sespie 	      int len = nonoption_flags_max_len = strlen (orig_str);
44500bf4279Sespie 	      if (nonoption_flags_max_len < argc)
44600bf4279Sespie 		nonoption_flags_max_len = argc;
44700bf4279Sespie 	      __getopt_nonoption_flags =
44800bf4279Sespie 		(char *) malloc (nonoption_flags_max_len);
44900bf4279Sespie 	      if (__getopt_nonoption_flags == NULL)
45000bf4279Sespie 		nonoption_flags_max_len = -1;
45100bf4279Sespie 	      else
4529588ddcfSespie 		memset (mempcpy (__getopt_nonoption_flags, orig_str, len),
45300bf4279Sespie 			'\0', nonoption_flags_max_len - len);
45400bf4279Sespie 	    }
45500bf4279Sespie 	}
45600bf4279Sespie       nonoption_flags_len = nonoption_flags_max_len;
45700bf4279Sespie     }
45800bf4279Sespie   else
45900bf4279Sespie     nonoption_flags_len = 0;
46000bf4279Sespie #endif
46100bf4279Sespie 
46200bf4279Sespie   return optstring;
46300bf4279Sespie }
46400bf4279Sespie 
46500bf4279Sespie /* Scan elements of ARGV (whose length is ARGC) for option characters
46600bf4279Sespie    given in OPTSTRING.
46700bf4279Sespie 
46800bf4279Sespie    If an element of ARGV starts with '-', and is not exactly "-" or "--",
46900bf4279Sespie    then it is an option element.  The characters of this element
47000bf4279Sespie    (aside from the initial '-') are option characters.  If `getopt'
47100bf4279Sespie    is called repeatedly, it returns successively each of the option characters
47200bf4279Sespie    from each of the option elements.
47300bf4279Sespie 
47400bf4279Sespie    If `getopt' finds another option character, it returns that character,
47500bf4279Sespie    updating `optind' and `nextchar' so that the next call to `getopt' can
47600bf4279Sespie    resume the scan with the following option character or ARGV-element.
47700bf4279Sespie 
47800bf4279Sespie    If there are no more option characters, `getopt' returns -1.
47900bf4279Sespie    Then `optind' is the index in ARGV of the first ARGV-element
48000bf4279Sespie    that is not an option.  (The ARGV-elements have been permuted
48100bf4279Sespie    so that those that are not options now come last.)
48200bf4279Sespie 
48300bf4279Sespie    OPTSTRING is a string containing the legitimate option characters.
48400bf4279Sespie    If an option character is seen that is not listed in OPTSTRING,
48500bf4279Sespie    return '?' after printing an error message.  If you set `opterr' to
48600bf4279Sespie    zero, the error message is suppressed but we still return '?'.
48700bf4279Sespie 
48800bf4279Sespie    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
48900bf4279Sespie    so the following text in the same ARGV-element, or the text of the following
49000bf4279Sespie    ARGV-element, is returned in `optarg'.  Two colons mean an option that
49100bf4279Sespie    wants an optional arg; if there is text in the current ARGV-element,
49200bf4279Sespie    it is returned in `optarg', otherwise `optarg' is set to zero.
49300bf4279Sespie 
49400bf4279Sespie    If OPTSTRING starts with `-' or `+', it requests different methods of
49500bf4279Sespie    handling the non-option ARGV-elements.
49600bf4279Sespie    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
49700bf4279Sespie 
49800bf4279Sespie    Long-named options begin with `--' instead of `-'.
49900bf4279Sespie    Their names may be abbreviated as long as the abbreviation is unique
50000bf4279Sespie    or is an exact match for some defined option.  If they have an
50100bf4279Sespie    argument, it follows the option name in the same ARGV-element, separated
50200bf4279Sespie    from the option name by a `=', or else the in next ARGV-element.
50300bf4279Sespie    When `getopt' finds a long-named option, it returns 0 if that option's
50400bf4279Sespie    `flag' field is nonzero, the value of the option's `val' field
50500bf4279Sespie    if the `flag' field is zero.
50600bf4279Sespie 
50700bf4279Sespie    The elements of ARGV aren't really const, because we permute them.
50800bf4279Sespie    But we pretend they're const in the prototype to be compatible
50900bf4279Sespie    with other systems.
51000bf4279Sespie 
51100bf4279Sespie    LONGOPTS is a vector of `struct option' terminated by an
51200bf4279Sespie    element containing a name which is zero.
51300bf4279Sespie 
51400bf4279Sespie    LONGIND returns the index in LONGOPT of the long-named option found.
51500bf4279Sespie    It is only valid when a long-named option has been found by the most
51600bf4279Sespie    recent call.
51700bf4279Sespie 
51800bf4279Sespie    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
51900bf4279Sespie    long-named options.  */
52000bf4279Sespie 
52100bf4279Sespie int
_getopt_internal(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,int long_only)522*20fce977Smiod _getopt_internal (int argc, char *const *argv, const char *optstring,
523*20fce977Smiod                   const struct option *longopts,
524*20fce977Smiod                   int *longind, int long_only)
52500bf4279Sespie {
52600bf4279Sespie   optarg = NULL;
52700bf4279Sespie 
52800bf4279Sespie   if (optind == 0 || !__getopt_initialized)
52900bf4279Sespie     {
53000bf4279Sespie       if (optind == 0)
53100bf4279Sespie 	optind = 1;	/* Don't scan ARGV[0], the program name.  */
53200bf4279Sespie       optstring = _getopt_initialize (argc, argv, optstring);
53300bf4279Sespie       __getopt_initialized = 1;
53400bf4279Sespie     }
53500bf4279Sespie 
53600bf4279Sespie   /* Test whether ARGV[optind] points to a non-option argument.
53700bf4279Sespie      Either it does not have option syntax, or there is an environment flag
53800bf4279Sespie      from the shell indicating it is not an option.  The later information
53900bf4279Sespie      is only used when the used in the GNU libc.  */
54000bf4279Sespie #ifdef _LIBC
54100bf4279Sespie # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'	      \
54200bf4279Sespie 		      || (optind < nonoption_flags_len			      \
54300bf4279Sespie 			  && __getopt_nonoption_flags[optind] == '1'))
54400bf4279Sespie #else
54500bf4279Sespie # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
54600bf4279Sespie #endif
54700bf4279Sespie 
54800bf4279Sespie   if (nextchar == NULL || *nextchar == '\0')
54900bf4279Sespie     {
55000bf4279Sespie       /* Advance to the next ARGV-element.  */
55100bf4279Sespie 
55200bf4279Sespie       /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
55300bf4279Sespie 	 moved back by the user (who may also have changed the arguments).  */
55400bf4279Sespie       if (last_nonopt > optind)
55500bf4279Sespie 	last_nonopt = optind;
55600bf4279Sespie       if (first_nonopt > optind)
55700bf4279Sespie 	first_nonopt = optind;
55800bf4279Sespie 
55900bf4279Sespie       if (ordering == PERMUTE)
56000bf4279Sespie 	{
56100bf4279Sespie 	  /* If we have just processed some options following some non-options,
56200bf4279Sespie 	     exchange them so that the options come first.  */
56300bf4279Sespie 
56400bf4279Sespie 	  if (first_nonopt != last_nonopt && last_nonopt != optind)
56500bf4279Sespie 	    exchange ((char **) argv);
56600bf4279Sespie 	  else if (last_nonopt != optind)
56700bf4279Sespie 	    first_nonopt = optind;
56800bf4279Sespie 
56900bf4279Sespie 	  /* Skip any additional non-options
57000bf4279Sespie 	     and extend the range of non-options previously skipped.  */
57100bf4279Sespie 
57200bf4279Sespie 	  while (optind < argc && NONOPTION_P)
57300bf4279Sespie 	    optind++;
57400bf4279Sespie 	  last_nonopt = optind;
57500bf4279Sespie 	}
57600bf4279Sespie 
57700bf4279Sespie       /* The special ARGV-element `--' means premature end of options.
57800bf4279Sespie 	 Skip it like a null option,
57900bf4279Sespie 	 then exchange with previous non-options as if it were an option,
58000bf4279Sespie 	 then skip everything else like a non-option.  */
58100bf4279Sespie 
58200bf4279Sespie       if (optind != argc && !strcmp (argv[optind], "--"))
58300bf4279Sespie 	{
58400bf4279Sespie 	  optind++;
58500bf4279Sespie 
58600bf4279Sespie 	  if (first_nonopt != last_nonopt && last_nonopt != optind)
58700bf4279Sespie 	    exchange ((char **) argv);
58800bf4279Sespie 	  else if (first_nonopt == last_nonopt)
58900bf4279Sespie 	    first_nonopt = optind;
59000bf4279Sespie 	  last_nonopt = argc;
59100bf4279Sespie 
59200bf4279Sespie 	  optind = argc;
59300bf4279Sespie 	}
59400bf4279Sespie 
59500bf4279Sespie       /* If we have done all the ARGV-elements, stop the scan
59600bf4279Sespie 	 and back over any non-options that we skipped and permuted.  */
59700bf4279Sespie 
59800bf4279Sespie       if (optind == argc)
59900bf4279Sespie 	{
60000bf4279Sespie 	  /* Set the next-arg-index to point at the non-options
60100bf4279Sespie 	     that we previously skipped, so the caller will digest them.  */
60200bf4279Sespie 	  if (first_nonopt != last_nonopt)
60300bf4279Sespie 	    optind = first_nonopt;
60400bf4279Sespie 	  return -1;
60500bf4279Sespie 	}
60600bf4279Sespie 
60700bf4279Sespie       /* If we have come to a non-option and did not permute it,
60800bf4279Sespie 	 either stop the scan or describe it to the caller and pass it by.  */
60900bf4279Sespie 
61000bf4279Sespie       if (NONOPTION_P)
61100bf4279Sespie 	{
61200bf4279Sespie 	  if (ordering == REQUIRE_ORDER)
61300bf4279Sespie 	    return -1;
61400bf4279Sespie 	  optarg = argv[optind++];
61500bf4279Sespie 	  return 1;
61600bf4279Sespie 	}
61700bf4279Sespie 
61800bf4279Sespie       /* We have found another option-ARGV-element.
61900bf4279Sespie 	 Skip the initial punctuation.  */
62000bf4279Sespie 
62100bf4279Sespie       nextchar = (argv[optind] + 1
62200bf4279Sespie 		  + (longopts != NULL && argv[optind][1] == '-'));
62300bf4279Sespie     }
62400bf4279Sespie 
62500bf4279Sespie   /* Decode the current option-ARGV-element.  */
62600bf4279Sespie 
62700bf4279Sespie   /* Check whether the ARGV-element is a long option.
62800bf4279Sespie 
62900bf4279Sespie      If long_only and the ARGV-element has the form "-f", where f is
63000bf4279Sespie      a valid short option, don't consider it an abbreviated form of
63100bf4279Sespie      a long option that starts with f.  Otherwise there would be no
63200bf4279Sespie      way to give the -f short option.
63300bf4279Sespie 
63400bf4279Sespie      On the other hand, if there's a long option "fubar" and
63500bf4279Sespie      the ARGV-element is "-fu", do consider that an abbreviation of
63600bf4279Sespie      the long option, just like "--fu", and not "-f" with arg "u".
63700bf4279Sespie 
63800bf4279Sespie      This distinction seems to be the most useful approach.  */
63900bf4279Sespie 
64000bf4279Sespie   if (longopts != NULL
64100bf4279Sespie       && (argv[optind][1] == '-'
64200bf4279Sespie 	  || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
64300bf4279Sespie     {
64400bf4279Sespie       char *nameend;
64500bf4279Sespie       const struct option *p;
64600bf4279Sespie       const struct option *pfound = NULL;
64700bf4279Sespie       int exact = 0;
64800bf4279Sespie       int ambig = 0;
64900bf4279Sespie       int indfound = -1;
65000bf4279Sespie       int option_index;
65100bf4279Sespie 
65200bf4279Sespie       for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
65300bf4279Sespie 	/* Do nothing.  */ ;
65400bf4279Sespie 
65500bf4279Sespie       /* Test all long options for either exact match
65600bf4279Sespie 	 or abbreviated matches.  */
65700bf4279Sespie       for (p = longopts, option_index = 0; p->name; p++, option_index++)
65800bf4279Sespie 	if (!strncmp (p->name, nextchar, nameend - nextchar))
65900bf4279Sespie 	  {
66000bf4279Sespie 	    if ((unsigned int) (nameend - nextchar)
66100bf4279Sespie 		== (unsigned int) strlen (p->name))
66200bf4279Sespie 	      {
66300bf4279Sespie 		/* Exact match found.  */
66400bf4279Sespie 		pfound = p;
66500bf4279Sespie 		indfound = option_index;
66600bf4279Sespie 		exact = 1;
66700bf4279Sespie 		break;
66800bf4279Sespie 	      }
66900bf4279Sespie 	    else if (pfound == NULL)
67000bf4279Sespie 	      {
67100bf4279Sespie 		/* First nonexact match found.  */
67200bf4279Sespie 		pfound = p;
67300bf4279Sespie 		indfound = option_index;
67400bf4279Sespie 	      }
67500bf4279Sespie 	    else
67600bf4279Sespie 	      /* Second or later nonexact match found.  */
67700bf4279Sespie 	      ambig = 1;
67800bf4279Sespie 	  }
67900bf4279Sespie 
68000bf4279Sespie       if (ambig && !exact)
68100bf4279Sespie 	{
68200bf4279Sespie 	  if (opterr)
68300bf4279Sespie 	    fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
68400bf4279Sespie 		     argv[0], argv[optind]);
68500bf4279Sespie 	  nextchar += strlen (nextchar);
68600bf4279Sespie 	  optind++;
68700bf4279Sespie 	  optopt = 0;
68800bf4279Sespie 	  return '?';
68900bf4279Sespie 	}
69000bf4279Sespie 
69100bf4279Sespie       if (pfound != NULL)
69200bf4279Sespie 	{
69300bf4279Sespie 	  option_index = indfound;
69400bf4279Sespie 	  optind++;
69500bf4279Sespie 	  if (*nameend)
69600bf4279Sespie 	    {
69700bf4279Sespie 	      /* Don't test has_arg with >, because some C compilers don't
69800bf4279Sespie 		 allow it to be used on enums.  */
69900bf4279Sespie 	      if (pfound->has_arg)
70000bf4279Sespie 		optarg = nameend + 1;
70100bf4279Sespie 	      else
70200bf4279Sespie 		{
70300bf4279Sespie 		  if (opterr)
70400bf4279Sespie 		    {
70500bf4279Sespie 		      if (argv[optind - 1][1] == '-')
70600bf4279Sespie 			/* --option */
70700bf4279Sespie 			fprintf (stderr,
70800bf4279Sespie 				 _("%s: option `--%s' doesn't allow an argument\n"),
70900bf4279Sespie 				 argv[0], pfound->name);
71000bf4279Sespie 		      else
71100bf4279Sespie 			/* +option or -option */
71200bf4279Sespie 			fprintf (stderr,
71300bf4279Sespie 				 _("%s: option `%c%s' doesn't allow an argument\n"),
71400bf4279Sespie 				 argv[0], argv[optind - 1][0], pfound->name);
71500bf4279Sespie 
71600bf4279Sespie 		      nextchar += strlen (nextchar);
71700bf4279Sespie 
71800bf4279Sespie 		      optopt = pfound->val;
71900bf4279Sespie 		      return '?';
72000bf4279Sespie 		    }
72100bf4279Sespie 		}
72200bf4279Sespie 	    }
72300bf4279Sespie 	  else if (pfound->has_arg == 1)
72400bf4279Sespie 	    {
72500bf4279Sespie 	      if (optind < argc)
72600bf4279Sespie 		optarg = argv[optind++];
72700bf4279Sespie 	      else
72800bf4279Sespie 		{
72900bf4279Sespie 		  if (opterr)
73000bf4279Sespie 		    fprintf (stderr,
73100bf4279Sespie 			   _("%s: option `%s' requires an argument\n"),
73200bf4279Sespie 			   argv[0], argv[optind - 1]);
73300bf4279Sespie 		  nextchar += strlen (nextchar);
73400bf4279Sespie 		  optopt = pfound->val;
73500bf4279Sespie 		  return optstring[0] == ':' ? ':' : '?';
73600bf4279Sespie 		}
73700bf4279Sespie 	    }
73800bf4279Sespie 	  nextchar += strlen (nextchar);
73900bf4279Sespie 	  if (longind != NULL)
74000bf4279Sespie 	    *longind = option_index;
74100bf4279Sespie 	  if (pfound->flag)
74200bf4279Sespie 	    {
74300bf4279Sespie 	      *(pfound->flag) = pfound->val;
74400bf4279Sespie 	      return 0;
74500bf4279Sespie 	    }
74600bf4279Sespie 	  return pfound->val;
74700bf4279Sespie 	}
74800bf4279Sespie 
74900bf4279Sespie       /* Can't find it as a long option.  If this is not getopt_long_only,
75000bf4279Sespie 	 or the option starts with '--' or is not a valid short
75100bf4279Sespie 	 option, then it's an error.
75200bf4279Sespie 	 Otherwise interpret it as a short option.  */
75300bf4279Sespie       if (!long_only || argv[optind][1] == '-'
75400bf4279Sespie 	  || my_index (optstring, *nextchar) == NULL)
75500bf4279Sespie 	{
75600bf4279Sespie 	  if (opterr)
75700bf4279Sespie 	    {
75800bf4279Sespie 	      if (argv[optind][1] == '-')
75900bf4279Sespie 		/* --option */
76000bf4279Sespie 		fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
76100bf4279Sespie 			 argv[0], nextchar);
76200bf4279Sespie 	      else
76300bf4279Sespie 		/* +option or -option */
76400bf4279Sespie 		fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
76500bf4279Sespie 			 argv[0], argv[optind][0], nextchar);
76600bf4279Sespie 	    }
76700bf4279Sespie 	  nextchar = (char *) "";
76800bf4279Sespie 	  optind++;
76900bf4279Sespie 	  optopt = 0;
77000bf4279Sespie 	  return '?';
77100bf4279Sespie 	}
77200bf4279Sespie     }
77300bf4279Sespie 
77400bf4279Sespie   /* Look at and handle the next short option-character.  */
77500bf4279Sespie 
77600bf4279Sespie   {
77700bf4279Sespie     char c = *nextchar++;
77800bf4279Sespie     char *temp = my_index (optstring, c);
77900bf4279Sespie 
78000bf4279Sespie     /* Increment `optind' when we start to process its last character.  */
78100bf4279Sespie     if (*nextchar == '\0')
78200bf4279Sespie       ++optind;
78300bf4279Sespie 
78400bf4279Sespie     if (temp == NULL || c == ':')
78500bf4279Sespie       {
78600bf4279Sespie 	if (opterr)
78700bf4279Sespie 	  {
78800bf4279Sespie 	    if (posixly_correct)
78900bf4279Sespie 	      /* 1003.2 specifies the format of this message.  */
79000bf4279Sespie 	      fprintf (stderr, _("%s: illegal option -- %c\n"),
79100bf4279Sespie 		       argv[0], c);
79200bf4279Sespie 	    else
79300bf4279Sespie 	      fprintf (stderr, _("%s: invalid option -- %c\n"),
79400bf4279Sespie 		       argv[0], c);
79500bf4279Sespie 	  }
79600bf4279Sespie 	optopt = c;
79700bf4279Sespie 	return '?';
79800bf4279Sespie       }
79900bf4279Sespie     /* Convenience. Treat POSIX -W foo same as long option --foo */
80000bf4279Sespie     if (temp[0] == 'W' && temp[1] == ';')
80100bf4279Sespie       {
80200bf4279Sespie 	char *nameend;
80300bf4279Sespie 	const struct option *p;
80400bf4279Sespie 	const struct option *pfound = NULL;
80500bf4279Sespie 	int exact = 0;
80600bf4279Sespie 	int ambig = 0;
80700bf4279Sespie 	int indfound = 0;
80800bf4279Sespie 	int option_index;
80900bf4279Sespie 
81000bf4279Sespie 	/* This is an option that requires an argument.  */
81100bf4279Sespie 	if (*nextchar != '\0')
81200bf4279Sespie 	  {
81300bf4279Sespie 	    optarg = nextchar;
81400bf4279Sespie 	    /* If we end this ARGV-element by taking the rest as an arg,
81500bf4279Sespie 	       we must advance to the next element now.  */
81600bf4279Sespie 	    optind++;
81700bf4279Sespie 	  }
81800bf4279Sespie 	else if (optind == argc)
81900bf4279Sespie 	  {
82000bf4279Sespie 	    if (opterr)
82100bf4279Sespie 	      {
82200bf4279Sespie 		/* 1003.2 specifies the format of this message.  */
82300bf4279Sespie 		fprintf (stderr, _("%s: option requires an argument -- %c\n"),
82400bf4279Sespie 			 argv[0], c);
82500bf4279Sespie 	      }
82600bf4279Sespie 	    optopt = c;
82700bf4279Sespie 	    if (optstring[0] == ':')
82800bf4279Sespie 	      c = ':';
82900bf4279Sespie 	    else
83000bf4279Sespie 	      c = '?';
83100bf4279Sespie 	    return c;
83200bf4279Sespie 	  }
83300bf4279Sespie 	else
83400bf4279Sespie 	  /* We already incremented `optind' once;
83500bf4279Sespie 	     increment it again when taking next ARGV-elt as argument.  */
83600bf4279Sespie 	  optarg = argv[optind++];
83700bf4279Sespie 
83800bf4279Sespie 	/* optarg is now the argument, see if it's in the
83900bf4279Sespie 	   table of longopts.  */
84000bf4279Sespie 
84100bf4279Sespie 	for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
84200bf4279Sespie 	  /* Do nothing.  */ ;
84300bf4279Sespie 
84400bf4279Sespie 	/* Test all long options for either exact match
84500bf4279Sespie 	   or abbreviated matches.  */
84600bf4279Sespie 	for (p = longopts, option_index = 0; p->name; p++, option_index++)
84700bf4279Sespie 	  if (!strncmp (p->name, nextchar, nameend - nextchar))
84800bf4279Sespie 	    {
84900bf4279Sespie 	      if ((unsigned int) (nameend - nextchar) == strlen (p->name))
85000bf4279Sespie 		{
85100bf4279Sespie 		  /* Exact match found.  */
85200bf4279Sespie 		  pfound = p;
85300bf4279Sespie 		  indfound = option_index;
85400bf4279Sespie 		  exact = 1;
85500bf4279Sespie 		  break;
85600bf4279Sespie 		}
85700bf4279Sespie 	      else if (pfound == NULL)
85800bf4279Sespie 		{
85900bf4279Sespie 		  /* First nonexact match found.  */
86000bf4279Sespie 		  pfound = p;
86100bf4279Sespie 		  indfound = option_index;
86200bf4279Sespie 		}
86300bf4279Sespie 	      else
86400bf4279Sespie 		/* Second or later nonexact match found.  */
86500bf4279Sespie 		ambig = 1;
86600bf4279Sespie 	    }
86700bf4279Sespie 	if (ambig && !exact)
86800bf4279Sespie 	  {
86900bf4279Sespie 	    if (opterr)
87000bf4279Sespie 	      fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
87100bf4279Sespie 		       argv[0], argv[optind]);
87200bf4279Sespie 	    nextchar += strlen (nextchar);
87300bf4279Sespie 	    optind++;
87400bf4279Sespie 	    return '?';
87500bf4279Sespie 	  }
87600bf4279Sespie 	if (pfound != NULL)
87700bf4279Sespie 	  {
87800bf4279Sespie 	    option_index = indfound;
87900bf4279Sespie 	    if (*nameend)
88000bf4279Sespie 	      {
88100bf4279Sespie 		/* Don't test has_arg with >, because some C compilers don't
88200bf4279Sespie 		   allow it to be used on enums.  */
88300bf4279Sespie 		if (pfound->has_arg)
88400bf4279Sespie 		  optarg = nameend + 1;
88500bf4279Sespie 		else
88600bf4279Sespie 		  {
88700bf4279Sespie 		    if (opterr)
88800bf4279Sespie 		      fprintf (stderr, _("\
88900bf4279Sespie %s: option `-W %s' doesn't allow an argument\n"),
89000bf4279Sespie 			       argv[0], pfound->name);
89100bf4279Sespie 
89200bf4279Sespie 		    nextchar += strlen (nextchar);
89300bf4279Sespie 		    return '?';
89400bf4279Sespie 		  }
89500bf4279Sespie 	      }
89600bf4279Sespie 	    else if (pfound->has_arg == 1)
89700bf4279Sespie 	      {
89800bf4279Sespie 		if (optind < argc)
89900bf4279Sespie 		  optarg = argv[optind++];
90000bf4279Sespie 		else
90100bf4279Sespie 		  {
90200bf4279Sespie 		    if (opterr)
90300bf4279Sespie 		      fprintf (stderr,
90400bf4279Sespie 			       _("%s: option `%s' requires an argument\n"),
90500bf4279Sespie 			       argv[0], argv[optind - 1]);
90600bf4279Sespie 		    nextchar += strlen (nextchar);
90700bf4279Sespie 		    return optstring[0] == ':' ? ':' : '?';
90800bf4279Sespie 		  }
90900bf4279Sespie 	      }
91000bf4279Sespie 	    nextchar += strlen (nextchar);
91100bf4279Sespie 	    if (longind != NULL)
91200bf4279Sespie 	      *longind = option_index;
91300bf4279Sespie 	    if (pfound->flag)
91400bf4279Sespie 	      {
91500bf4279Sespie 		*(pfound->flag) = pfound->val;
91600bf4279Sespie 		return 0;
91700bf4279Sespie 	      }
91800bf4279Sespie 	    return pfound->val;
91900bf4279Sespie 	  }
92000bf4279Sespie 	  nextchar = NULL;
92100bf4279Sespie 	  return 'W';	/* Let the application handle it.   */
92200bf4279Sespie       }
92300bf4279Sespie     if (temp[1] == ':')
92400bf4279Sespie       {
92500bf4279Sespie 	if (temp[2] == ':')
92600bf4279Sespie 	  {
92700bf4279Sespie 	    /* This is an option that accepts an argument optionally.  */
92800bf4279Sespie 	    if (*nextchar != '\0')
92900bf4279Sespie 	      {
93000bf4279Sespie 		optarg = nextchar;
93100bf4279Sespie 		optind++;
93200bf4279Sespie 	      }
93300bf4279Sespie 	    else
93400bf4279Sespie 	      optarg = NULL;
93500bf4279Sespie 	    nextchar = NULL;
93600bf4279Sespie 	  }
93700bf4279Sespie 	else
93800bf4279Sespie 	  {
93900bf4279Sespie 	    /* This is an option that requires an argument.  */
94000bf4279Sespie 	    if (*nextchar != '\0')
94100bf4279Sespie 	      {
94200bf4279Sespie 		optarg = nextchar;
94300bf4279Sespie 		/* If we end this ARGV-element by taking the rest as an arg,
94400bf4279Sespie 		   we must advance to the next element now.  */
94500bf4279Sespie 		optind++;
94600bf4279Sespie 	      }
94700bf4279Sespie 	    else if (optind == argc)
94800bf4279Sespie 	      {
94900bf4279Sespie 		if (opterr)
95000bf4279Sespie 		  {
95100bf4279Sespie 		    /* 1003.2 specifies the format of this message.  */
95200bf4279Sespie 		    fprintf (stderr,
95300bf4279Sespie 			   _("%s: option requires an argument -- %c\n"),
95400bf4279Sespie 			   argv[0], c);
95500bf4279Sespie 		  }
95600bf4279Sespie 		optopt = c;
95700bf4279Sespie 		if (optstring[0] == ':')
95800bf4279Sespie 		  c = ':';
95900bf4279Sespie 		else
96000bf4279Sespie 		  c = '?';
96100bf4279Sespie 	      }
96200bf4279Sespie 	    else
96300bf4279Sespie 	      /* We already incremented `optind' once;
96400bf4279Sespie 		 increment it again when taking next ARGV-elt as argument.  */
96500bf4279Sespie 	      optarg = argv[optind++];
96600bf4279Sespie 	    nextchar = NULL;
96700bf4279Sespie 	  }
96800bf4279Sespie       }
96900bf4279Sespie     return c;
97000bf4279Sespie   }
97100bf4279Sespie }
97200bf4279Sespie 
97300bf4279Sespie int
getopt(int argc,char * const * argv,const char * optstring)974*20fce977Smiod getopt (int argc, char *const *argv, const char *optstring)
97500bf4279Sespie {
97600bf4279Sespie   return _getopt_internal (argc, argv, optstring,
97700bf4279Sespie 			   (const struct option *) 0,
97800bf4279Sespie 			   (int *) 0,
97900bf4279Sespie 			   0);
98000bf4279Sespie }
98100bf4279Sespie 
98200bf4279Sespie #endif	/* Not ELIDE_CODE.  */
98300bf4279Sespie 
98400bf4279Sespie #ifdef TEST
98500bf4279Sespie 
98600bf4279Sespie /* Compile with -DTEST to make an executable for use in testing
98700bf4279Sespie    the above definition of `getopt'.  */
98800bf4279Sespie 
98900bf4279Sespie int
main(int argc,char ** argv)990*20fce977Smiod main (int argc, char **argv)
99100bf4279Sespie {
99200bf4279Sespie   int c;
99300bf4279Sespie   int digit_optind = 0;
99400bf4279Sespie 
99500bf4279Sespie   while (1)
99600bf4279Sespie     {
99700bf4279Sespie       int this_option_optind = optind ? optind : 1;
99800bf4279Sespie 
99900bf4279Sespie       c = getopt (argc, argv, "abc:d:0123456789");
100000bf4279Sespie       if (c == -1)
100100bf4279Sespie 	break;
100200bf4279Sespie 
100300bf4279Sespie       switch (c)
100400bf4279Sespie 	{
100500bf4279Sespie 	case '0':
100600bf4279Sespie 	case '1':
100700bf4279Sespie 	case '2':
100800bf4279Sespie 	case '3':
100900bf4279Sespie 	case '4':
101000bf4279Sespie 	case '5':
101100bf4279Sespie 	case '6':
101200bf4279Sespie 	case '7':
101300bf4279Sespie 	case '8':
101400bf4279Sespie 	case '9':
101500bf4279Sespie 	  if (digit_optind != 0 && digit_optind != this_option_optind)
101600bf4279Sespie 	    printf ("digits occur in two different argv-elements.\n");
101700bf4279Sespie 	  digit_optind = this_option_optind;
101800bf4279Sespie 	  printf ("option %c\n", c);
101900bf4279Sespie 	  break;
102000bf4279Sespie 
102100bf4279Sespie 	case 'a':
102200bf4279Sespie 	  printf ("option a\n");
102300bf4279Sespie 	  break;
102400bf4279Sespie 
102500bf4279Sespie 	case 'b':
102600bf4279Sespie 	  printf ("option b\n");
102700bf4279Sespie 	  break;
102800bf4279Sespie 
102900bf4279Sespie 	case 'c':
103000bf4279Sespie 	  printf ("option c with value `%s'\n", optarg);
103100bf4279Sespie 	  break;
103200bf4279Sespie 
103300bf4279Sespie 	case '?':
103400bf4279Sespie 	  break;
103500bf4279Sespie 
103600bf4279Sespie 	default:
103700bf4279Sespie 	  printf ("?? getopt returned character code 0%o ??\n", c);
103800bf4279Sespie 	}
103900bf4279Sespie     }
104000bf4279Sespie 
104100bf4279Sespie   if (optind < argc)
104200bf4279Sespie     {
104300bf4279Sespie       printf ("non-option ARGV-elements: ");
104400bf4279Sespie       while (optind < argc)
104500bf4279Sespie 	printf ("%s ", argv[optind++]);
104600bf4279Sespie       printf ("\n");
104700bf4279Sespie     }
104800bf4279Sespie 
104900bf4279Sespie   exit (0);
105000bf4279Sespie }
105100bf4279Sespie 
105200bf4279Sespie #endif /* TEST */
1053