1840175f0Skstailey /* Getopt for GNU.
2*a1acfa9bSespie NOTE: getopt is now part of the C library, so if you don't know what
3*a1acfa9bSespie "Keep this file name-space clean" means, talk to drepper@gnu.org
4*a1acfa9bSespie before changing it!
5*a1acfa9bSespie Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004
6840175f0Skstailey Free Software Foundation, Inc.
7*a1acfa9bSespie This file is part of the GNU C Library.
8840175f0Skstailey
9*a1acfa9bSespie This program is free software; you can redistribute it and/or modify
10*a1acfa9bSespie it under the terms of the GNU General Public License as published by
11*a1acfa9bSespie the Free Software Foundation; either version 2, or (at your option)
12*a1acfa9bSespie any later version.
13840175f0Skstailey
14840175f0Skstailey This program is distributed in the hope that it will be useful,
15840175f0Skstailey but WITHOUT ANY WARRANTY; without even the implied warranty of
16840175f0Skstailey MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17840175f0Skstailey GNU General Public License for more details.
18840175f0Skstailey
19*a1acfa9bSespie You should have received a copy of the GNU General Public License along
20*a1acfa9bSespie with this program; if not, write to the Free Software Foundation,
213fb98d4aSespie Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22840175f0Skstailey
23840175f0Skstailey /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
24840175f0Skstailey Ditto for AIX 3.2 and <stdlib.h>. */
25840175f0Skstailey #ifndef _NO_PROTO
26840175f0Skstailey # define _NO_PROTO
27840175f0Skstailey #endif
28840175f0Skstailey
29840175f0Skstailey #ifdef HAVE_CONFIG_H
30840175f0Skstailey # include <config.h>
313fb98d4aSespie #endif
32840175f0Skstailey
33840175f0Skstailey #include <stdio.h>
34840175f0Skstailey
35840175f0Skstailey /* This needs to come after some library #include
36840175f0Skstailey to get __GNU_LIBRARY__ defined. */
37840175f0Skstailey #ifdef __GNU_LIBRARY__
38840175f0Skstailey /* Don't include stdlib.h for non-GNU C libraries because some of them
39840175f0Skstailey contain conflicting prototypes for getopt. */
40840175f0Skstailey # include <stdlib.h>
41840175f0Skstailey # include <unistd.h>
42840175f0Skstailey #endif /* GNU C library. */
43840175f0Skstailey
44*a1acfa9bSespie #include <string.h>
45*a1acfa9bSespie
46840175f0Skstailey #ifdef VMS
47840175f0Skstailey # include <unixlib.h>
48840175f0Skstailey #endif
49840175f0Skstailey
50*a1acfa9bSespie #ifdef _LIBC
51840175f0Skstailey # include <libintl.h>
52840175f0Skstailey #else
53*a1acfa9bSespie # include "gettext.h"
54*a1acfa9bSespie # define _(msgid) gettext (msgid)
55840175f0Skstailey #endif
56*a1acfa9bSespie
57*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
58*a1acfa9bSespie # include <wchar.h>
59*a1acfa9bSespie #endif
60*a1acfa9bSespie
61*a1acfa9bSespie #ifndef attribute_hidden
62*a1acfa9bSespie # define attribute_hidden
63840175f0Skstailey #endif
64840175f0Skstailey
65840175f0Skstailey /* This version of `getopt' appears to the caller like standard Unix `getopt'
66840175f0Skstailey but it behaves differently for the user, since it allows the user
67840175f0Skstailey to intersperse the options with the other arguments.
68840175f0Skstailey
69840175f0Skstailey As `getopt' works, it permutes the elements of ARGV so that,
70840175f0Skstailey when it is done, all the options precede everything else. Thus
71840175f0Skstailey all application programs are extended to handle flexible argument order.
72840175f0Skstailey
73840175f0Skstailey Setting the environment variable POSIXLY_CORRECT disables permutation.
74840175f0Skstailey Then the behavior is completely standard.
75840175f0Skstailey
76840175f0Skstailey GNU application programs can use a third alternative mode in which
77840175f0Skstailey they can distinguish the relative order of options and other arguments. */
78840175f0Skstailey
79840175f0Skstailey #include "getopt.h"
80*a1acfa9bSespie #include "getopt_int.h"
81840175f0Skstailey
82840175f0Skstailey /* For communication from `getopt' to the caller.
83840175f0Skstailey When `getopt' finds an option that takes an argument,
84840175f0Skstailey the argument value is returned here.
85840175f0Skstailey Also, when `ordering' is RETURN_IN_ORDER,
86840175f0Skstailey each non-option ARGV-element is returned here. */
87840175f0Skstailey
883fb98d4aSespie char *optarg;
89840175f0Skstailey
90840175f0Skstailey /* Index in ARGV of the next element to be scanned.
91840175f0Skstailey This is used for communication to and from the caller
92840175f0Skstailey and for communication between successive calls to `getopt'.
93840175f0Skstailey
94840175f0Skstailey On entry to `getopt', zero means this is the first call; initialize.
95840175f0Skstailey
96840175f0Skstailey When `getopt' returns -1, this is the index of the first of the
97840175f0Skstailey non-option elements that the caller should itself scan.
98840175f0Skstailey
99840175f0Skstailey Otherwise, `optind' communicates from one call to the next
100840175f0Skstailey how much of ARGV has been scanned so far. */
101840175f0Skstailey
102840175f0Skstailey /* 1003.2 says this must be 1 before any call. */
103840175f0Skstailey int optind = 1;
104840175f0Skstailey
105840175f0Skstailey /* Callers store zero here to inhibit the error message
106840175f0Skstailey for unrecognized options. */
107840175f0Skstailey
108840175f0Skstailey int opterr = 1;
109840175f0Skstailey
110840175f0Skstailey /* Set to an option character which was unrecognized.
111840175f0Skstailey This must be initialized on some systems to avoid linking in the
112840175f0Skstailey system's own getopt implementation. */
113840175f0Skstailey
114840175f0Skstailey int optopt = '?';
115840175f0Skstailey
116*a1acfa9bSespie /* Keep a global copy of all internal members of getopt_data. */
117840175f0Skstailey
118*a1acfa9bSespie static struct _getopt_data getopt_data;
119840175f0Skstailey
120840175f0Skstailey
121*a1acfa9bSespie #ifndef __GNU_LIBRARY__
1221cc83814Sespie
123840175f0Skstailey /* Avoid depending on library functions or files
124840175f0Skstailey whose names are inconsistent. */
125840175f0Skstailey
1261cc83814Sespie #ifndef getenv
1271cc83814Sespie extern char *getenv ();
1281cc83814Sespie #endif
129840175f0Skstailey
130840175f0Skstailey #endif /* not __GNU_LIBRARY__ */
131840175f0Skstailey
132840175f0Skstailey #ifdef _LIBC
133*a1acfa9bSespie /* Stored original parameters.
134*a1acfa9bSespie XXX This is no good solution. We should rather copy the args so
135*a1acfa9bSespie that we can compare them later. But we must not use malloc(3). */
136*a1acfa9bSespie extern int __libc_argc;
137*a1acfa9bSespie extern char **__libc_argv;
138*a1acfa9bSespie
139840175f0Skstailey /* Bash 2.0 gives us an environment variable containing flags
140840175f0Skstailey indicating ARGV elements that should not be considered arguments. */
141840175f0Skstailey
142*a1acfa9bSespie # ifdef USE_NONOPTION_FLAGS
143840175f0Skstailey /* Defined in getopt_init.c */
144840175f0Skstailey extern char *__getopt_nonoption_flags;
145*a1acfa9bSespie # endif
146840175f0Skstailey
147*a1acfa9bSespie # ifdef USE_NONOPTION_FLAGS
148840175f0Skstailey # define SWAP_FLAGS(ch1, ch2) \
149*a1acfa9bSespie if (d->__nonoption_flags_len > 0) \
150840175f0Skstailey { \
151840175f0Skstailey char __tmp = __getopt_nonoption_flags[ch1]; \
152840175f0Skstailey __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
153840175f0Skstailey __getopt_nonoption_flags[ch2] = __tmp; \
154840175f0Skstailey }
155*a1acfa9bSespie # else
156*a1acfa9bSespie # define SWAP_FLAGS(ch1, ch2)
157*a1acfa9bSespie # endif
158840175f0Skstailey #else /* !_LIBC */
159840175f0Skstailey # define SWAP_FLAGS(ch1, ch2)
160840175f0Skstailey #endif /* _LIBC */
161840175f0Skstailey
162840175f0Skstailey /* Exchange two adjacent subsequences of ARGV.
163840175f0Skstailey One subsequence is elements [first_nonopt,last_nonopt)
164840175f0Skstailey which contains all the non-options that have been skipped so far.
165840175f0Skstailey The other is elements [last_nonopt,optind), which contains all
166840175f0Skstailey the options processed since those non-options were skipped.
167840175f0Skstailey
168840175f0Skstailey `first_nonopt' and `last_nonopt' are relocated so that they describe
169840175f0Skstailey the new indices of the non-options in ARGV after they are moved. */
170840175f0Skstailey
171840175f0Skstailey static void
exchange(char ** argv,struct _getopt_data * d)172*a1acfa9bSespie exchange (char **argv, struct _getopt_data *d)
173840175f0Skstailey {
174*a1acfa9bSespie int bottom = d->__first_nonopt;
175*a1acfa9bSespie int middle = d->__last_nonopt;
176*a1acfa9bSespie int top = d->optind;
177840175f0Skstailey char *tem;
178840175f0Skstailey
179840175f0Skstailey /* Exchange the shorter segment with the far end of the longer segment.
180840175f0Skstailey That puts the shorter segment into the right place.
181840175f0Skstailey It leaves the longer segment in the right place overall,
182840175f0Skstailey but it consists of two parts that need to be swapped next. */
183840175f0Skstailey
184*a1acfa9bSespie #if defined _LIBC && defined USE_NONOPTION_FLAGS
185840175f0Skstailey /* First make sure the handling of the `__getopt_nonoption_flags'
186840175f0Skstailey string can work normally. Our top argument must be in the range
187840175f0Skstailey of the string. */
188*a1acfa9bSespie if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
189840175f0Skstailey {
190840175f0Skstailey /* We must extend the array. The user plays games with us and
191840175f0Skstailey presents new arguments. */
192840175f0Skstailey char *new_str = malloc (top + 1);
193840175f0Skstailey if (new_str == NULL)
194*a1acfa9bSespie d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
195840175f0Skstailey else
196840175f0Skstailey {
19728ea187bSespie memset (__mempcpy (new_str, __getopt_nonoption_flags,
198*a1acfa9bSespie d->__nonoption_flags_max_len),
199*a1acfa9bSespie '\0', top + 1 - d->__nonoption_flags_max_len);
200*a1acfa9bSespie d->__nonoption_flags_max_len = top + 1;
201840175f0Skstailey __getopt_nonoption_flags = new_str;
202840175f0Skstailey }
203840175f0Skstailey }
204840175f0Skstailey #endif
205840175f0Skstailey
206840175f0Skstailey while (top > middle && middle > bottom)
207840175f0Skstailey {
208840175f0Skstailey if (top - middle > middle - bottom)
209840175f0Skstailey {
210840175f0Skstailey /* Bottom segment is the short one. */
211840175f0Skstailey int len = middle - bottom;
212840175f0Skstailey register int i;
213840175f0Skstailey
214840175f0Skstailey /* Swap it with the top part of the top segment. */
215840175f0Skstailey for (i = 0; i < len; i++)
216840175f0Skstailey {
217840175f0Skstailey tem = argv[bottom + i];
218840175f0Skstailey argv[bottom + i] = argv[top - (middle - bottom) + i];
219840175f0Skstailey argv[top - (middle - bottom) + i] = tem;
220840175f0Skstailey SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
221840175f0Skstailey }
222840175f0Skstailey /* Exclude the moved bottom segment from further swapping. */
223840175f0Skstailey top -= len;
224840175f0Skstailey }
225840175f0Skstailey else
226840175f0Skstailey {
227840175f0Skstailey /* Top segment is the short one. */
228840175f0Skstailey int len = top - middle;
229840175f0Skstailey register int i;
230840175f0Skstailey
231840175f0Skstailey /* Swap it with the bottom part of the bottom segment. */
232840175f0Skstailey for (i = 0; i < len; i++)
233840175f0Skstailey {
234840175f0Skstailey tem = argv[bottom + i];
235840175f0Skstailey argv[bottom + i] = argv[middle + i];
236840175f0Skstailey argv[middle + i] = tem;
237840175f0Skstailey SWAP_FLAGS (bottom + i, middle + i);
238840175f0Skstailey }
239840175f0Skstailey /* Exclude the moved top segment from further swapping. */
240840175f0Skstailey bottom += len;
241840175f0Skstailey }
242840175f0Skstailey }
243840175f0Skstailey
244840175f0Skstailey /* Update records for the slots the non-options now occupy. */
245840175f0Skstailey
246*a1acfa9bSespie d->__first_nonopt += (d->optind - d->__last_nonopt);
247*a1acfa9bSespie d->__last_nonopt = d->optind;
248840175f0Skstailey }
249840175f0Skstailey
250840175f0Skstailey /* Initialize the internal data when the first call is made. */
251840175f0Skstailey
252840175f0Skstailey static const char *
_getopt_initialize(int argc,char * const * argv,const char * optstring,struct _getopt_data * d)253*a1acfa9bSespie _getopt_initialize (int argc, char *const *argv, const char *optstring,
254*a1acfa9bSespie struct _getopt_data *d)
255840175f0Skstailey {
256840175f0Skstailey /* Start processing options with ARGV-element 1 (since ARGV-element 0
257840175f0Skstailey is the program name); the sequence of previously skipped
258840175f0Skstailey non-option ARGV-elements is empty. */
259840175f0Skstailey
260*a1acfa9bSespie d->__first_nonopt = d->__last_nonopt = d->optind;
261840175f0Skstailey
262*a1acfa9bSespie d->__nextchar = NULL;
263840175f0Skstailey
264*a1acfa9bSespie d->__posixly_correct = !!getenv ("POSIXLY_CORRECT");
265840175f0Skstailey
266840175f0Skstailey /* Determine how to handle the ordering of options and nonoptions. */
267840175f0Skstailey
268840175f0Skstailey if (optstring[0] == '-')
269840175f0Skstailey {
270*a1acfa9bSespie d->__ordering = RETURN_IN_ORDER;
271840175f0Skstailey ++optstring;
272840175f0Skstailey }
273840175f0Skstailey else if (optstring[0] == '+')
274840175f0Skstailey {
275*a1acfa9bSespie d->__ordering = REQUIRE_ORDER;
276840175f0Skstailey ++optstring;
277840175f0Skstailey }
278*a1acfa9bSespie else if (d->__posixly_correct)
279*a1acfa9bSespie d->__ordering = REQUIRE_ORDER;
280840175f0Skstailey else
281*a1acfa9bSespie d->__ordering = PERMUTE;
282840175f0Skstailey
283*a1acfa9bSespie #if defined _LIBC && defined USE_NONOPTION_FLAGS
284*a1acfa9bSespie if (!d->__posixly_correct
285*a1acfa9bSespie && argc == __libc_argc && argv == __libc_argv)
286840175f0Skstailey {
287*a1acfa9bSespie if (d->__nonoption_flags_max_len == 0)
288840175f0Skstailey {
289840175f0Skstailey if (__getopt_nonoption_flags == NULL
290840175f0Skstailey || __getopt_nonoption_flags[0] == '\0')
291*a1acfa9bSespie d->__nonoption_flags_max_len = -1;
292840175f0Skstailey else
293840175f0Skstailey {
294840175f0Skstailey const char *orig_str = __getopt_nonoption_flags;
295*a1acfa9bSespie int len = d->__nonoption_flags_max_len = strlen (orig_str);
296*a1acfa9bSespie if (d->__nonoption_flags_max_len < argc)
297*a1acfa9bSespie d->__nonoption_flags_max_len = argc;
298840175f0Skstailey __getopt_nonoption_flags =
299*a1acfa9bSespie (char *) malloc (d->__nonoption_flags_max_len);
300840175f0Skstailey if (__getopt_nonoption_flags == NULL)
301*a1acfa9bSespie d->__nonoption_flags_max_len = -1;
302840175f0Skstailey else
30328ea187bSespie memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
304*a1acfa9bSespie '\0', d->__nonoption_flags_max_len - len);
305840175f0Skstailey }
306840175f0Skstailey }
307*a1acfa9bSespie d->__nonoption_flags_len = d->__nonoption_flags_max_len;
308840175f0Skstailey }
309840175f0Skstailey else
310*a1acfa9bSespie d->__nonoption_flags_len = 0;
311840175f0Skstailey #endif
312840175f0Skstailey
313840175f0Skstailey return optstring;
314840175f0Skstailey }
315840175f0Skstailey
316840175f0Skstailey /* Scan elements of ARGV (whose length is ARGC) for option characters
317840175f0Skstailey given in OPTSTRING.
318840175f0Skstailey
319840175f0Skstailey If an element of ARGV starts with '-', and is not exactly "-" or "--",
320840175f0Skstailey then it is an option element. The characters of this element
321840175f0Skstailey (aside from the initial '-') are option characters. If `getopt'
322840175f0Skstailey is called repeatedly, it returns successively each of the option characters
323840175f0Skstailey from each of the option elements.
324840175f0Skstailey
325840175f0Skstailey If `getopt' finds another option character, it returns that character,
326840175f0Skstailey updating `optind' and `nextchar' so that the next call to `getopt' can
327840175f0Skstailey resume the scan with the following option character or ARGV-element.
328840175f0Skstailey
329840175f0Skstailey If there are no more option characters, `getopt' returns -1.
330840175f0Skstailey Then `optind' is the index in ARGV of the first ARGV-element
331840175f0Skstailey that is not an option. (The ARGV-elements have been permuted
332840175f0Skstailey so that those that are not options now come last.)
333840175f0Skstailey
334840175f0Skstailey OPTSTRING is a string containing the legitimate option characters.
335840175f0Skstailey If an option character is seen that is not listed in OPTSTRING,
336840175f0Skstailey return '?' after printing an error message. If you set `opterr' to
337840175f0Skstailey zero, the error message is suppressed but we still return '?'.
338840175f0Skstailey
339840175f0Skstailey If a char in OPTSTRING is followed by a colon, that means it wants an arg,
340840175f0Skstailey so the following text in the same ARGV-element, or the text of the following
341840175f0Skstailey ARGV-element, is returned in `optarg'. Two colons mean an option that
342840175f0Skstailey wants an optional arg; if there is text in the current ARGV-element,
343840175f0Skstailey it is returned in `optarg', otherwise `optarg' is set to zero.
344840175f0Skstailey
345840175f0Skstailey If OPTSTRING starts with `-' or `+', it requests different methods of
346840175f0Skstailey handling the non-option ARGV-elements.
347840175f0Skstailey See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
348840175f0Skstailey
349840175f0Skstailey Long-named options begin with `--' instead of `-'.
350840175f0Skstailey Their names may be abbreviated as long as the abbreviation is unique
351840175f0Skstailey or is an exact match for some defined option. If they have an
352840175f0Skstailey argument, it follows the option name in the same ARGV-element, separated
353840175f0Skstailey from the option name by a `=', or else the in next ARGV-element.
354840175f0Skstailey When `getopt' finds a long-named option, it returns 0 if that option's
355840175f0Skstailey `flag' field is nonzero, the value of the option's `val' field
356840175f0Skstailey if the `flag' field is zero.
357840175f0Skstailey
358840175f0Skstailey The elements of ARGV aren't really const, because we permute them.
359840175f0Skstailey But we pretend they're const in the prototype to be compatible
360840175f0Skstailey with other systems.
361840175f0Skstailey
362840175f0Skstailey LONGOPTS is a vector of `struct option' terminated by an
363840175f0Skstailey element containing a name which is zero.
364840175f0Skstailey
365840175f0Skstailey LONGIND returns the index in LONGOPT of the long-named option found.
366840175f0Skstailey It is only valid when a long-named option has been found by the most
367840175f0Skstailey recent call.
368840175f0Skstailey
369840175f0Skstailey If LONG_ONLY is nonzero, '-' as well as '--' can introduce
370840175f0Skstailey long-named options. */
371840175f0Skstailey
372840175f0Skstailey int
_getopt_internal_r(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,int long_only,struct _getopt_data * d)373*a1acfa9bSespie _getopt_internal_r (int argc, char *const *argv, const char *optstring,
374*a1acfa9bSespie const struct option *longopts, int *longind,
375*a1acfa9bSespie int long_only, struct _getopt_data *d)
376840175f0Skstailey {
377*a1acfa9bSespie int print_errors = d->opterr;
378*a1acfa9bSespie if (optstring[0] == ':')
379*a1acfa9bSespie print_errors = 0;
380840175f0Skstailey
381*a1acfa9bSespie if (argc < 1)
382*a1acfa9bSespie return -1;
383*a1acfa9bSespie
384*a1acfa9bSespie d->optarg = NULL;
385*a1acfa9bSespie
386*a1acfa9bSespie if (d->optind == 0 || !d->__initialized)
387840175f0Skstailey {
388*a1acfa9bSespie if (d->optind == 0)
389*a1acfa9bSespie d->optind = 1; /* Don't scan ARGV[0], the program name. */
390*a1acfa9bSespie optstring = _getopt_initialize (argc, argv, optstring, d);
391*a1acfa9bSespie d->__initialized = 1;
392840175f0Skstailey }
393840175f0Skstailey
394840175f0Skstailey /* Test whether ARGV[optind] points to a non-option argument.
395840175f0Skstailey Either it does not have option syntax, or there is an environment flag
396840175f0Skstailey from the shell indicating it is not an option. The later information
397840175f0Skstailey is only used when the used in the GNU libc. */
398*a1acfa9bSespie #if defined _LIBC && defined USE_NONOPTION_FLAGS
399*a1acfa9bSespie # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \
400*a1acfa9bSespie || (d->optind < d->__nonoption_flags_len \
401*a1acfa9bSespie && __getopt_nonoption_flags[d->optind] == '1'))
402840175f0Skstailey #else
403*a1acfa9bSespie # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
404840175f0Skstailey #endif
405840175f0Skstailey
406*a1acfa9bSespie if (d->__nextchar == NULL || *d->__nextchar == '\0')
407840175f0Skstailey {
408840175f0Skstailey /* Advance to the next ARGV-element. */
409840175f0Skstailey
410840175f0Skstailey /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
411840175f0Skstailey moved back by the user (who may also have changed the arguments). */
412*a1acfa9bSespie if (d->__last_nonopt > d->optind)
413*a1acfa9bSespie d->__last_nonopt = d->optind;
414*a1acfa9bSespie if (d->__first_nonopt > d->optind)
415*a1acfa9bSespie d->__first_nonopt = d->optind;
416840175f0Skstailey
417*a1acfa9bSespie if (d->__ordering == PERMUTE)
418840175f0Skstailey {
419840175f0Skstailey /* If we have just processed some options following some non-options,
420840175f0Skstailey exchange them so that the options come first. */
421840175f0Skstailey
422*a1acfa9bSespie if (d->__first_nonopt != d->__last_nonopt
423*a1acfa9bSespie && d->__last_nonopt != d->optind)
424*a1acfa9bSespie exchange ((char **) argv, d);
425*a1acfa9bSespie else if (d->__last_nonopt != d->optind)
426*a1acfa9bSespie d->__first_nonopt = d->optind;
427840175f0Skstailey
428840175f0Skstailey /* Skip any additional non-options
429840175f0Skstailey and extend the range of non-options previously skipped. */
430840175f0Skstailey
431*a1acfa9bSespie while (d->optind < argc && NONOPTION_P)
432*a1acfa9bSespie d->optind++;
433*a1acfa9bSespie d->__last_nonopt = d->optind;
434840175f0Skstailey }
435840175f0Skstailey
436840175f0Skstailey /* The special ARGV-element `--' means premature end of options.
437840175f0Skstailey Skip it like a null option,
438840175f0Skstailey then exchange with previous non-options as if it were an option,
439840175f0Skstailey then skip everything else like a non-option. */
440840175f0Skstailey
441*a1acfa9bSespie if (d->optind != argc && !strcmp (argv[d->optind], "--"))
442840175f0Skstailey {
443*a1acfa9bSespie d->optind++;
444840175f0Skstailey
445*a1acfa9bSespie if (d->__first_nonopt != d->__last_nonopt
446*a1acfa9bSespie && d->__last_nonopt != d->optind)
447*a1acfa9bSespie exchange ((char **) argv, d);
448*a1acfa9bSespie else if (d->__first_nonopt == d->__last_nonopt)
449*a1acfa9bSespie d->__first_nonopt = d->optind;
450*a1acfa9bSespie d->__last_nonopt = argc;
451840175f0Skstailey
452*a1acfa9bSespie d->optind = argc;
453840175f0Skstailey }
454840175f0Skstailey
455840175f0Skstailey /* If we have done all the ARGV-elements, stop the scan
456840175f0Skstailey and back over any non-options that we skipped and permuted. */
457840175f0Skstailey
458*a1acfa9bSespie if (d->optind == argc)
459840175f0Skstailey {
460840175f0Skstailey /* Set the next-arg-index to point at the non-options
461840175f0Skstailey that we previously skipped, so the caller will digest them. */
462*a1acfa9bSespie if (d->__first_nonopt != d->__last_nonopt)
463*a1acfa9bSespie d->optind = d->__first_nonopt;
464840175f0Skstailey return -1;
465840175f0Skstailey }
466840175f0Skstailey
467840175f0Skstailey /* If we have come to a non-option and did not permute it,
468840175f0Skstailey either stop the scan or describe it to the caller and pass it by. */
469840175f0Skstailey
470840175f0Skstailey if (NONOPTION_P)
471840175f0Skstailey {
472*a1acfa9bSespie if (d->__ordering == REQUIRE_ORDER)
473840175f0Skstailey return -1;
474*a1acfa9bSespie d->optarg = argv[d->optind++];
475840175f0Skstailey return 1;
476840175f0Skstailey }
477840175f0Skstailey
478840175f0Skstailey /* We have found another option-ARGV-element.
479840175f0Skstailey Skip the initial punctuation. */
480840175f0Skstailey
481*a1acfa9bSespie d->__nextchar = (argv[d->optind] + 1
482*a1acfa9bSespie + (longopts != NULL && argv[d->optind][1] == '-'));
483840175f0Skstailey }
484840175f0Skstailey
485840175f0Skstailey /* Decode the current option-ARGV-element. */
486840175f0Skstailey
487840175f0Skstailey /* Check whether the ARGV-element is a long option.
488840175f0Skstailey
489840175f0Skstailey If long_only and the ARGV-element has the form "-f", where f is
490840175f0Skstailey a valid short option, don't consider it an abbreviated form of
491840175f0Skstailey a long option that starts with f. Otherwise there would be no
492840175f0Skstailey way to give the -f short option.
493840175f0Skstailey
494840175f0Skstailey On the other hand, if there's a long option "fubar" and
495840175f0Skstailey the ARGV-element is "-fu", do consider that an abbreviation of
496840175f0Skstailey the long option, just like "--fu", and not "-f" with arg "u".
497840175f0Skstailey
498840175f0Skstailey This distinction seems to be the most useful approach. */
499840175f0Skstailey
500840175f0Skstailey if (longopts != NULL
501*a1acfa9bSespie && (argv[d->optind][1] == '-'
502*a1acfa9bSespie || (long_only && (argv[d->optind][2]
503*a1acfa9bSespie || !strchr (optstring, argv[d->optind][1])))))
504840175f0Skstailey {
505840175f0Skstailey char *nameend;
506840175f0Skstailey const struct option *p;
507840175f0Skstailey const struct option *pfound = NULL;
508840175f0Skstailey int exact = 0;
509840175f0Skstailey int ambig = 0;
510840175f0Skstailey int indfound = -1;
511840175f0Skstailey int option_index;
512840175f0Skstailey
513*a1acfa9bSespie for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
514840175f0Skstailey /* Do nothing. */ ;
515840175f0Skstailey
516840175f0Skstailey /* Test all long options for either exact match
517840175f0Skstailey or abbreviated matches. */
518840175f0Skstailey for (p = longopts, option_index = 0; p->name; p++, option_index++)
519*a1acfa9bSespie if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
520840175f0Skstailey {
521*a1acfa9bSespie if ((unsigned int) (nameend - d->__nextchar)
522840175f0Skstailey == (unsigned int) strlen (p->name))
523840175f0Skstailey {
524840175f0Skstailey /* Exact match found. */
525840175f0Skstailey pfound = p;
526840175f0Skstailey indfound = option_index;
527840175f0Skstailey exact = 1;
528840175f0Skstailey break;
529840175f0Skstailey }
530840175f0Skstailey else if (pfound == NULL)
531840175f0Skstailey {
532840175f0Skstailey /* First nonexact match found. */
533840175f0Skstailey pfound = p;
534840175f0Skstailey indfound = option_index;
535840175f0Skstailey }
536*a1acfa9bSespie else if (long_only
537*a1acfa9bSespie || pfound->has_arg != p->has_arg
538*a1acfa9bSespie || pfound->flag != p->flag
539*a1acfa9bSespie || pfound->val != p->val)
540840175f0Skstailey /* Second or later nonexact match found. */
541840175f0Skstailey ambig = 1;
542840175f0Skstailey }
543840175f0Skstailey
544840175f0Skstailey if (ambig && !exact)
545840175f0Skstailey {
546*a1acfa9bSespie if (print_errors)
547*a1acfa9bSespie {
548*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
549*a1acfa9bSespie char *buf;
550*a1acfa9bSespie
551*a1acfa9bSespie if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
552*a1acfa9bSespie argv[0], argv[d->optind]) >= 0)
553*a1acfa9bSespie {
554*a1acfa9bSespie _IO_flockfile (stderr);
555*a1acfa9bSespie
556*a1acfa9bSespie int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
557*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
558*a1acfa9bSespie
559*a1acfa9bSespie if (_IO_fwide (stderr, 0) > 0)
560*a1acfa9bSespie __fwprintf (stderr, L"%s", buf);
561*a1acfa9bSespie else
562*a1acfa9bSespie fputs (buf, stderr);
563*a1acfa9bSespie
564*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 = old_flags2;
565*a1acfa9bSespie _IO_funlockfile (stderr);
566*a1acfa9bSespie
567*a1acfa9bSespie free (buf);
568*a1acfa9bSespie }
569*a1acfa9bSespie #else
570840175f0Skstailey fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
571*a1acfa9bSespie argv[0], argv[d->optind]);
572*a1acfa9bSespie #endif
573*a1acfa9bSespie }
574*a1acfa9bSespie d->__nextchar += strlen (d->__nextchar);
575*a1acfa9bSespie d->optind++;
576*a1acfa9bSespie d->optopt = 0;
577840175f0Skstailey return '?';
578840175f0Skstailey }
579840175f0Skstailey
580840175f0Skstailey if (pfound != NULL)
581840175f0Skstailey {
582840175f0Skstailey option_index = indfound;
583*a1acfa9bSespie d->optind++;
584840175f0Skstailey if (*nameend)
585840175f0Skstailey {
586840175f0Skstailey /* Don't test has_arg with >, because some C compilers don't
587840175f0Skstailey allow it to be used on enums. */
588840175f0Skstailey if (pfound->has_arg)
589*a1acfa9bSespie d->optarg = nameend + 1;
590840175f0Skstailey else
591840175f0Skstailey {
592*a1acfa9bSespie if (print_errors)
5933fb98d4aSespie {
594*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
595*a1acfa9bSespie char *buf;
596*a1acfa9bSespie int n;
597*a1acfa9bSespie #endif
598*a1acfa9bSespie
599*a1acfa9bSespie if (argv[d->optind - 1][1] == '-')
600*a1acfa9bSespie {
601840175f0Skstailey /* --option */
602*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
603*a1acfa9bSespie n = __asprintf (&buf, _("\
604*a1acfa9bSespie %s: option `--%s' doesn't allow an argument\n"),
605840175f0Skstailey argv[0], pfound->name);
606*a1acfa9bSespie #else
607*a1acfa9bSespie fprintf (stderr, _("\
608*a1acfa9bSespie %s: option `--%s' doesn't allow an argument\n"),
609*a1acfa9bSespie argv[0], pfound->name);
610*a1acfa9bSespie #endif
611*a1acfa9bSespie }
612840175f0Skstailey else
613*a1acfa9bSespie {
614840175f0Skstailey /* +option or -option */
615*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
616*a1acfa9bSespie n = __asprintf (&buf, _("\
617*a1acfa9bSespie %s: option `%c%s' doesn't allow an argument\n"),
618*a1acfa9bSespie argv[0], argv[d->optind - 1][0],
619*a1acfa9bSespie pfound->name);
620*a1acfa9bSespie #else
621*a1acfa9bSespie fprintf (stderr, _("\
622*a1acfa9bSespie %s: option `%c%s' doesn't allow an argument\n"),
623*a1acfa9bSespie argv[0], argv[d->optind - 1][0],
624*a1acfa9bSespie pfound->name);
625*a1acfa9bSespie #endif
6263fb98d4aSespie }
627840175f0Skstailey
628*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
629*a1acfa9bSespie if (n >= 0)
630*a1acfa9bSespie {
631*a1acfa9bSespie _IO_flockfile (stderr);
632840175f0Skstailey
633*a1acfa9bSespie int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
634*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2
635*a1acfa9bSespie |= _IO_FLAGS2_NOTCANCEL;
636*a1acfa9bSespie
637*a1acfa9bSespie if (_IO_fwide (stderr, 0) > 0)
638*a1acfa9bSespie __fwprintf (stderr, L"%s", buf);
639*a1acfa9bSespie else
640*a1acfa9bSespie fputs (buf, stderr);
641*a1acfa9bSespie
642*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 = old_flags2;
643*a1acfa9bSespie _IO_funlockfile (stderr);
644*a1acfa9bSespie
645*a1acfa9bSespie free (buf);
646*a1acfa9bSespie }
647*a1acfa9bSespie #endif
648*a1acfa9bSespie }
649*a1acfa9bSespie
650*a1acfa9bSespie d->__nextchar += strlen (d->__nextchar);
651*a1acfa9bSespie
652*a1acfa9bSespie d->optopt = pfound->val;
653840175f0Skstailey return '?';
654840175f0Skstailey }
655840175f0Skstailey }
656840175f0Skstailey else if (pfound->has_arg == 1)
657840175f0Skstailey {
658*a1acfa9bSespie if (d->optind < argc)
659*a1acfa9bSespie d->optarg = argv[d->optind++];
660840175f0Skstailey else
661840175f0Skstailey {
662*a1acfa9bSespie if (print_errors)
663*a1acfa9bSespie {
664*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
665*a1acfa9bSespie char *buf;
666*a1acfa9bSespie
667*a1acfa9bSespie if (__asprintf (&buf, _("\
668*a1acfa9bSespie %s: option `%s' requires an argument\n"),
669*a1acfa9bSespie argv[0], argv[d->optind - 1]) >= 0)
670*a1acfa9bSespie {
671*a1acfa9bSespie _IO_flockfile (stderr);
672*a1acfa9bSespie
673*a1acfa9bSespie int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
674*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2
675*a1acfa9bSespie |= _IO_FLAGS2_NOTCANCEL;
676*a1acfa9bSespie
677*a1acfa9bSespie if (_IO_fwide (stderr, 0) > 0)
678*a1acfa9bSespie __fwprintf (stderr, L"%s", buf);
679*a1acfa9bSespie else
680*a1acfa9bSespie fputs (buf, stderr);
681*a1acfa9bSespie
682*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 = old_flags2;
683*a1acfa9bSespie _IO_funlockfile (stderr);
684*a1acfa9bSespie
685*a1acfa9bSespie free (buf);
686*a1acfa9bSespie }
687*a1acfa9bSespie #else
688840175f0Skstailey fprintf (stderr,
689840175f0Skstailey _("%s: option `%s' requires an argument\n"),
690*a1acfa9bSespie argv[0], argv[d->optind - 1]);
691*a1acfa9bSespie #endif
692*a1acfa9bSespie }
693*a1acfa9bSespie d->__nextchar += strlen (d->__nextchar);
694*a1acfa9bSespie d->optopt = pfound->val;
695840175f0Skstailey return optstring[0] == ':' ? ':' : '?';
696840175f0Skstailey }
697840175f0Skstailey }
698*a1acfa9bSespie d->__nextchar += strlen (d->__nextchar);
699840175f0Skstailey if (longind != NULL)
700840175f0Skstailey *longind = option_index;
701840175f0Skstailey if (pfound->flag)
702840175f0Skstailey {
703840175f0Skstailey *(pfound->flag) = pfound->val;
704840175f0Skstailey return 0;
705840175f0Skstailey }
706840175f0Skstailey return pfound->val;
707840175f0Skstailey }
708840175f0Skstailey
709840175f0Skstailey /* Can't find it as a long option. If this is not getopt_long_only,
710840175f0Skstailey or the option starts with '--' or is not a valid short
711840175f0Skstailey option, then it's an error.
712840175f0Skstailey Otherwise interpret it as a short option. */
713*a1acfa9bSespie if (!long_only || argv[d->optind][1] == '-'
714*a1acfa9bSespie || strchr (optstring, *d->__nextchar) == NULL)
715840175f0Skstailey {
716*a1acfa9bSespie if (print_errors)
717840175f0Skstailey {
718*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
719*a1acfa9bSespie char *buf;
720*a1acfa9bSespie int n;
721*a1acfa9bSespie #endif
722*a1acfa9bSespie
723*a1acfa9bSespie if (argv[d->optind][1] == '-')
724*a1acfa9bSespie {
725840175f0Skstailey /* --option */
726*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
727*a1acfa9bSespie n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
728*a1acfa9bSespie argv[0], d->__nextchar);
729*a1acfa9bSespie #else
730840175f0Skstailey fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
731*a1acfa9bSespie argv[0], d->__nextchar);
732*a1acfa9bSespie #endif
733840175f0Skstailey }
734*a1acfa9bSespie else
735*a1acfa9bSespie {
736*a1acfa9bSespie /* +option or -option */
737*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
738*a1acfa9bSespie n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
739*a1acfa9bSespie argv[0], argv[d->optind][0], d->__nextchar);
740*a1acfa9bSespie #else
741*a1acfa9bSespie fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
742*a1acfa9bSespie argv[0], argv[d->optind][0], d->__nextchar);
743*a1acfa9bSespie #endif
744*a1acfa9bSespie }
745*a1acfa9bSespie
746*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
747*a1acfa9bSespie if (n >= 0)
748*a1acfa9bSespie {
749*a1acfa9bSespie _IO_flockfile (stderr);
750*a1acfa9bSespie
751*a1acfa9bSespie int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
752*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
753*a1acfa9bSespie
754*a1acfa9bSespie if (_IO_fwide (stderr, 0) > 0)
755*a1acfa9bSespie __fwprintf (stderr, L"%s", buf);
756*a1acfa9bSespie else
757*a1acfa9bSespie fputs (buf, stderr);
758*a1acfa9bSespie
759*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 = old_flags2;
760*a1acfa9bSespie _IO_funlockfile (stderr);
761*a1acfa9bSespie
762*a1acfa9bSespie free (buf);
763*a1acfa9bSespie }
764*a1acfa9bSespie #endif
765*a1acfa9bSespie }
766*a1acfa9bSespie d->__nextchar = (char *) "";
767*a1acfa9bSespie d->optind++;
768*a1acfa9bSespie d->optopt = 0;
769840175f0Skstailey return '?';
770840175f0Skstailey }
771840175f0Skstailey }
772840175f0Skstailey
773840175f0Skstailey /* Look at and handle the next short option-character. */
774840175f0Skstailey
775840175f0Skstailey {
776*a1acfa9bSespie char c = *d->__nextchar++;
777*a1acfa9bSespie char *temp = strchr (optstring, c);
778840175f0Skstailey
779840175f0Skstailey /* Increment `optind' when we start to process its last character. */
780*a1acfa9bSespie if (*d->__nextchar == '\0')
781*a1acfa9bSespie ++d->optind;
782840175f0Skstailey
783840175f0Skstailey if (temp == NULL || c == ':')
784840175f0Skstailey {
785*a1acfa9bSespie if (print_errors)
786840175f0Skstailey {
787*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
788*a1acfa9bSespie char *buf;
789*a1acfa9bSespie int n;
790*a1acfa9bSespie #endif
791*a1acfa9bSespie
792*a1acfa9bSespie if (d->__posixly_correct)
793*a1acfa9bSespie {
794840175f0Skstailey /* 1003.2 specifies the format of this message. */
795*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
796*a1acfa9bSespie n = __asprintf (&buf, _("%s: illegal option -- %c\n"),
797840175f0Skstailey argv[0], c);
798*a1acfa9bSespie #else
799*a1acfa9bSespie fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
800*a1acfa9bSespie #endif
801840175f0Skstailey }
802*a1acfa9bSespie else
803*a1acfa9bSespie {
804*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
805*a1acfa9bSespie n = __asprintf (&buf, _("%s: invalid option -- %c\n"),
806*a1acfa9bSespie argv[0], c);
807*a1acfa9bSespie #else
808*a1acfa9bSespie fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
809*a1acfa9bSespie #endif
810*a1acfa9bSespie }
811*a1acfa9bSespie
812*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
813*a1acfa9bSespie if (n >= 0)
814*a1acfa9bSespie {
815*a1acfa9bSespie _IO_flockfile (stderr);
816*a1acfa9bSespie
817*a1acfa9bSespie int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
818*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
819*a1acfa9bSespie
820*a1acfa9bSespie if (_IO_fwide (stderr, 0) > 0)
821*a1acfa9bSespie __fwprintf (stderr, L"%s", buf);
822*a1acfa9bSespie else
823*a1acfa9bSespie fputs (buf, stderr);
824*a1acfa9bSespie
825*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 = old_flags2;
826*a1acfa9bSespie _IO_funlockfile (stderr);
827*a1acfa9bSespie
828*a1acfa9bSespie free (buf);
829*a1acfa9bSespie }
830*a1acfa9bSespie #endif
831*a1acfa9bSespie }
832*a1acfa9bSespie d->optopt = c;
833840175f0Skstailey return '?';
834840175f0Skstailey }
835840175f0Skstailey /* Convenience. Treat POSIX -W foo same as long option --foo */
836840175f0Skstailey if (temp[0] == 'W' && temp[1] == ';')
837840175f0Skstailey {
838840175f0Skstailey char *nameend;
839840175f0Skstailey const struct option *p;
840840175f0Skstailey const struct option *pfound = NULL;
841840175f0Skstailey int exact = 0;
842840175f0Skstailey int ambig = 0;
843840175f0Skstailey int indfound = 0;
844840175f0Skstailey int option_index;
845840175f0Skstailey
846840175f0Skstailey /* This is an option that requires an argument. */
847*a1acfa9bSespie if (*d->__nextchar != '\0')
848840175f0Skstailey {
849*a1acfa9bSespie d->optarg = d->__nextchar;
850840175f0Skstailey /* If we end this ARGV-element by taking the rest as an arg,
851840175f0Skstailey we must advance to the next element now. */
852*a1acfa9bSespie d->optind++;
853840175f0Skstailey }
854*a1acfa9bSespie else if (d->optind == argc)
855840175f0Skstailey {
856*a1acfa9bSespie if (print_errors)
857840175f0Skstailey {
858840175f0Skstailey /* 1003.2 specifies the format of this message. */
859*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
860*a1acfa9bSespie char *buf;
861*a1acfa9bSespie
862*a1acfa9bSespie if (__asprintf (&buf,
863*a1acfa9bSespie _("%s: option requires an argument -- %c\n"),
864*a1acfa9bSespie argv[0], c) >= 0)
865*a1acfa9bSespie {
866*a1acfa9bSespie _IO_flockfile (stderr);
867*a1acfa9bSespie
868*a1acfa9bSespie int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
869*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
870*a1acfa9bSespie
871*a1acfa9bSespie if (_IO_fwide (stderr, 0) > 0)
872*a1acfa9bSespie __fwprintf (stderr, L"%s", buf);
873*a1acfa9bSespie else
874*a1acfa9bSespie fputs (buf, stderr);
875*a1acfa9bSespie
876*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 = old_flags2;
877*a1acfa9bSespie _IO_funlockfile (stderr);
878*a1acfa9bSespie
879*a1acfa9bSespie free (buf);
880*a1acfa9bSespie }
881*a1acfa9bSespie #else
882840175f0Skstailey fprintf (stderr, _("%s: option requires an argument -- %c\n"),
883840175f0Skstailey argv[0], c);
884*a1acfa9bSespie #endif
885840175f0Skstailey }
886*a1acfa9bSespie d->optopt = c;
887840175f0Skstailey if (optstring[0] == ':')
888840175f0Skstailey c = ':';
889840175f0Skstailey else
890840175f0Skstailey c = '?';
891840175f0Skstailey return c;
892840175f0Skstailey }
893840175f0Skstailey else
894*a1acfa9bSespie /* We already incremented `d->optind' once;
895840175f0Skstailey increment it again when taking next ARGV-elt as argument. */
896*a1acfa9bSespie d->optarg = argv[d->optind++];
897840175f0Skstailey
898840175f0Skstailey /* optarg is now the argument, see if it's in the
899840175f0Skstailey table of longopts. */
900840175f0Skstailey
901*a1acfa9bSespie for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
902*a1acfa9bSespie nameend++)
903840175f0Skstailey /* Do nothing. */ ;
904840175f0Skstailey
905840175f0Skstailey /* Test all long options for either exact match
906840175f0Skstailey or abbreviated matches. */
907840175f0Skstailey for (p = longopts, option_index = 0; p->name; p++, option_index++)
908*a1acfa9bSespie if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
909840175f0Skstailey {
910*a1acfa9bSespie if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
911840175f0Skstailey {
912840175f0Skstailey /* Exact match found. */
913840175f0Skstailey pfound = p;
914840175f0Skstailey indfound = option_index;
915840175f0Skstailey exact = 1;
916840175f0Skstailey break;
917840175f0Skstailey }
918840175f0Skstailey else if (pfound == NULL)
919840175f0Skstailey {
920840175f0Skstailey /* First nonexact match found. */
921840175f0Skstailey pfound = p;
922840175f0Skstailey indfound = option_index;
923840175f0Skstailey }
924840175f0Skstailey else
925840175f0Skstailey /* Second or later nonexact match found. */
926840175f0Skstailey ambig = 1;
927840175f0Skstailey }
928840175f0Skstailey if (ambig && !exact)
929840175f0Skstailey {
930*a1acfa9bSespie if (print_errors)
931*a1acfa9bSespie {
932*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
933*a1acfa9bSespie char *buf;
934*a1acfa9bSespie
935*a1acfa9bSespie if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
936*a1acfa9bSespie argv[0], argv[d->optind]) >= 0)
937*a1acfa9bSespie {
938*a1acfa9bSespie _IO_flockfile (stderr);
939*a1acfa9bSespie
940*a1acfa9bSespie int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
941*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
942*a1acfa9bSespie
943*a1acfa9bSespie if (_IO_fwide (stderr, 0) > 0)
944*a1acfa9bSespie __fwprintf (stderr, L"%s", buf);
945*a1acfa9bSespie else
946*a1acfa9bSespie fputs (buf, stderr);
947*a1acfa9bSespie
948*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 = old_flags2;
949*a1acfa9bSespie _IO_funlockfile (stderr);
950*a1acfa9bSespie
951*a1acfa9bSespie free (buf);
952*a1acfa9bSespie }
953*a1acfa9bSespie #else
954840175f0Skstailey fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
955*a1acfa9bSespie argv[0], argv[d->optind]);
956*a1acfa9bSespie #endif
957*a1acfa9bSespie }
958*a1acfa9bSespie d->__nextchar += strlen (d->__nextchar);
959*a1acfa9bSespie d->optind++;
960840175f0Skstailey return '?';
961840175f0Skstailey }
962840175f0Skstailey if (pfound != NULL)
963840175f0Skstailey {
964840175f0Skstailey option_index = indfound;
965840175f0Skstailey if (*nameend)
966840175f0Skstailey {
967840175f0Skstailey /* Don't test has_arg with >, because some C compilers don't
968840175f0Skstailey allow it to be used on enums. */
969840175f0Skstailey if (pfound->has_arg)
970*a1acfa9bSespie d->optarg = nameend + 1;
971840175f0Skstailey else
972840175f0Skstailey {
973*a1acfa9bSespie if (print_errors)
974*a1acfa9bSespie {
975*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
976*a1acfa9bSespie char *buf;
977*a1acfa9bSespie
978*a1acfa9bSespie if (__asprintf (&buf, _("\
979*a1acfa9bSespie %s: option `-W %s' doesn't allow an argument\n"),
980*a1acfa9bSespie argv[0], pfound->name) >= 0)
981*a1acfa9bSespie {
982*a1acfa9bSespie _IO_flockfile (stderr);
983*a1acfa9bSespie
984*a1acfa9bSespie int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
985*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2
986*a1acfa9bSespie |= _IO_FLAGS2_NOTCANCEL;
987*a1acfa9bSespie
988*a1acfa9bSespie if (_IO_fwide (stderr, 0) > 0)
989*a1acfa9bSespie __fwprintf (stderr, L"%s", buf);
990*a1acfa9bSespie else
991*a1acfa9bSespie fputs (buf, stderr);
992*a1acfa9bSespie
993*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 = old_flags2;
994*a1acfa9bSespie _IO_funlockfile (stderr);
995*a1acfa9bSespie
996*a1acfa9bSespie free (buf);
997*a1acfa9bSespie }
998*a1acfa9bSespie #else
999840175f0Skstailey fprintf (stderr, _("\
1000840175f0Skstailey %s: option `-W %s' doesn't allow an argument\n"),
1001840175f0Skstailey argv[0], pfound->name);
1002*a1acfa9bSespie #endif
1003*a1acfa9bSespie }
1004840175f0Skstailey
1005*a1acfa9bSespie d->__nextchar += strlen (d->__nextchar);
1006840175f0Skstailey return '?';
1007840175f0Skstailey }
1008840175f0Skstailey }
1009840175f0Skstailey else if (pfound->has_arg == 1)
1010840175f0Skstailey {
1011*a1acfa9bSespie if (d->optind < argc)
1012*a1acfa9bSespie d->optarg = argv[d->optind++];
1013840175f0Skstailey else
1014840175f0Skstailey {
1015*a1acfa9bSespie if (print_errors)
1016*a1acfa9bSespie {
1017*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
1018*a1acfa9bSespie char *buf;
1019*a1acfa9bSespie
1020*a1acfa9bSespie if (__asprintf (&buf, _("\
1021*a1acfa9bSespie %s: option `%s' requires an argument\n"),
1022*a1acfa9bSespie argv[0], argv[d->optind - 1]) >= 0)
1023*a1acfa9bSespie {
1024*a1acfa9bSespie _IO_flockfile (stderr);
1025*a1acfa9bSespie
1026*a1acfa9bSespie int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
1027*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2
1028*a1acfa9bSespie |= _IO_FLAGS2_NOTCANCEL;
1029*a1acfa9bSespie
1030*a1acfa9bSespie if (_IO_fwide (stderr, 0) > 0)
1031*a1acfa9bSespie __fwprintf (stderr, L"%s", buf);
1032*a1acfa9bSespie else
1033*a1acfa9bSespie fputs (buf, stderr);
1034*a1acfa9bSespie
1035*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 = old_flags2;
1036*a1acfa9bSespie _IO_funlockfile (stderr);
1037*a1acfa9bSespie
1038*a1acfa9bSespie free (buf);
1039*a1acfa9bSespie }
1040*a1acfa9bSespie #else
1041840175f0Skstailey fprintf (stderr,
1042840175f0Skstailey _("%s: option `%s' requires an argument\n"),
1043*a1acfa9bSespie argv[0], argv[d->optind - 1]);
1044*a1acfa9bSespie #endif
1045*a1acfa9bSespie }
1046*a1acfa9bSespie d->__nextchar += strlen (d->__nextchar);
1047840175f0Skstailey return optstring[0] == ':' ? ':' : '?';
1048840175f0Skstailey }
1049840175f0Skstailey }
1050*a1acfa9bSespie d->__nextchar += strlen (d->__nextchar);
1051840175f0Skstailey if (longind != NULL)
1052840175f0Skstailey *longind = option_index;
1053840175f0Skstailey if (pfound->flag)
1054840175f0Skstailey {
1055840175f0Skstailey *(pfound->flag) = pfound->val;
1056840175f0Skstailey return 0;
1057840175f0Skstailey }
1058840175f0Skstailey return pfound->val;
1059840175f0Skstailey }
1060*a1acfa9bSespie d->__nextchar = NULL;
1061840175f0Skstailey return 'W'; /* Let the application handle it. */
1062840175f0Skstailey }
1063840175f0Skstailey if (temp[1] == ':')
1064840175f0Skstailey {
1065840175f0Skstailey if (temp[2] == ':')
1066840175f0Skstailey {
1067840175f0Skstailey /* This is an option that accepts an argument optionally. */
1068*a1acfa9bSespie if (*d->__nextchar != '\0')
1069840175f0Skstailey {
1070*a1acfa9bSespie d->optarg = d->__nextchar;
1071*a1acfa9bSespie d->optind++;
1072840175f0Skstailey }
1073840175f0Skstailey else
1074*a1acfa9bSespie d->optarg = NULL;
1075*a1acfa9bSespie d->__nextchar = NULL;
1076840175f0Skstailey }
1077840175f0Skstailey else
1078840175f0Skstailey {
1079840175f0Skstailey /* This is an option that requires an argument. */
1080*a1acfa9bSespie if (*d->__nextchar != '\0')
1081840175f0Skstailey {
1082*a1acfa9bSespie d->optarg = d->__nextchar;
1083840175f0Skstailey /* If we end this ARGV-element by taking the rest as an arg,
1084840175f0Skstailey we must advance to the next element now. */
1085*a1acfa9bSespie d->optind++;
1086840175f0Skstailey }
1087*a1acfa9bSespie else if (d->optind == argc)
1088840175f0Skstailey {
1089*a1acfa9bSespie if (print_errors)
1090840175f0Skstailey {
1091840175f0Skstailey /* 1003.2 specifies the format of this message. */
1092*a1acfa9bSespie #if defined _LIBC && defined USE_IN_LIBIO
1093*a1acfa9bSespie char *buf;
1094*a1acfa9bSespie
1095*a1acfa9bSespie if (__asprintf (&buf, _("\
1096*a1acfa9bSespie %s: option requires an argument -- %c\n"),
1097*a1acfa9bSespie argv[0], c) >= 0)
1098*a1acfa9bSespie {
1099*a1acfa9bSespie _IO_flockfile (stderr);
1100*a1acfa9bSespie
1101*a1acfa9bSespie int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
1102*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
1103*a1acfa9bSespie
1104*a1acfa9bSespie if (_IO_fwide (stderr, 0) > 0)
1105*a1acfa9bSespie __fwprintf (stderr, L"%s", buf);
1106*a1acfa9bSespie else
1107*a1acfa9bSespie fputs (buf, stderr);
1108*a1acfa9bSespie
1109*a1acfa9bSespie ((_IO_FILE *) stderr)->_flags2 = old_flags2;
1110*a1acfa9bSespie _IO_funlockfile (stderr);
1111*a1acfa9bSespie
1112*a1acfa9bSespie free (buf);
1113*a1acfa9bSespie }
1114*a1acfa9bSespie #else
1115840175f0Skstailey fprintf (stderr,
1116840175f0Skstailey _("%s: option requires an argument -- %c\n"),
1117840175f0Skstailey argv[0], c);
1118*a1acfa9bSespie #endif
1119840175f0Skstailey }
1120*a1acfa9bSespie d->optopt = c;
1121840175f0Skstailey if (optstring[0] == ':')
1122840175f0Skstailey c = ':';
1123840175f0Skstailey else
1124840175f0Skstailey c = '?';
1125840175f0Skstailey }
1126840175f0Skstailey else
1127840175f0Skstailey /* We already incremented `optind' once;
1128840175f0Skstailey increment it again when taking next ARGV-elt as argument. */
1129*a1acfa9bSespie d->optarg = argv[d->optind++];
1130*a1acfa9bSespie d->__nextchar = NULL;
1131840175f0Skstailey }
1132840175f0Skstailey }
1133840175f0Skstailey return c;
1134840175f0Skstailey }
1135840175f0Skstailey }
1136840175f0Skstailey
1137840175f0Skstailey int
_getopt_internal(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,int long_only)1138*a1acfa9bSespie _getopt_internal (int argc, char *const *argv, const char *optstring,
1139*a1acfa9bSespie const struct option *longopts, int *longind, int long_only)
1140*a1acfa9bSespie {
1141*a1acfa9bSespie int result;
1142*a1acfa9bSespie
1143*a1acfa9bSespie getopt_data.optind = optind;
1144*a1acfa9bSespie getopt_data.opterr = opterr;
1145*a1acfa9bSespie
1146*a1acfa9bSespie result = _getopt_internal_r (argc, argv, optstring, longopts,
1147*a1acfa9bSespie longind, long_only, &getopt_data);
1148*a1acfa9bSespie
1149*a1acfa9bSespie optind = getopt_data.optind;
1150*a1acfa9bSespie optarg = getopt_data.optarg;
1151*a1acfa9bSespie optopt = getopt_data.optopt;
1152*a1acfa9bSespie
1153*a1acfa9bSespie return result;
1154*a1acfa9bSespie }
1155*a1acfa9bSespie
1156*a1acfa9bSespie int
getopt(int argc,char * const * argv,const char * optstring)1157*a1acfa9bSespie getopt (int argc, char *const *argv, const char *optstring)
1158840175f0Skstailey {
1159840175f0Skstailey return _getopt_internal (argc, argv, optstring,
1160840175f0Skstailey (const struct option *) 0,
1161840175f0Skstailey (int *) 0,
1162840175f0Skstailey 0);
1163840175f0Skstailey }
1164840175f0Skstailey
1165840175f0Skstailey
1166840175f0Skstailey #ifdef TEST
1167840175f0Skstailey
1168840175f0Skstailey /* Compile with -DTEST to make an executable for use in testing
1169840175f0Skstailey the above definition of `getopt'. */
1170840175f0Skstailey
1171840175f0Skstailey int
main(int argc,char ** argv)1172*a1acfa9bSespie main (int argc, char **argv)
1173840175f0Skstailey {
1174840175f0Skstailey int c;
1175840175f0Skstailey int digit_optind = 0;
1176840175f0Skstailey
1177840175f0Skstailey while (1)
1178840175f0Skstailey {
1179840175f0Skstailey int this_option_optind = optind ? optind : 1;
1180840175f0Skstailey
1181840175f0Skstailey c = getopt (argc, argv, "abc:d:0123456789");
1182840175f0Skstailey if (c == -1)
1183840175f0Skstailey break;
1184840175f0Skstailey
1185840175f0Skstailey switch (c)
1186840175f0Skstailey {
1187840175f0Skstailey case '0':
1188840175f0Skstailey case '1':
1189840175f0Skstailey case '2':
1190840175f0Skstailey case '3':
1191840175f0Skstailey case '4':
1192840175f0Skstailey case '5':
1193840175f0Skstailey case '6':
1194840175f0Skstailey case '7':
1195840175f0Skstailey case '8':
1196840175f0Skstailey case '9':
1197840175f0Skstailey if (digit_optind != 0 && digit_optind != this_option_optind)
1198840175f0Skstailey printf ("digits occur in two different argv-elements.\n");
1199840175f0Skstailey digit_optind = this_option_optind;
1200840175f0Skstailey printf ("option %c\n", c);
1201840175f0Skstailey break;
1202840175f0Skstailey
1203840175f0Skstailey case 'a':
1204840175f0Skstailey printf ("option a\n");
1205840175f0Skstailey break;
1206840175f0Skstailey
1207840175f0Skstailey case 'b':
1208840175f0Skstailey printf ("option b\n");
1209840175f0Skstailey break;
1210840175f0Skstailey
1211840175f0Skstailey case 'c':
1212840175f0Skstailey printf ("option c with value `%s'\n", optarg);
1213840175f0Skstailey break;
1214840175f0Skstailey
1215840175f0Skstailey case '?':
1216840175f0Skstailey break;
1217840175f0Skstailey
1218840175f0Skstailey default:
1219840175f0Skstailey printf ("?? getopt returned character code 0%o ??\n", c);
1220840175f0Skstailey }
1221840175f0Skstailey }
1222840175f0Skstailey
1223840175f0Skstailey if (optind < argc)
1224840175f0Skstailey {
1225840175f0Skstailey printf ("non-option ARGV-elements: ");
1226840175f0Skstailey while (optind < argc)
1227840175f0Skstailey printf ("%s ", argv[optind++]);
1228840175f0Skstailey printf ("\n");
1229840175f0Skstailey }
1230840175f0Skstailey
1231840175f0Skstailey exit (0);
1232840175f0Skstailey }
1233840175f0Skstailey
1234840175f0Skstailey #endif /* TEST */
1235