1*d3737e9cSchristos /* $NetBSD: getopt.c,v 1.2 2016/01/14 00:34:53 christos Exp $ */
229619d2aSchristos
329619d2aSchristos /* Getopt for GNU.
429619d2aSchristos NOTE: getopt is now part of the C library, so if you don't know what
529619d2aSchristos "Keep this file name-space clean" means, talk to drepper@gnu.org
629619d2aSchristos before changing it!
729619d2aSchristos Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004
829619d2aSchristos Free Software Foundation, Inc.
929619d2aSchristos This file is part of the GNU C Library.
1029619d2aSchristos
1129619d2aSchristos This program is free software; you can redistribute it and/or modify
1229619d2aSchristos it under the terms of the GNU General Public License as published by
1329619d2aSchristos the Free Software Foundation; either version 2, or (at your option)
1429619d2aSchristos any later version.
1529619d2aSchristos
1629619d2aSchristos This program is distributed in the hope that it will be useful,
1729619d2aSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1829619d2aSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1929619d2aSchristos GNU General Public License for more details.
2029619d2aSchristos
2129619d2aSchristos You should have received a copy of the GNU General Public License along
2229619d2aSchristos with this program; if not, write to the Free Software Foundation,
2329619d2aSchristos Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
2429619d2aSchristos
2529619d2aSchristos /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
2629619d2aSchristos Ditto for AIX 3.2 and <stdlib.h>. */
2729619d2aSchristos #ifndef _NO_PROTO
2829619d2aSchristos # define _NO_PROTO
2929619d2aSchristos #endif
3029619d2aSchristos
3129619d2aSchristos #ifdef HAVE_CONFIG_H
3229619d2aSchristos # include <config.h>
3329619d2aSchristos #endif
3429619d2aSchristos
3529619d2aSchristos #include <stdio.h>
3629619d2aSchristos
3729619d2aSchristos /* This needs to come after some library #include
3829619d2aSchristos to get __GNU_LIBRARY__ defined. */
3929619d2aSchristos #ifdef __GNU_LIBRARY__
4029619d2aSchristos /* Don't include stdlib.h for non-GNU C libraries because some of them
4129619d2aSchristos contain conflicting prototypes for getopt. */
4229619d2aSchristos # include <stdlib.h>
4329619d2aSchristos # include <unistd.h>
4429619d2aSchristos #endif /* GNU C library. */
4529619d2aSchristos
4629619d2aSchristos #include <string.h>
4729619d2aSchristos
4829619d2aSchristos #ifdef VMS
4929619d2aSchristos # include <unixlib.h>
5029619d2aSchristos #endif
5129619d2aSchristos
5229619d2aSchristos #ifdef _LIBC
5329619d2aSchristos # include <libintl.h>
5429619d2aSchristos #else
5529619d2aSchristos # include "gettext.h"
5629619d2aSchristos # define _(msgid) gettext (msgid)
5729619d2aSchristos #endif
5829619d2aSchristos
5929619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
6029619d2aSchristos # include <wchar.h>
6129619d2aSchristos #endif
6229619d2aSchristos
6329619d2aSchristos #ifndef attribute_hidden
6429619d2aSchristos # define attribute_hidden
6529619d2aSchristos #endif
6629619d2aSchristos
6729619d2aSchristos /* This version of `getopt' appears to the caller like standard Unix `getopt'
6829619d2aSchristos but it behaves differently for the user, since it allows the user
6929619d2aSchristos to intersperse the options with the other arguments.
7029619d2aSchristos
7129619d2aSchristos As `getopt' works, it permutes the elements of ARGV so that,
7229619d2aSchristos when it is done, all the options precede everything else. Thus
7329619d2aSchristos all application programs are extended to handle flexible argument order.
7429619d2aSchristos
7529619d2aSchristos Setting the environment variable POSIXLY_CORRECT disables permutation.
7629619d2aSchristos Then the behavior is completely standard.
7729619d2aSchristos
7829619d2aSchristos GNU application programs can use a third alternative mode in which
7929619d2aSchristos they can distinguish the relative order of options and other arguments. */
8029619d2aSchristos
8129619d2aSchristos #include "getopt.h"
8229619d2aSchristos #include "getopt_int.h"
8329619d2aSchristos
8429619d2aSchristos /* For communication from `getopt' to the caller.
8529619d2aSchristos When `getopt' finds an option that takes an argument,
8629619d2aSchristos the argument value is returned here.
8729619d2aSchristos Also, when `ordering' is RETURN_IN_ORDER,
8829619d2aSchristos each non-option ARGV-element is returned here. */
8929619d2aSchristos
9029619d2aSchristos char *optarg;
9129619d2aSchristos
9229619d2aSchristos /* Index in ARGV of the next element to be scanned.
9329619d2aSchristos This is used for communication to and from the caller
9429619d2aSchristos and for communication between successive calls to `getopt'.
9529619d2aSchristos
9629619d2aSchristos On entry to `getopt', zero means this is the first call; initialize.
9729619d2aSchristos
9829619d2aSchristos When `getopt' returns -1, this is the index of the first of the
9929619d2aSchristos non-option elements that the caller should itself scan.
10029619d2aSchristos
10129619d2aSchristos Otherwise, `optind' communicates from one call to the next
10229619d2aSchristos how much of ARGV has been scanned so far. */
10329619d2aSchristos
10429619d2aSchristos /* 1003.2 says this must be 1 before any call. */
10529619d2aSchristos int optind = 1;
10629619d2aSchristos
10729619d2aSchristos /* Callers store zero here to inhibit the error message
10829619d2aSchristos for unrecognized options. */
10929619d2aSchristos
11029619d2aSchristos int opterr = 1;
11129619d2aSchristos
11229619d2aSchristos /* Set to an option character which was unrecognized.
11329619d2aSchristos This must be initialized on some systems to avoid linking in the
11429619d2aSchristos system's own getopt implementation. */
11529619d2aSchristos
11629619d2aSchristos int optopt = '?';
11729619d2aSchristos
11829619d2aSchristos /* Keep a global copy of all internal members of getopt_data. */
11929619d2aSchristos
12029619d2aSchristos static struct _getopt_data getopt_data;
12129619d2aSchristos
12229619d2aSchristos
12329619d2aSchristos #ifndef __GNU_LIBRARY__
12429619d2aSchristos
12529619d2aSchristos /* Avoid depending on library functions or files
12629619d2aSchristos whose names are inconsistent. */
12729619d2aSchristos
12829619d2aSchristos #ifndef getenv
12929619d2aSchristos extern char *getenv ();
13029619d2aSchristos #endif
13129619d2aSchristos
13229619d2aSchristos #endif /* not __GNU_LIBRARY__ */
13329619d2aSchristos
13429619d2aSchristos #ifdef _LIBC
13529619d2aSchristos /* Stored original parameters.
13629619d2aSchristos XXX This is no good solution. We should rather copy the args so
13729619d2aSchristos that we can compare them later. But we must not use malloc(3). */
13829619d2aSchristos extern int __libc_argc;
13929619d2aSchristos extern char **__libc_argv;
14029619d2aSchristos
14129619d2aSchristos /* Bash 2.0 gives us an environment variable containing flags
14229619d2aSchristos indicating ARGV elements that should not be considered arguments. */
14329619d2aSchristos
14429619d2aSchristos # ifdef USE_NONOPTION_FLAGS
14529619d2aSchristos /* Defined in getopt_init.c */
14629619d2aSchristos extern char *__getopt_nonoption_flags;
14729619d2aSchristos # endif
14829619d2aSchristos
14929619d2aSchristos # ifdef USE_NONOPTION_FLAGS
15029619d2aSchristos # define SWAP_FLAGS(ch1, ch2) \
15129619d2aSchristos if (d->__nonoption_flags_len > 0) \
15229619d2aSchristos { \
15329619d2aSchristos char __tmp = __getopt_nonoption_flags[ch1]; \
15429619d2aSchristos __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
15529619d2aSchristos __getopt_nonoption_flags[ch2] = __tmp; \
15629619d2aSchristos }
15729619d2aSchristos # else
15829619d2aSchristos # define SWAP_FLAGS(ch1, ch2)
15929619d2aSchristos # endif
16029619d2aSchristos #else /* !_LIBC */
16129619d2aSchristos # define SWAP_FLAGS(ch1, ch2)
16229619d2aSchristos #endif /* _LIBC */
16329619d2aSchristos
16429619d2aSchristos /* Exchange two adjacent subsequences of ARGV.
16529619d2aSchristos One subsequence is elements [first_nonopt,last_nonopt)
16629619d2aSchristos which contains all the non-options that have been skipped so far.
16729619d2aSchristos The other is elements [last_nonopt,optind), which contains all
16829619d2aSchristos the options processed since those non-options were skipped.
16929619d2aSchristos
17029619d2aSchristos `first_nonopt' and `last_nonopt' are relocated so that they describe
17129619d2aSchristos the new indices of the non-options in ARGV after they are moved. */
17229619d2aSchristos
17329619d2aSchristos static void
exchange(char ** argv,struct _getopt_data * d)17429619d2aSchristos exchange (char **argv, struct _getopt_data *d)
17529619d2aSchristos {
17629619d2aSchristos int bottom = d->__first_nonopt;
17729619d2aSchristos int middle = d->__last_nonopt;
17829619d2aSchristos int top = d->optind;
17929619d2aSchristos char *tem;
18029619d2aSchristos
18129619d2aSchristos /* Exchange the shorter segment with the far end of the longer segment.
18229619d2aSchristos That puts the shorter segment into the right place.
18329619d2aSchristos It leaves the longer segment in the right place overall,
18429619d2aSchristos but it consists of two parts that need to be swapped next. */
18529619d2aSchristos
18629619d2aSchristos #if defined _LIBC && defined USE_NONOPTION_FLAGS
18729619d2aSchristos /* First make sure the handling of the `__getopt_nonoption_flags'
18829619d2aSchristos string can work normally. Our top argument must be in the range
18929619d2aSchristos of the string. */
19029619d2aSchristos if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
19129619d2aSchristos {
19229619d2aSchristos /* We must extend the array. The user plays games with us and
19329619d2aSchristos presents new arguments. */
19429619d2aSchristos char *new_str = malloc (top + 1);
19529619d2aSchristos if (new_str == NULL)
19629619d2aSchristos d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
19729619d2aSchristos else
19829619d2aSchristos {
19929619d2aSchristos memset (__mempcpy (new_str, __getopt_nonoption_flags,
20029619d2aSchristos d->__nonoption_flags_max_len),
20129619d2aSchristos '\0', top + 1 - d->__nonoption_flags_max_len);
20229619d2aSchristos d->__nonoption_flags_max_len = top + 1;
20329619d2aSchristos __getopt_nonoption_flags = new_str;
20429619d2aSchristos }
20529619d2aSchristos }
20629619d2aSchristos #endif
20729619d2aSchristos
20829619d2aSchristos while (top > middle && middle > bottom)
20929619d2aSchristos {
21029619d2aSchristos if (top - middle > middle - bottom)
21129619d2aSchristos {
21229619d2aSchristos /* Bottom segment is the short one. */
21329619d2aSchristos int len = middle - bottom;
21429619d2aSchristos register int i;
21529619d2aSchristos
21629619d2aSchristos /* Swap it with the top part of the top segment. */
21729619d2aSchristos for (i = 0; i < len; i++)
21829619d2aSchristos {
21929619d2aSchristos tem = argv[bottom + i];
22029619d2aSchristos argv[bottom + i] = argv[top - (middle - bottom) + i];
22129619d2aSchristos argv[top - (middle - bottom) + i] = tem;
22229619d2aSchristos SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
22329619d2aSchristos }
22429619d2aSchristos /* Exclude the moved bottom segment from further swapping. */
22529619d2aSchristos top -= len;
22629619d2aSchristos }
22729619d2aSchristos else
22829619d2aSchristos {
22929619d2aSchristos /* Top segment is the short one. */
23029619d2aSchristos int len = top - middle;
23129619d2aSchristos register int i;
23229619d2aSchristos
23329619d2aSchristos /* Swap it with the bottom part of the bottom segment. */
23429619d2aSchristos for (i = 0; i < len; i++)
23529619d2aSchristos {
23629619d2aSchristos tem = argv[bottom + i];
23729619d2aSchristos argv[bottom + i] = argv[middle + i];
23829619d2aSchristos argv[middle + i] = tem;
23929619d2aSchristos SWAP_FLAGS (bottom + i, middle + i);
24029619d2aSchristos }
24129619d2aSchristos /* Exclude the moved top segment from further swapping. */
24229619d2aSchristos bottom += len;
24329619d2aSchristos }
24429619d2aSchristos }
24529619d2aSchristos
24629619d2aSchristos /* Update records for the slots the non-options now occupy. */
24729619d2aSchristos
24829619d2aSchristos d->__first_nonopt += (d->optind - d->__last_nonopt);
24929619d2aSchristos d->__last_nonopt = d->optind;
25029619d2aSchristos }
25129619d2aSchristos
25229619d2aSchristos /* Initialize the internal data when the first call is made. */
25329619d2aSchristos
25429619d2aSchristos static const char *
_getopt_initialize(int argc,char * const * argv,const char * optstring,struct _getopt_data * d)25529619d2aSchristos _getopt_initialize (int argc, char *const *argv, const char *optstring,
25629619d2aSchristos struct _getopt_data *d)
25729619d2aSchristos {
25829619d2aSchristos /* Start processing options with ARGV-element 1 (since ARGV-element 0
25929619d2aSchristos is the program name); the sequence of previously skipped
26029619d2aSchristos non-option ARGV-elements is empty. */
26129619d2aSchristos
26229619d2aSchristos d->__first_nonopt = d->__last_nonopt = d->optind;
26329619d2aSchristos
26429619d2aSchristos d->__nextchar = NULL;
26529619d2aSchristos
26629619d2aSchristos d->__posixly_correct = !!getenv ("POSIXLY_CORRECT");
26729619d2aSchristos
26829619d2aSchristos /* Determine how to handle the ordering of options and nonoptions. */
26929619d2aSchristos
27029619d2aSchristos if (optstring[0] == '-')
27129619d2aSchristos {
27229619d2aSchristos d->__ordering = RETURN_IN_ORDER;
27329619d2aSchristos ++optstring;
27429619d2aSchristos }
27529619d2aSchristos else if (optstring[0] == '+')
27629619d2aSchristos {
27729619d2aSchristos d->__ordering = REQUIRE_ORDER;
27829619d2aSchristos ++optstring;
27929619d2aSchristos }
28029619d2aSchristos else if (d->__posixly_correct)
28129619d2aSchristos d->__ordering = REQUIRE_ORDER;
28229619d2aSchristos else
28329619d2aSchristos d->__ordering = PERMUTE;
28429619d2aSchristos
28529619d2aSchristos #if defined _LIBC && defined USE_NONOPTION_FLAGS
28629619d2aSchristos if (!d->__posixly_correct
28729619d2aSchristos && argc == __libc_argc && argv == __libc_argv)
28829619d2aSchristos {
28929619d2aSchristos if (d->__nonoption_flags_max_len == 0)
29029619d2aSchristos {
29129619d2aSchristos if (__getopt_nonoption_flags == NULL
29229619d2aSchristos || __getopt_nonoption_flags[0] == '\0')
29329619d2aSchristos d->__nonoption_flags_max_len = -1;
29429619d2aSchristos else
29529619d2aSchristos {
29629619d2aSchristos const char *orig_str = __getopt_nonoption_flags;
29729619d2aSchristos int len = d->__nonoption_flags_max_len = strlen (orig_str);
29829619d2aSchristos if (d->__nonoption_flags_max_len < argc)
29929619d2aSchristos d->__nonoption_flags_max_len = argc;
30029619d2aSchristos __getopt_nonoption_flags =
30129619d2aSchristos (char *) malloc (d->__nonoption_flags_max_len);
30229619d2aSchristos if (__getopt_nonoption_flags == NULL)
30329619d2aSchristos d->__nonoption_flags_max_len = -1;
30429619d2aSchristos else
30529619d2aSchristos memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
30629619d2aSchristos '\0', d->__nonoption_flags_max_len - len);
30729619d2aSchristos }
30829619d2aSchristos }
30929619d2aSchristos d->__nonoption_flags_len = d->__nonoption_flags_max_len;
31029619d2aSchristos }
31129619d2aSchristos else
31229619d2aSchristos d->__nonoption_flags_len = 0;
31329619d2aSchristos #endif
31429619d2aSchristos
31529619d2aSchristos return optstring;
31629619d2aSchristos }
31729619d2aSchristos
31829619d2aSchristos /* Scan elements of ARGV (whose length is ARGC) for option characters
31929619d2aSchristos given in OPTSTRING.
32029619d2aSchristos
32129619d2aSchristos If an element of ARGV starts with '-', and is not exactly "-" or "--",
32229619d2aSchristos then it is an option element. The characters of this element
32329619d2aSchristos (aside from the initial '-') are option characters. If `getopt'
32429619d2aSchristos is called repeatedly, it returns successively each of the option characters
32529619d2aSchristos from each of the option elements.
32629619d2aSchristos
32729619d2aSchristos If `getopt' finds another option character, it returns that character,
32829619d2aSchristos updating `optind' and `nextchar' so that the next call to `getopt' can
32929619d2aSchristos resume the scan with the following option character or ARGV-element.
33029619d2aSchristos
33129619d2aSchristos If there are no more option characters, `getopt' returns -1.
33229619d2aSchristos Then `optind' is the index in ARGV of the first ARGV-element
33329619d2aSchristos that is not an option. (The ARGV-elements have been permuted
33429619d2aSchristos so that those that are not options now come last.)
33529619d2aSchristos
33629619d2aSchristos OPTSTRING is a string containing the legitimate option characters.
33729619d2aSchristos If an option character is seen that is not listed in OPTSTRING,
33829619d2aSchristos return '?' after printing an error message. If you set `opterr' to
33929619d2aSchristos zero, the error message is suppressed but we still return '?'.
34029619d2aSchristos
34129619d2aSchristos If a char in OPTSTRING is followed by a colon, that means it wants an arg,
34229619d2aSchristos so the following text in the same ARGV-element, or the text of the following
34329619d2aSchristos ARGV-element, is returned in `optarg'. Two colons mean an option that
34429619d2aSchristos wants an optional arg; if there is text in the current ARGV-element,
34529619d2aSchristos it is returned in `optarg', otherwise `optarg' is set to zero.
34629619d2aSchristos
34729619d2aSchristos If OPTSTRING starts with `-' or `+', it requests different methods of
34829619d2aSchristos handling the non-option ARGV-elements.
34929619d2aSchristos See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
35029619d2aSchristos
35129619d2aSchristos Long-named options begin with `--' instead of `-'.
35229619d2aSchristos Their names may be abbreviated as long as the abbreviation is unique
35329619d2aSchristos or is an exact match for some defined option. If they have an
35429619d2aSchristos argument, it follows the option name in the same ARGV-element, separated
35529619d2aSchristos from the option name by a `=', or else the in next ARGV-element.
35629619d2aSchristos When `getopt' finds a long-named option, it returns 0 if that option's
35729619d2aSchristos `flag' field is nonzero, the value of the option's `val' field
35829619d2aSchristos if the `flag' field is zero.
35929619d2aSchristos
36029619d2aSchristos The elements of ARGV aren't really const, because we permute them.
36129619d2aSchristos But we pretend they're const in the prototype to be compatible
36229619d2aSchristos with other systems.
36329619d2aSchristos
36429619d2aSchristos LONGOPTS is a vector of `struct option' terminated by an
36529619d2aSchristos element containing a name which is zero.
36629619d2aSchristos
36729619d2aSchristos LONGIND returns the index in LONGOPT of the long-named option found.
36829619d2aSchristos It is only valid when a long-named option has been found by the most
36929619d2aSchristos recent call.
37029619d2aSchristos
37129619d2aSchristos If LONG_ONLY is nonzero, '-' as well as '--' can introduce
37229619d2aSchristos long-named options. */
37329619d2aSchristos
37429619d2aSchristos 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)37529619d2aSchristos _getopt_internal_r (int argc, char *const *argv, const char *optstring,
37629619d2aSchristos const struct option *longopts, int *longind,
37729619d2aSchristos int long_only, struct _getopt_data *d)
37829619d2aSchristos {
37929619d2aSchristos int print_errors = d->opterr;
38029619d2aSchristos if (optstring[0] == ':')
38129619d2aSchristos print_errors = 0;
38229619d2aSchristos
38329619d2aSchristos if (argc < 1)
38429619d2aSchristos return -1;
38529619d2aSchristos
38629619d2aSchristos d->optarg = NULL;
38729619d2aSchristos
38829619d2aSchristos if (d->optind == 0 || !d->__initialized)
38929619d2aSchristos {
39029619d2aSchristos if (d->optind == 0)
39129619d2aSchristos d->optind = 1; /* Don't scan ARGV[0], the program name. */
39229619d2aSchristos optstring = _getopt_initialize (argc, argv, optstring, d);
39329619d2aSchristos d->__initialized = 1;
39429619d2aSchristos }
39529619d2aSchristos
39629619d2aSchristos /* Test whether ARGV[optind] points to a non-option argument.
39729619d2aSchristos Either it does not have option syntax, or there is an environment flag
39829619d2aSchristos from the shell indicating it is not an option. The later information
39929619d2aSchristos is only used when the used in the GNU libc. */
40029619d2aSchristos #if defined _LIBC && defined USE_NONOPTION_FLAGS
40129619d2aSchristos # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \
40229619d2aSchristos || (d->optind < d->__nonoption_flags_len \
40329619d2aSchristos && __getopt_nonoption_flags[d->optind] == '1'))
40429619d2aSchristos #else
40529619d2aSchristos # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
40629619d2aSchristos #endif
40729619d2aSchristos
40829619d2aSchristos if (d->__nextchar == NULL || *d->__nextchar == '\0')
40929619d2aSchristos {
41029619d2aSchristos /* Advance to the next ARGV-element. */
41129619d2aSchristos
41229619d2aSchristos /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
41329619d2aSchristos moved back by the user (who may also have changed the arguments). */
41429619d2aSchristos if (d->__last_nonopt > d->optind)
41529619d2aSchristos d->__last_nonopt = d->optind;
41629619d2aSchristos if (d->__first_nonopt > d->optind)
41729619d2aSchristos d->__first_nonopt = d->optind;
41829619d2aSchristos
41929619d2aSchristos if (d->__ordering == PERMUTE)
42029619d2aSchristos {
42129619d2aSchristos /* If we have just processed some options following some non-options,
42229619d2aSchristos exchange them so that the options come first. */
42329619d2aSchristos
42429619d2aSchristos if (d->__first_nonopt != d->__last_nonopt
42529619d2aSchristos && d->__last_nonopt != d->optind)
42629619d2aSchristos exchange ((char **) argv, d);
42729619d2aSchristos else if (d->__last_nonopt != d->optind)
42829619d2aSchristos d->__first_nonopt = d->optind;
42929619d2aSchristos
43029619d2aSchristos /* Skip any additional non-options
43129619d2aSchristos and extend the range of non-options previously skipped. */
43229619d2aSchristos
43329619d2aSchristos while (d->optind < argc && NONOPTION_P)
43429619d2aSchristos d->optind++;
43529619d2aSchristos d->__last_nonopt = d->optind;
43629619d2aSchristos }
43729619d2aSchristos
43829619d2aSchristos /* The special ARGV-element `--' means premature end of options.
43929619d2aSchristos Skip it like a null option,
44029619d2aSchristos then exchange with previous non-options as if it were an option,
44129619d2aSchristos then skip everything else like a non-option. */
44229619d2aSchristos
44329619d2aSchristos if (d->optind != argc && !strcmp (argv[d->optind], "--"))
44429619d2aSchristos {
44529619d2aSchristos d->optind++;
44629619d2aSchristos
44729619d2aSchristos if (d->__first_nonopt != d->__last_nonopt
44829619d2aSchristos && d->__last_nonopt != d->optind)
44929619d2aSchristos exchange ((char **) argv, d);
45029619d2aSchristos else if (d->__first_nonopt == d->__last_nonopt)
45129619d2aSchristos d->__first_nonopt = d->optind;
45229619d2aSchristos d->__last_nonopt = argc;
45329619d2aSchristos
45429619d2aSchristos d->optind = argc;
45529619d2aSchristos }
45629619d2aSchristos
45729619d2aSchristos /* If we have done all the ARGV-elements, stop the scan
45829619d2aSchristos and back over any non-options that we skipped and permuted. */
45929619d2aSchristos
46029619d2aSchristos if (d->optind == argc)
46129619d2aSchristos {
46229619d2aSchristos /* Set the next-arg-index to point at the non-options
46329619d2aSchristos that we previously skipped, so the caller will digest them. */
46429619d2aSchristos if (d->__first_nonopt != d->__last_nonopt)
46529619d2aSchristos d->optind = d->__first_nonopt;
46629619d2aSchristos return -1;
46729619d2aSchristos }
46829619d2aSchristos
46929619d2aSchristos /* If we have come to a non-option and did not permute it,
47029619d2aSchristos either stop the scan or describe it to the caller and pass it by. */
47129619d2aSchristos
47229619d2aSchristos if (NONOPTION_P)
47329619d2aSchristos {
47429619d2aSchristos if (d->__ordering == REQUIRE_ORDER)
47529619d2aSchristos return -1;
47629619d2aSchristos d->optarg = argv[d->optind++];
47729619d2aSchristos return 1;
47829619d2aSchristos }
47929619d2aSchristos
48029619d2aSchristos /* We have found another option-ARGV-element.
48129619d2aSchristos Skip the initial punctuation. */
48229619d2aSchristos
48329619d2aSchristos d->__nextchar = (argv[d->optind] + 1
48429619d2aSchristos + (longopts != NULL && argv[d->optind][1] == '-'));
48529619d2aSchristos }
48629619d2aSchristos
48729619d2aSchristos /* Decode the current option-ARGV-element. */
48829619d2aSchristos
48929619d2aSchristos /* Check whether the ARGV-element is a long option.
49029619d2aSchristos
49129619d2aSchristos If long_only and the ARGV-element has the form "-f", where f is
49229619d2aSchristos a valid short option, don't consider it an abbreviated form of
49329619d2aSchristos a long option that starts with f. Otherwise there would be no
49429619d2aSchristos way to give the -f short option.
49529619d2aSchristos
49629619d2aSchristos On the other hand, if there's a long option "fubar" and
49729619d2aSchristos the ARGV-element is "-fu", do consider that an abbreviation of
49829619d2aSchristos the long option, just like "--fu", and not "-f" with arg "u".
49929619d2aSchristos
50029619d2aSchristos This distinction seems to be the most useful approach. */
50129619d2aSchristos
50229619d2aSchristos if (longopts != NULL
50329619d2aSchristos && (argv[d->optind][1] == '-'
50429619d2aSchristos || (long_only && (argv[d->optind][2]
50529619d2aSchristos || !strchr (optstring, argv[d->optind][1])))))
50629619d2aSchristos {
50729619d2aSchristos char *nameend;
50829619d2aSchristos const struct option *p;
50929619d2aSchristos const struct option *pfound = NULL;
51029619d2aSchristos int exact = 0;
51129619d2aSchristos int ambig = 0;
51229619d2aSchristos int indfound = -1;
51329619d2aSchristos int option_index;
51429619d2aSchristos
51529619d2aSchristos for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
51629619d2aSchristos /* Do nothing. */ ;
51729619d2aSchristos
51829619d2aSchristos /* Test all long options for either exact match
51929619d2aSchristos or abbreviated matches. */
52029619d2aSchristos for (p = longopts, option_index = 0; p->name; p++, option_index++)
52129619d2aSchristos if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
52229619d2aSchristos {
52329619d2aSchristos if ((unsigned int) (nameend - d->__nextchar)
52429619d2aSchristos == (unsigned int) strlen (p->name))
52529619d2aSchristos {
52629619d2aSchristos /* Exact match found. */
52729619d2aSchristos pfound = p;
52829619d2aSchristos indfound = option_index;
52929619d2aSchristos exact = 1;
53029619d2aSchristos break;
53129619d2aSchristos }
53229619d2aSchristos else if (pfound == NULL)
53329619d2aSchristos {
53429619d2aSchristos /* First nonexact match found. */
53529619d2aSchristos pfound = p;
53629619d2aSchristos indfound = option_index;
53729619d2aSchristos }
53829619d2aSchristos else if (long_only
53929619d2aSchristos || pfound->has_arg != p->has_arg
54029619d2aSchristos || pfound->flag != p->flag
54129619d2aSchristos || pfound->val != p->val)
54229619d2aSchristos /* Second or later nonexact match found. */
54329619d2aSchristos ambig = 1;
54429619d2aSchristos }
54529619d2aSchristos
54629619d2aSchristos if (ambig && !exact)
54729619d2aSchristos {
54829619d2aSchristos if (print_errors)
54929619d2aSchristos {
55029619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
55129619d2aSchristos char *buf;
55229619d2aSchristos
55329619d2aSchristos if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
55429619d2aSchristos argv[0], argv[d->optind]) >= 0)
55529619d2aSchristos {
55629619d2aSchristos _IO_flockfile (stderr);
55729619d2aSchristos
55829619d2aSchristos int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
55929619d2aSchristos ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
56029619d2aSchristos
56129619d2aSchristos if (_IO_fwide (stderr, 0) > 0)
56229619d2aSchristos __fwprintf (stderr, L"%s", buf);
56329619d2aSchristos else
56429619d2aSchristos fputs (buf, stderr);
56529619d2aSchristos
56629619d2aSchristos ((_IO_FILE *) stderr)->_flags2 = old_flags2;
56729619d2aSchristos _IO_funlockfile (stderr);
56829619d2aSchristos
56929619d2aSchristos free (buf);
57029619d2aSchristos }
57129619d2aSchristos #else
57229619d2aSchristos fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
57329619d2aSchristos argv[0], argv[d->optind]);
57429619d2aSchristos #endif
57529619d2aSchristos }
57629619d2aSchristos d->__nextchar += strlen (d->__nextchar);
57729619d2aSchristos d->optind++;
57829619d2aSchristos d->optopt = 0;
57929619d2aSchristos return '?';
58029619d2aSchristos }
58129619d2aSchristos
58229619d2aSchristos if (pfound != NULL)
58329619d2aSchristos {
58429619d2aSchristos option_index = indfound;
58529619d2aSchristos d->optind++;
58629619d2aSchristos if (*nameend)
58729619d2aSchristos {
58829619d2aSchristos /* Don't test has_arg with >, because some C compilers don't
58929619d2aSchristos allow it to be used on enums. */
59029619d2aSchristos if (pfound->has_arg)
59129619d2aSchristos d->optarg = nameend + 1;
59229619d2aSchristos else
59329619d2aSchristos {
59429619d2aSchristos if (print_errors)
59529619d2aSchristos {
59629619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
59729619d2aSchristos char *buf;
59829619d2aSchristos int n;
59929619d2aSchristos #endif
60029619d2aSchristos
60129619d2aSchristos if (argv[d->optind - 1][1] == '-')
60229619d2aSchristos {
60329619d2aSchristos /* --option */
60429619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
60529619d2aSchristos n = __asprintf (&buf, _("\
60629619d2aSchristos %s: option `--%s' doesn't allow an argument\n"),
60729619d2aSchristos argv[0], pfound->name);
60829619d2aSchristos #else
60929619d2aSchristos fprintf (stderr, _("\
61029619d2aSchristos %s: option `--%s' doesn't allow an argument\n"),
61129619d2aSchristos argv[0], pfound->name);
61229619d2aSchristos #endif
61329619d2aSchristos }
61429619d2aSchristos else
61529619d2aSchristos {
61629619d2aSchristos /* +option or -option */
61729619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
61829619d2aSchristos n = __asprintf (&buf, _("\
61929619d2aSchristos %s: option `%c%s' doesn't allow an argument\n"),
62029619d2aSchristos argv[0], argv[d->optind - 1][0],
62129619d2aSchristos pfound->name);
62229619d2aSchristos #else
62329619d2aSchristos fprintf (stderr, _("\
62429619d2aSchristos %s: option `%c%s' doesn't allow an argument\n"),
62529619d2aSchristos argv[0], argv[d->optind - 1][0],
62629619d2aSchristos pfound->name);
62729619d2aSchristos #endif
62829619d2aSchristos }
62929619d2aSchristos
63029619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
63129619d2aSchristos if (n >= 0)
63229619d2aSchristos {
63329619d2aSchristos _IO_flockfile (stderr);
63429619d2aSchristos
63529619d2aSchristos int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
63629619d2aSchristos ((_IO_FILE *) stderr)->_flags2
63729619d2aSchristos |= _IO_FLAGS2_NOTCANCEL;
63829619d2aSchristos
63929619d2aSchristos if (_IO_fwide (stderr, 0) > 0)
64029619d2aSchristos __fwprintf (stderr, L"%s", buf);
64129619d2aSchristos else
64229619d2aSchristos fputs (buf, stderr);
64329619d2aSchristos
64429619d2aSchristos ((_IO_FILE *) stderr)->_flags2 = old_flags2;
64529619d2aSchristos _IO_funlockfile (stderr);
64629619d2aSchristos
64729619d2aSchristos free (buf);
64829619d2aSchristos }
64929619d2aSchristos #endif
65029619d2aSchristos }
65129619d2aSchristos
65229619d2aSchristos d->__nextchar += strlen (d->__nextchar);
65329619d2aSchristos
65429619d2aSchristos d->optopt = pfound->val;
65529619d2aSchristos return '?';
65629619d2aSchristos }
65729619d2aSchristos }
65829619d2aSchristos else if (pfound->has_arg == 1)
65929619d2aSchristos {
66029619d2aSchristos if (d->optind < argc)
66129619d2aSchristos d->optarg = argv[d->optind++];
66229619d2aSchristos else
66329619d2aSchristos {
66429619d2aSchristos if (print_errors)
66529619d2aSchristos {
66629619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
66729619d2aSchristos char *buf;
66829619d2aSchristos
66929619d2aSchristos if (__asprintf (&buf, _("\
67029619d2aSchristos %s: option `%s' requires an argument\n"),
67129619d2aSchristos argv[0], argv[d->optind - 1]) >= 0)
67229619d2aSchristos {
67329619d2aSchristos _IO_flockfile (stderr);
67429619d2aSchristos
67529619d2aSchristos int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
67629619d2aSchristos ((_IO_FILE *) stderr)->_flags2
67729619d2aSchristos |= _IO_FLAGS2_NOTCANCEL;
67829619d2aSchristos
67929619d2aSchristos if (_IO_fwide (stderr, 0) > 0)
68029619d2aSchristos __fwprintf (stderr, L"%s", buf);
68129619d2aSchristos else
68229619d2aSchristos fputs (buf, stderr);
68329619d2aSchristos
68429619d2aSchristos ((_IO_FILE *) stderr)->_flags2 = old_flags2;
68529619d2aSchristos _IO_funlockfile (stderr);
68629619d2aSchristos
68729619d2aSchristos free (buf);
68829619d2aSchristos }
68929619d2aSchristos #else
69029619d2aSchristos fprintf (stderr,
69129619d2aSchristos _("%s: option `%s' requires an argument\n"),
69229619d2aSchristos argv[0], argv[d->optind - 1]);
69329619d2aSchristos #endif
69429619d2aSchristos }
69529619d2aSchristos d->__nextchar += strlen (d->__nextchar);
69629619d2aSchristos d->optopt = pfound->val;
69729619d2aSchristos return optstring[0] == ':' ? ':' : '?';
69829619d2aSchristos }
69929619d2aSchristos }
70029619d2aSchristos d->__nextchar += strlen (d->__nextchar);
70129619d2aSchristos if (longind != NULL)
70229619d2aSchristos *longind = option_index;
70329619d2aSchristos if (pfound->flag)
70429619d2aSchristos {
70529619d2aSchristos *(pfound->flag) = pfound->val;
70629619d2aSchristos return 0;
70729619d2aSchristos }
70829619d2aSchristos return pfound->val;
70929619d2aSchristos }
71029619d2aSchristos
71129619d2aSchristos /* Can't find it as a long option. If this is not getopt_long_only,
71229619d2aSchristos or the option starts with '--' or is not a valid short
71329619d2aSchristos option, then it's an error.
71429619d2aSchristos Otherwise interpret it as a short option. */
71529619d2aSchristos if (!long_only || argv[d->optind][1] == '-'
71629619d2aSchristos || strchr (optstring, *d->__nextchar) == NULL)
71729619d2aSchristos {
71829619d2aSchristos if (print_errors)
71929619d2aSchristos {
72029619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
72129619d2aSchristos char *buf;
72229619d2aSchristos int n;
72329619d2aSchristos #endif
72429619d2aSchristos
72529619d2aSchristos if (argv[d->optind][1] == '-')
72629619d2aSchristos {
72729619d2aSchristos /* --option */
72829619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
72929619d2aSchristos n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
73029619d2aSchristos argv[0], d->__nextchar);
73129619d2aSchristos #else
73229619d2aSchristos fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
73329619d2aSchristos argv[0], d->__nextchar);
73429619d2aSchristos #endif
73529619d2aSchristos }
73629619d2aSchristos else
73729619d2aSchristos {
73829619d2aSchristos /* +option or -option */
73929619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
74029619d2aSchristos n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
74129619d2aSchristos argv[0], argv[d->optind][0], d->__nextchar);
74229619d2aSchristos #else
74329619d2aSchristos fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
74429619d2aSchristos argv[0], argv[d->optind][0], d->__nextchar);
74529619d2aSchristos #endif
74629619d2aSchristos }
74729619d2aSchristos
74829619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
74929619d2aSchristos if (n >= 0)
75029619d2aSchristos {
75129619d2aSchristos _IO_flockfile (stderr);
75229619d2aSchristos
75329619d2aSchristos int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
75429619d2aSchristos ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
75529619d2aSchristos
75629619d2aSchristos if (_IO_fwide (stderr, 0) > 0)
75729619d2aSchristos __fwprintf (stderr, L"%s", buf);
75829619d2aSchristos else
75929619d2aSchristos fputs (buf, stderr);
76029619d2aSchristos
76129619d2aSchristos ((_IO_FILE *) stderr)->_flags2 = old_flags2;
76229619d2aSchristos _IO_funlockfile (stderr);
76329619d2aSchristos
76429619d2aSchristos free (buf);
76529619d2aSchristos }
76629619d2aSchristos #endif
76729619d2aSchristos }
76829619d2aSchristos d->__nextchar = (char *) "";
76929619d2aSchristos d->optind++;
77029619d2aSchristos d->optopt = 0;
77129619d2aSchristos return '?';
77229619d2aSchristos }
77329619d2aSchristos }
77429619d2aSchristos
77529619d2aSchristos /* Look at and handle the next short option-character. */
77629619d2aSchristos
77729619d2aSchristos {
77829619d2aSchristos char c = *d->__nextchar++;
77929619d2aSchristos char *temp = strchr (optstring, c);
78029619d2aSchristos
78129619d2aSchristos /* Increment `optind' when we start to process its last character. */
78229619d2aSchristos if (*d->__nextchar == '\0')
78329619d2aSchristos ++d->optind;
78429619d2aSchristos
78529619d2aSchristos if (temp == NULL || c == ':')
78629619d2aSchristos {
78729619d2aSchristos if (print_errors)
78829619d2aSchristos {
78929619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
79029619d2aSchristos char *buf;
79129619d2aSchristos int n;
79229619d2aSchristos #endif
79329619d2aSchristos
79429619d2aSchristos if (d->__posixly_correct)
79529619d2aSchristos {
79629619d2aSchristos /* 1003.2 specifies the format of this message. */
79729619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
79829619d2aSchristos n = __asprintf (&buf, _("%s: illegal option -- %c\n"),
79929619d2aSchristos argv[0], c);
80029619d2aSchristos #else
80129619d2aSchristos fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
80229619d2aSchristos #endif
80329619d2aSchristos }
80429619d2aSchristos else
80529619d2aSchristos {
80629619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
80729619d2aSchristos n = __asprintf (&buf, _("%s: invalid option -- %c\n"),
80829619d2aSchristos argv[0], c);
80929619d2aSchristos #else
81029619d2aSchristos fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
81129619d2aSchristos #endif
81229619d2aSchristos }
81329619d2aSchristos
81429619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
81529619d2aSchristos if (n >= 0)
81629619d2aSchristos {
81729619d2aSchristos _IO_flockfile (stderr);
81829619d2aSchristos
81929619d2aSchristos int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
82029619d2aSchristos ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
82129619d2aSchristos
82229619d2aSchristos if (_IO_fwide (stderr, 0) > 0)
82329619d2aSchristos __fwprintf (stderr, L"%s", buf);
82429619d2aSchristos else
82529619d2aSchristos fputs (buf, stderr);
82629619d2aSchristos
82729619d2aSchristos ((_IO_FILE *) stderr)->_flags2 = old_flags2;
82829619d2aSchristos _IO_funlockfile (stderr);
82929619d2aSchristos
83029619d2aSchristos free (buf);
83129619d2aSchristos }
83229619d2aSchristos #endif
83329619d2aSchristos }
83429619d2aSchristos d->optopt = c;
83529619d2aSchristos return '?';
83629619d2aSchristos }
83729619d2aSchristos /* Convenience. Treat POSIX -W foo same as long option --foo */
83829619d2aSchristos if (temp[0] == 'W' && temp[1] == ';')
83929619d2aSchristos {
84029619d2aSchristos char *nameend;
84129619d2aSchristos const struct option *p;
84229619d2aSchristos const struct option *pfound = NULL;
84329619d2aSchristos int exact = 0;
84429619d2aSchristos int ambig = 0;
84529619d2aSchristos int indfound = 0;
84629619d2aSchristos int option_index;
84729619d2aSchristos
84829619d2aSchristos /* This is an option that requires an argument. */
84929619d2aSchristos if (*d->__nextchar != '\0')
85029619d2aSchristos {
85129619d2aSchristos d->optarg = d->__nextchar;
85229619d2aSchristos /* If we end this ARGV-element by taking the rest as an arg,
85329619d2aSchristos we must advance to the next element now. */
85429619d2aSchristos d->optind++;
85529619d2aSchristos }
85629619d2aSchristos else if (d->optind == argc)
85729619d2aSchristos {
85829619d2aSchristos if (print_errors)
85929619d2aSchristos {
86029619d2aSchristos /* 1003.2 specifies the format of this message. */
86129619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
86229619d2aSchristos char *buf;
86329619d2aSchristos
86429619d2aSchristos if (__asprintf (&buf,
86529619d2aSchristos _("%s: option requires an argument -- %c\n"),
86629619d2aSchristos argv[0], c) >= 0)
86729619d2aSchristos {
86829619d2aSchristos _IO_flockfile (stderr);
86929619d2aSchristos
87029619d2aSchristos int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
87129619d2aSchristos ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
87229619d2aSchristos
87329619d2aSchristos if (_IO_fwide (stderr, 0) > 0)
87429619d2aSchristos __fwprintf (stderr, L"%s", buf);
87529619d2aSchristos else
87629619d2aSchristos fputs (buf, stderr);
87729619d2aSchristos
87829619d2aSchristos ((_IO_FILE *) stderr)->_flags2 = old_flags2;
87929619d2aSchristos _IO_funlockfile (stderr);
88029619d2aSchristos
88129619d2aSchristos free (buf);
88229619d2aSchristos }
88329619d2aSchristos #else
88429619d2aSchristos fprintf (stderr, _("%s: option requires an argument -- %c\n"),
88529619d2aSchristos argv[0], c);
88629619d2aSchristos #endif
88729619d2aSchristos }
88829619d2aSchristos d->optopt = c;
88929619d2aSchristos if (optstring[0] == ':')
89029619d2aSchristos c = ':';
89129619d2aSchristos else
89229619d2aSchristos c = '?';
89329619d2aSchristos return c;
89429619d2aSchristos }
89529619d2aSchristos else
89629619d2aSchristos /* We already incremented `d->optind' once;
89729619d2aSchristos increment it again when taking next ARGV-elt as argument. */
89829619d2aSchristos d->optarg = argv[d->optind++];
89929619d2aSchristos
90029619d2aSchristos /* optarg is now the argument, see if it's in the
90129619d2aSchristos table of longopts. */
90229619d2aSchristos
90329619d2aSchristos for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
90429619d2aSchristos nameend++)
90529619d2aSchristos /* Do nothing. */ ;
90629619d2aSchristos
90729619d2aSchristos /* Test all long options for either exact match
90829619d2aSchristos or abbreviated matches. */
90929619d2aSchristos for (p = longopts, option_index = 0; p->name; p++, option_index++)
91029619d2aSchristos if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
91129619d2aSchristos {
91229619d2aSchristos if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
91329619d2aSchristos {
91429619d2aSchristos /* Exact match found. */
91529619d2aSchristos pfound = p;
91629619d2aSchristos indfound = option_index;
91729619d2aSchristos exact = 1;
91829619d2aSchristos break;
91929619d2aSchristos }
92029619d2aSchristos else if (pfound == NULL)
92129619d2aSchristos {
92229619d2aSchristos /* First nonexact match found. */
92329619d2aSchristos pfound = p;
92429619d2aSchristos indfound = option_index;
92529619d2aSchristos }
92629619d2aSchristos else
92729619d2aSchristos /* Second or later nonexact match found. */
92829619d2aSchristos ambig = 1;
92929619d2aSchristos }
93029619d2aSchristos if (ambig && !exact)
93129619d2aSchristos {
93229619d2aSchristos if (print_errors)
93329619d2aSchristos {
93429619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
93529619d2aSchristos char *buf;
93629619d2aSchristos
93729619d2aSchristos if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
93829619d2aSchristos argv[0], argv[d->optind]) >= 0)
93929619d2aSchristos {
94029619d2aSchristos _IO_flockfile (stderr);
94129619d2aSchristos
94229619d2aSchristos int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
94329619d2aSchristos ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
94429619d2aSchristos
94529619d2aSchristos if (_IO_fwide (stderr, 0) > 0)
94629619d2aSchristos __fwprintf (stderr, L"%s", buf);
94729619d2aSchristos else
94829619d2aSchristos fputs (buf, stderr);
94929619d2aSchristos
95029619d2aSchristos ((_IO_FILE *) stderr)->_flags2 = old_flags2;
95129619d2aSchristos _IO_funlockfile (stderr);
95229619d2aSchristos
95329619d2aSchristos free (buf);
95429619d2aSchristos }
95529619d2aSchristos #else
95629619d2aSchristos fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
95729619d2aSchristos argv[0], argv[d->optind]);
95829619d2aSchristos #endif
95929619d2aSchristos }
96029619d2aSchristos d->__nextchar += strlen (d->__nextchar);
96129619d2aSchristos d->optind++;
96229619d2aSchristos return '?';
96329619d2aSchristos }
96429619d2aSchristos if (pfound != NULL)
96529619d2aSchristos {
96629619d2aSchristos option_index = indfound;
96729619d2aSchristos if (*nameend)
96829619d2aSchristos {
96929619d2aSchristos /* Don't test has_arg with >, because some C compilers don't
97029619d2aSchristos allow it to be used on enums. */
97129619d2aSchristos if (pfound->has_arg)
97229619d2aSchristos d->optarg = nameend + 1;
97329619d2aSchristos else
97429619d2aSchristos {
97529619d2aSchristos if (print_errors)
97629619d2aSchristos {
97729619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
97829619d2aSchristos char *buf;
97929619d2aSchristos
98029619d2aSchristos if (__asprintf (&buf, _("\
98129619d2aSchristos %s: option `-W %s' doesn't allow an argument\n"),
98229619d2aSchristos argv[0], pfound->name) >= 0)
98329619d2aSchristos {
98429619d2aSchristos _IO_flockfile (stderr);
98529619d2aSchristos
98629619d2aSchristos int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
98729619d2aSchristos ((_IO_FILE *) stderr)->_flags2
98829619d2aSchristos |= _IO_FLAGS2_NOTCANCEL;
98929619d2aSchristos
99029619d2aSchristos if (_IO_fwide (stderr, 0) > 0)
99129619d2aSchristos __fwprintf (stderr, L"%s", buf);
99229619d2aSchristos else
99329619d2aSchristos fputs (buf, stderr);
99429619d2aSchristos
99529619d2aSchristos ((_IO_FILE *) stderr)->_flags2 = old_flags2;
99629619d2aSchristos _IO_funlockfile (stderr);
99729619d2aSchristos
99829619d2aSchristos free (buf);
99929619d2aSchristos }
100029619d2aSchristos #else
100129619d2aSchristos fprintf (stderr, _("\
100229619d2aSchristos %s: option `-W %s' doesn't allow an argument\n"),
100329619d2aSchristos argv[0], pfound->name);
100429619d2aSchristos #endif
100529619d2aSchristos }
100629619d2aSchristos
100729619d2aSchristos d->__nextchar += strlen (d->__nextchar);
100829619d2aSchristos return '?';
100929619d2aSchristos }
101029619d2aSchristos }
101129619d2aSchristos else if (pfound->has_arg == 1)
101229619d2aSchristos {
101329619d2aSchristos if (d->optind < argc)
101429619d2aSchristos d->optarg = argv[d->optind++];
101529619d2aSchristos else
101629619d2aSchristos {
101729619d2aSchristos if (print_errors)
101829619d2aSchristos {
101929619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
102029619d2aSchristos char *buf;
102129619d2aSchristos
102229619d2aSchristos if (__asprintf (&buf, _("\
102329619d2aSchristos %s: option `%s' requires an argument\n"),
102429619d2aSchristos argv[0], argv[d->optind - 1]) >= 0)
102529619d2aSchristos {
102629619d2aSchristos _IO_flockfile (stderr);
102729619d2aSchristos
102829619d2aSchristos int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
102929619d2aSchristos ((_IO_FILE *) stderr)->_flags2
103029619d2aSchristos |= _IO_FLAGS2_NOTCANCEL;
103129619d2aSchristos
103229619d2aSchristos if (_IO_fwide (stderr, 0) > 0)
103329619d2aSchristos __fwprintf (stderr, L"%s", buf);
103429619d2aSchristos else
103529619d2aSchristos fputs (buf, stderr);
103629619d2aSchristos
103729619d2aSchristos ((_IO_FILE *) stderr)->_flags2 = old_flags2;
103829619d2aSchristos _IO_funlockfile (stderr);
103929619d2aSchristos
104029619d2aSchristos free (buf);
104129619d2aSchristos }
104229619d2aSchristos #else
104329619d2aSchristos fprintf (stderr,
104429619d2aSchristos _("%s: option `%s' requires an argument\n"),
104529619d2aSchristos argv[0], argv[d->optind - 1]);
104629619d2aSchristos #endif
104729619d2aSchristos }
104829619d2aSchristos d->__nextchar += strlen (d->__nextchar);
104929619d2aSchristos return optstring[0] == ':' ? ':' : '?';
105029619d2aSchristos }
105129619d2aSchristos }
105229619d2aSchristos d->__nextchar += strlen (d->__nextchar);
105329619d2aSchristos if (longind != NULL)
105429619d2aSchristos *longind = option_index;
105529619d2aSchristos if (pfound->flag)
105629619d2aSchristos {
105729619d2aSchristos *(pfound->flag) = pfound->val;
105829619d2aSchristos return 0;
105929619d2aSchristos }
106029619d2aSchristos return pfound->val;
106129619d2aSchristos }
106229619d2aSchristos d->__nextchar = NULL;
106329619d2aSchristos return 'W'; /* Let the application handle it. */
106429619d2aSchristos }
106529619d2aSchristos if (temp[1] == ':')
106629619d2aSchristos {
106729619d2aSchristos if (temp[2] == ':')
106829619d2aSchristos {
106929619d2aSchristos /* This is an option that accepts an argument optionally. */
107029619d2aSchristos if (*d->__nextchar != '\0')
107129619d2aSchristos {
107229619d2aSchristos d->optarg = d->__nextchar;
107329619d2aSchristos d->optind++;
107429619d2aSchristos }
107529619d2aSchristos else
107629619d2aSchristos d->optarg = NULL;
107729619d2aSchristos d->__nextchar = NULL;
107829619d2aSchristos }
107929619d2aSchristos else
108029619d2aSchristos {
108129619d2aSchristos /* This is an option that requires an argument. */
108229619d2aSchristos if (*d->__nextchar != '\0')
108329619d2aSchristos {
108429619d2aSchristos d->optarg = d->__nextchar;
108529619d2aSchristos /* If we end this ARGV-element by taking the rest as an arg,
108629619d2aSchristos we must advance to the next element now. */
108729619d2aSchristos d->optind++;
108829619d2aSchristos }
108929619d2aSchristos else if (d->optind == argc)
109029619d2aSchristos {
109129619d2aSchristos if (print_errors)
109229619d2aSchristos {
109329619d2aSchristos /* 1003.2 specifies the format of this message. */
109429619d2aSchristos #if defined _LIBC && defined USE_IN_LIBIO
109529619d2aSchristos char *buf;
109629619d2aSchristos
109729619d2aSchristos if (__asprintf (&buf, _("\
109829619d2aSchristos %s: option requires an argument -- %c\n"),
109929619d2aSchristos argv[0], c) >= 0)
110029619d2aSchristos {
110129619d2aSchristos _IO_flockfile (stderr);
110229619d2aSchristos
110329619d2aSchristos int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
110429619d2aSchristos ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
110529619d2aSchristos
110629619d2aSchristos if (_IO_fwide (stderr, 0) > 0)
110729619d2aSchristos __fwprintf (stderr, L"%s", buf);
110829619d2aSchristos else
110929619d2aSchristos fputs (buf, stderr);
111029619d2aSchristos
111129619d2aSchristos ((_IO_FILE *) stderr)->_flags2 = old_flags2;
111229619d2aSchristos _IO_funlockfile (stderr);
111329619d2aSchristos
111429619d2aSchristos free (buf);
111529619d2aSchristos }
111629619d2aSchristos #else
111729619d2aSchristos fprintf (stderr,
111829619d2aSchristos _("%s: option requires an argument -- %c\n"),
111929619d2aSchristos argv[0], c);
112029619d2aSchristos #endif
112129619d2aSchristos }
112229619d2aSchristos d->optopt = c;
112329619d2aSchristos if (optstring[0] == ':')
112429619d2aSchristos c = ':';
112529619d2aSchristos else
112629619d2aSchristos c = '?';
112729619d2aSchristos }
112829619d2aSchristos else
112929619d2aSchristos /* We already incremented `optind' once;
113029619d2aSchristos increment it again when taking next ARGV-elt as argument. */
113129619d2aSchristos d->optarg = argv[d->optind++];
113229619d2aSchristos d->__nextchar = NULL;
113329619d2aSchristos }
113429619d2aSchristos }
113529619d2aSchristos return c;
113629619d2aSchristos }
113729619d2aSchristos }
113829619d2aSchristos
113929619d2aSchristos int
_getopt_internal(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,int long_only)114029619d2aSchristos _getopt_internal (int argc, char *const *argv, const char *optstring,
114129619d2aSchristos const struct option *longopts, int *longind, int long_only)
114229619d2aSchristos {
114329619d2aSchristos int result;
114429619d2aSchristos
114529619d2aSchristos getopt_data.optind = optind;
114629619d2aSchristos getopt_data.opterr = opterr;
114729619d2aSchristos
114829619d2aSchristos result = _getopt_internal_r (argc, argv, optstring, longopts,
114929619d2aSchristos longind, long_only, &getopt_data);
115029619d2aSchristos
115129619d2aSchristos optind = getopt_data.optind;
115229619d2aSchristos optarg = getopt_data.optarg;
115329619d2aSchristos optopt = getopt_data.optopt;
115429619d2aSchristos
115529619d2aSchristos return result;
115629619d2aSchristos }
115729619d2aSchristos
115829619d2aSchristos int
getopt(int argc,char * const * argv,const char * optstring)115929619d2aSchristos getopt (int argc, char *const *argv, const char *optstring)
116029619d2aSchristos {
116129619d2aSchristos return _getopt_internal (argc, argv, optstring,
116229619d2aSchristos (const struct option *) 0,
116329619d2aSchristos (int *) 0,
116429619d2aSchristos 0);
116529619d2aSchristos }
116629619d2aSchristos
116729619d2aSchristos
116829619d2aSchristos #ifdef TEST
116929619d2aSchristos
117029619d2aSchristos /* Compile with -DTEST to make an executable for use in testing
117129619d2aSchristos the above definition of `getopt'. */
117229619d2aSchristos
117329619d2aSchristos int
main(int argc,char ** argv)117429619d2aSchristos main (int argc, char **argv)
117529619d2aSchristos {
117629619d2aSchristos int c;
117729619d2aSchristos int digit_optind = 0;
117829619d2aSchristos
117929619d2aSchristos while (1)
118029619d2aSchristos {
118129619d2aSchristos int this_option_optind = optind ? optind : 1;
118229619d2aSchristos
118329619d2aSchristos c = getopt (argc, argv, "abc:d:0123456789");
118429619d2aSchristos if (c == -1)
118529619d2aSchristos break;
118629619d2aSchristos
118729619d2aSchristos switch (c)
118829619d2aSchristos {
118929619d2aSchristos case '0':
119029619d2aSchristos case '1':
119129619d2aSchristos case '2':
119229619d2aSchristos case '3':
119329619d2aSchristos case '4':
119429619d2aSchristos case '5':
119529619d2aSchristos case '6':
119629619d2aSchristos case '7':
119729619d2aSchristos case '8':
119829619d2aSchristos case '9':
119929619d2aSchristos if (digit_optind != 0 && digit_optind != this_option_optind)
120029619d2aSchristos printf ("digits occur in two different argv-elements.\n");
120129619d2aSchristos digit_optind = this_option_optind;
120229619d2aSchristos printf ("option %c\n", c);
120329619d2aSchristos break;
120429619d2aSchristos
120529619d2aSchristos case 'a':
120629619d2aSchristos printf ("option a\n");
120729619d2aSchristos break;
120829619d2aSchristos
120929619d2aSchristos case 'b':
121029619d2aSchristos printf ("option b\n");
121129619d2aSchristos break;
121229619d2aSchristos
121329619d2aSchristos case 'c':
121429619d2aSchristos printf ("option c with value `%s'\n", optarg);
121529619d2aSchristos break;
121629619d2aSchristos
121729619d2aSchristos case '?':
121829619d2aSchristos break;
121929619d2aSchristos
122029619d2aSchristos default:
122129619d2aSchristos printf ("?? getopt returned character code 0%o ??\n", c);
122229619d2aSchristos }
122329619d2aSchristos }
122429619d2aSchristos
122529619d2aSchristos if (optind < argc)
122629619d2aSchristos {
122729619d2aSchristos printf ("non-option ARGV-elements: ");
122829619d2aSchristos while (optind < argc)
122929619d2aSchristos printf ("%s ", argv[optind++]);
123029619d2aSchristos printf ("\n");
123129619d2aSchristos }
123229619d2aSchristos
123329619d2aSchristos exit (0);
123429619d2aSchristos }
123529619d2aSchristos
123629619d2aSchristos #endif /* TEST */
1237