195b7b453SJohn Marino /* Getopt for GNU.
2*09d4459fSDaniel Fojt Copyright (C) 1987-2020 Free Software Foundation, Inc.
3*09d4459fSDaniel Fojt This file is part of the GNU C Library and is also part of gnulib.
4*09d4459fSDaniel Fojt Patches to this file should be submitted to both projects.
595b7b453SJohn Marino
6*09d4459fSDaniel Fojt The GNU C Library is free software; you can redistribute it and/or
7*09d4459fSDaniel Fojt modify it under the terms of the GNU General Public
8*09d4459fSDaniel Fojt License as published by the Free Software Foundation; either
9*09d4459fSDaniel Fojt version 3 of the License, or (at your option) any later version.
1095b7b453SJohn Marino
11*09d4459fSDaniel Fojt The GNU C Library is distributed in the hope that it will be useful,
1295b7b453SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
13*09d4459fSDaniel Fojt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14*09d4459fSDaniel Fojt General Public License for more details.
1595b7b453SJohn Marino
16*09d4459fSDaniel Fojt You should have received a copy of the GNU General Public
17*09d4459fSDaniel Fojt License along with the GNU C Library; if not, see
18*09d4459fSDaniel Fojt <https://www.gnu.org/licenses/>. */
1995b7b453SJohn Marino
2095b7b453SJohn Marino #ifndef _LIBC
2195b7b453SJohn Marino # include <config.h>
2295b7b453SJohn Marino #endif
2395b7b453SJohn Marino
2495b7b453SJohn Marino #include "getopt.h"
2595b7b453SJohn Marino
2695b7b453SJohn Marino #include <stdio.h>
2795b7b453SJohn Marino #include <stdlib.h>
2895b7b453SJohn Marino #include <string.h>
2995b7b453SJohn Marino #include <unistd.h>
3095b7b453SJohn Marino
3195b7b453SJohn Marino #ifdef _LIBC
32*09d4459fSDaniel Fojt /* When used as part of glibc, error printing must be done differently
33*09d4459fSDaniel Fojt for standards compliance. getopt is not a cancellation point, so
34*09d4459fSDaniel Fojt it must not call functions that are, and it is specified by an
35*09d4459fSDaniel Fojt older standard than stdio locking, so it must not refer to
36*09d4459fSDaniel Fojt functions in the "user namespace" related to stdio locking.
37*09d4459fSDaniel Fojt Finally, it must use glibc's internal message translation so that
38*09d4459fSDaniel Fojt the messages are looked up in the proper text domain. */
3995b7b453SJohn Marino # include <libintl.h>
40*09d4459fSDaniel Fojt # define fprintf __fxprintf_nocancel
41*09d4459fSDaniel Fojt # define flockfile(fp) _IO_flockfile (fp)
42*09d4459fSDaniel Fojt # define funlockfile(fp) _IO_funlockfile (fp)
4395b7b453SJohn Marino #else
4495b7b453SJohn Marino # include "gettext.h"
4595b7b453SJohn Marino # define _(msgid) gettext (msgid)
46*09d4459fSDaniel Fojt /* When used standalone, flockfile and funlockfile might not be
47*09d4459fSDaniel Fojt available. */
48*09d4459fSDaniel Fojt # if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \
49*09d4459fSDaniel Fojt || (defined _WIN32 && ! defined __CYGWIN__))
50*09d4459fSDaniel Fojt # define flockfile(fp) /* nop */
51*09d4459fSDaniel Fojt # define funlockfile(fp) /* nop */
52*09d4459fSDaniel Fojt # endif
53*09d4459fSDaniel Fojt /* When used standalone, do not attempt to use alloca. */
54*09d4459fSDaniel Fojt # define __libc_use_alloca(size) 0
55*09d4459fSDaniel Fojt # undef alloca
56*09d4459fSDaniel Fojt # define alloca(size) (abort (), (void *)0)
5795b7b453SJohn Marino #endif
5895b7b453SJohn Marino
59*09d4459fSDaniel Fojt /* This implementation of 'getopt' has three modes for handling
60*09d4459fSDaniel Fojt options interspersed with non-option arguments. It can stop
61*09d4459fSDaniel Fojt scanning for options at the first non-option argument encountered,
62*09d4459fSDaniel Fojt as POSIX specifies. It can continue scanning for options after the
63*09d4459fSDaniel Fojt first non-option argument, but permute 'argv' as it goes so that,
64*09d4459fSDaniel Fojt after 'getopt' is done, all the options precede all the non-option
65*09d4459fSDaniel Fojt arguments and 'optind' points to the first non-option argument.
66*09d4459fSDaniel Fojt Or, it can report non-option arguments as if they were arguments to
67*09d4459fSDaniel Fojt the option character '\x01'.
6895b7b453SJohn Marino
69*09d4459fSDaniel Fojt The default behavior of 'getopt_long' is to permute the argument list.
70*09d4459fSDaniel Fojt When this implementation is used standalone, the default behavior of
71*09d4459fSDaniel Fojt 'getopt' is to stop at the first non-option argument, but when it is
72*09d4459fSDaniel Fojt used as part of GNU libc it also permutes the argument list. In both
73*09d4459fSDaniel Fojt cases, setting the environment variable POSIXLY_CORRECT to any value
7495b7b453SJohn Marino disables permutation.
7595b7b453SJohn Marino
76*09d4459fSDaniel Fojt If the first character of the OPTSTRING argument to 'getopt' or
77*09d4459fSDaniel Fojt 'getopt_long' is '+', both functions will stop at the first
78*09d4459fSDaniel Fojt non-option argument. If it is '-', both functions will report
79*09d4459fSDaniel Fojt non-option arguments as arguments to the option character '\x01'. */
8095b7b453SJohn Marino
8195b7b453SJohn Marino #include "getopt_int.h"
8295b7b453SJohn Marino
83cf28ed85SJohn Marino /* For communication from 'getopt' to the caller.
84cf28ed85SJohn Marino When 'getopt' finds an option that takes an argument,
8595b7b453SJohn Marino the argument value is returned here.
86cf28ed85SJohn Marino Also, when 'ordering' is RETURN_IN_ORDER,
8795b7b453SJohn Marino each non-option ARGV-element is returned here. */
8895b7b453SJohn Marino
8995b7b453SJohn Marino char *optarg;
9095b7b453SJohn Marino
9195b7b453SJohn Marino /* Index in ARGV of the next element to be scanned.
9295b7b453SJohn Marino This is used for communication to and from the caller
93cf28ed85SJohn Marino and for communication between successive calls to 'getopt'.
9495b7b453SJohn Marino
95cf28ed85SJohn Marino On entry to 'getopt', zero means this is the first call; initialize.
9695b7b453SJohn Marino
97cf28ed85SJohn Marino When 'getopt' returns -1, this is the index of the first of the
9895b7b453SJohn Marino non-option elements that the caller should itself scan.
9995b7b453SJohn Marino
100cf28ed85SJohn Marino Otherwise, 'optind' communicates from one call to the next
10195b7b453SJohn Marino how much of ARGV has been scanned so far. */
10295b7b453SJohn Marino
10395b7b453SJohn Marino /* 1003.2 says this must be 1 before any call. */
10495b7b453SJohn Marino int optind = 1;
10595b7b453SJohn Marino
10695b7b453SJohn Marino /* Callers store zero here to inhibit the error message
10795b7b453SJohn Marino for unrecognized options. */
10895b7b453SJohn Marino
10995b7b453SJohn Marino int opterr = 1;
11095b7b453SJohn Marino
11195b7b453SJohn Marino /* Set to an option character which was unrecognized.
11295b7b453SJohn Marino This must be initialized on some systems to avoid linking in the
11395b7b453SJohn Marino system's own getopt implementation. */
11495b7b453SJohn Marino
11595b7b453SJohn Marino int optopt = '?';
11695b7b453SJohn Marino
11795b7b453SJohn Marino /* Keep a global copy of all internal members of getopt_data. */
11895b7b453SJohn Marino
11995b7b453SJohn Marino static struct _getopt_data getopt_data;
12095b7b453SJohn Marino
12195b7b453SJohn Marino /* Exchange two adjacent subsequences of ARGV.
12295b7b453SJohn Marino One subsequence is elements [first_nonopt,last_nonopt)
12395b7b453SJohn Marino which contains all the non-options that have been skipped so far.
12495b7b453SJohn Marino The other is elements [last_nonopt,optind), which contains all
12595b7b453SJohn Marino the options processed since those non-options were skipped.
12695b7b453SJohn Marino
127cf28ed85SJohn Marino 'first_nonopt' and 'last_nonopt' are relocated so that they describe
12895b7b453SJohn Marino the new indices of the non-options in ARGV after they are moved. */
12995b7b453SJohn Marino
13095b7b453SJohn Marino static void
exchange(char ** argv,struct _getopt_data * d)13195b7b453SJohn Marino exchange (char **argv, struct _getopt_data *d)
13295b7b453SJohn Marino {
13395b7b453SJohn Marino int bottom = d->__first_nonopt;
13495b7b453SJohn Marino int middle = d->__last_nonopt;
13595b7b453SJohn Marino int top = d->optind;
13695b7b453SJohn Marino char *tem;
13795b7b453SJohn Marino
13895b7b453SJohn Marino /* Exchange the shorter segment with the far end of the longer segment.
13995b7b453SJohn Marino That puts the shorter segment into the right place.
14095b7b453SJohn Marino It leaves the longer segment in the right place overall,
14195b7b453SJohn Marino but it consists of two parts that need to be swapped next. */
14295b7b453SJohn Marino
14395b7b453SJohn Marino while (top > middle && middle > bottom)
14495b7b453SJohn Marino {
14595b7b453SJohn Marino if (top - middle > middle - bottom)
14695b7b453SJohn Marino {
14795b7b453SJohn Marino /* Bottom segment is the short one. */
14895b7b453SJohn Marino int len = middle - bottom;
149*09d4459fSDaniel Fojt int i;
15095b7b453SJohn Marino
15195b7b453SJohn Marino /* Swap it with the top part of the top segment. */
15295b7b453SJohn Marino for (i = 0; i < len; i++)
15395b7b453SJohn Marino {
15495b7b453SJohn Marino tem = argv[bottom + i];
15595b7b453SJohn Marino argv[bottom + i] = argv[top - (middle - bottom) + i];
15695b7b453SJohn Marino argv[top - (middle - bottom) + i] = tem;
15795b7b453SJohn Marino }
15895b7b453SJohn Marino /* Exclude the moved bottom segment from further swapping. */
15995b7b453SJohn Marino top -= len;
16095b7b453SJohn Marino }
16195b7b453SJohn Marino else
16295b7b453SJohn Marino {
16395b7b453SJohn Marino /* Top segment is the short one. */
16495b7b453SJohn Marino int len = top - middle;
165*09d4459fSDaniel Fojt int i;
16695b7b453SJohn Marino
16795b7b453SJohn Marino /* Swap it with the bottom part of the bottom segment. */
16895b7b453SJohn Marino for (i = 0; i < len; i++)
16995b7b453SJohn Marino {
17095b7b453SJohn Marino tem = argv[bottom + i];
17195b7b453SJohn Marino argv[bottom + i] = argv[middle + i];
17295b7b453SJohn Marino argv[middle + i] = tem;
17395b7b453SJohn Marino }
17495b7b453SJohn Marino /* Exclude the moved top segment from further swapping. */
17595b7b453SJohn Marino bottom += len;
17695b7b453SJohn Marino }
17795b7b453SJohn Marino }
17895b7b453SJohn Marino
17995b7b453SJohn Marino /* Update records for the slots the non-options now occupy. */
18095b7b453SJohn Marino
18195b7b453SJohn Marino d->__first_nonopt += (d->optind - d->__last_nonopt);
18295b7b453SJohn Marino d->__last_nonopt = d->optind;
18395b7b453SJohn Marino }
18495b7b453SJohn Marino
185*09d4459fSDaniel Fojt /* Process the argument starting with d->__nextchar as a long option.
186*09d4459fSDaniel Fojt d->optind should *not* have been advanced over this argument.
187*09d4459fSDaniel Fojt
188*09d4459fSDaniel Fojt If the value returned is -1, it was not actually a long option, the
189*09d4459fSDaniel Fojt state is unchanged, and the argument should be processed as a set
190*09d4459fSDaniel Fojt of short options (this can only happen when long_only is true).
191*09d4459fSDaniel Fojt Otherwise, the option (and its argument, if any) have been consumed
192*09d4459fSDaniel Fojt and the return value is the value to return from _getopt_internal_r. */
193*09d4459fSDaniel Fojt static int
process_long_option(int argc,char ** argv,const char * optstring,const struct option * longopts,int * longind,int long_only,struct _getopt_data * d,int print_errors,const char * prefix)194*09d4459fSDaniel Fojt process_long_option (int argc, char **argv, const char *optstring,
195*09d4459fSDaniel Fojt const struct option *longopts, int *longind,
196*09d4459fSDaniel Fojt int long_only, struct _getopt_data *d,
197*09d4459fSDaniel Fojt int print_errors, const char *prefix)
198*09d4459fSDaniel Fojt {
199*09d4459fSDaniel Fojt char *nameend;
200*09d4459fSDaniel Fojt size_t namelen;
201*09d4459fSDaniel Fojt const struct option *p;
202*09d4459fSDaniel Fojt const struct option *pfound = NULL;
203*09d4459fSDaniel Fojt int n_options;
204*09d4459fSDaniel Fojt int option_index;
205*09d4459fSDaniel Fojt
206*09d4459fSDaniel Fojt for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
207*09d4459fSDaniel Fojt /* Do nothing. */ ;
208*09d4459fSDaniel Fojt namelen = nameend - d->__nextchar;
209*09d4459fSDaniel Fojt
210*09d4459fSDaniel Fojt /* First look for an exact match, counting the options as a side
211*09d4459fSDaniel Fojt effect. */
212*09d4459fSDaniel Fojt for (p = longopts, n_options = 0; p->name; p++, n_options++)
213*09d4459fSDaniel Fojt if (!strncmp (p->name, d->__nextchar, namelen)
214*09d4459fSDaniel Fojt && namelen == strlen (p->name))
215*09d4459fSDaniel Fojt {
216*09d4459fSDaniel Fojt /* Exact match found. */
217*09d4459fSDaniel Fojt pfound = p;
218*09d4459fSDaniel Fojt option_index = n_options;
219*09d4459fSDaniel Fojt break;
220*09d4459fSDaniel Fojt }
221*09d4459fSDaniel Fojt
222*09d4459fSDaniel Fojt if (pfound == NULL)
223*09d4459fSDaniel Fojt {
224*09d4459fSDaniel Fojt /* Didn't find an exact match, so look for abbreviations. */
225*09d4459fSDaniel Fojt unsigned char *ambig_set = NULL;
226*09d4459fSDaniel Fojt int ambig_malloced = 0;
227*09d4459fSDaniel Fojt int ambig_fallback = 0;
228*09d4459fSDaniel Fojt int indfound = -1;
229*09d4459fSDaniel Fojt
230*09d4459fSDaniel Fojt for (p = longopts, option_index = 0; p->name; p++, option_index++)
231*09d4459fSDaniel Fojt if (!strncmp (p->name, d->__nextchar, namelen))
232*09d4459fSDaniel Fojt {
233*09d4459fSDaniel Fojt if (pfound == NULL)
234*09d4459fSDaniel Fojt {
235*09d4459fSDaniel Fojt /* First nonexact match found. */
236*09d4459fSDaniel Fojt pfound = p;
237*09d4459fSDaniel Fojt indfound = option_index;
238*09d4459fSDaniel Fojt }
239*09d4459fSDaniel Fojt else if (long_only
240*09d4459fSDaniel Fojt || pfound->has_arg != p->has_arg
241*09d4459fSDaniel Fojt || pfound->flag != p->flag
242*09d4459fSDaniel Fojt || pfound->val != p->val)
243*09d4459fSDaniel Fojt {
244*09d4459fSDaniel Fojt /* Second or later nonexact match found. */
245*09d4459fSDaniel Fojt if (!ambig_fallback)
246*09d4459fSDaniel Fojt {
247*09d4459fSDaniel Fojt if (!print_errors)
248*09d4459fSDaniel Fojt /* Don't waste effort tracking the ambig set if
249*09d4459fSDaniel Fojt we're not going to print it anyway. */
250*09d4459fSDaniel Fojt ambig_fallback = 1;
251*09d4459fSDaniel Fojt else if (!ambig_set)
252*09d4459fSDaniel Fojt {
253*09d4459fSDaniel Fojt if (__libc_use_alloca (n_options))
254*09d4459fSDaniel Fojt ambig_set = alloca (n_options);
255*09d4459fSDaniel Fojt else if ((ambig_set = malloc (n_options)) == NULL)
256*09d4459fSDaniel Fojt /* Fall back to simpler error message. */
257*09d4459fSDaniel Fojt ambig_fallback = 1;
258*09d4459fSDaniel Fojt else
259*09d4459fSDaniel Fojt ambig_malloced = 1;
260*09d4459fSDaniel Fojt
261*09d4459fSDaniel Fojt if (ambig_set)
262*09d4459fSDaniel Fojt {
263*09d4459fSDaniel Fojt memset (ambig_set, 0, n_options);
264*09d4459fSDaniel Fojt ambig_set[indfound] = 1;
265*09d4459fSDaniel Fojt }
266*09d4459fSDaniel Fojt }
267*09d4459fSDaniel Fojt if (ambig_set)
268*09d4459fSDaniel Fojt ambig_set[option_index] = 1;
269*09d4459fSDaniel Fojt }
270*09d4459fSDaniel Fojt }
271*09d4459fSDaniel Fojt }
272*09d4459fSDaniel Fojt
273*09d4459fSDaniel Fojt if (ambig_set || ambig_fallback)
274*09d4459fSDaniel Fojt {
275*09d4459fSDaniel Fojt if (print_errors)
276*09d4459fSDaniel Fojt {
277*09d4459fSDaniel Fojt if (ambig_fallback)
278*09d4459fSDaniel Fojt fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"),
279*09d4459fSDaniel Fojt argv[0], prefix, d->__nextchar);
280*09d4459fSDaniel Fojt else
281*09d4459fSDaniel Fojt {
282*09d4459fSDaniel Fojt flockfile (stderr);
283*09d4459fSDaniel Fojt fprintf (stderr,
284*09d4459fSDaniel Fojt _("%s: option '%s%s' is ambiguous; possibilities:"),
285*09d4459fSDaniel Fojt argv[0], prefix, d->__nextchar);
286*09d4459fSDaniel Fojt
287*09d4459fSDaniel Fojt for (option_index = 0; option_index < n_options; option_index++)
288*09d4459fSDaniel Fojt if (ambig_set[option_index])
289*09d4459fSDaniel Fojt fprintf (stderr, " '%s%s'",
290*09d4459fSDaniel Fojt prefix, longopts[option_index].name);
291*09d4459fSDaniel Fojt
292*09d4459fSDaniel Fojt /* This must use 'fprintf' even though it's only
293*09d4459fSDaniel Fojt printing a single character, so that it goes through
294*09d4459fSDaniel Fojt __fxprintf_nocancel when compiled as part of glibc. */
295*09d4459fSDaniel Fojt fprintf (stderr, "\n");
296*09d4459fSDaniel Fojt funlockfile (stderr);
297*09d4459fSDaniel Fojt }
298*09d4459fSDaniel Fojt }
299*09d4459fSDaniel Fojt if (ambig_malloced)
300*09d4459fSDaniel Fojt free (ambig_set);
301*09d4459fSDaniel Fojt d->__nextchar += strlen (d->__nextchar);
302*09d4459fSDaniel Fojt d->optind++;
303*09d4459fSDaniel Fojt d->optopt = 0;
304*09d4459fSDaniel Fojt return '?';
305*09d4459fSDaniel Fojt }
306*09d4459fSDaniel Fojt
307*09d4459fSDaniel Fojt option_index = indfound;
308*09d4459fSDaniel Fojt }
309*09d4459fSDaniel Fojt
310*09d4459fSDaniel Fojt if (pfound == NULL)
311*09d4459fSDaniel Fojt {
312*09d4459fSDaniel Fojt /* Can't find it as a long option. If this is not getopt_long_only,
313*09d4459fSDaniel Fojt or the option starts with '--' or is not a valid short option,
314*09d4459fSDaniel Fojt then it's an error. */
315*09d4459fSDaniel Fojt if (!long_only || argv[d->optind][1] == '-'
316*09d4459fSDaniel Fojt || strchr (optstring, *d->__nextchar) == NULL)
317*09d4459fSDaniel Fojt {
318*09d4459fSDaniel Fojt if (print_errors)
319*09d4459fSDaniel Fojt fprintf (stderr, _("%s: unrecognized option '%s%s'\n"),
320*09d4459fSDaniel Fojt argv[0], prefix, d->__nextchar);
321*09d4459fSDaniel Fojt
322*09d4459fSDaniel Fojt d->__nextchar = NULL;
323*09d4459fSDaniel Fojt d->optind++;
324*09d4459fSDaniel Fojt d->optopt = 0;
325*09d4459fSDaniel Fojt return '?';
326*09d4459fSDaniel Fojt }
327*09d4459fSDaniel Fojt
328*09d4459fSDaniel Fojt /* Otherwise interpret it as a short option. */
329*09d4459fSDaniel Fojt return -1;
330*09d4459fSDaniel Fojt }
331*09d4459fSDaniel Fojt
332*09d4459fSDaniel Fojt /* We have found a matching long option. Consume it. */
333*09d4459fSDaniel Fojt d->optind++;
334*09d4459fSDaniel Fojt d->__nextchar = NULL;
335*09d4459fSDaniel Fojt if (*nameend)
336*09d4459fSDaniel Fojt {
337*09d4459fSDaniel Fojt /* Don't test has_arg with >, because some C compilers don't
338*09d4459fSDaniel Fojt allow it to be used on enums. */
339*09d4459fSDaniel Fojt if (pfound->has_arg)
340*09d4459fSDaniel Fojt d->optarg = nameend + 1;
341*09d4459fSDaniel Fojt else
342*09d4459fSDaniel Fojt {
343*09d4459fSDaniel Fojt if (print_errors)
344*09d4459fSDaniel Fojt fprintf (stderr,
345*09d4459fSDaniel Fojt _("%s: option '%s%s' doesn't allow an argument\n"),
346*09d4459fSDaniel Fojt argv[0], prefix, pfound->name);
347*09d4459fSDaniel Fojt
348*09d4459fSDaniel Fojt d->optopt = pfound->val;
349*09d4459fSDaniel Fojt return '?';
350*09d4459fSDaniel Fojt }
351*09d4459fSDaniel Fojt }
352*09d4459fSDaniel Fojt else if (pfound->has_arg == 1)
353*09d4459fSDaniel Fojt {
354*09d4459fSDaniel Fojt if (d->optind < argc)
355*09d4459fSDaniel Fojt d->optarg = argv[d->optind++];
356*09d4459fSDaniel Fojt else
357*09d4459fSDaniel Fojt {
358*09d4459fSDaniel Fojt if (print_errors)
359*09d4459fSDaniel Fojt fprintf (stderr,
360*09d4459fSDaniel Fojt _("%s: option '%s%s' requires an argument\n"),
361*09d4459fSDaniel Fojt argv[0], prefix, pfound->name);
362*09d4459fSDaniel Fojt
363*09d4459fSDaniel Fojt d->optopt = pfound->val;
364*09d4459fSDaniel Fojt return optstring[0] == ':' ? ':' : '?';
365*09d4459fSDaniel Fojt }
366*09d4459fSDaniel Fojt }
367*09d4459fSDaniel Fojt
368*09d4459fSDaniel Fojt if (longind != NULL)
369*09d4459fSDaniel Fojt *longind = option_index;
370*09d4459fSDaniel Fojt if (pfound->flag)
371*09d4459fSDaniel Fojt {
372*09d4459fSDaniel Fojt *(pfound->flag) = pfound->val;
373*09d4459fSDaniel Fojt return 0;
374*09d4459fSDaniel Fojt }
375*09d4459fSDaniel Fojt return pfound->val;
376*09d4459fSDaniel Fojt }
377*09d4459fSDaniel Fojt
378*09d4459fSDaniel Fojt /* Initialize internal data upon the first call to getopt. */
37995b7b453SJohn Marino
38095b7b453SJohn Marino static const char *
_getopt_initialize(int argc _GL_UNUSED,char ** argv _GL_UNUSED,const char * optstring,struct _getopt_data * d,int posixly_correct)38195b7b453SJohn Marino _getopt_initialize (int argc _GL_UNUSED,
38295b7b453SJohn Marino char **argv _GL_UNUSED, const char *optstring,
38395b7b453SJohn Marino struct _getopt_data *d, int posixly_correct)
38495b7b453SJohn Marino {
38595b7b453SJohn Marino /* Start processing options with ARGV-element 1 (since ARGV-element 0
38695b7b453SJohn Marino is the program name); the sequence of previously skipped
38795b7b453SJohn Marino non-option ARGV-elements is empty. */
388*09d4459fSDaniel Fojt if (d->optind == 0)
389*09d4459fSDaniel Fojt d->optind = 1;
39095b7b453SJohn Marino
39195b7b453SJohn Marino d->__first_nonopt = d->__last_nonopt = d->optind;
39295b7b453SJohn Marino d->__nextchar = NULL;
39395b7b453SJohn Marino
39495b7b453SJohn Marino /* Determine how to handle the ordering of options and nonoptions. */
39595b7b453SJohn Marino if (optstring[0] == '-')
39695b7b453SJohn Marino {
39795b7b453SJohn Marino d->__ordering = RETURN_IN_ORDER;
39895b7b453SJohn Marino ++optstring;
39995b7b453SJohn Marino }
40095b7b453SJohn Marino else if (optstring[0] == '+')
40195b7b453SJohn Marino {
40295b7b453SJohn Marino d->__ordering = REQUIRE_ORDER;
40395b7b453SJohn Marino ++optstring;
40495b7b453SJohn Marino }
405*09d4459fSDaniel Fojt else if (posixly_correct || !!getenv ("POSIXLY_CORRECT"))
40695b7b453SJohn Marino d->__ordering = REQUIRE_ORDER;
40795b7b453SJohn Marino else
40895b7b453SJohn Marino d->__ordering = PERMUTE;
40995b7b453SJohn Marino
410*09d4459fSDaniel Fojt d->__initialized = 1;
41195b7b453SJohn Marino return optstring;
41295b7b453SJohn Marino }
41395b7b453SJohn Marino
41495b7b453SJohn Marino /* Scan elements of ARGV (whose length is ARGC) for option characters
41595b7b453SJohn Marino given in OPTSTRING.
41695b7b453SJohn Marino
41795b7b453SJohn Marino If an element of ARGV starts with '-', and is not exactly "-" or "--",
41895b7b453SJohn Marino then it is an option element. The characters of this element
419cf28ed85SJohn Marino (aside from the initial '-') are option characters. If 'getopt'
42095b7b453SJohn Marino is called repeatedly, it returns successively each of the option characters
42195b7b453SJohn Marino from each of the option elements.
42295b7b453SJohn Marino
423cf28ed85SJohn Marino If 'getopt' finds another option character, it returns that character,
424cf28ed85SJohn Marino updating 'optind' and 'nextchar' so that the next call to 'getopt' can
42595b7b453SJohn Marino resume the scan with the following option character or ARGV-element.
42695b7b453SJohn Marino
427cf28ed85SJohn Marino If there are no more option characters, 'getopt' returns -1.
428cf28ed85SJohn Marino Then 'optind' is the index in ARGV of the first ARGV-element
42995b7b453SJohn Marino that is not an option. (The ARGV-elements have been permuted
43095b7b453SJohn Marino so that those that are not options now come last.)
43195b7b453SJohn Marino
43295b7b453SJohn Marino OPTSTRING is a string containing the legitimate option characters.
43395b7b453SJohn Marino If an option character is seen that is not listed in OPTSTRING,
434cf28ed85SJohn Marino return '?' after printing an error message. If you set 'opterr' to
43595b7b453SJohn Marino zero, the error message is suppressed but we still return '?'.
43695b7b453SJohn Marino
43795b7b453SJohn Marino If a char in OPTSTRING is followed by a colon, that means it wants an arg,
43895b7b453SJohn Marino so the following text in the same ARGV-element, or the text of the following
439cf28ed85SJohn Marino ARGV-element, is returned in 'optarg'. Two colons mean an option that
44095b7b453SJohn Marino wants an optional arg; if there is text in the current ARGV-element,
441cf28ed85SJohn Marino it is returned in 'optarg', otherwise 'optarg' is set to zero.
44295b7b453SJohn Marino
443cf28ed85SJohn Marino If OPTSTRING starts with '-' or '+', it requests different methods of
44495b7b453SJohn Marino handling the non-option ARGV-elements.
44595b7b453SJohn Marino See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
44695b7b453SJohn Marino
447cf28ed85SJohn Marino Long-named options begin with '--' instead of '-'.
44895b7b453SJohn Marino Their names may be abbreviated as long as the abbreviation is unique
44995b7b453SJohn Marino or is an exact match for some defined option. If they have an
45095b7b453SJohn Marino argument, it follows the option name in the same ARGV-element, separated
451cf28ed85SJohn Marino from the option name by a '=', or else the in next ARGV-element.
452cf28ed85SJohn Marino When 'getopt' finds a long-named option, it returns 0 if that option's
453cf28ed85SJohn Marino 'flag' field is nonzero, the value of the option's 'val' field
454cf28ed85SJohn Marino if the 'flag' field is zero.
45595b7b453SJohn Marino
45695b7b453SJohn Marino The elements of ARGV aren't really const, because we permute them.
45795b7b453SJohn Marino But we pretend they're const in the prototype to be compatible
45895b7b453SJohn Marino with other systems.
45995b7b453SJohn Marino
460cf28ed85SJohn Marino LONGOPTS is a vector of 'struct option' terminated by an
46195b7b453SJohn Marino element containing a name which is zero.
46295b7b453SJohn Marino
46395b7b453SJohn Marino LONGIND returns the index in LONGOPT of the long-named option found.
46495b7b453SJohn Marino It is only valid when a long-named option has been found by the most
46595b7b453SJohn Marino recent call.
46695b7b453SJohn Marino
46795b7b453SJohn Marino If LONG_ONLY is nonzero, '-' as well as '--' can introduce
46895b7b453SJohn Marino long-named options. */
46995b7b453SJohn Marino
47095b7b453SJohn Marino int
_getopt_internal_r(int argc,char ** argv,const char * optstring,const struct option * longopts,int * longind,int long_only,struct _getopt_data * d,int posixly_correct)47195b7b453SJohn Marino _getopt_internal_r (int argc, char **argv, const char *optstring,
47295b7b453SJohn Marino const struct option *longopts, int *longind,
47395b7b453SJohn Marino int long_only, struct _getopt_data *d, int posixly_correct)
47495b7b453SJohn Marino {
47595b7b453SJohn Marino int print_errors = d->opterr;
47695b7b453SJohn Marino
47795b7b453SJohn Marino if (argc < 1)
47895b7b453SJohn Marino return -1;
47995b7b453SJohn Marino
48095b7b453SJohn Marino d->optarg = NULL;
48195b7b453SJohn Marino
48295b7b453SJohn Marino if (d->optind == 0 || !d->__initialized)
483*09d4459fSDaniel Fojt optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct);
48495b7b453SJohn Marino else if (optstring[0] == '-' || optstring[0] == '+')
48595b7b453SJohn Marino optstring++;
486*09d4459fSDaniel Fojt
48795b7b453SJohn Marino if (optstring[0] == ':')
48895b7b453SJohn Marino print_errors = 0;
48995b7b453SJohn Marino
490*09d4459fSDaniel Fojt /* Test whether ARGV[optind] points to a non-option argument. */
49195b7b453SJohn Marino #define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
49295b7b453SJohn Marino
49395b7b453SJohn Marino if (d->__nextchar == NULL || *d->__nextchar == '\0')
49495b7b453SJohn Marino {
49595b7b453SJohn Marino /* Advance to the next ARGV-element. */
49695b7b453SJohn Marino
49795b7b453SJohn Marino /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
49895b7b453SJohn Marino moved back by the user (who may also have changed the arguments). */
49995b7b453SJohn Marino if (d->__last_nonopt > d->optind)
50095b7b453SJohn Marino d->__last_nonopt = d->optind;
50195b7b453SJohn Marino if (d->__first_nonopt > d->optind)
50295b7b453SJohn Marino d->__first_nonopt = d->optind;
50395b7b453SJohn Marino
50495b7b453SJohn Marino if (d->__ordering == PERMUTE)
50595b7b453SJohn Marino {
50695b7b453SJohn Marino /* If we have just processed some options following some non-options,
50795b7b453SJohn Marino exchange them so that the options come first. */
50895b7b453SJohn Marino
50995b7b453SJohn Marino if (d->__first_nonopt != d->__last_nonopt
51095b7b453SJohn Marino && d->__last_nonopt != d->optind)
511*09d4459fSDaniel Fojt exchange (argv, d);
51295b7b453SJohn Marino else if (d->__last_nonopt != d->optind)
51395b7b453SJohn Marino d->__first_nonopt = d->optind;
51495b7b453SJohn Marino
51595b7b453SJohn Marino /* Skip any additional non-options
51695b7b453SJohn Marino and extend the range of non-options previously skipped. */
51795b7b453SJohn Marino
51895b7b453SJohn Marino while (d->optind < argc && NONOPTION_P)
51995b7b453SJohn Marino d->optind++;
52095b7b453SJohn Marino d->__last_nonopt = d->optind;
52195b7b453SJohn Marino }
52295b7b453SJohn Marino
523cf28ed85SJohn Marino /* The special ARGV-element '--' means premature end of options.
52495b7b453SJohn Marino Skip it like a null option,
52595b7b453SJohn Marino then exchange with previous non-options as if it were an option,
52695b7b453SJohn Marino then skip everything else like a non-option. */
52795b7b453SJohn Marino
52895b7b453SJohn Marino if (d->optind != argc && !strcmp (argv[d->optind], "--"))
52995b7b453SJohn Marino {
53095b7b453SJohn Marino d->optind++;
53195b7b453SJohn Marino
53295b7b453SJohn Marino if (d->__first_nonopt != d->__last_nonopt
53395b7b453SJohn Marino && d->__last_nonopt != d->optind)
534*09d4459fSDaniel Fojt exchange (argv, d);
53595b7b453SJohn Marino else if (d->__first_nonopt == d->__last_nonopt)
53695b7b453SJohn Marino d->__first_nonopt = d->optind;
53795b7b453SJohn Marino d->__last_nonopt = argc;
53895b7b453SJohn Marino
53995b7b453SJohn Marino d->optind = argc;
54095b7b453SJohn Marino }
54195b7b453SJohn Marino
54295b7b453SJohn Marino /* If we have done all the ARGV-elements, stop the scan
54395b7b453SJohn Marino and back over any non-options that we skipped and permuted. */
54495b7b453SJohn Marino
54595b7b453SJohn Marino if (d->optind == argc)
54695b7b453SJohn Marino {
54795b7b453SJohn Marino /* Set the next-arg-index to point at the non-options
54895b7b453SJohn Marino that we previously skipped, so the caller will digest them. */
54995b7b453SJohn Marino if (d->__first_nonopt != d->__last_nonopt)
55095b7b453SJohn Marino d->optind = d->__first_nonopt;
55195b7b453SJohn Marino return -1;
55295b7b453SJohn Marino }
55395b7b453SJohn Marino
55495b7b453SJohn Marino /* If we have come to a non-option and did not permute it,
55595b7b453SJohn Marino either stop the scan or describe it to the caller and pass it by. */
55695b7b453SJohn Marino
55795b7b453SJohn Marino if (NONOPTION_P)
55895b7b453SJohn Marino {
55995b7b453SJohn Marino if (d->__ordering == REQUIRE_ORDER)
56095b7b453SJohn Marino return -1;
56195b7b453SJohn Marino d->optarg = argv[d->optind++];
56295b7b453SJohn Marino return 1;
56395b7b453SJohn Marino }
56495b7b453SJohn Marino
56595b7b453SJohn Marino /* We have found another option-ARGV-element.
566*09d4459fSDaniel Fojt Check whether it might be a long option. */
567*09d4459fSDaniel Fojt if (longopts)
56895b7b453SJohn Marino {
56995b7b453SJohn Marino if (argv[d->optind][1] == '-')
57095b7b453SJohn Marino {
571*09d4459fSDaniel Fojt /* "--foo" is always a long option. The special option
572*09d4459fSDaniel Fojt "--" was handled above. */
573*09d4459fSDaniel Fojt d->__nextchar = argv[d->optind] + 2;
574*09d4459fSDaniel Fojt return process_long_option (argc, argv, optstring, longopts,
575*09d4459fSDaniel Fojt longind, long_only, d,
576*09d4459fSDaniel Fojt print_errors, "--");
57795b7b453SJohn Marino }
578*09d4459fSDaniel Fojt
579*09d4459fSDaniel Fojt /* If long_only and the ARGV-element has the form "-f",
580*09d4459fSDaniel Fojt where f is a valid short option, don't consider it an
581*09d4459fSDaniel Fojt abbreviated form of a long option that starts with f.
582*09d4459fSDaniel Fojt Otherwise there would be no way to give the -f short
583*09d4459fSDaniel Fojt option.
584*09d4459fSDaniel Fojt
585*09d4459fSDaniel Fojt On the other hand, if there's a long option "fubar" and
586*09d4459fSDaniel Fojt the ARGV-element is "-fu", do consider that an
587*09d4459fSDaniel Fojt abbreviation of the long option, just like "--fu", and
588*09d4459fSDaniel Fojt not "-f" with arg "u".
589*09d4459fSDaniel Fojt
590*09d4459fSDaniel Fojt This distinction seems to be the most useful approach. */
591*09d4459fSDaniel Fojt if (long_only && (argv[d->optind][2]
592*09d4459fSDaniel Fojt || !strchr (optstring, argv[d->optind][1])))
59395b7b453SJohn Marino {
594*09d4459fSDaniel Fojt int code;
595*09d4459fSDaniel Fojt d->__nextchar = argv[d->optind] + 1;
596*09d4459fSDaniel Fojt code = process_long_option (argc, argv, optstring, longopts,
597*09d4459fSDaniel Fojt longind, long_only, d,
598*09d4459fSDaniel Fojt print_errors, "-");
599*09d4459fSDaniel Fojt if (code != -1)
600*09d4459fSDaniel Fojt return code;
601*09d4459fSDaniel Fojt }
60295b7b453SJohn Marino }
60395b7b453SJohn Marino
604*09d4459fSDaniel Fojt /* It is not a long option. Skip the initial punctuation. */
605*09d4459fSDaniel Fojt d->__nextchar = argv[d->optind] + 1;
60695b7b453SJohn Marino }
60795b7b453SJohn Marino
60895b7b453SJohn Marino /* Look at and handle the next short option-character. */
60995b7b453SJohn Marino
61095b7b453SJohn Marino {
61195b7b453SJohn Marino char c = *d->__nextchar++;
61295b7b453SJohn Marino const char *temp = strchr (optstring, c);
61395b7b453SJohn Marino
614cf28ed85SJohn Marino /* Increment 'optind' when we start to process its last character. */
61595b7b453SJohn Marino if (*d->__nextchar == '\0')
61695b7b453SJohn Marino ++d->optind;
61795b7b453SJohn Marino
61895b7b453SJohn Marino if (temp == NULL || c == ':' || c == ';')
61995b7b453SJohn Marino {
62095b7b453SJohn Marino if (print_errors)
62195b7b453SJohn Marino fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c);
62295b7b453SJohn Marino d->optopt = c;
62395b7b453SJohn Marino return '?';
62495b7b453SJohn Marino }
625*09d4459fSDaniel Fojt
62695b7b453SJohn Marino /* Convenience. Treat POSIX -W foo same as long option --foo */
627*09d4459fSDaniel Fojt if (temp[0] == 'W' && temp[1] == ';' && longopts != NULL)
62895b7b453SJohn Marino {
62995b7b453SJohn Marino /* This is an option that requires an argument. */
63095b7b453SJohn Marino if (*d->__nextchar != '\0')
63195b7b453SJohn Marino d->optarg = d->__nextchar;
63295b7b453SJohn Marino else if (d->optind == argc)
63395b7b453SJohn Marino {
63495b7b453SJohn Marino if (print_errors)
63595b7b453SJohn Marino fprintf (stderr,
63695b7b453SJohn Marino _("%s: option requires an argument -- '%c'\n"),
63795b7b453SJohn Marino argv[0], c);
638*09d4459fSDaniel Fojt
63995b7b453SJohn Marino d->optopt = c;
64095b7b453SJohn Marino if (optstring[0] == ':')
64195b7b453SJohn Marino c = ':';
64295b7b453SJohn Marino else
64395b7b453SJohn Marino c = '?';
64495b7b453SJohn Marino return c;
64595b7b453SJohn Marino }
64695b7b453SJohn Marino else
647*09d4459fSDaniel Fojt d->optarg = argv[d->optind];
64895b7b453SJohn Marino
649*09d4459fSDaniel Fojt d->__nextchar = d->optarg;
65095b7b453SJohn Marino d->optarg = NULL;
651*09d4459fSDaniel Fojt return process_long_option (argc, argv, optstring, longopts, longind,
652*09d4459fSDaniel Fojt 0 /* long_only */, d, print_errors, "-W ");
65395b7b453SJohn Marino }
65495b7b453SJohn Marino if (temp[1] == ':')
65595b7b453SJohn Marino {
65695b7b453SJohn Marino if (temp[2] == ':')
65795b7b453SJohn Marino {
65895b7b453SJohn Marino /* This is an option that accepts an argument optionally. */
65995b7b453SJohn Marino if (*d->__nextchar != '\0')
66095b7b453SJohn Marino {
66195b7b453SJohn Marino d->optarg = d->__nextchar;
66295b7b453SJohn Marino d->optind++;
66395b7b453SJohn Marino }
66495b7b453SJohn Marino else
66595b7b453SJohn Marino d->optarg = NULL;
66695b7b453SJohn Marino d->__nextchar = NULL;
66795b7b453SJohn Marino }
66895b7b453SJohn Marino else
66995b7b453SJohn Marino {
67095b7b453SJohn Marino /* This is an option that requires an argument. */
67195b7b453SJohn Marino if (*d->__nextchar != '\0')
67295b7b453SJohn Marino {
67395b7b453SJohn Marino d->optarg = d->__nextchar;
67495b7b453SJohn Marino /* If we end this ARGV-element by taking the rest as an arg,
67595b7b453SJohn Marino we must advance to the next element now. */
67695b7b453SJohn Marino d->optind++;
67795b7b453SJohn Marino }
67895b7b453SJohn Marino else if (d->optind == argc)
67995b7b453SJohn Marino {
68095b7b453SJohn Marino if (print_errors)
68195b7b453SJohn Marino fprintf (stderr,
68295b7b453SJohn Marino _("%s: option requires an argument -- '%c'\n"),
68395b7b453SJohn Marino argv[0], c);
684*09d4459fSDaniel Fojt
68595b7b453SJohn Marino d->optopt = c;
68695b7b453SJohn Marino if (optstring[0] == ':')
68795b7b453SJohn Marino c = ':';
68895b7b453SJohn Marino else
68995b7b453SJohn Marino c = '?';
69095b7b453SJohn Marino }
69195b7b453SJohn Marino else
692cf28ed85SJohn Marino /* We already incremented 'optind' once;
69395b7b453SJohn Marino increment it again when taking next ARGV-elt as argument. */
69495b7b453SJohn Marino d->optarg = argv[d->optind++];
69595b7b453SJohn Marino d->__nextchar = NULL;
69695b7b453SJohn Marino }
69795b7b453SJohn Marino }
69895b7b453SJohn Marino return c;
69995b7b453SJohn Marino }
70095b7b453SJohn Marino }
70195b7b453SJohn Marino
70295b7b453SJohn Marino int
_getopt_internal(int argc,char ** argv,const char * optstring,const struct option * longopts,int * longind,int long_only,int posixly_correct)70395b7b453SJohn Marino _getopt_internal (int argc, char **argv, const char *optstring,
70495b7b453SJohn Marino const struct option *longopts, int *longind, int long_only,
70595b7b453SJohn Marino int posixly_correct)
70695b7b453SJohn Marino {
70795b7b453SJohn Marino int result;
70895b7b453SJohn Marino
70995b7b453SJohn Marino getopt_data.optind = optind;
71095b7b453SJohn Marino getopt_data.opterr = opterr;
71195b7b453SJohn Marino
71295b7b453SJohn Marino result = _getopt_internal_r (argc, argv, optstring, longopts,
71395b7b453SJohn Marino longind, long_only, &getopt_data,
71495b7b453SJohn Marino posixly_correct);
71595b7b453SJohn Marino
71695b7b453SJohn Marino optind = getopt_data.optind;
71795b7b453SJohn Marino optarg = getopt_data.optarg;
71895b7b453SJohn Marino optopt = getopt_data.optopt;
71995b7b453SJohn Marino
72095b7b453SJohn Marino return result;
72195b7b453SJohn Marino }
72295b7b453SJohn Marino
723*09d4459fSDaniel Fojt /* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt.
724*09d4459fSDaniel Fojt Standalone applications just get a POSIX-compliant getopt.
725*09d4459fSDaniel Fojt POSIX and LSB both require these functions to take 'char *const *argv'
726*09d4459fSDaniel Fojt even though this is incorrect (because of the permutation). */
727*09d4459fSDaniel Fojt #define GETOPT_ENTRY(NAME, POSIXLY_CORRECT) \
728*09d4459fSDaniel Fojt int \
729*09d4459fSDaniel Fojt NAME (int argc, char *const *argv, const char *optstring) \
730*09d4459fSDaniel Fojt { \
731*09d4459fSDaniel Fojt return _getopt_internal (argc, (char **)argv, optstring, \
732*09d4459fSDaniel Fojt 0, 0, 0, POSIXLY_CORRECT); \
73395b7b453SJohn Marino }
73495b7b453SJohn Marino
73595b7b453SJohn Marino #ifdef _LIBC
736*09d4459fSDaniel Fojt GETOPT_ENTRY(getopt, 0)
737*09d4459fSDaniel Fojt GETOPT_ENTRY(__posix_getopt, 1)
738*09d4459fSDaniel Fojt #else
739*09d4459fSDaniel Fojt GETOPT_ENTRY(getopt, 1)
74095b7b453SJohn Marino #endif
74195b7b453SJohn Marino
74295b7b453SJohn Marino
74395b7b453SJohn Marino #ifdef TEST
74495b7b453SJohn Marino
74595b7b453SJohn Marino /* Compile with -DTEST to make an executable for use in testing
746cf28ed85SJohn Marino the above definition of 'getopt'. */
74795b7b453SJohn Marino
74895b7b453SJohn Marino int
main(int argc,char ** argv)74995b7b453SJohn Marino main (int argc, char **argv)
75095b7b453SJohn Marino {
75195b7b453SJohn Marino int c;
75295b7b453SJohn Marino int digit_optind = 0;
75395b7b453SJohn Marino
75495b7b453SJohn Marino while (1)
75595b7b453SJohn Marino {
75695b7b453SJohn Marino int this_option_optind = optind ? optind : 1;
75795b7b453SJohn Marino
75895b7b453SJohn Marino c = getopt (argc, argv, "abc:d:0123456789");
75995b7b453SJohn Marino if (c == -1)
76095b7b453SJohn Marino break;
76195b7b453SJohn Marino
76295b7b453SJohn Marino switch (c)
76395b7b453SJohn Marino {
76495b7b453SJohn Marino case '0':
76595b7b453SJohn Marino case '1':
76695b7b453SJohn Marino case '2':
76795b7b453SJohn Marino case '3':
76895b7b453SJohn Marino case '4':
76995b7b453SJohn Marino case '5':
77095b7b453SJohn Marino case '6':
77195b7b453SJohn Marino case '7':
77295b7b453SJohn Marino case '8':
77395b7b453SJohn Marino case '9':
77495b7b453SJohn Marino if (digit_optind != 0 && digit_optind != this_option_optind)
77595b7b453SJohn Marino printf ("digits occur in two different argv-elements.\n");
77695b7b453SJohn Marino digit_optind = this_option_optind;
77795b7b453SJohn Marino printf ("option %c\n", c);
77895b7b453SJohn Marino break;
77995b7b453SJohn Marino
78095b7b453SJohn Marino case 'a':
78195b7b453SJohn Marino printf ("option a\n");
78295b7b453SJohn Marino break;
78395b7b453SJohn Marino
78495b7b453SJohn Marino case 'b':
78595b7b453SJohn Marino printf ("option b\n");
78695b7b453SJohn Marino break;
78795b7b453SJohn Marino
78895b7b453SJohn Marino case 'c':
78995b7b453SJohn Marino printf ("option c with value '%s'\n", optarg);
79095b7b453SJohn Marino break;
79195b7b453SJohn Marino
79295b7b453SJohn Marino case '?':
79395b7b453SJohn Marino break;
79495b7b453SJohn Marino
79595b7b453SJohn Marino default:
79695b7b453SJohn Marino printf ("?? getopt returned character code 0%o ??\n", c);
79795b7b453SJohn Marino }
79895b7b453SJohn Marino }
79995b7b453SJohn Marino
80095b7b453SJohn Marino if (optind < argc)
80195b7b453SJohn Marino {
80295b7b453SJohn Marino printf ("non-option ARGV-elements: ");
80395b7b453SJohn Marino while (optind < argc)
80495b7b453SJohn Marino printf ("%s ", argv[optind++]);
80595b7b453SJohn Marino printf ("\n");
80695b7b453SJohn Marino }
80795b7b453SJohn Marino
80895b7b453SJohn Marino exit (0);
80995b7b453SJohn Marino }
81095b7b453SJohn Marino
81195b7b453SJohn Marino #endif /* TEST */
812