1 /* Getopt for GNU.
2    Copyright (C) 1987-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library and is also part of gnulib.
4    Patches to this file should be submitted to both projects.
5 
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10 
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15 
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, see
18    <https://www.gnu.org/licenses/>.  */
19 
20 #ifndef _LIBC
21 # include <config.h>
22 #endif
23 
24 #include "getopt.h"
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 
31 #ifdef _LIBC
32 /* When used as part of glibc, error printing must be done differently
33    for standards compliance.  getopt is not a cancellation point, so
34    it must not call functions that are, and it is specified by an
35    older standard than stdio locking, so it must not refer to
36    functions in the "user namespace" related to stdio locking.
37    Finally, it must use glibc's internal message translation so that
38    the messages are looked up in the proper text domain.  */
39 # include <libintl.h>
40 # define fprintf __fxprintf_nocancel
41 # define flockfile(fp) _IO_flockfile (fp)
42 # define funlockfile(fp) _IO_funlockfile (fp)
43 #else
44 # include "gettext.h"
45 # define _(msgid) gettext (msgid)
46 /* When used standalone, flockfile and funlockfile might not be
47    available.  */
48 # ifndef _POSIX_THREAD_SAFE_FUNCTIONS
49 #  define flockfile(fp) /* nop */
50 #  define funlockfile(fp) /* nop */
51 # endif
52 /* When used standalone, do not attempt to use alloca.  */
53 # define __libc_use_alloca(size) 0
54 # undef alloca
55 # define alloca(size) (abort (), (void *)0)
56 #endif
57 
58 /* This implementation of 'getopt' has three modes for handling
59    options interspersed with non-option arguments.  It can stop
60    scanning for options at the first non-option argument encountered,
61    as POSIX specifies.  It can continue scanning for options after the
62    first non-option argument, but permute 'argv' as it goes so that,
63    after 'getopt' is done, all the options precede all the non-option
64    arguments and 'optind' points to the first non-option argument.
65    Or, it can report non-option arguments as if they were arguments to
66    the option character '\x01'.
67 
68    The default behavior of 'getopt_long' is to permute the argument list.
69    When this implementation is used standalone, the default behavior of
70    'getopt' is to stop at the first non-option argument, but when it is
71    used as part of GNU libc it also permutes the argument list.  In both
72    cases, setting the environment variable POSIXLY_CORRECT to any value
73    disables permutation.
74 
75    If the first character of the OPTSTRING argument to 'getopt' or
76    'getopt_long' is '+', both functions will stop at the first
77    non-option argument.  If it is '-', both functions will report
78    non-option arguments as arguments to the option character '\x01'.  */
79 
80 #include "getopt_int.h"
81 
82 /* For communication from 'getopt' to the caller.
83    When 'getopt' finds an option that takes an argument,
84    the argument value is returned here.
85    Also, when 'ordering' is RETURN_IN_ORDER,
86    each non-option ARGV-element is returned here.  */
87 
88 char *optarg;
89 
90 /* Index in ARGV of the next element to be scanned.
91    This is used for communication to and from the caller
92    and for communication between successive calls to 'getopt'.
93 
94    On entry to 'getopt', zero means this is the first call; initialize.
95 
96    When 'getopt' returns -1, this is the index of the first of the
97    non-option elements that the caller should itself scan.
98 
99    Otherwise, 'optind' communicates from one call to the next
100    how much of ARGV has been scanned so far.  */
101 
102 /* 1003.2 says this must be 1 before any call.  */
103 int optind = 1;
104 
105 /* Callers store zero here to inhibit the error message
106    for unrecognized options.  */
107 
108 int opterr = 1;
109 
110 /* Set to an option character which was unrecognized.
111    This must be initialized on some systems to avoid linking in the
112    system's own getopt implementation.  */
113 
114 int optopt = '?';
115 
116 /* Keep a global copy of all internal members of getopt_data.  */
117 
118 static struct _getopt_data getopt_data;
119 
120 /* Exchange two adjacent subsequences of ARGV.
121    One subsequence is elements [first_nonopt,last_nonopt)
122    which contains all the non-options that have been skipped so far.
123    The other is elements [last_nonopt,optind), which contains all
124    the options processed since those non-options were skipped.
125 
126    'first_nonopt' and 'last_nonopt' are relocated so that they describe
127    the new indices of the non-options in ARGV after they are moved.  */
128 
129 static void
exchange(char ** argv,struct _getopt_data * d)130 exchange (char **argv, struct _getopt_data *d)
131 {
132   int bottom = d->__first_nonopt;
133   int middle = d->__last_nonopt;
134   int top = d->optind;
135   char *tem;
136 
137   /* Exchange the shorter segment with the far end of the longer segment.
138      That puts the shorter segment into the right place.
139      It leaves the longer segment in the right place overall,
140      but it consists of two parts that need to be swapped next.  */
141 
142   while (top > middle && middle > bottom)
143     {
144       if (top - middle > middle - bottom)
145 	{
146 	  /* Bottom segment is the short one.  */
147 	  int len = middle - bottom;
148 	  int i;
149 
150 	  /* Swap it with the top part of the top segment.  */
151 	  for (i = 0; i < len; i++)
152 	    {
153 	      tem = argv[bottom + i];
154 	      argv[bottom + i] = argv[top - (middle - bottom) + i];
155 	      argv[top - (middle - bottom) + i] = tem;
156 	    }
157 	  /* Exclude the moved bottom segment from further swapping.  */
158 	  top -= len;
159 	}
160       else
161 	{
162 	  /* Top segment is the short one.  */
163 	  int len = top - middle;
164 	  int i;
165 
166 	  /* Swap it with the bottom part of the bottom segment.  */
167 	  for (i = 0; i < len; i++)
168 	    {
169 	      tem = argv[bottom + i];
170 	      argv[bottom + i] = argv[middle + i];
171 	      argv[middle + i] = tem;
172 	    }
173 	  /* Exclude the moved top segment from further swapping.  */
174 	  bottom += len;
175 	}
176     }
177 
178   /* Update records for the slots the non-options now occupy.  */
179 
180   d->__first_nonopt += (d->optind - d->__last_nonopt);
181   d->__last_nonopt = d->optind;
182 }
183 
184 /* Process the argument starting with d->__nextchar as a long option.
185    d->optind should *not* have been advanced over this argument.
186 
187    If the value returned is -1, it was not actually a long option, the
188    state is unchanged, and the argument should be processed as a set
189    of short options (this can only happen when long_only is true).
190    Otherwise, the option (and its argument, if any) have been consumed
191    and the return value is the value to return from _getopt_internal_r.  */
192 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)193 process_long_option (int argc, char **argv, const char *optstring,
194 		     const struct option *longopts, int *longind,
195 		     int long_only, struct _getopt_data *d,
196 		     int print_errors, const char *prefix)
197 {
198   char *nameend;
199   size_t namelen;
200   const struct option *p;
201   const struct option *pfound = NULL;
202   int n_options;
203   int option_index;
204 
205   for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
206     /* Do nothing.  */ ;
207   namelen = nameend - d->__nextchar;
208 
209   /* First look for an exact match, counting the options as a side
210      effect.  */
211   for (p = longopts, n_options = 0; p->name; p++, n_options++)
212     if (!strncmp (p->name, d->__nextchar, namelen)
213 	&& namelen == strlen (p->name))
214       {
215 	/* Exact match found.  */
216 	pfound = p;
217 	option_index = n_options;
218 	break;
219       }
220 
221   if (pfound == NULL)
222     {
223       /* Didn't find an exact match, so look for abbreviations.  */
224       unsigned char *ambig_set = NULL;
225       int ambig_malloced = 0;
226       int ambig_fallback = 0;
227       int indfound = -1;
228 
229       for (p = longopts, option_index = 0; p->name; p++, option_index++)
230 	if (!strncmp (p->name, d->__nextchar, namelen))
231 	  {
232 	    if (pfound == NULL)
233 	      {
234 		/* First nonexact match found.  */
235 		pfound = p;
236 		indfound = option_index;
237 	      }
238 	    else if (long_only
239 		     || pfound->has_arg != p->has_arg
240 		     || pfound->flag != p->flag
241 		     || pfound->val != p->val)
242 	      {
243 		/* Second or later nonexact match found.  */
244 		if (!ambig_fallback)
245 		  {
246 		    if (!print_errors)
247 		      /* Don't waste effort tracking the ambig set if
248 			 we're not going to print it anyway.  */
249 		      ambig_fallback = 1;
250 		    else if (!ambig_set)
251 		      {
252 			if (__libc_use_alloca (n_options))
253 			  ambig_set = alloca (n_options);
254 			else if ((ambig_set = malloc (n_options)) == NULL)
255 			  /* Fall back to simpler error message.  */
256 			  ambig_fallback = 1;
257 			else
258 			  ambig_malloced = 1;
259 
260 			if (ambig_set)
261 			  {
262 			    memset (ambig_set, 0, n_options);
263 			    ambig_set[indfound] = 1;
264 			  }
265 		      }
266 		    if (ambig_set)
267 		      ambig_set[option_index] = 1;
268 		  }
269 	      }
270 	  }
271 
272       if (ambig_set || ambig_fallback)
273 	{
274 	  if (print_errors)
275 	    {
276 	      if (ambig_fallback)
277 		fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"),
278 			 argv[0], prefix, d->__nextchar);
279 	      else
280 		{
281 		  flockfile (stderr);
282 		  fprintf (stderr,
283 			   _("%s: option '%s%s' is ambiguous; possibilities:"),
284 			   argv[0], prefix, d->__nextchar);
285 
286 		  for (option_index = 0; option_index < n_options; option_index++)
287 		    if (ambig_set[option_index])
288 		      fprintf (stderr, " '%s%s'",
289 			       prefix, longopts[option_index].name);
290 
291 		  /* This must use 'fprintf' even though it's only
292 		     printing a single character, so that it goes through
293 		     __fxprintf_nocancel when compiled as part of glibc.  */
294 		  fprintf (stderr, "\n");
295 		  funlockfile (stderr);
296 		}
297 	    }
298 	  if (ambig_malloced)
299 	    free (ambig_set);
300 	  d->__nextchar += strlen (d->__nextchar);
301 	  d->optind++;
302 	  d->optopt = 0;
303 	  return '?';
304 	}
305 
306       option_index = indfound;
307     }
308 
309   if (pfound == NULL)
310     {
311       /* Can't find it as a long option.  If this is not getopt_long_only,
312 	 or the option starts with '--' or is not a valid short option,
313 	 then it's an error.  */
314       if (!long_only || argv[d->optind][1] == '-'
315 	  || strchr (optstring, *d->__nextchar) == NULL)
316 	{
317 	  if (print_errors)
318 	    fprintf (stderr, _("%s: unrecognized option '%s%s'\n"),
319 		     argv[0], prefix, d->__nextchar);
320 
321 	  d->__nextchar = NULL;
322 	  d->optind++;
323 	  d->optopt = 0;
324 	  return '?';
325 	}
326 
327       /* Otherwise interpret it as a short option.  */
328       return -1;
329     }
330 
331   /* We have found a matching long option.  Consume it.  */
332   d->optind++;
333   d->__nextchar = NULL;
334   if (*nameend)
335     {
336       /* Don't test has_arg with >, because some C compilers don't
337 	 allow it to be used on enums.  */
338       if (pfound->has_arg)
339 	d->optarg = nameend + 1;
340       else
341 	{
342 	  if (print_errors)
343 	    fprintf (stderr,
344 		     _("%s: option '%s%s' doesn't allow an argument\n"),
345 		     argv[0], prefix, pfound->name);
346 
347 	  d->optopt = pfound->val;
348 	  return '?';
349 	}
350     }
351   else if (pfound->has_arg == 1)
352     {
353       if (d->optind < argc)
354 	d->optarg = argv[d->optind++];
355       else
356 	{
357 	  if (print_errors)
358 	    fprintf (stderr,
359 		     _("%s: option '%s%s' requires an argument\n"),
360 		     argv[0], prefix, pfound->name);
361 
362 	  d->optopt = pfound->val;
363 	  return optstring[0] == ':' ? ':' : '?';
364 	}
365     }
366 
367   if (longind != NULL)
368     *longind = option_index;
369   if (pfound->flag)
370     {
371       *(pfound->flag) = pfound->val;
372       return 0;
373     }
374   return pfound->val;
375 }
376 
377 /* Initialize internal data upon the first call to getopt.  */
378 
379 static const char *
_getopt_initialize(int argc _GL_UNUSED,char ** argv _GL_UNUSED,const char * optstring,struct _getopt_data * d,int posixly_correct)380 _getopt_initialize (int argc _GL_UNUSED,
381 		    char **argv _GL_UNUSED, const char *optstring,
382 		    struct _getopt_data *d, int posixly_correct)
383 {
384   /* Start processing options with ARGV-element 1 (since ARGV-element 0
385      is the program name); the sequence of previously skipped
386      non-option ARGV-elements is empty.  */
387   if (d->optind == 0)
388     d->optind = 1;
389 
390   d->__first_nonopt = d->__last_nonopt = d->optind;
391   d->__nextchar = NULL;
392 
393   /* Determine how to handle the ordering of options and nonoptions.  */
394   if (optstring[0] == '-')
395     {
396       d->__ordering = RETURN_IN_ORDER;
397       ++optstring;
398     }
399   else if (optstring[0] == '+')
400     {
401       d->__ordering = REQUIRE_ORDER;
402       ++optstring;
403     }
404   else if (posixly_correct || !!getenv ("POSIXLY_CORRECT"))
405     d->__ordering = REQUIRE_ORDER;
406   else
407     d->__ordering = PERMUTE;
408 
409   d->__initialized = 1;
410   return optstring;
411 }
412 
413 /* Scan elements of ARGV (whose length is ARGC) for option characters
414    given in OPTSTRING.
415 
416    If an element of ARGV starts with '-', and is not exactly "-" or "--",
417    then it is an option element.  The characters of this element
418    (aside from the initial '-') are option characters.  If 'getopt'
419    is called repeatedly, it returns successively each of the option characters
420    from each of the option elements.
421 
422    If 'getopt' finds another option character, it returns that character,
423    updating 'optind' and 'nextchar' so that the next call to 'getopt' can
424    resume the scan with the following option character or ARGV-element.
425 
426    If there are no more option characters, 'getopt' returns -1.
427    Then 'optind' is the index in ARGV of the first ARGV-element
428    that is not an option.  (The ARGV-elements have been permuted
429    so that those that are not options now come last.)
430 
431    OPTSTRING is a string containing the legitimate option characters.
432    If an option character is seen that is not listed in OPTSTRING,
433    return '?' after printing an error message.  If you set 'opterr' to
434    zero, the error message is suppressed but we still return '?'.
435 
436    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
437    so the following text in the same ARGV-element, or the text of the following
438    ARGV-element, is returned in 'optarg'.  Two colons mean an option that
439    wants an optional arg; if there is text in the current ARGV-element,
440    it is returned in 'optarg', otherwise 'optarg' is set to zero.
441 
442    If OPTSTRING starts with '-' or '+', it requests different methods of
443    handling the non-option ARGV-elements.
444    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
445 
446    Long-named options begin with '--' instead of '-'.
447    Their names may be abbreviated as long as the abbreviation is unique
448    or is an exact match for some defined option.  If they have an
449    argument, it follows the option name in the same ARGV-element, separated
450    from the option name by a '=', or else the in next ARGV-element.
451    When 'getopt' finds a long-named option, it returns 0 if that option's
452    'flag' field is nonzero, the value of the option's 'val' field
453    if the 'flag' field is zero.
454 
455    The elements of ARGV aren't really const, because we permute them.
456    But we pretend they're const in the prototype to be compatible
457    with other systems.
458 
459    LONGOPTS is a vector of 'struct option' terminated by an
460    element containing a name which is zero.
461 
462    LONGIND returns the index in LONGOPT of the long-named option found.
463    It is only valid when a long-named option has been found by the most
464    recent call.
465 
466    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
467    long-named options.  */
468 
469 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)470 _getopt_internal_r (int argc, char **argv, const char *optstring,
471 		    const struct option *longopts, int *longind,
472 		    int long_only, struct _getopt_data *d, int posixly_correct)
473 {
474   int print_errors = d->opterr;
475 
476   if (argc < 1)
477     return -1;
478 
479   d->optarg = NULL;
480 
481   if (d->optind == 0 || !d->__initialized)
482     optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct);
483   else if (optstring[0] == '-' || optstring[0] == '+')
484     optstring++;
485 
486   if (optstring[0] == ':')
487     print_errors = 0;
488 
489   /* Test whether ARGV[optind] points to a non-option argument.  */
490 #define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
491 
492   if (d->__nextchar == NULL || *d->__nextchar == '\0')
493     {
494       /* Advance to the next ARGV-element.  */
495 
496       /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
497 	 moved back by the user (who may also have changed the arguments).  */
498       if (d->__last_nonopt > d->optind)
499 	d->__last_nonopt = d->optind;
500       if (d->__first_nonopt > d->optind)
501 	d->__first_nonopt = d->optind;
502 
503       if (d->__ordering == PERMUTE)
504 	{
505 	  /* If we have just processed some options following some non-options,
506 	     exchange them so that the options come first.  */
507 
508 	  if (d->__first_nonopt != d->__last_nonopt
509 	      && d->__last_nonopt != d->optind)
510 	    exchange (argv, d);
511 	  else if (d->__last_nonopt != d->optind)
512 	    d->__first_nonopt = d->optind;
513 
514 	  /* Skip any additional non-options
515 	     and extend the range of non-options previously skipped.  */
516 
517 	  while (d->optind < argc && NONOPTION_P)
518 	    d->optind++;
519 	  d->__last_nonopt = d->optind;
520 	}
521 
522       /* The special ARGV-element '--' means premature end of options.
523 	 Skip it like a null option,
524 	 then exchange with previous non-options as if it were an option,
525 	 then skip everything else like a non-option.  */
526 
527       if (d->optind != argc && !strcmp (argv[d->optind], "--"))
528 	{
529 	  d->optind++;
530 
531 	  if (d->__first_nonopt != d->__last_nonopt
532 	      && d->__last_nonopt != d->optind)
533 	    exchange (argv, d);
534 	  else if (d->__first_nonopt == d->__last_nonopt)
535 	    d->__first_nonopt = d->optind;
536 	  d->__last_nonopt = argc;
537 
538 	  d->optind = argc;
539 	}
540 
541       /* If we have done all the ARGV-elements, stop the scan
542 	 and back over any non-options that we skipped and permuted.  */
543 
544       if (d->optind == argc)
545 	{
546 	  /* Set the next-arg-index to point at the non-options
547 	     that we previously skipped, so the caller will digest them.  */
548 	  if (d->__first_nonopt != d->__last_nonopt)
549 	    d->optind = d->__first_nonopt;
550 	  return -1;
551 	}
552 
553       /* If we have come to a non-option and did not permute it,
554 	 either stop the scan or describe it to the caller and pass it by.  */
555 
556       if (NONOPTION_P)
557 	{
558 	  if (d->__ordering == REQUIRE_ORDER)
559 	    return -1;
560 	  d->optarg = argv[d->optind++];
561 	  return 1;
562 	}
563 
564       /* We have found another option-ARGV-element.
565 	 Check whether it might be a long option.  */
566       if (longopts)
567 	{
568 	  if (argv[d->optind][1] == '-')
569 	    {
570 	      /* "--foo" is always a long option.  The special option
571 		 "--" was handled above.  */
572 	      d->__nextchar = argv[d->optind] + 2;
573 	      return process_long_option (argc, argv, optstring, longopts,
574 					  longind, long_only, d,
575 					  print_errors, "--");
576 	    }
577 
578 	  /* If long_only and the ARGV-element has the form "-f",
579 	     where f is a valid short option, don't consider it an
580 	     abbreviated form of a long option that starts with f.
581 	     Otherwise there would be no way to give the -f short
582 	     option.
583 
584 	     On the other hand, if there's a long option "fubar" and
585 	     the ARGV-element is "-fu", do consider that an
586 	     abbreviation of the long option, just like "--fu", and
587 	     not "-f" with arg "u".
588 
589 	     This distinction seems to be the most useful approach.  */
590 	  if (long_only && (argv[d->optind][2]
591 			    || !strchr (optstring, argv[d->optind][1])))
592 	    {
593 	      int code;
594 	      d->__nextchar = argv[d->optind] + 1;
595 	      code = process_long_option (argc, argv, optstring, longopts,
596 					  longind, long_only, d,
597 					  print_errors, "-");
598 	      if (code != -1)
599 		return code;
600 	    }
601 	}
602 
603       /* It is not a long option.  Skip the initial punctuation.  */
604       d->__nextchar = argv[d->optind] + 1;
605     }
606 
607   /* Look at and handle the next short option-character.  */
608 
609   {
610     char c = *d->__nextchar++;
611     const char *temp = strchr (optstring, c);
612 
613     /* Increment 'optind' when we start to process its last character.  */
614     if (*d->__nextchar == '\0')
615       ++d->optind;
616 
617     if (temp == NULL || c == ':' || c == ';')
618       {
619 	if (print_errors)
620 	  fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c);
621 	d->optopt = c;
622 	return '?';
623       }
624 
625     /* Convenience. Treat POSIX -W foo same as long option --foo */
626     if (temp[0] == 'W' && temp[1] == ';' && longopts != NULL)
627       {
628 	/* This is an option that requires an argument.  */
629 	if (*d->__nextchar != '\0')
630 	  d->optarg = d->__nextchar;
631 	else if (d->optind == argc)
632 	  {
633 	    if (print_errors)
634 	      fprintf (stderr,
635 		       _("%s: option requires an argument -- '%c'\n"),
636 		       argv[0], c);
637 
638 	    d->optopt = c;
639 	    if (optstring[0] == ':')
640 	      c = ':';
641 	    else
642 	      c = '?';
643 	    return c;
644 	  }
645 	else
646 	  d->optarg = argv[d->optind];
647 
648 	d->__nextchar = d->optarg;
649 	d->optarg = NULL;
650 	return process_long_option (argc, argv, optstring, longopts, longind,
651 				    0 /* long_only */, d, print_errors, "-W ");
652       }
653     if (temp[1] == ':')
654       {
655 	if (temp[2] == ':')
656 	  {
657 	    /* This is an option that accepts an argument optionally.  */
658 	    if (*d->__nextchar != '\0')
659 	      {
660 		d->optarg = d->__nextchar;
661 		d->optind++;
662 	      }
663 	    else
664 	      d->optarg = NULL;
665 	    d->__nextchar = NULL;
666 	  }
667 	else
668 	  {
669 	    /* This is an option that requires an argument.  */
670 	    if (*d->__nextchar != '\0')
671 	      {
672 		d->optarg = d->__nextchar;
673 		/* If we end this ARGV-element by taking the rest as an arg,
674 		   we must advance to the next element now.  */
675 		d->optind++;
676 	      }
677 	    else if (d->optind == argc)
678 	      {
679 		if (print_errors)
680 		  fprintf (stderr,
681 			   _("%s: option requires an argument -- '%c'\n"),
682 			   argv[0], c);
683 
684 		d->optopt = c;
685 		if (optstring[0] == ':')
686 		  c = ':';
687 		else
688 		  c = '?';
689 	      }
690 	    else
691 	      /* We already incremented 'optind' once;
692 		 increment it again when taking next ARGV-elt as argument.  */
693 	      d->optarg = argv[d->optind++];
694 	    d->__nextchar = NULL;
695 	  }
696       }
697     return c;
698   }
699 }
700 
701 int
_getopt_internal(int argc,char ** argv,const char * optstring,const struct option * longopts,int * longind,int long_only,int posixly_correct)702 _getopt_internal (int argc, char **argv, const char *optstring,
703 		  const struct option *longopts, int *longind, int long_only,
704 		  int posixly_correct)
705 {
706   int result;
707 
708   getopt_data.optind = optind;
709   getopt_data.opterr = opterr;
710 
711   result = _getopt_internal_r (argc, argv, optstring, longopts,
712 			       longind, long_only, &getopt_data,
713 			       posixly_correct);
714 
715   optind = getopt_data.optind;
716   optarg = getopt_data.optarg;
717   optopt = getopt_data.optopt;
718 
719   return result;
720 }
721 
722 /* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt.
723    Standalone applications just get a POSIX-compliant getopt.
724    POSIX and LSB both require these functions to take 'char *const *argv'
725    even though this is incorrect (because of the permutation).  */
726 #define GETOPT_ENTRY(NAME, POSIXLY_CORRECT)			\
727   int								\
728   NAME (int argc, char *const *argv, const char *optstring)	\
729   {								\
730     return _getopt_internal (argc, (char **)argv, optstring,	\
731 			     0, 0, 0, POSIXLY_CORRECT);		\
732   }
733 
734 #ifdef _LIBC
735 GETOPT_ENTRY(getopt, 0)
736 GETOPT_ENTRY(__posix_getopt, 1)
737 #else
738 GETOPT_ENTRY(getopt, 1)
739 #endif
740 
741 
742 #ifdef TEST
743 
744 /* Compile with -DTEST to make an executable for use in testing
745    the above definition of 'getopt'.  */
746 
747 int
main(int argc,char ** argv)748 main (int argc, char **argv)
749 {
750   int c;
751   int digit_optind = 0;
752 
753   while (1)
754     {
755       int this_option_optind = optind ? optind : 1;
756 
757       c = getopt (argc, argv, "abc:d:0123456789");
758       if (c == -1)
759 	break;
760 
761       switch (c)
762 	{
763 	case '0':
764 	case '1':
765 	case '2':
766 	case '3':
767 	case '4':
768 	case '5':
769 	case '6':
770 	case '7':
771 	case '8':
772 	case '9':
773 	  if (digit_optind != 0 && digit_optind != this_option_optind)
774 	    printf ("digits occur in two different argv-elements.\n");
775 	  digit_optind = this_option_optind;
776 	  printf ("option %c\n", c);
777 	  break;
778 
779 	case 'a':
780 	  printf ("option a\n");
781 	  break;
782 
783 	case 'b':
784 	  printf ("option b\n");
785 	  break;
786 
787 	case 'c':
788 	  printf ("option c with value '%s'\n", optarg);
789 	  break;
790 
791 	case '?':
792 	  break;
793 
794 	default:
795 	  printf ("?? getopt returned character code 0%o ??\n", c);
796 	}
797     }
798 
799   if (optind < argc)
800     {
801       printf ("non-option ARGV-elements: ");
802       while (optind < argc)
803 	printf ("%s ", argv[optind++]);
804       printf ("\n");
805     }
806 
807   exit (0);
808 }
809 
810 #endif /* TEST */
811