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