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