xref: /dflybsd-src/contrib/grep/lib/getopt.c (revision 91b9ed38d3db6a8a8ac5b66da1d43e6e331e259a)
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