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