xref: /titanic_50/usr/src/grub/grub-0.97/lib/getopt.c (revision 1b8adde7ba7d5e04395c141c5400dc2cffd7d809)
1*1b8adde7SWilliam Kucharski /* Getopt for GNU.
2*1b8adde7SWilliam Kucharski    NOTE: getopt is now part of the C library, so if you don't know what
3*1b8adde7SWilliam Kucharski    "Keep this file name-space clean" means, talk to drepper@gnu.org
4*1b8adde7SWilliam Kucharski    before changing it!
5*1b8adde7SWilliam Kucharski 
6*1b8adde7SWilliam Kucharski    Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98
7*1b8adde7SWilliam Kucharski    	Free Software Foundation, Inc.
8*1b8adde7SWilliam Kucharski 
9*1b8adde7SWilliam Kucharski    NOTE: The canonical source of this file is maintained with the GNU C Library.
10*1b8adde7SWilliam Kucharski    Bugs can be reported to bug-glibc@gnu.org.
11*1b8adde7SWilliam Kucharski 
12*1b8adde7SWilliam Kucharski    This program is free software; you can redistribute it and/or modify it
13*1b8adde7SWilliam Kucharski    under the terms of the GNU General Public License as published by the
14*1b8adde7SWilliam Kucharski    Free Software Foundation; either version 2, or (at your option) any
15*1b8adde7SWilliam Kucharski    later version.
16*1b8adde7SWilliam Kucharski 
17*1b8adde7SWilliam Kucharski    This program is distributed in the hope that it will be useful,
18*1b8adde7SWilliam Kucharski    but WITHOUT ANY WARRANTY; without even the implied warranty of
19*1b8adde7SWilliam Kucharski    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20*1b8adde7SWilliam Kucharski    GNU General Public License for more details.
21*1b8adde7SWilliam Kucharski 
22*1b8adde7SWilliam Kucharski    You should have received a copy of the GNU General Public License
23*1b8adde7SWilliam Kucharski    along with this program; if not, write to the Free Software
24*1b8adde7SWilliam Kucharski    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25*1b8adde7SWilliam Kucharski    USA.  */
26*1b8adde7SWilliam Kucharski 
27*1b8adde7SWilliam Kucharski /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
28*1b8adde7SWilliam Kucharski    Ditto for AIX 3.2 and <stdlib.h>.  */
29*1b8adde7SWilliam Kucharski #ifndef _NO_PROTO
30*1b8adde7SWilliam Kucharski # define _NO_PROTO
31*1b8adde7SWilliam Kucharski #endif
32*1b8adde7SWilliam Kucharski 
33*1b8adde7SWilliam Kucharski #ifdef HAVE_CONFIG_H
34*1b8adde7SWilliam Kucharski # include <config.h>
35*1b8adde7SWilliam Kucharski #endif
36*1b8adde7SWilliam Kucharski 
37*1b8adde7SWilliam Kucharski #if !defined __STDC__ || !__STDC__
38*1b8adde7SWilliam Kucharski /* This is a separate conditional since some stdc systems
39*1b8adde7SWilliam Kucharski    reject `defined (const)'.  */
40*1b8adde7SWilliam Kucharski # ifndef const
41*1b8adde7SWilliam Kucharski #  define const
42*1b8adde7SWilliam Kucharski # endif
43*1b8adde7SWilliam Kucharski #endif
44*1b8adde7SWilliam Kucharski 
45*1b8adde7SWilliam Kucharski #include <stdio.h>
46*1b8adde7SWilliam Kucharski 
47*1b8adde7SWilliam Kucharski /* Comment out all this code if we are using the GNU C Library, and are not
48*1b8adde7SWilliam Kucharski    actually compiling the library itself.  This code is part of the GNU C
49*1b8adde7SWilliam Kucharski    Library, but also included in many other GNU distributions.  Compiling
50*1b8adde7SWilliam Kucharski    and linking in this code is a waste when using the GNU C library
51*1b8adde7SWilliam Kucharski    (especially if it is a shared library).  Rather than having every GNU
52*1b8adde7SWilliam Kucharski    program understand `configure --with-gnu-libc' and omit the object files,
53*1b8adde7SWilliam Kucharski    it is simpler to just do this in the source for each such file.  */
54*1b8adde7SWilliam Kucharski 
55*1b8adde7SWilliam Kucharski #define GETOPT_INTERFACE_VERSION 2
56*1b8adde7SWilliam Kucharski #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
57*1b8adde7SWilliam Kucharski # include <gnu-versions.h>
58*1b8adde7SWilliam Kucharski # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
59*1b8adde7SWilliam Kucharski #  define ELIDE_CODE
60*1b8adde7SWilliam Kucharski # endif
61*1b8adde7SWilliam Kucharski #endif
62*1b8adde7SWilliam Kucharski 
63*1b8adde7SWilliam Kucharski #ifndef ELIDE_CODE
64*1b8adde7SWilliam Kucharski 
65*1b8adde7SWilliam Kucharski 
66*1b8adde7SWilliam Kucharski /* This needs to come after some library #include
67*1b8adde7SWilliam Kucharski    to get __GNU_LIBRARY__ defined.  */
68*1b8adde7SWilliam Kucharski #ifdef	__GNU_LIBRARY__
69*1b8adde7SWilliam Kucharski /* Don't include stdlib.h for non-GNU C libraries because some of them
70*1b8adde7SWilliam Kucharski    contain conflicting prototypes for getopt.  */
71*1b8adde7SWilliam Kucharski # include <stdlib.h>
72*1b8adde7SWilliam Kucharski # include <unistd.h>
73*1b8adde7SWilliam Kucharski #endif	/* GNU C library.  */
74*1b8adde7SWilliam Kucharski 
75*1b8adde7SWilliam Kucharski #ifdef VMS
76*1b8adde7SWilliam Kucharski # include <unixlib.h>
77*1b8adde7SWilliam Kucharski # if HAVE_STRING_H - 0
78*1b8adde7SWilliam Kucharski #  include <string.h>
79*1b8adde7SWilliam Kucharski # endif
80*1b8adde7SWilliam Kucharski #endif
81*1b8adde7SWilliam Kucharski 
82*1b8adde7SWilliam Kucharski #ifndef _
83*1b8adde7SWilliam Kucharski /* This is for other GNU distributions with internationalized messages.
84*1b8adde7SWilliam Kucharski    When compiling libc, the _ macro is predefined.  */
85*1b8adde7SWilliam Kucharski # ifdef HAVE_LIBINTL_H
86*1b8adde7SWilliam Kucharski #  include <libintl.h>
87*1b8adde7SWilliam Kucharski #  define _(msgid)	gettext (msgid)
88*1b8adde7SWilliam Kucharski # else
89*1b8adde7SWilliam Kucharski #  define _(msgid)	(msgid)
90*1b8adde7SWilliam Kucharski # endif
91*1b8adde7SWilliam Kucharski #endif
92*1b8adde7SWilliam Kucharski 
93*1b8adde7SWilliam Kucharski /* This version of `getopt' appears to the caller like standard Unix `getopt'
94*1b8adde7SWilliam Kucharski    but it behaves differently for the user, since it allows the user
95*1b8adde7SWilliam Kucharski    to intersperse the options with the other arguments.
96*1b8adde7SWilliam Kucharski 
97*1b8adde7SWilliam Kucharski    As `getopt' works, it permutes the elements of ARGV so that,
98*1b8adde7SWilliam Kucharski    when it is done, all the options precede everything else.  Thus
99*1b8adde7SWilliam Kucharski    all application programs are extended to handle flexible argument order.
100*1b8adde7SWilliam Kucharski 
101*1b8adde7SWilliam Kucharski    Setting the environment variable POSIXLY_CORRECT disables permutation.
102*1b8adde7SWilliam Kucharski    Then the behavior is completely standard.
103*1b8adde7SWilliam Kucharski 
104*1b8adde7SWilliam Kucharski    GNU application programs can use a third alternative mode in which
105*1b8adde7SWilliam Kucharski    they can distinguish the relative order of options and other arguments.  */
106*1b8adde7SWilliam Kucharski 
107*1b8adde7SWilliam Kucharski #include "getopt.h"
108*1b8adde7SWilliam Kucharski 
109*1b8adde7SWilliam Kucharski /* For communication from `getopt' to the caller.
110*1b8adde7SWilliam Kucharski    When `getopt' finds an option that takes an argument,
111*1b8adde7SWilliam Kucharski    the argument value is returned here.
112*1b8adde7SWilliam Kucharski    Also, when `ordering' is RETURN_IN_ORDER,
113*1b8adde7SWilliam Kucharski    each non-option ARGV-element is returned here.  */
114*1b8adde7SWilliam Kucharski 
115*1b8adde7SWilliam Kucharski char *optarg = NULL;
116*1b8adde7SWilliam Kucharski 
117*1b8adde7SWilliam Kucharski /* Index in ARGV of the next element to be scanned.
118*1b8adde7SWilliam Kucharski    This is used for communication to and from the caller
119*1b8adde7SWilliam Kucharski    and for communication between successive calls to `getopt'.
120*1b8adde7SWilliam Kucharski 
121*1b8adde7SWilliam Kucharski    On entry to `getopt', zero means this is the first call; initialize.
122*1b8adde7SWilliam Kucharski 
123*1b8adde7SWilliam Kucharski    When `getopt' returns -1, this is the index of the first of the
124*1b8adde7SWilliam Kucharski    non-option elements that the caller should itself scan.
125*1b8adde7SWilliam Kucharski 
126*1b8adde7SWilliam Kucharski    Otherwise, `optind' communicates from one call to the next
127*1b8adde7SWilliam Kucharski    how much of ARGV has been scanned so far.  */
128*1b8adde7SWilliam Kucharski 
129*1b8adde7SWilliam Kucharski /* 1003.2 says this must be 1 before any call.  */
130*1b8adde7SWilliam Kucharski int optind = 1;
131*1b8adde7SWilliam Kucharski 
132*1b8adde7SWilliam Kucharski /* Formerly, initialization of getopt depended on optind==0, which
133*1b8adde7SWilliam Kucharski    causes problems with re-calling getopt as programs generally don't
134*1b8adde7SWilliam Kucharski    know that. */
135*1b8adde7SWilliam Kucharski 
136*1b8adde7SWilliam Kucharski int __getopt_initialized = 0;
137*1b8adde7SWilliam Kucharski 
138*1b8adde7SWilliam Kucharski /* The next char to be scanned in the option-element
139*1b8adde7SWilliam Kucharski    in which the last option character we returned was found.
140*1b8adde7SWilliam Kucharski    This allows us to pick up the scan where we left off.
141*1b8adde7SWilliam Kucharski 
142*1b8adde7SWilliam Kucharski    If this is zero, or a null string, it means resume the scan
143*1b8adde7SWilliam Kucharski    by advancing to the next ARGV-element.  */
144*1b8adde7SWilliam Kucharski 
145*1b8adde7SWilliam Kucharski static char *nextchar;
146*1b8adde7SWilliam Kucharski 
147*1b8adde7SWilliam Kucharski /* Callers store zero here to inhibit the error message
148*1b8adde7SWilliam Kucharski    for unrecognized options.  */
149*1b8adde7SWilliam Kucharski 
150*1b8adde7SWilliam Kucharski int opterr = 1;
151*1b8adde7SWilliam Kucharski 
152*1b8adde7SWilliam Kucharski /* Set to an option character which was unrecognized.
153*1b8adde7SWilliam Kucharski    This must be initialized on some systems to avoid linking in the
154*1b8adde7SWilliam Kucharski    system's own getopt implementation.  */
155*1b8adde7SWilliam Kucharski 
156*1b8adde7SWilliam Kucharski int optopt = '?';
157*1b8adde7SWilliam Kucharski 
158*1b8adde7SWilliam Kucharski /* Describe how to deal with options that follow non-option ARGV-elements.
159*1b8adde7SWilliam Kucharski 
160*1b8adde7SWilliam Kucharski    If the caller did not specify anything,
161*1b8adde7SWilliam Kucharski    the default is REQUIRE_ORDER if the environment variable
162*1b8adde7SWilliam Kucharski    POSIXLY_CORRECT is defined, PERMUTE otherwise.
163*1b8adde7SWilliam Kucharski 
164*1b8adde7SWilliam Kucharski    REQUIRE_ORDER means don't recognize them as options;
165*1b8adde7SWilliam Kucharski    stop option processing when the first non-option is seen.
166*1b8adde7SWilliam Kucharski    This is what Unix does.
167*1b8adde7SWilliam Kucharski    This mode of operation is selected by either setting the environment
168*1b8adde7SWilliam Kucharski    variable POSIXLY_CORRECT, or using `+' as the first character
169*1b8adde7SWilliam Kucharski    of the list of option characters.
170*1b8adde7SWilliam Kucharski 
171*1b8adde7SWilliam Kucharski    PERMUTE is the default.  We permute the contents of ARGV as we scan,
172*1b8adde7SWilliam Kucharski    so that eventually all the non-options are at the end.  This allows options
173*1b8adde7SWilliam Kucharski    to be given in any order, even with programs that were not written to
174*1b8adde7SWilliam Kucharski    expect this.
175*1b8adde7SWilliam Kucharski 
176*1b8adde7SWilliam Kucharski    RETURN_IN_ORDER is an option available to programs that were written
177*1b8adde7SWilliam Kucharski    to expect options and other ARGV-elements in any order and that care about
178*1b8adde7SWilliam Kucharski    the ordering of the two.  We describe each non-option ARGV-element
179*1b8adde7SWilliam Kucharski    as if it were the argument of an option with character code 1.
180*1b8adde7SWilliam Kucharski    Using `-' as the first character of the list of option characters
181*1b8adde7SWilliam Kucharski    selects this mode of operation.
182*1b8adde7SWilliam Kucharski 
183*1b8adde7SWilliam Kucharski    The special argument `--' forces an end of option-scanning regardless
184*1b8adde7SWilliam Kucharski    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
185*1b8adde7SWilliam Kucharski    `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
186*1b8adde7SWilliam Kucharski 
187*1b8adde7SWilliam Kucharski static enum
188*1b8adde7SWilliam Kucharski {
189*1b8adde7SWilliam Kucharski   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
190*1b8adde7SWilliam Kucharski } ordering;
191*1b8adde7SWilliam Kucharski 
192*1b8adde7SWilliam Kucharski /* Value of POSIXLY_CORRECT environment variable.  */
193*1b8adde7SWilliam Kucharski static char *posixly_correct;
194*1b8adde7SWilliam Kucharski 
195*1b8adde7SWilliam Kucharski #ifdef	__GNU_LIBRARY__
196*1b8adde7SWilliam Kucharski /* We want to avoid inclusion of string.h with non-GNU libraries
197*1b8adde7SWilliam Kucharski    because there are many ways it can cause trouble.
198*1b8adde7SWilliam Kucharski    On some systems, it contains special magic macros that don't work
199*1b8adde7SWilliam Kucharski    in GCC.  */
200*1b8adde7SWilliam Kucharski # include <string.h>
201*1b8adde7SWilliam Kucharski # define my_index	strchr
202*1b8adde7SWilliam Kucharski #else
203*1b8adde7SWilliam Kucharski 
204*1b8adde7SWilliam Kucharski # if HAVE_STRING_H
205*1b8adde7SWilliam Kucharski #  include <string.h>
206*1b8adde7SWilliam Kucharski # else
207*1b8adde7SWilliam Kucharski #  include <strings.h>
208*1b8adde7SWilliam Kucharski # endif
209*1b8adde7SWilliam Kucharski 
210*1b8adde7SWilliam Kucharski /* Avoid depending on library functions or files
211*1b8adde7SWilliam Kucharski    whose names are inconsistent.  */
212*1b8adde7SWilliam Kucharski 
213*1b8adde7SWilliam Kucharski #ifndef getenv
214*1b8adde7SWilliam Kucharski extern char *getenv ();
215*1b8adde7SWilliam Kucharski #endif
216*1b8adde7SWilliam Kucharski 
217*1b8adde7SWilliam Kucharski static char *
my_index(str,chr)218*1b8adde7SWilliam Kucharski my_index (str, chr)
219*1b8adde7SWilliam Kucharski      const char *str;
220*1b8adde7SWilliam Kucharski      int chr;
221*1b8adde7SWilliam Kucharski {
222*1b8adde7SWilliam Kucharski   while (*str)
223*1b8adde7SWilliam Kucharski     {
224*1b8adde7SWilliam Kucharski       if (*str == chr)
225*1b8adde7SWilliam Kucharski 	return (char *) str;
226*1b8adde7SWilliam Kucharski       str++;
227*1b8adde7SWilliam Kucharski     }
228*1b8adde7SWilliam Kucharski   return 0;
229*1b8adde7SWilliam Kucharski }
230*1b8adde7SWilliam Kucharski 
231*1b8adde7SWilliam Kucharski /* If using GCC, we can safely declare strlen this way.
232*1b8adde7SWilliam Kucharski    If not using GCC, it is ok not to declare it.  */
233*1b8adde7SWilliam Kucharski #ifdef __GNUC__
234*1b8adde7SWilliam Kucharski /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
235*1b8adde7SWilliam Kucharski    That was relevant to code that was here before.  */
236*1b8adde7SWilliam Kucharski # if (!defined __STDC__ || !__STDC__) && !defined strlen
237*1b8adde7SWilliam Kucharski /* gcc with -traditional declares the built-in strlen to return int,
238*1b8adde7SWilliam Kucharski    and has done so at least since version 2.4.5. -- rms.  */
239*1b8adde7SWilliam Kucharski extern int strlen (const char *);
240*1b8adde7SWilliam Kucharski # endif /* not __STDC__ */
241*1b8adde7SWilliam Kucharski #endif /* __GNUC__ */
242*1b8adde7SWilliam Kucharski 
243*1b8adde7SWilliam Kucharski #endif /* not __GNU_LIBRARY__ */
244*1b8adde7SWilliam Kucharski 
245*1b8adde7SWilliam Kucharski /* Handle permutation of arguments.  */
246*1b8adde7SWilliam Kucharski 
247*1b8adde7SWilliam Kucharski /* Describe the part of ARGV that contains non-options that have
248*1b8adde7SWilliam Kucharski    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
249*1b8adde7SWilliam Kucharski    `last_nonopt' is the index after the last of them.  */
250*1b8adde7SWilliam Kucharski 
251*1b8adde7SWilliam Kucharski static int first_nonopt;
252*1b8adde7SWilliam Kucharski static int last_nonopt;
253*1b8adde7SWilliam Kucharski 
254*1b8adde7SWilliam Kucharski #ifdef _LIBC
255*1b8adde7SWilliam Kucharski /* Bash 2.0 gives us an environment variable containing flags
256*1b8adde7SWilliam Kucharski    indicating ARGV elements that should not be considered arguments.  */
257*1b8adde7SWilliam Kucharski 
258*1b8adde7SWilliam Kucharski /* Defined in getopt_init.c  */
259*1b8adde7SWilliam Kucharski extern char *__getopt_nonoption_flags;
260*1b8adde7SWilliam Kucharski 
261*1b8adde7SWilliam Kucharski static int nonoption_flags_max_len;
262*1b8adde7SWilliam Kucharski static int nonoption_flags_len;
263*1b8adde7SWilliam Kucharski 
264*1b8adde7SWilliam Kucharski static int original_argc;
265*1b8adde7SWilliam Kucharski static char *const *original_argv;
266*1b8adde7SWilliam Kucharski 
267*1b8adde7SWilliam Kucharski /* Make sure the environment variable bash 2.0 puts in the environment
268*1b8adde7SWilliam Kucharski    is valid for the getopt call we must make sure that the ARGV passed
269*1b8adde7SWilliam Kucharski    to getopt is that one passed to the process.  */
270*1b8adde7SWilliam Kucharski static void
271*1b8adde7SWilliam Kucharski __attribute__ ((unused))
store_args_and_env(int argc,char * const * argv)272*1b8adde7SWilliam Kucharski store_args_and_env (int argc, char *const *argv)
273*1b8adde7SWilliam Kucharski {
274*1b8adde7SWilliam Kucharski   /* XXX This is no good solution.  We should rather copy the args so
275*1b8adde7SWilliam Kucharski      that we can compare them later.  But we must not use malloc(3).  */
276*1b8adde7SWilliam Kucharski   original_argc = argc;
277*1b8adde7SWilliam Kucharski   original_argv = argv;
278*1b8adde7SWilliam Kucharski }
279*1b8adde7SWilliam Kucharski # ifdef text_set_element
280*1b8adde7SWilliam Kucharski text_set_element (__libc_subinit, store_args_and_env);
281*1b8adde7SWilliam Kucharski # endif /* text_set_element */
282*1b8adde7SWilliam Kucharski 
283*1b8adde7SWilliam Kucharski # define SWAP_FLAGS(ch1, ch2) \
284*1b8adde7SWilliam Kucharski   if (nonoption_flags_len > 0)						      \
285*1b8adde7SWilliam Kucharski     {									      \
286*1b8adde7SWilliam Kucharski       char __tmp = __getopt_nonoption_flags[ch1];			      \
287*1b8adde7SWilliam Kucharski       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];	      \
288*1b8adde7SWilliam Kucharski       __getopt_nonoption_flags[ch2] = __tmp;				      \
289*1b8adde7SWilliam Kucharski     }
290*1b8adde7SWilliam Kucharski #else	/* !_LIBC */
291*1b8adde7SWilliam Kucharski # define SWAP_FLAGS(ch1, ch2)
292*1b8adde7SWilliam Kucharski #endif	/* _LIBC */
293*1b8adde7SWilliam Kucharski 
294*1b8adde7SWilliam Kucharski /* Exchange two adjacent subsequences of ARGV.
295*1b8adde7SWilliam Kucharski    One subsequence is elements [first_nonopt,last_nonopt)
296*1b8adde7SWilliam Kucharski    which contains all the non-options that have been skipped so far.
297*1b8adde7SWilliam Kucharski    The other is elements [last_nonopt,optind), which contains all
298*1b8adde7SWilliam Kucharski    the options processed since those non-options were skipped.
299*1b8adde7SWilliam Kucharski 
300*1b8adde7SWilliam Kucharski    `first_nonopt' and `last_nonopt' are relocated so that they describe
301*1b8adde7SWilliam Kucharski    the new indices of the non-options in ARGV after they are moved.  */
302*1b8adde7SWilliam Kucharski 
303*1b8adde7SWilliam Kucharski #if defined __STDC__ && __STDC__
304*1b8adde7SWilliam Kucharski static void exchange (char **);
305*1b8adde7SWilliam Kucharski #endif
306*1b8adde7SWilliam Kucharski 
307*1b8adde7SWilliam Kucharski static void
exchange(argv)308*1b8adde7SWilliam Kucharski exchange (argv)
309*1b8adde7SWilliam Kucharski      char **argv;
310*1b8adde7SWilliam Kucharski {
311*1b8adde7SWilliam Kucharski   int bottom = first_nonopt;
312*1b8adde7SWilliam Kucharski   int middle = last_nonopt;
313*1b8adde7SWilliam Kucharski   int top = optind;
314*1b8adde7SWilliam Kucharski   char *tem;
315*1b8adde7SWilliam Kucharski 
316*1b8adde7SWilliam Kucharski   /* Exchange the shorter segment with the far end of the longer segment.
317*1b8adde7SWilliam Kucharski      That puts the shorter segment into the right place.
318*1b8adde7SWilliam Kucharski      It leaves the longer segment in the right place overall,
319*1b8adde7SWilliam Kucharski      but it consists of two parts that need to be swapped next.  */
320*1b8adde7SWilliam Kucharski 
321*1b8adde7SWilliam Kucharski #ifdef _LIBC
322*1b8adde7SWilliam Kucharski   /* First make sure the handling of the `__getopt_nonoption_flags'
323*1b8adde7SWilliam Kucharski      string can work normally.  Our top argument must be in the range
324*1b8adde7SWilliam Kucharski      of the string.  */
325*1b8adde7SWilliam Kucharski   if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
326*1b8adde7SWilliam Kucharski     {
327*1b8adde7SWilliam Kucharski       /* We must extend the array.  The user plays games with us and
328*1b8adde7SWilliam Kucharski 	 presents new arguments.  */
329*1b8adde7SWilliam Kucharski       char *new_str = malloc (top + 1);
330*1b8adde7SWilliam Kucharski       if (new_str == NULL)
331*1b8adde7SWilliam Kucharski 	nonoption_flags_len = nonoption_flags_max_len = 0;
332*1b8adde7SWilliam Kucharski       else
333*1b8adde7SWilliam Kucharski 	{
334*1b8adde7SWilliam Kucharski 	  memset (__mempcpy (new_str, __getopt_nonoption_flags,
335*1b8adde7SWilliam Kucharski 			     nonoption_flags_max_len),
336*1b8adde7SWilliam Kucharski 		  '\0', top + 1 - nonoption_flags_max_len);
337*1b8adde7SWilliam Kucharski 	  nonoption_flags_max_len = top + 1;
338*1b8adde7SWilliam Kucharski 	  __getopt_nonoption_flags = new_str;
339*1b8adde7SWilliam Kucharski 	}
340*1b8adde7SWilliam Kucharski     }
341*1b8adde7SWilliam Kucharski #endif
342*1b8adde7SWilliam Kucharski 
343*1b8adde7SWilliam Kucharski   while (top > middle && middle > bottom)
344*1b8adde7SWilliam Kucharski     {
345*1b8adde7SWilliam Kucharski       if (top - middle > middle - bottom)
346*1b8adde7SWilliam Kucharski 	{
347*1b8adde7SWilliam Kucharski 	  /* Bottom segment is the short one.  */
348*1b8adde7SWilliam Kucharski 	  int len = middle - bottom;
349*1b8adde7SWilliam Kucharski 	  register int i;
350*1b8adde7SWilliam Kucharski 
351*1b8adde7SWilliam Kucharski 	  /* Swap it with the top part of the top segment.  */
352*1b8adde7SWilliam Kucharski 	  for (i = 0; i < len; i++)
353*1b8adde7SWilliam Kucharski 	    {
354*1b8adde7SWilliam Kucharski 	      tem = argv[bottom + i];
355*1b8adde7SWilliam Kucharski 	      argv[bottom + i] = argv[top - (middle - bottom) + i];
356*1b8adde7SWilliam Kucharski 	      argv[top - (middle - bottom) + i] = tem;
357*1b8adde7SWilliam Kucharski 	      SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
358*1b8adde7SWilliam Kucharski 	    }
359*1b8adde7SWilliam Kucharski 	  /* Exclude the moved bottom segment from further swapping.  */
360*1b8adde7SWilliam Kucharski 	  top -= len;
361*1b8adde7SWilliam Kucharski 	}
362*1b8adde7SWilliam Kucharski       else
363*1b8adde7SWilliam Kucharski 	{
364*1b8adde7SWilliam Kucharski 	  /* Top segment is the short one.  */
365*1b8adde7SWilliam Kucharski 	  int len = top - middle;
366*1b8adde7SWilliam Kucharski 	  register int i;
367*1b8adde7SWilliam Kucharski 
368*1b8adde7SWilliam Kucharski 	  /* Swap it with the bottom part of the bottom segment.  */
369*1b8adde7SWilliam Kucharski 	  for (i = 0; i < len; i++)
370*1b8adde7SWilliam Kucharski 	    {
371*1b8adde7SWilliam Kucharski 	      tem = argv[bottom + i];
372*1b8adde7SWilliam Kucharski 	      argv[bottom + i] = argv[middle + i];
373*1b8adde7SWilliam Kucharski 	      argv[middle + i] = tem;
374*1b8adde7SWilliam Kucharski 	      SWAP_FLAGS (bottom + i, middle + i);
375*1b8adde7SWilliam Kucharski 	    }
376*1b8adde7SWilliam Kucharski 	  /* Exclude the moved top segment from further swapping.  */
377*1b8adde7SWilliam Kucharski 	  bottom += len;
378*1b8adde7SWilliam Kucharski 	}
379*1b8adde7SWilliam Kucharski     }
380*1b8adde7SWilliam Kucharski 
381*1b8adde7SWilliam Kucharski   /* Update records for the slots the non-options now occupy.  */
382*1b8adde7SWilliam Kucharski 
383*1b8adde7SWilliam Kucharski   first_nonopt += (optind - last_nonopt);
384*1b8adde7SWilliam Kucharski   last_nonopt = optind;
385*1b8adde7SWilliam Kucharski }
386*1b8adde7SWilliam Kucharski 
387*1b8adde7SWilliam Kucharski /* Initialize the internal data when the first call is made.  */
388*1b8adde7SWilliam Kucharski 
389*1b8adde7SWilliam Kucharski #if defined __STDC__ && __STDC__
390*1b8adde7SWilliam Kucharski static const char *_getopt_initialize (int, char *const *, const char *);
391*1b8adde7SWilliam Kucharski #endif
392*1b8adde7SWilliam Kucharski static const char *
_getopt_initialize(argc,argv,optstring)393*1b8adde7SWilliam Kucharski _getopt_initialize (argc, argv, optstring)
394*1b8adde7SWilliam Kucharski      int argc;
395*1b8adde7SWilliam Kucharski      char *const *argv;
396*1b8adde7SWilliam Kucharski      const char *optstring;
397*1b8adde7SWilliam Kucharski {
398*1b8adde7SWilliam Kucharski   /* Start processing options with ARGV-element 1 (since ARGV-element 0
399*1b8adde7SWilliam Kucharski      is the program name); the sequence of previously skipped
400*1b8adde7SWilliam Kucharski      non-option ARGV-elements is empty.  */
401*1b8adde7SWilliam Kucharski 
402*1b8adde7SWilliam Kucharski   first_nonopt = last_nonopt = optind;
403*1b8adde7SWilliam Kucharski 
404*1b8adde7SWilliam Kucharski   nextchar = NULL;
405*1b8adde7SWilliam Kucharski 
406*1b8adde7SWilliam Kucharski   posixly_correct = getenv ("POSIXLY_CORRECT");
407*1b8adde7SWilliam Kucharski 
408*1b8adde7SWilliam Kucharski   /* Determine how to handle the ordering of options and nonoptions.  */
409*1b8adde7SWilliam Kucharski 
410*1b8adde7SWilliam Kucharski   if (optstring[0] == '-')
411*1b8adde7SWilliam Kucharski     {
412*1b8adde7SWilliam Kucharski       ordering = RETURN_IN_ORDER;
413*1b8adde7SWilliam Kucharski       ++optstring;
414*1b8adde7SWilliam Kucharski     }
415*1b8adde7SWilliam Kucharski   else if (optstring[0] == '+')
416*1b8adde7SWilliam Kucharski     {
417*1b8adde7SWilliam Kucharski       ordering = REQUIRE_ORDER;
418*1b8adde7SWilliam Kucharski       ++optstring;
419*1b8adde7SWilliam Kucharski     }
420*1b8adde7SWilliam Kucharski   else if (posixly_correct != NULL)
421*1b8adde7SWilliam Kucharski     ordering = REQUIRE_ORDER;
422*1b8adde7SWilliam Kucharski   else
423*1b8adde7SWilliam Kucharski     ordering = PERMUTE;
424*1b8adde7SWilliam Kucharski 
425*1b8adde7SWilliam Kucharski #ifdef _LIBC
426*1b8adde7SWilliam Kucharski   if (posixly_correct == NULL
427*1b8adde7SWilliam Kucharski       && argc == original_argc && argv == original_argv)
428*1b8adde7SWilliam Kucharski     {
429*1b8adde7SWilliam Kucharski       if (nonoption_flags_max_len == 0)
430*1b8adde7SWilliam Kucharski 	{
431*1b8adde7SWilliam Kucharski 	  if (__getopt_nonoption_flags == NULL
432*1b8adde7SWilliam Kucharski 	      || __getopt_nonoption_flags[0] == '\0')
433*1b8adde7SWilliam Kucharski 	    nonoption_flags_max_len = -1;
434*1b8adde7SWilliam Kucharski 	  else
435*1b8adde7SWilliam Kucharski 	    {
436*1b8adde7SWilliam Kucharski 	      const char *orig_str = __getopt_nonoption_flags;
437*1b8adde7SWilliam Kucharski 	      int len = nonoption_flags_max_len = strlen (orig_str);
438*1b8adde7SWilliam Kucharski 	      if (nonoption_flags_max_len < argc)
439*1b8adde7SWilliam Kucharski 		nonoption_flags_max_len = argc;
440*1b8adde7SWilliam Kucharski 	      __getopt_nonoption_flags =
441*1b8adde7SWilliam Kucharski 		(char *) malloc (nonoption_flags_max_len);
442*1b8adde7SWilliam Kucharski 	      if (__getopt_nonoption_flags == NULL)
443*1b8adde7SWilliam Kucharski 		nonoption_flags_max_len = -1;
444*1b8adde7SWilliam Kucharski 	      else
445*1b8adde7SWilliam Kucharski 		memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
446*1b8adde7SWilliam Kucharski 			'\0', nonoption_flags_max_len - len);
447*1b8adde7SWilliam Kucharski 	    }
448*1b8adde7SWilliam Kucharski 	}
449*1b8adde7SWilliam Kucharski       nonoption_flags_len = nonoption_flags_max_len;
450*1b8adde7SWilliam Kucharski     }
451*1b8adde7SWilliam Kucharski   else
452*1b8adde7SWilliam Kucharski     nonoption_flags_len = 0;
453*1b8adde7SWilliam Kucharski #endif
454*1b8adde7SWilliam Kucharski 
455*1b8adde7SWilliam Kucharski   return optstring;
456*1b8adde7SWilliam Kucharski }
457*1b8adde7SWilliam Kucharski 
458*1b8adde7SWilliam Kucharski /* Scan elements of ARGV (whose length is ARGC) for option characters
459*1b8adde7SWilliam Kucharski    given in OPTSTRING.
460*1b8adde7SWilliam Kucharski 
461*1b8adde7SWilliam Kucharski    If an element of ARGV starts with '-', and is not exactly "-" or "--",
462*1b8adde7SWilliam Kucharski    then it is an option element.  The characters of this element
463*1b8adde7SWilliam Kucharski    (aside from the initial '-') are option characters.  If `getopt'
464*1b8adde7SWilliam Kucharski    is called repeatedly, it returns successively each of the option characters
465*1b8adde7SWilliam Kucharski    from each of the option elements.
466*1b8adde7SWilliam Kucharski 
467*1b8adde7SWilliam Kucharski    If `getopt' finds another option character, it returns that character,
468*1b8adde7SWilliam Kucharski    updating `optind' and `nextchar' so that the next call to `getopt' can
469*1b8adde7SWilliam Kucharski    resume the scan with the following option character or ARGV-element.
470*1b8adde7SWilliam Kucharski 
471*1b8adde7SWilliam Kucharski    If there are no more option characters, `getopt' returns -1.
472*1b8adde7SWilliam Kucharski    Then `optind' is the index in ARGV of the first ARGV-element
473*1b8adde7SWilliam Kucharski    that is not an option.  (The ARGV-elements have been permuted
474*1b8adde7SWilliam Kucharski    so that those that are not options now come last.)
475*1b8adde7SWilliam Kucharski 
476*1b8adde7SWilliam Kucharski    OPTSTRING is a string containing the legitimate option characters.
477*1b8adde7SWilliam Kucharski    If an option character is seen that is not listed in OPTSTRING,
478*1b8adde7SWilliam Kucharski    return '?' after printing an error message.  If you set `opterr' to
479*1b8adde7SWilliam Kucharski    zero, the error message is suppressed but we still return '?'.
480*1b8adde7SWilliam Kucharski 
481*1b8adde7SWilliam Kucharski    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
482*1b8adde7SWilliam Kucharski    so the following text in the same ARGV-element, or the text of the following
483*1b8adde7SWilliam Kucharski    ARGV-element, is returned in `optarg'.  Two colons mean an option that
484*1b8adde7SWilliam Kucharski    wants an optional arg; if there is text in the current ARGV-element,
485*1b8adde7SWilliam Kucharski    it is returned in `optarg', otherwise `optarg' is set to zero.
486*1b8adde7SWilliam Kucharski 
487*1b8adde7SWilliam Kucharski    If OPTSTRING starts with `-' or `+', it requests different methods of
488*1b8adde7SWilliam Kucharski    handling the non-option ARGV-elements.
489*1b8adde7SWilliam Kucharski    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
490*1b8adde7SWilliam Kucharski 
491*1b8adde7SWilliam Kucharski    Long-named options begin with `--' instead of `-'.
492*1b8adde7SWilliam Kucharski    Their names may be abbreviated as long as the abbreviation is unique
493*1b8adde7SWilliam Kucharski    or is an exact match for some defined option.  If they have an
494*1b8adde7SWilliam Kucharski    argument, it follows the option name in the same ARGV-element, separated
495*1b8adde7SWilliam Kucharski    from the option name by a `=', or else the in next ARGV-element.
496*1b8adde7SWilliam Kucharski    When `getopt' finds a long-named option, it returns 0 if that option's
497*1b8adde7SWilliam Kucharski    `flag' field is nonzero, the value of the option's `val' field
498*1b8adde7SWilliam Kucharski    if the `flag' field is zero.
499*1b8adde7SWilliam Kucharski 
500*1b8adde7SWilliam Kucharski    The elements of ARGV aren't really const, because we permute them.
501*1b8adde7SWilliam Kucharski    But we pretend they're const in the prototype to be compatible
502*1b8adde7SWilliam Kucharski    with other systems.
503*1b8adde7SWilliam Kucharski 
504*1b8adde7SWilliam Kucharski    LONGOPTS is a vector of `struct option' terminated by an
505*1b8adde7SWilliam Kucharski    element containing a name which is zero.
506*1b8adde7SWilliam Kucharski 
507*1b8adde7SWilliam Kucharski    LONGIND returns the index in LONGOPT of the long-named option found.
508*1b8adde7SWilliam Kucharski    It is only valid when a long-named option has been found by the most
509*1b8adde7SWilliam Kucharski    recent call.
510*1b8adde7SWilliam Kucharski 
511*1b8adde7SWilliam Kucharski    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
512*1b8adde7SWilliam Kucharski    long-named options.  */
513*1b8adde7SWilliam Kucharski 
514*1b8adde7SWilliam Kucharski int
_getopt_internal(argc,argv,optstring,longopts,longind,long_only)515*1b8adde7SWilliam Kucharski _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
516*1b8adde7SWilliam Kucharski      int argc;
517*1b8adde7SWilliam Kucharski      char *const *argv;
518*1b8adde7SWilliam Kucharski      const char *optstring;
519*1b8adde7SWilliam Kucharski      const struct option *longopts;
520*1b8adde7SWilliam Kucharski      int *longind;
521*1b8adde7SWilliam Kucharski      int long_only;
522*1b8adde7SWilliam Kucharski {
523*1b8adde7SWilliam Kucharski   optarg = NULL;
524*1b8adde7SWilliam Kucharski 
525*1b8adde7SWilliam Kucharski   if (optind == 0 || !__getopt_initialized)
526*1b8adde7SWilliam Kucharski     {
527*1b8adde7SWilliam Kucharski       if (optind == 0)
528*1b8adde7SWilliam Kucharski 	optind = 1;	/* Don't scan ARGV[0], the program name.  */
529*1b8adde7SWilliam Kucharski       optstring = _getopt_initialize (argc, argv, optstring);
530*1b8adde7SWilliam Kucharski       __getopt_initialized = 1;
531*1b8adde7SWilliam Kucharski     }
532*1b8adde7SWilliam Kucharski 
533*1b8adde7SWilliam Kucharski   /* Test whether ARGV[optind] points to a non-option argument.
534*1b8adde7SWilliam Kucharski      Either it does not have option syntax, or there is an environment flag
535*1b8adde7SWilliam Kucharski      from the shell indicating it is not an option.  The later information
536*1b8adde7SWilliam Kucharski      is only used when the used in the GNU libc.  */
537*1b8adde7SWilliam Kucharski #ifdef _LIBC
538*1b8adde7SWilliam Kucharski # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'	      \
539*1b8adde7SWilliam Kucharski 		      || (optind < nonoption_flags_len			      \
540*1b8adde7SWilliam Kucharski 			  && __getopt_nonoption_flags[optind] == '1'))
541*1b8adde7SWilliam Kucharski #else
542*1b8adde7SWilliam Kucharski # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
543*1b8adde7SWilliam Kucharski #endif
544*1b8adde7SWilliam Kucharski 
545*1b8adde7SWilliam Kucharski   if (nextchar == NULL || *nextchar == '\0')
546*1b8adde7SWilliam Kucharski     {
547*1b8adde7SWilliam Kucharski       /* Advance to the next ARGV-element.  */
548*1b8adde7SWilliam Kucharski 
549*1b8adde7SWilliam Kucharski       /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
550*1b8adde7SWilliam Kucharski 	 moved back by the user (who may also have changed the arguments).  */
551*1b8adde7SWilliam Kucharski       if (last_nonopt > optind)
552*1b8adde7SWilliam Kucharski 	last_nonopt = optind;
553*1b8adde7SWilliam Kucharski       if (first_nonopt > optind)
554*1b8adde7SWilliam Kucharski 	first_nonopt = optind;
555*1b8adde7SWilliam Kucharski 
556*1b8adde7SWilliam Kucharski       if (ordering == PERMUTE)
557*1b8adde7SWilliam Kucharski 	{
558*1b8adde7SWilliam Kucharski 	  /* If we have just processed some options following some non-options,
559*1b8adde7SWilliam Kucharski 	     exchange them so that the options come first.  */
560*1b8adde7SWilliam Kucharski 
561*1b8adde7SWilliam Kucharski 	  if (first_nonopt != last_nonopt && last_nonopt != optind)
562*1b8adde7SWilliam Kucharski 	    exchange ((char **) argv);
563*1b8adde7SWilliam Kucharski 	  else if (last_nonopt != optind)
564*1b8adde7SWilliam Kucharski 	    first_nonopt = optind;
565*1b8adde7SWilliam Kucharski 
566*1b8adde7SWilliam Kucharski 	  /* Skip any additional non-options
567*1b8adde7SWilliam Kucharski 	     and extend the range of non-options previously skipped.  */
568*1b8adde7SWilliam Kucharski 
569*1b8adde7SWilliam Kucharski 	  while (optind < argc && NONOPTION_P)
570*1b8adde7SWilliam Kucharski 	    optind++;
571*1b8adde7SWilliam Kucharski 	  last_nonopt = optind;
572*1b8adde7SWilliam Kucharski 	}
573*1b8adde7SWilliam Kucharski 
574*1b8adde7SWilliam Kucharski       /* The special ARGV-element `--' means premature end of options.
575*1b8adde7SWilliam Kucharski 	 Skip it like a null option,
576*1b8adde7SWilliam Kucharski 	 then exchange with previous non-options as if it were an option,
577*1b8adde7SWilliam Kucharski 	 then skip everything else like a non-option.  */
578*1b8adde7SWilliam Kucharski 
579*1b8adde7SWilliam Kucharski       if (optind != argc && !strcmp (argv[optind], "--"))
580*1b8adde7SWilliam Kucharski 	{
581*1b8adde7SWilliam Kucharski 	  optind++;
582*1b8adde7SWilliam Kucharski 
583*1b8adde7SWilliam Kucharski 	  if (first_nonopt != last_nonopt && last_nonopt != optind)
584*1b8adde7SWilliam Kucharski 	    exchange ((char **) argv);
585*1b8adde7SWilliam Kucharski 	  else if (first_nonopt == last_nonopt)
586*1b8adde7SWilliam Kucharski 	    first_nonopt = optind;
587*1b8adde7SWilliam Kucharski 	  last_nonopt = argc;
588*1b8adde7SWilliam Kucharski 
589*1b8adde7SWilliam Kucharski 	  optind = argc;
590*1b8adde7SWilliam Kucharski 	}
591*1b8adde7SWilliam Kucharski 
592*1b8adde7SWilliam Kucharski       /* If we have done all the ARGV-elements, stop the scan
593*1b8adde7SWilliam Kucharski 	 and back over any non-options that we skipped and permuted.  */
594*1b8adde7SWilliam Kucharski 
595*1b8adde7SWilliam Kucharski       if (optind == argc)
596*1b8adde7SWilliam Kucharski 	{
597*1b8adde7SWilliam Kucharski 	  /* Set the next-arg-index to point at the non-options
598*1b8adde7SWilliam Kucharski 	     that we previously skipped, so the caller will digest them.  */
599*1b8adde7SWilliam Kucharski 	  if (first_nonopt != last_nonopt)
600*1b8adde7SWilliam Kucharski 	    optind = first_nonopt;
601*1b8adde7SWilliam Kucharski 	  return -1;
602*1b8adde7SWilliam Kucharski 	}
603*1b8adde7SWilliam Kucharski 
604*1b8adde7SWilliam Kucharski       /* If we have come to a non-option and did not permute it,
605*1b8adde7SWilliam Kucharski 	 either stop the scan or describe it to the caller and pass it by.  */
606*1b8adde7SWilliam Kucharski 
607*1b8adde7SWilliam Kucharski       if (NONOPTION_P)
608*1b8adde7SWilliam Kucharski 	{
609*1b8adde7SWilliam Kucharski 	  if (ordering == REQUIRE_ORDER)
610*1b8adde7SWilliam Kucharski 	    return -1;
611*1b8adde7SWilliam Kucharski 	  optarg = argv[optind++];
612*1b8adde7SWilliam Kucharski 	  return 1;
613*1b8adde7SWilliam Kucharski 	}
614*1b8adde7SWilliam Kucharski 
615*1b8adde7SWilliam Kucharski       /* We have found another option-ARGV-element.
616*1b8adde7SWilliam Kucharski 	 Skip the initial punctuation.  */
617*1b8adde7SWilliam Kucharski 
618*1b8adde7SWilliam Kucharski       nextchar = (argv[optind] + 1
619*1b8adde7SWilliam Kucharski 		  + (longopts != NULL && argv[optind][1] == '-'));
620*1b8adde7SWilliam Kucharski     }
621*1b8adde7SWilliam Kucharski 
622*1b8adde7SWilliam Kucharski   /* Decode the current option-ARGV-element.  */
623*1b8adde7SWilliam Kucharski 
624*1b8adde7SWilliam Kucharski   /* Check whether the ARGV-element is a long option.
625*1b8adde7SWilliam Kucharski 
626*1b8adde7SWilliam Kucharski      If long_only and the ARGV-element has the form "-f", where f is
627*1b8adde7SWilliam Kucharski      a valid short option, don't consider it an abbreviated form of
628*1b8adde7SWilliam Kucharski      a long option that starts with f.  Otherwise there would be no
629*1b8adde7SWilliam Kucharski      way to give the -f short option.
630*1b8adde7SWilliam Kucharski 
631*1b8adde7SWilliam Kucharski      On the other hand, if there's a long option "fubar" and
632*1b8adde7SWilliam Kucharski      the ARGV-element is "-fu", do consider that an abbreviation of
633*1b8adde7SWilliam Kucharski      the long option, just like "--fu", and not "-f" with arg "u".
634*1b8adde7SWilliam Kucharski 
635*1b8adde7SWilliam Kucharski      This distinction seems to be the most useful approach.  */
636*1b8adde7SWilliam Kucharski 
637*1b8adde7SWilliam Kucharski   if (longopts != NULL
638*1b8adde7SWilliam Kucharski       && (argv[optind][1] == '-'
639*1b8adde7SWilliam Kucharski 	  || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
640*1b8adde7SWilliam Kucharski     {
641*1b8adde7SWilliam Kucharski       char *nameend;
642*1b8adde7SWilliam Kucharski       const struct option *p;
643*1b8adde7SWilliam Kucharski       const struct option *pfound = NULL;
644*1b8adde7SWilliam Kucharski       int exact = 0;
645*1b8adde7SWilliam Kucharski       int ambig = 0;
646*1b8adde7SWilliam Kucharski       int indfound = -1;
647*1b8adde7SWilliam Kucharski       int option_index;
648*1b8adde7SWilliam Kucharski 
649*1b8adde7SWilliam Kucharski       for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
650*1b8adde7SWilliam Kucharski 	/* Do nothing.  */ ;
651*1b8adde7SWilliam Kucharski 
652*1b8adde7SWilliam Kucharski       /* Test all long options for either exact match
653*1b8adde7SWilliam Kucharski 	 or abbreviated matches.  */
654*1b8adde7SWilliam Kucharski       for (p = longopts, option_index = 0; p->name; p++, option_index++)
655*1b8adde7SWilliam Kucharski 	if (!strncmp (p->name, nextchar, nameend - nextchar))
656*1b8adde7SWilliam Kucharski 	  {
657*1b8adde7SWilliam Kucharski 	    if ((unsigned int) (nameend - nextchar)
658*1b8adde7SWilliam Kucharski 		== (unsigned int) strlen (p->name))
659*1b8adde7SWilliam Kucharski 	      {
660*1b8adde7SWilliam Kucharski 		/* Exact match found.  */
661*1b8adde7SWilliam Kucharski 		pfound = p;
662*1b8adde7SWilliam Kucharski 		indfound = option_index;
663*1b8adde7SWilliam Kucharski 		exact = 1;
664*1b8adde7SWilliam Kucharski 		break;
665*1b8adde7SWilliam Kucharski 	      }
666*1b8adde7SWilliam Kucharski 	    else if (pfound == NULL)
667*1b8adde7SWilliam Kucharski 	      {
668*1b8adde7SWilliam Kucharski 		/* First nonexact match found.  */
669*1b8adde7SWilliam Kucharski 		pfound = p;
670*1b8adde7SWilliam Kucharski 		indfound = option_index;
671*1b8adde7SWilliam Kucharski 	      }
672*1b8adde7SWilliam Kucharski 	    else
673*1b8adde7SWilliam Kucharski 	      /* Second or later nonexact match found.  */
674*1b8adde7SWilliam Kucharski 	      ambig = 1;
675*1b8adde7SWilliam Kucharski 	  }
676*1b8adde7SWilliam Kucharski 
677*1b8adde7SWilliam Kucharski       if (ambig && !exact)
678*1b8adde7SWilliam Kucharski 	{
679*1b8adde7SWilliam Kucharski 	  if (opterr)
680*1b8adde7SWilliam Kucharski 	    fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
681*1b8adde7SWilliam Kucharski 		     argv[0], argv[optind]);
682*1b8adde7SWilliam Kucharski 	  nextchar += strlen (nextchar);
683*1b8adde7SWilliam Kucharski 	  optind++;
684*1b8adde7SWilliam Kucharski 	  optopt = 0;
685*1b8adde7SWilliam Kucharski 	  return '?';
686*1b8adde7SWilliam Kucharski 	}
687*1b8adde7SWilliam Kucharski 
688*1b8adde7SWilliam Kucharski       if (pfound != NULL)
689*1b8adde7SWilliam Kucharski 	{
690*1b8adde7SWilliam Kucharski 	  option_index = indfound;
691*1b8adde7SWilliam Kucharski 	  optind++;
692*1b8adde7SWilliam Kucharski 	  if (*nameend)
693*1b8adde7SWilliam Kucharski 	    {
694*1b8adde7SWilliam Kucharski 	      /* Don't test has_arg with >, because some C compilers don't
695*1b8adde7SWilliam Kucharski 		 allow it to be used on enums.  */
696*1b8adde7SWilliam Kucharski 	      if (pfound->has_arg)
697*1b8adde7SWilliam Kucharski 		optarg = nameend + 1;
698*1b8adde7SWilliam Kucharski 	      else
699*1b8adde7SWilliam Kucharski 		{
700*1b8adde7SWilliam Kucharski 		  if (opterr)
701*1b8adde7SWilliam Kucharski 		    {
702*1b8adde7SWilliam Kucharski 		      if (argv[optind - 1][1] == '-')
703*1b8adde7SWilliam Kucharski 			/* --option */
704*1b8adde7SWilliam Kucharski 			fprintf (stderr,
705*1b8adde7SWilliam Kucharski 				 _("%s: option `--%s' doesn't allow an argument\n"),
706*1b8adde7SWilliam Kucharski 				 argv[0], pfound->name);
707*1b8adde7SWilliam Kucharski 		      else
708*1b8adde7SWilliam Kucharski 			/* +option or -option */
709*1b8adde7SWilliam Kucharski 			fprintf (stderr,
710*1b8adde7SWilliam Kucharski 				 _("%s: option `%c%s' doesn't allow an argument\n"),
711*1b8adde7SWilliam Kucharski 				 argv[0], argv[optind - 1][0], pfound->name);
712*1b8adde7SWilliam Kucharski 		    }
713*1b8adde7SWilliam Kucharski 		  nextchar += strlen (nextchar);
714*1b8adde7SWilliam Kucharski 
715*1b8adde7SWilliam Kucharski 		  optopt = pfound->val;
716*1b8adde7SWilliam Kucharski 		  return '?';
717*1b8adde7SWilliam Kucharski 		}
718*1b8adde7SWilliam Kucharski 	    }
719*1b8adde7SWilliam Kucharski 	  else if (pfound->has_arg == 1)
720*1b8adde7SWilliam Kucharski 	    {
721*1b8adde7SWilliam Kucharski 	      if (optind < argc)
722*1b8adde7SWilliam Kucharski 		optarg = argv[optind++];
723*1b8adde7SWilliam Kucharski 	      else
724*1b8adde7SWilliam Kucharski 		{
725*1b8adde7SWilliam Kucharski 		  if (opterr)
726*1b8adde7SWilliam Kucharski 		    fprintf (stderr,
727*1b8adde7SWilliam Kucharski 			   _("%s: option `%s' requires an argument\n"),
728*1b8adde7SWilliam Kucharski 			   argv[0], argv[optind - 1]);
729*1b8adde7SWilliam Kucharski 		  nextchar += strlen (nextchar);
730*1b8adde7SWilliam Kucharski 		  optopt = pfound->val;
731*1b8adde7SWilliam Kucharski 		  return optstring[0] == ':' ? ':' : '?';
732*1b8adde7SWilliam Kucharski 		}
733*1b8adde7SWilliam Kucharski 	    }
734*1b8adde7SWilliam Kucharski 	  nextchar += strlen (nextchar);
735*1b8adde7SWilliam Kucharski 	  if (longind != NULL)
736*1b8adde7SWilliam Kucharski 	    *longind = option_index;
737*1b8adde7SWilliam Kucharski 	  if (pfound->flag)
738*1b8adde7SWilliam Kucharski 	    {
739*1b8adde7SWilliam Kucharski 	      *(pfound->flag) = pfound->val;
740*1b8adde7SWilliam Kucharski 	      return 0;
741*1b8adde7SWilliam Kucharski 	    }
742*1b8adde7SWilliam Kucharski 	  return pfound->val;
743*1b8adde7SWilliam Kucharski 	}
744*1b8adde7SWilliam Kucharski 
745*1b8adde7SWilliam Kucharski       /* Can't find it as a long option.  If this is not getopt_long_only,
746*1b8adde7SWilliam Kucharski 	 or the option starts with '--' or is not a valid short
747*1b8adde7SWilliam Kucharski 	 option, then it's an error.
748*1b8adde7SWilliam Kucharski 	 Otherwise interpret it as a short option.  */
749*1b8adde7SWilliam Kucharski       if (!long_only || argv[optind][1] == '-'
750*1b8adde7SWilliam Kucharski 	  || my_index (optstring, *nextchar) == NULL)
751*1b8adde7SWilliam Kucharski 	{
752*1b8adde7SWilliam Kucharski 	  if (opterr)
753*1b8adde7SWilliam Kucharski 	    {
754*1b8adde7SWilliam Kucharski 	      if (argv[optind][1] == '-')
755*1b8adde7SWilliam Kucharski 		/* --option */
756*1b8adde7SWilliam Kucharski 		fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
757*1b8adde7SWilliam Kucharski 			 argv[0], nextchar);
758*1b8adde7SWilliam Kucharski 	      else
759*1b8adde7SWilliam Kucharski 		/* +option or -option */
760*1b8adde7SWilliam Kucharski 		fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
761*1b8adde7SWilliam Kucharski 			 argv[0], argv[optind][0], nextchar);
762*1b8adde7SWilliam Kucharski 	    }
763*1b8adde7SWilliam Kucharski 	  nextchar = (char *) "";
764*1b8adde7SWilliam Kucharski 	  optind++;
765*1b8adde7SWilliam Kucharski 	  optopt = 0;
766*1b8adde7SWilliam Kucharski 	  return '?';
767*1b8adde7SWilliam Kucharski 	}
768*1b8adde7SWilliam Kucharski     }
769*1b8adde7SWilliam Kucharski 
770*1b8adde7SWilliam Kucharski   /* Look at and handle the next short option-character.  */
771*1b8adde7SWilliam Kucharski 
772*1b8adde7SWilliam Kucharski   {
773*1b8adde7SWilliam Kucharski     char c = *nextchar++;
774*1b8adde7SWilliam Kucharski     char *temp = my_index (optstring, c);
775*1b8adde7SWilliam Kucharski 
776*1b8adde7SWilliam Kucharski     /* Increment `optind' when we start to process its last character.  */
777*1b8adde7SWilliam Kucharski     if (*nextchar == '\0')
778*1b8adde7SWilliam Kucharski       ++optind;
779*1b8adde7SWilliam Kucharski 
780*1b8adde7SWilliam Kucharski     if (temp == NULL || c == ':')
781*1b8adde7SWilliam Kucharski       {
782*1b8adde7SWilliam Kucharski 	if (opterr)
783*1b8adde7SWilliam Kucharski 	  {
784*1b8adde7SWilliam Kucharski 	    if (posixly_correct)
785*1b8adde7SWilliam Kucharski 	      /* 1003.2 specifies the format of this message.  */
786*1b8adde7SWilliam Kucharski 	      fprintf (stderr, _("%s: illegal option -- %c\n"),
787*1b8adde7SWilliam Kucharski 		       argv[0], c);
788*1b8adde7SWilliam Kucharski 	    else
789*1b8adde7SWilliam Kucharski 	      fprintf (stderr, _("%s: invalid option -- %c\n"),
790*1b8adde7SWilliam Kucharski 		       argv[0], c);
791*1b8adde7SWilliam Kucharski 	  }
792*1b8adde7SWilliam Kucharski 	optopt = c;
793*1b8adde7SWilliam Kucharski 	return '?';
794*1b8adde7SWilliam Kucharski       }
795*1b8adde7SWilliam Kucharski     /* Convenience. Treat POSIX -W foo same as long option --foo */
796*1b8adde7SWilliam Kucharski     if (temp[0] == 'W' && temp[1] == ';')
797*1b8adde7SWilliam Kucharski       {
798*1b8adde7SWilliam Kucharski 	char *nameend;
799*1b8adde7SWilliam Kucharski 	const struct option *p;
800*1b8adde7SWilliam Kucharski 	const struct option *pfound = NULL;
801*1b8adde7SWilliam Kucharski 	int exact = 0;
802*1b8adde7SWilliam Kucharski 	int ambig = 0;
803*1b8adde7SWilliam Kucharski 	int indfound = 0;
804*1b8adde7SWilliam Kucharski 	int option_index;
805*1b8adde7SWilliam Kucharski 
806*1b8adde7SWilliam Kucharski 	/* This is an option that requires an argument.  */
807*1b8adde7SWilliam Kucharski 	if (*nextchar != '\0')
808*1b8adde7SWilliam Kucharski 	  {
809*1b8adde7SWilliam Kucharski 	    optarg = nextchar;
810*1b8adde7SWilliam Kucharski 	    /* If we end this ARGV-element by taking the rest as an arg,
811*1b8adde7SWilliam Kucharski 	       we must advance to the next element now.  */
812*1b8adde7SWilliam Kucharski 	    optind++;
813*1b8adde7SWilliam Kucharski 	  }
814*1b8adde7SWilliam Kucharski 	else if (optind == argc)
815*1b8adde7SWilliam Kucharski 	  {
816*1b8adde7SWilliam Kucharski 	    if (opterr)
817*1b8adde7SWilliam Kucharski 	      {
818*1b8adde7SWilliam Kucharski 		/* 1003.2 specifies the format of this message.  */
819*1b8adde7SWilliam Kucharski 		fprintf (stderr, _("%s: option requires an argument -- %c\n"),
820*1b8adde7SWilliam Kucharski 			 argv[0], c);
821*1b8adde7SWilliam Kucharski 	      }
822*1b8adde7SWilliam Kucharski 	    optopt = c;
823*1b8adde7SWilliam Kucharski 	    if (optstring[0] == ':')
824*1b8adde7SWilliam Kucharski 	      c = ':';
825*1b8adde7SWilliam Kucharski 	    else
826*1b8adde7SWilliam Kucharski 	      c = '?';
827*1b8adde7SWilliam Kucharski 	    return c;
828*1b8adde7SWilliam Kucharski 	  }
829*1b8adde7SWilliam Kucharski 	else
830*1b8adde7SWilliam Kucharski 	  /* We already incremented `optind' once;
831*1b8adde7SWilliam Kucharski 	     increment it again when taking next ARGV-elt as argument.  */
832*1b8adde7SWilliam Kucharski 	  optarg = argv[optind++];
833*1b8adde7SWilliam Kucharski 
834*1b8adde7SWilliam Kucharski 	/* optarg is now the argument, see if it's in the
835*1b8adde7SWilliam Kucharski 	   table of longopts.  */
836*1b8adde7SWilliam Kucharski 
837*1b8adde7SWilliam Kucharski 	for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
838*1b8adde7SWilliam Kucharski 	  /* Do nothing.  */ ;
839*1b8adde7SWilliam Kucharski 
840*1b8adde7SWilliam Kucharski 	/* Test all long options for either exact match
841*1b8adde7SWilliam Kucharski 	   or abbreviated matches.  */
842*1b8adde7SWilliam Kucharski 	for (p = longopts, option_index = 0; p->name; p++, option_index++)
843*1b8adde7SWilliam Kucharski 	  if (!strncmp (p->name, nextchar, nameend - nextchar))
844*1b8adde7SWilliam Kucharski 	    {
845*1b8adde7SWilliam Kucharski 	      if ((unsigned int) (nameend - nextchar) == strlen (p->name))
846*1b8adde7SWilliam Kucharski 		{
847*1b8adde7SWilliam Kucharski 		  /* Exact match found.  */
848*1b8adde7SWilliam Kucharski 		  pfound = p;
849*1b8adde7SWilliam Kucharski 		  indfound = option_index;
850*1b8adde7SWilliam Kucharski 		  exact = 1;
851*1b8adde7SWilliam Kucharski 		  break;
852*1b8adde7SWilliam Kucharski 		}
853*1b8adde7SWilliam Kucharski 	      else if (pfound == NULL)
854*1b8adde7SWilliam Kucharski 		{
855*1b8adde7SWilliam Kucharski 		  /* First nonexact match found.  */
856*1b8adde7SWilliam Kucharski 		  pfound = p;
857*1b8adde7SWilliam Kucharski 		  indfound = option_index;
858*1b8adde7SWilliam Kucharski 		}
859*1b8adde7SWilliam Kucharski 	      else
860*1b8adde7SWilliam Kucharski 		/* Second or later nonexact match found.  */
861*1b8adde7SWilliam Kucharski 		ambig = 1;
862*1b8adde7SWilliam Kucharski 	    }
863*1b8adde7SWilliam Kucharski 	if (ambig && !exact)
864*1b8adde7SWilliam Kucharski 	  {
865*1b8adde7SWilliam Kucharski 	    if (opterr)
866*1b8adde7SWilliam Kucharski 	      fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
867*1b8adde7SWilliam Kucharski 		       argv[0], argv[optind]);
868*1b8adde7SWilliam Kucharski 	    nextchar += strlen (nextchar);
869*1b8adde7SWilliam Kucharski 	    optind++;
870*1b8adde7SWilliam Kucharski 	    return '?';
871*1b8adde7SWilliam Kucharski 	  }
872*1b8adde7SWilliam Kucharski 	if (pfound != NULL)
873*1b8adde7SWilliam Kucharski 	  {
874*1b8adde7SWilliam Kucharski 	    option_index = indfound;
875*1b8adde7SWilliam Kucharski 	    if (*nameend)
876*1b8adde7SWilliam Kucharski 	      {
877*1b8adde7SWilliam Kucharski 		/* Don't test has_arg with >, because some C compilers don't
878*1b8adde7SWilliam Kucharski 		   allow it to be used on enums.  */
879*1b8adde7SWilliam Kucharski 		if (pfound->has_arg)
880*1b8adde7SWilliam Kucharski 		  optarg = nameend + 1;
881*1b8adde7SWilliam Kucharski 		else
882*1b8adde7SWilliam Kucharski 		  {
883*1b8adde7SWilliam Kucharski 		    if (opterr)
884*1b8adde7SWilliam Kucharski 		      fprintf (stderr, _("\
885*1b8adde7SWilliam Kucharski %s: option `-W %s' doesn't allow an argument\n"),
886*1b8adde7SWilliam Kucharski 			       argv[0], pfound->name);
887*1b8adde7SWilliam Kucharski 
888*1b8adde7SWilliam Kucharski 		    nextchar += strlen (nextchar);
889*1b8adde7SWilliam Kucharski 		    return '?';
890*1b8adde7SWilliam Kucharski 		  }
891*1b8adde7SWilliam Kucharski 	      }
892*1b8adde7SWilliam Kucharski 	    else if (pfound->has_arg == 1)
893*1b8adde7SWilliam Kucharski 	      {
894*1b8adde7SWilliam Kucharski 		if (optind < argc)
895*1b8adde7SWilliam Kucharski 		  optarg = argv[optind++];
896*1b8adde7SWilliam Kucharski 		else
897*1b8adde7SWilliam Kucharski 		  {
898*1b8adde7SWilliam Kucharski 		    if (opterr)
899*1b8adde7SWilliam Kucharski 		      fprintf (stderr,
900*1b8adde7SWilliam Kucharski 			       _("%s: option `%s' requires an argument\n"),
901*1b8adde7SWilliam Kucharski 			       argv[0], argv[optind - 1]);
902*1b8adde7SWilliam Kucharski 		    nextchar += strlen (nextchar);
903*1b8adde7SWilliam Kucharski 		    return optstring[0] == ':' ? ':' : '?';
904*1b8adde7SWilliam Kucharski 		  }
905*1b8adde7SWilliam Kucharski 	      }
906*1b8adde7SWilliam Kucharski 	    nextchar += strlen (nextchar);
907*1b8adde7SWilliam Kucharski 	    if (longind != NULL)
908*1b8adde7SWilliam Kucharski 	      *longind = option_index;
909*1b8adde7SWilliam Kucharski 	    if (pfound->flag)
910*1b8adde7SWilliam Kucharski 	      {
911*1b8adde7SWilliam Kucharski 		*(pfound->flag) = pfound->val;
912*1b8adde7SWilliam Kucharski 		return 0;
913*1b8adde7SWilliam Kucharski 	      }
914*1b8adde7SWilliam Kucharski 	    return pfound->val;
915*1b8adde7SWilliam Kucharski 	  }
916*1b8adde7SWilliam Kucharski 	  nextchar = NULL;
917*1b8adde7SWilliam Kucharski 	  return 'W';	/* Let the application handle it.   */
918*1b8adde7SWilliam Kucharski       }
919*1b8adde7SWilliam Kucharski     if (temp[1] == ':')
920*1b8adde7SWilliam Kucharski       {
921*1b8adde7SWilliam Kucharski 	if (temp[2] == ':')
922*1b8adde7SWilliam Kucharski 	  {
923*1b8adde7SWilliam Kucharski 	    /* This is an option that accepts an argument optionally.  */
924*1b8adde7SWilliam Kucharski 	    if (*nextchar != '\0')
925*1b8adde7SWilliam Kucharski 	      {
926*1b8adde7SWilliam Kucharski 		optarg = nextchar;
927*1b8adde7SWilliam Kucharski 		optind++;
928*1b8adde7SWilliam Kucharski 	      }
929*1b8adde7SWilliam Kucharski 	    else
930*1b8adde7SWilliam Kucharski 	      optarg = NULL;
931*1b8adde7SWilliam Kucharski 	    nextchar = NULL;
932*1b8adde7SWilliam Kucharski 	  }
933*1b8adde7SWilliam Kucharski 	else
934*1b8adde7SWilliam Kucharski 	  {
935*1b8adde7SWilliam Kucharski 	    /* This is an option that requires an argument.  */
936*1b8adde7SWilliam Kucharski 	    if (*nextchar != '\0')
937*1b8adde7SWilliam Kucharski 	      {
938*1b8adde7SWilliam Kucharski 		optarg = nextchar;
939*1b8adde7SWilliam Kucharski 		/* If we end this ARGV-element by taking the rest as an arg,
940*1b8adde7SWilliam Kucharski 		   we must advance to the next element now.  */
941*1b8adde7SWilliam Kucharski 		optind++;
942*1b8adde7SWilliam Kucharski 	      }
943*1b8adde7SWilliam Kucharski 	    else if (optind == argc)
944*1b8adde7SWilliam Kucharski 	      {
945*1b8adde7SWilliam Kucharski 		if (opterr)
946*1b8adde7SWilliam Kucharski 		  {
947*1b8adde7SWilliam Kucharski 		    /* 1003.2 specifies the format of this message.  */
948*1b8adde7SWilliam Kucharski 		    fprintf (stderr,
949*1b8adde7SWilliam Kucharski 			   _("%s: option requires an argument -- %c\n"),
950*1b8adde7SWilliam Kucharski 			   argv[0], c);
951*1b8adde7SWilliam Kucharski 		  }
952*1b8adde7SWilliam Kucharski 		optopt = c;
953*1b8adde7SWilliam Kucharski 		if (optstring[0] == ':')
954*1b8adde7SWilliam Kucharski 		  c = ':';
955*1b8adde7SWilliam Kucharski 		else
956*1b8adde7SWilliam Kucharski 		  c = '?';
957*1b8adde7SWilliam Kucharski 	      }
958*1b8adde7SWilliam Kucharski 	    else
959*1b8adde7SWilliam Kucharski 	      /* We already incremented `optind' once;
960*1b8adde7SWilliam Kucharski 		 increment it again when taking next ARGV-elt as argument.  */
961*1b8adde7SWilliam Kucharski 	      optarg = argv[optind++];
962*1b8adde7SWilliam Kucharski 	    nextchar = NULL;
963*1b8adde7SWilliam Kucharski 	  }
964*1b8adde7SWilliam Kucharski       }
965*1b8adde7SWilliam Kucharski     return c;
966*1b8adde7SWilliam Kucharski   }
967*1b8adde7SWilliam Kucharski }
968*1b8adde7SWilliam Kucharski 
969*1b8adde7SWilliam Kucharski int
getopt(argc,argv,optstring)970*1b8adde7SWilliam Kucharski getopt (argc, argv, optstring)
971*1b8adde7SWilliam Kucharski      int argc;
972*1b8adde7SWilliam Kucharski      char *const *argv;
973*1b8adde7SWilliam Kucharski      const char *optstring;
974*1b8adde7SWilliam Kucharski {
975*1b8adde7SWilliam Kucharski   return _getopt_internal (argc, argv, optstring,
976*1b8adde7SWilliam Kucharski 			   (const struct option *) 0,
977*1b8adde7SWilliam Kucharski 			   (int *) 0,
978*1b8adde7SWilliam Kucharski 			   0);
979*1b8adde7SWilliam Kucharski }
980*1b8adde7SWilliam Kucharski 
981*1b8adde7SWilliam Kucharski #endif	/* Not ELIDE_CODE.  */
982*1b8adde7SWilliam Kucharski 
983*1b8adde7SWilliam Kucharski #ifdef TEST
984*1b8adde7SWilliam Kucharski 
985*1b8adde7SWilliam Kucharski /* Compile with -DTEST to make an executable for use in testing
986*1b8adde7SWilliam Kucharski    the above definition of `getopt'.  */
987*1b8adde7SWilliam Kucharski 
988*1b8adde7SWilliam Kucharski int
main(argc,argv)989*1b8adde7SWilliam Kucharski main (argc, argv)
990*1b8adde7SWilliam Kucharski      int argc;
991*1b8adde7SWilliam Kucharski      char **argv;
992*1b8adde7SWilliam Kucharski {
993*1b8adde7SWilliam Kucharski   int c;
994*1b8adde7SWilliam Kucharski   int digit_optind = 0;
995*1b8adde7SWilliam Kucharski 
996*1b8adde7SWilliam Kucharski   while (1)
997*1b8adde7SWilliam Kucharski     {
998*1b8adde7SWilliam Kucharski       int this_option_optind = optind ? optind : 1;
999*1b8adde7SWilliam Kucharski 
1000*1b8adde7SWilliam Kucharski       c = getopt (argc, argv, "abc:d:0123456789");
1001*1b8adde7SWilliam Kucharski       if (c == -1)
1002*1b8adde7SWilliam Kucharski 	break;
1003*1b8adde7SWilliam Kucharski 
1004*1b8adde7SWilliam Kucharski       switch (c)
1005*1b8adde7SWilliam Kucharski 	{
1006*1b8adde7SWilliam Kucharski 	case '0':
1007*1b8adde7SWilliam Kucharski 	case '1':
1008*1b8adde7SWilliam Kucharski 	case '2':
1009*1b8adde7SWilliam Kucharski 	case '3':
1010*1b8adde7SWilliam Kucharski 	case '4':
1011*1b8adde7SWilliam Kucharski 	case '5':
1012*1b8adde7SWilliam Kucharski 	case '6':
1013*1b8adde7SWilliam Kucharski 	case '7':
1014*1b8adde7SWilliam Kucharski 	case '8':
1015*1b8adde7SWilliam Kucharski 	case '9':
1016*1b8adde7SWilliam Kucharski 	  if (digit_optind != 0 && digit_optind != this_option_optind)
1017*1b8adde7SWilliam Kucharski 	    printf ("digits occur in two different argv-elements.\n");
1018*1b8adde7SWilliam Kucharski 	  digit_optind = this_option_optind;
1019*1b8adde7SWilliam Kucharski 	  printf ("option %c\n", c);
1020*1b8adde7SWilliam Kucharski 	  break;
1021*1b8adde7SWilliam Kucharski 
1022*1b8adde7SWilliam Kucharski 	case 'a':
1023*1b8adde7SWilliam Kucharski 	  printf ("option a\n");
1024*1b8adde7SWilliam Kucharski 	  break;
1025*1b8adde7SWilliam Kucharski 
1026*1b8adde7SWilliam Kucharski 	case 'b':
1027*1b8adde7SWilliam Kucharski 	  printf ("option b\n");
1028*1b8adde7SWilliam Kucharski 	  break;
1029*1b8adde7SWilliam Kucharski 
1030*1b8adde7SWilliam Kucharski 	case 'c':
1031*1b8adde7SWilliam Kucharski 	  printf ("option c with value `%s'\n", optarg);
1032*1b8adde7SWilliam Kucharski 	  break;
1033*1b8adde7SWilliam Kucharski 
1034*1b8adde7SWilliam Kucharski 	case '?':
1035*1b8adde7SWilliam Kucharski 	  break;
1036*1b8adde7SWilliam Kucharski 
1037*1b8adde7SWilliam Kucharski 	default:
1038*1b8adde7SWilliam Kucharski 	  printf ("?? getopt returned character code 0%o ??\n", c);
1039*1b8adde7SWilliam Kucharski 	}
1040*1b8adde7SWilliam Kucharski     }
1041*1b8adde7SWilliam Kucharski 
1042*1b8adde7SWilliam Kucharski   if (optind < argc)
1043*1b8adde7SWilliam Kucharski     {
1044*1b8adde7SWilliam Kucharski       printf ("non-option ARGV-elements: ");
1045*1b8adde7SWilliam Kucharski       while (optind < argc)
1046*1b8adde7SWilliam Kucharski 	printf ("%s ", argv[optind++]);
1047*1b8adde7SWilliam Kucharski       printf ("\n");
1048*1b8adde7SWilliam Kucharski     }
1049*1b8adde7SWilliam Kucharski 
1050*1b8adde7SWilliam Kucharski   exit (0);
1051*1b8adde7SWilliam Kucharski }
1052*1b8adde7SWilliam Kucharski 
1053*1b8adde7SWilliam Kucharski #endif /* TEST */
1054