Code

Merge branch 'upstream' into experimental
[pkg-rrdtool.git] / src / rrd_getopt.c
1 /* Getopt for GNU.
2    NOTE: getopt is now part of the C library, so if you don't know what
3    "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
4    before changing it!
6    Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
7    Free Software Foundation, Inc.
9    This file is part of the GNU C Library.  Its master source is NOT part of
10    the C library, however.  The master source lives in /gd/gnu/lib.
12    The GNU C Library is free software; you can redistribute it and/or
13    modify it under the terms of the GNU Library General Public License as
14    published by the Free Software Foundation; either version 2 of the
15    License, or (at your option) any later version.
17    The GNU C Library is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    Library General Public License for more details.
22    You should have received a copy of the GNU Library General Public
23    License along with the GNU C Library; see the file COPYING.LIB.  If not,
24    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25    Boston, MA 02111-1307, USA.  */
26 \f
27 /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
28    Ditto for AIX 3.2 and <stdlib.h>.  */
29 #ifndef _NO_PROTO
30 #define _NO_PROTO
31 #endif
33 #ifndef WIN32
35 #if !defined (__STDC__) || !__STDC__
36 /* This is a separate conditional since some stdc systems
37    reject `defined (const)'.  */
38 #ifndef const
39 #define const
40 #endif
41 #endif
43 #endif // WIN32
45 #ifdef HAVE_CONFIG_H
46 #include "../rrd_config.h"
47 #endif
49 #include "rrd_i18n.h"
52 #include <stdio.h>
54 /* Comment out all this code if we are using the GNU C Library, and are not
55    actually compiling the library itself.  This code is part of the GNU C
56    Library, but also included in many other GNU distributions.  Compiling
57    and linking in this code is a waste when using the GNU C library
58    (especially if it is a shared library).  Rather than having every GNU
59    program understand `configure --with-gnu-libc' and omit the object files,
60    it is simpler to just do this in the source for each such file.  */
62 #define GETOPT_INTERFACE_VERSION 2
63 #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
64 #include <gnu-versions.h>
65 #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
66 #define ELIDE_CODE
67 #endif
68 #endif
70 #ifndef ELIDE_CODE
73 /* This needs to come after some library #include
74    to get __GNU_LIBRARY__ defined.  */
75 #ifdef  __GNU_LIBRARY__
76 /* Don't include stdlib.h for non-GNU C libraries because some of them
77    contain conflicting prototypes for getopt.  */
78 #include <stdlib.h>
79 #include <unistd.h>
80 #endif                          /* GNU C library.  */
82 #ifdef VMS
83 #include <unixlib.h>
84 #if HAVE_STRING_H - 0
85 #include <string.h>
86 #endif
87 #endif
89 #if defined (_WIN32) && !defined (__CYGWIN32__)
90 /* It's not Unix, really.  See?  Capital letters.  */
91 #include <windows.h>
92 #define getpid() GetCurrentProcessId()
93 #endif
95 /* This version of `getopt' appears to the caller like standard Unix `getopt'
96    but it behaves differently for the user, since it allows the user
97    to intersperse the options with the other arguments.
99    As `getopt' works, it permutes the elements of ARGV so that,
100    when it is done, all the options precede everything else.  Thus
101    all application programs are extended to handle flexible argument order.
103    Setting the environment variable POSIXLY_CORRECT disables permutation.
104    Then the behavior is completely standard.
106    GNU application programs can use a third alternative mode in which
107    they can distinguish the relative order of options and other arguments.  */
109 #include "rrd_getopt.h"
111 /* For communication from `getopt' to the caller.
112    When `getopt' finds an option that takes an argument,
113    the argument value is returned here.
114    Also, when `ordering' is RETURN_IN_ORDER,
115    each non-option ARGV-element is returned here.  */
117 char     *optarg = NULL;
119 /* Index in ARGV of the next element to be scanned.
120    This is used for communication to and from the caller
121    and for communication between successive calls to `getopt'.
123    On entry to `getopt', zero means this is the first call; initialize.
125    When `getopt' returns -1, this is the index of the first of the
126    non-option elements that the caller should itself scan.
128    Otherwise, `optind' communicates from one call to the next
129    how much of ARGV has been scanned so far.  */
131 /* 1003.2 says this must be 1 before any call.  */
132 int       optind = 1;
134 /* Formerly, initialization of getopt depended on optind==0, which
135    causes problems with re-calling getopt as programs generally don't
136    know that. */
138 int       __getopt_initialized = 0;
140 /* The next char to be scanned in the option-element
141    in which the last option character we returned was found.
142    This allows us to pick up the scan where we left off.
144    If this is zero, or a null string, it means resume the scan
145    by advancing to the next ARGV-element.  */
147 static char *nextchar;
149 /* Callers store zero here to inhibit the error message
150    for unrecognized options.  */
152 int       opterr = 1;
154 /* Set to an option character which was unrecognized.
155    This must be initialized on some systems to avoid linking in the
156    system's own getopt implementation.  */
158 int       optopt = '?';
160 /* Describe how to deal with options that follow non-option ARGV-elements.
162    If the caller did not specify anything,
163    the default is REQUIRE_ORDER if the environment variable
164    POSIXLY_CORRECT is defined, PERMUTE otherwise.
166    REQUIRE_ORDER means don't recognize them as options;
167    stop option processing when the first non-option is seen.
168    This is what Unix does.
169    This mode of operation is selected by either setting the environment
170    variable POSIXLY_CORRECT, or using `+' as the first character
171    of the list of option characters.
173    PERMUTE is the default.  We permute the contents of ARGV as we scan,
174    so that eventually all the non-options are at the end.  This allows options
175    to be given in any order, even with programs that were not written to
176    expect this.
178    RETURN_IN_ORDER is an option available to programs that were written
179    to expect options and other ARGV-elements in any order and that care about
180    the ordering of the two.  We describe each non-option ARGV-element
181    as if it were the argument of an option with character code 1.
182    Using `-' as the first character of the list of option characters
183    selects this mode of operation.
185    The special argument `--' forces an end of option-scanning regardless
186    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
187    `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
189 static enum {
190     REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
191 } ordering;
193 /* Value of POSIXLY_CORRECT environment variable.  */
194 static char *posixly_correct;
195 \f
196 /* we must include string as there are warnings without it ... */
197 #include <string.h>
199 #ifdef  __GNU_LIBRARY__
200 /* We want to avoid inclusion of string.h with non-GNU libraries
201    because there are many ways it can cause trouble.
202    On some systems, it contains special magic macros that don't work
203    in GCC.  */
204 #define my_index        strchr
205 #else
207 /* Avoid depending on library functions or files
208    whose names are inconsistent.  */
210 char     *getenv(
211     );
213 #ifdef WIN32
214 static char* my_index(const char* str, int chr)
215 #else // WIN32
216 static char *my_index(
217     str,
218     chr)
219     const char *str;
220     int chr;
221 #endif // wIN32
223     while (*str) {
224         if (*str == chr)
225             return (char *) str;
226         str++;
227     }
228     return 0;
231 /* If using GCC, we can safely declare strlen this way.
232    If not using GCC, it is ok not to declare it.  */
233 #ifdef __GNUC__
234 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
235    That was relevant to code that was here before.  */
236 #if !defined (__STDC__) || !__STDC__
237 /* gcc with -traditional declares the built-in strlen to return int,
238    and has done so at least since version 2.4.5. -- rms.  */
239 extern int strlen(
240     const char *);
241 #endif                          /* not __STDC__ */
242 #endif                          /* __GNUC__ */
244 #endif                          /* not __GNU_LIBRARY__ */
245 \f
246 /* Handle permutation of arguments.  */
248 /* Describe the part of ARGV that contains non-options that have
249    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
250    `last_nonopt' is the index after the last of them.  */
252 static int first_nonopt;
253 static int last_nonopt;
255 #ifdef _LIBC
256 /* Bash 2.0 gives us an environment variable containing flags
257    indicating ARGV elements that should not be considered arguments.  */
259 static const char *nonoption_flags;
260 static int nonoption_flags_len;
262 static int original_argc;
263 static char *const *original_argv;
265 /* Make sure the environment variable bash 2.0 puts in the environment
266    is valid for the getopt call we must make sure that the ARGV passed
267    to getopt is that one passed to the process.  */
268 static void store_args(
269     int argc,
270     char *const *argv) __attribute__ ((unused));
271 static void store_args(
272     int argc,
273     char *const *argv)
275     /* XXX This is no good solution.  We should rather copy the args so
276        that we can compare them later.  But we must not use malloc(3).  */
277     original_argc = argc;
278     original_argv = argv;
281 text_set_element(__libc_subinit, store_args);
282 #endif
284 /* Exchange two adjacent subsequences of ARGV.
285    One subsequence is elements [first_nonopt,last_nonopt)
286    which contains all the non-options that have been skipped so far.
287    The other is elements [last_nonopt,optind), which contains all
288    the options processed since those non-options were skipped.
290    `first_nonopt' and `last_nonopt' are relocated so that they describe
291    the new indices of the non-options in ARGV after they are moved.  */
293 #if defined (__STDC__) && __STDC__
294 static void exchange(
295     char **);
296 #endif
298 #ifdef WIN32
299 static void exchange(char** argv)
300 #else // WIN32
301 static void exchange(
302     argv)
303     char    **argv;
304 #endif // WIN32
306     int       bottom = first_nonopt;
307     int       middle = last_nonopt;
308     int       top = optind;
309     char     *tem;
311     /* Exchange the shorter segment with the far end of the longer segment.
312        That puts the shorter segment into the right place.
313        It leaves the longer segment in the right place overall,
314        but it consists of two parts that need to be swapped next.  */
316     while (top > middle && middle > bottom) {
317         if (top - middle > middle - bottom) {
318             /* Bottom segment is the short one.  */
319             int       len = middle - bottom;
320             register int i;
322             /* Swap it with the top part of the top segment.  */
323             for (i = 0; i < len; i++) {
324                 tem = argv[bottom + i];
325                 argv[bottom + i] = argv[top - (middle - bottom) + i];
326                 argv[top - (middle - bottom) + i] = tem;
327             }
328             /* Exclude the moved bottom segment from further swapping.  */
329             top -= len;
330         } else {
331             /* Top segment is the short one.  */
332             int       len = top - middle;
333             register int i;
335             /* Swap it with the bottom part of the bottom segment.  */
336             for (i = 0; i < len; i++) {
337                 tem = argv[bottom + i];
338                 argv[bottom + i] = argv[middle + i];
339                 argv[middle + i] = tem;
340             }
341             /* Exclude the moved top segment from further swapping.  */
342             bottom += len;
343         }
344     }
346     /* Update records for the slots the non-options now occupy.  */
348     first_nonopt += (optind - last_nonopt);
349     last_nonopt = optind;
352 /* Initialize the internal data when the first call is made.  */
354 #if defined (__STDC__) && __STDC__
355 static const char *_getopt_initialize(
356     int,
357     char *const *,
358     const char *);
359 #endif
361 #ifdef WIN32
362 static const char* _getopt_initialize(int argc,
363                                       char** argv,
364                                       const char* optstring)
365 #else // WIN32
366 static const char *_getopt_initialize(
367     argc,
368     argv,
369     optstring)
370     int argc;
371     char     *const *argv;
372     const char *optstring;
373 #endif // WIN32
375     /* Start processing options with ARGV-element 1 (since ARGV-element 0
376        is the program name); the sequence of previously skipped
377        non-option ARGV-elements is empty.  */
379     first_nonopt = last_nonopt = optind = 1;
381     nextchar = NULL;
383     posixly_correct = getenv("POSIXLY_CORRECT");
385     /* Determine how to handle the ordering of options and nonoptions.  */
387     if (optstring[0] == '-') {
388         ordering = RETURN_IN_ORDER;
389         ++optstring;
390     } else if (optstring[0] == '+') {
391         ordering = REQUIRE_ORDER;
392         ++optstring;
393     } else if (posixly_correct != NULL)
394         ordering = REQUIRE_ORDER;
395     else
396         ordering = PERMUTE;
398 #ifdef _LIBC
399     if (posixly_correct == NULL
400         && argc == original_argc && argv == original_argv) {
401         /* Bash 2.0 puts a special variable in the environment for each
402            command it runs, specifying which ARGV elements are the results of
403            file name wildcard expansion and therefore should not be
404            considered as options.  */
405         char      var[100];
407         sprintf(var, "_%d_GNU_nonoption_argv_flags_", getpid());
408         nonoption_flags = getenv(var);
409         if (nonoption_flags == NULL)
410             nonoption_flags_len = 0;
411         else
412             nonoption_flags_len = strlen(nonoption_flags);
413     } else
414         nonoption_flags_len = 0;
415 #endif
417     return optstring;
419 \f
420 /* Scan elements of ARGV (whose length is ARGC) for option characters
421    given in OPTSTRING.
423    If an element of ARGV starts with '-', and is not exactly "-" or "--",
424    then it is an option element.  The characters of this element
425    (aside from the initial '-') are option characters.  If `getopt'
426    is called repeatedly, it returns successively each of the option characters
427    from each of the option elements.
429    If `getopt' finds another option character, it returns that character,
430    updating `optind' and `nextchar' so that the next call to `getopt' can
431    resume the scan with the following option character or ARGV-element.
433    If there are no more option characters, `getopt' returns -1.
434    Then `optind' is the index in ARGV of the first ARGV-element
435    that is not an option.  (The ARGV-elements have been permuted
436    so that those that are not options now come last.)
438    OPTSTRING is a string containing the legitimate option characters.
439    If an option character is seen that is not listed in OPTSTRING,
440    return '?' after printing an error message.  If you set `opterr' to
441    zero, the error message is suppressed but we still return '?'.
443    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
444    so the following text in the same ARGV-element, or the text of the following
445    ARGV-element, is returned in `optarg'.  Two colons mean an option that
446    wants an optional arg; if there is text in the current ARGV-element,
447    it is returned in `optarg', otherwise `optarg' is set to zero.
449    If OPTSTRING starts with `-' or `+', it requests different methods of
450    handling the non-option ARGV-elements.
451    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
453    Long-named options begin with `--' instead of `-'.
454    Their names may be abbreviated as long as the abbreviation is unique
455    or is an exact match for some defined option.  If they have an
456    argument, it follows the option name in the same ARGV-element, separated
457    from the option name by a `=', or else the in next ARGV-element.
458    When `getopt' finds a long-named option, it returns 0 if that option's
459    `flag' field is nonzero, the value of the option's `val' field
460    if the `flag' field is zero.
462    The elements of ARGV aren't really const, because we permute them.
463    But we pretend they're const in the prototype to be compatible
464    with other systems.
466    LONGOPTS is a vector of `struct option' terminated by an
467    element containing a name which is zero.
469    LONGIND returns the index in LONGOPT of the long-named option found.
470    It is only valid when a long-named option has been found by the most
471    recent call.
473    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
474    long-named options.  */
476 #ifdef WIN32
477 int _getopt_internal(int argc,
478                      char** argv,
479                      const char *optstring,
480                      const struct option *longopts,
481                      int* longind,
482                      int long_only)
483 #else // WIN32
484 int _getopt_internal(
485     argc,
486     argv,
487     optstring,
488     longopts,
489     longind,
490     long_only)
491     int argc;
492     char     *const *argv;
493     const char *optstring;
494     const struct option *longopts;
495     int      *longind;
496     int long_only;
497 #endif // WIN32
499     optarg = NULL;
501     if (!__getopt_initialized || optind == 0) {
502         optstring = _getopt_initialize(argc, argv, optstring);
503         optind = 1;     /* Don't scan ARGV[0], the program name.  */
504         __getopt_initialized = 1;
505     }
507     /* Test whether ARGV[optind] points to a non-option argument.
508        Either it does not have option syntax, or there is an environment flag
509        from the shell indicating it is not an option.  The later information
510        is only used when the used in the GNU libc.  */
511 #ifdef _LIBC
512 #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'        \
513                      || (optind < nonoption_flags_len                         \
514                          && nonoption_flags[optind] == '1'))
515 #else
516 #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
517 #endif
519     if (nextchar == NULL || *nextchar == '\0') {
520         /* Advance to the next ARGV-element.  */
522         /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
523            moved back by the user (who may also have changed the arguments).  */
524         if (last_nonopt > optind)
525             last_nonopt = optind;
526         if (first_nonopt > optind)
527             first_nonopt = optind;
529         if (ordering == PERMUTE) {
530             /* If we have just processed some options following some non-options,
531                exchange them so that the options come first.  */
533             if (first_nonopt != last_nonopt && last_nonopt != optind)
534                 exchange((char **) argv);
535             else if (last_nonopt != optind)
536                 first_nonopt = optind;
538             /* Skip any additional non-options
539                and extend the range of non-options previously skipped.  */
541             while (optind < argc && NONOPTION_P)
542                 optind++;
543             last_nonopt = optind;
544         }
546         /* The special ARGV-element `--' means premature end of options.
547            Skip it like a null option,
548            then exchange with previous non-options as if it were an option,
549            then skip everything else like a non-option.  */
551         if (optind != argc && !strcmp(argv[optind], "--")) {
552             optind++;
554             if (first_nonopt != last_nonopt && last_nonopt != optind)
555                 exchange((char **) argv);
556             else if (first_nonopt == last_nonopt)
557                 first_nonopt = optind;
558             last_nonopt = argc;
560             optind = argc;
561         }
563         /* If we have done all the ARGV-elements, stop the scan
564            and back over any non-options that we skipped and permuted.  */
566         if (optind == argc) {
567             /* Set the next-arg-index to point at the non-options
568                that we previously skipped, so the caller will digest them.  */
569             if (first_nonopt != last_nonopt)
570                 optind = first_nonopt;
571             return -1;
572         }
574         /* If we have come to a non-option and did not permute it,
575            either stop the scan or describe it to the caller and pass it by.  */
577         if (NONOPTION_P) {
578             if (ordering == REQUIRE_ORDER)
579                 return -1;
580             optarg = argv[optind++];
581             return 1;
582         }
584         /* We have found another option-ARGV-element.
585            Skip the initial punctuation.  */
587         nextchar = (argv[optind] + 1
588                     + (longopts != NULL && argv[optind][1] == '-'));
589     }
591     /* Decode the current option-ARGV-element.  */
593     /* Check whether the ARGV-element is a long option.
595        If long_only and the ARGV-element has the form "-f", where f is
596        a valid short option, don't consider it an abbreviated form of
597        a long option that starts with f.  Otherwise there would be no
598        way to give the -f short option.
600        On the other hand, if there's a long option "fubar" and
601        the ARGV-element is "-fu", do consider that an abbreviation of
602        the long option, just like "--fu", and not "-f" with arg "u".
604        This distinction seems to be the most useful approach.  */
606     if (longopts != NULL
607         && (argv[optind][1] == '-' || (long_only && (argv[optind][2]
608                                                      || !my_index(optstring,
609                                                                   argv[optind]
610                                                                   [1]))))) {
611         char     *nameend;
612         const struct option *p;
613         const struct option *pfound = NULL;
614         int       exact = 0;
615         int       ambig = 0;
616         int       indfound = -1;
617         int       option_index;
619         for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
620             /* Do nothing.  */ ;
622         /* Test all long options for either exact match
623            or abbreviated matches.  */
624         for (p = longopts, option_index = 0; p->name; p++, option_index++)
625             if (!strncmp(p->name, nextchar, nameend - nextchar)) {
626                 if ((unsigned int) (nameend - nextchar)
627                     == (unsigned int) strlen(p->name)) {
628                     /* Exact match found.  */
629                     pfound = p;
630                     indfound = option_index;
631                     exact = 1;
632                     break;
633                 } else if (pfound == NULL) {
634                     /* First nonexact match found.  */
635                     pfound = p;
636                     indfound = option_index;
637                 } else
638                     /* Second or later nonexact match found.  */
639                     ambig = 1;
640             }
642         if (ambig && !exact) {
643             if (opterr)
644                 fprintf(stderr, _("%s: option `%s' is ambiguous\n"),
645                         argv[0], argv[optind]);
646             nextchar += strlen(nextchar);
647             optind++;
648             optopt = 0;
649             return '?';
650         }
652         if (pfound != NULL) {
653             option_index = indfound;
654             optind++;
655             if (*nameend) {
656                 /* Don't test has_arg with >, because some C compilers don't
657                    allow it to be used on enums.  */
658                 if (pfound->has_arg)
659                     optarg = nameend + 1;
660                 else {
661                     if (opterr) {
662                         if (argv[optind - 1][1] == '-')
663                             /* --option */
664                             fprintf(stderr,
665                                     _
666                                     ("%s: option `--%s' doesn't allow an argument\n"),
667                                     argv[0], pfound->name);
668                         else
669                             /* +option or -option */
670                             fprintf(stderr,
671                                     _
672                                     ("%s: option `%c%s' doesn't allow an argument\n"),
673                                     argv[0], argv[optind - 1][0],
674                                     pfound->name);
675                     }
676                     nextchar += strlen(nextchar);
678                     optopt = pfound->val;
679                     return '?';
680                 }
681             } else if (pfound->has_arg == 1) {
682                 if (optind < argc)
683                     optarg = argv[optind++];
684                 else {
685                     if (opterr)
686                         fprintf(stderr,
687                                 _("%s: option `%s' requires an argument\n"),
688                                 argv[0], argv[optind - 1]);
689                     nextchar += strlen(nextchar);
690                     optopt = pfound->val;
691                     return optstring[0] == ':' ? ':' : '?';
692                 }
693             }
694             nextchar += strlen(nextchar);
695             if (longind != NULL)
696                 *longind = option_index;
697             if (pfound->flag) {
698                 *(pfound->flag) = pfound->val;
699                 return 0;
700             }
701             return pfound->val;
702         }
704         /* Can't find it as a long option.  If this is not getopt_long_only,
705            or the option starts with '--' or is not a valid short
706            option, then it's an error.
707            Otherwise interpret it as a short option.  */
708         if (!long_only || argv[optind][1] == '-'
709             || my_index(optstring, *nextchar) == NULL) {
710             if (opterr) {
711                 if (argv[optind][1] == '-')
712                     /* --option */
713                     fprintf(stderr, _("%s: unrecognized option `--%s'\n"),
714                             argv[0], nextchar);
715                 else
716                     /* +option or -option */
717                     fprintf(stderr, _("%s: unrecognized option `%c%s'\n"),
718                             argv[0], argv[optind][0], nextchar);
719             }
720             nextchar = (char *) "";
721             optind++;
722             optopt = 0;
723             return '?';
724         }
725     }
727     /* Look at and handle the next short option-character.  */
729     {
730         char      c = *nextchar++;
731         char     *temp = my_index(optstring, c);
733         /* Increment `optind' when we start to process its last character.  */
734         if (*nextchar == '\0')
735             ++optind;
737         if (temp == NULL || c == ':') {
738             if (opterr) {
739                 if (posixly_correct)
740                     /* 1003.2 specifies the format of this message.  */
741                     fprintf(stderr, _("%s: illegal option -- %c\n"),
742                             argv[0], c);
743                 else
744                     fprintf(stderr, _("%s: invalid option -- %c\n"),
745                             argv[0], c);
746             }
747             optopt = c;
748             return '?';
749         }
750         /* Convenience. Treat POSIX -W foo same as long option --foo */
751         if (temp[0] == 'W' && temp[1] == ';') {
752             char     *nameend;
753             const struct option *p;
754             const struct option *pfound = NULL;
755             int       exact = 0;
756             int       ambig = 0;
757             int       indfound = 0;
758             int       option_index;
760             /* This is an option that requires an argument.  */
761             if (*nextchar != '\0') {
762                 optarg = nextchar;
763                 /* If we end this ARGV-element by taking the rest as an arg,
764                    we must advance to the next element now.  */
765                 optind++;
766             } else if (optind == argc) {
767                 if (opterr) {
768                     /* 1003.2 specifies the format of this message.  */
769                     fprintf(stderr,
770                             _("%s: option requires an argument -- %c\n"),
771                             argv[0], c);
772                 }
773                 optopt = c;
774                 if (optstring[0] == ':')
775                     c = ':';
776                 else
777                     c = '?';
778                 return c;
779             } else
780                 /* We already incremented `optind' once;
781                    increment it again when taking next ARGV-elt as argument.  */
782                 optarg = argv[optind++];
784             /* optarg is now the argument, see if it's in the
785                table of longopts.  */
787             for (nextchar = nameend = optarg; *nameend && *nameend != '=';
788                  nameend++)
789                 /* Do nothing.  */ ;
791             /* Test all long options for either exact match
792                or abbreviated matches.  */
793             for (p = longopts, option_index = 0; p->name; p++, option_index++)
794                 if (!strncmp(p->name, nextchar, nameend - nextchar)) {
795                     if ((unsigned int) (nameend - nextchar) ==
796                         strlen(p->name)) {
797                         /* Exact match found.  */
798                         pfound = p;
799                         indfound = option_index;
800                         exact = 1;
801                         break;
802                     } else if (pfound == NULL) {
803                         /* First nonexact match found.  */
804                         pfound = p;
805                         indfound = option_index;
806                     } else
807                         /* Second or later nonexact match found.  */
808                         ambig = 1;
809                 }
810             if (ambig && !exact) {
811                 if (opterr)
812                     fprintf(stderr, _("%s: option `-W %s' is ambiguous\n"),
813                             argv[0], argv[optind]);
814                 nextchar += strlen(nextchar);
815                 optind++;
816                 return '?';
817             }
818             if (pfound != NULL) {
819                 option_index = indfound;
820                 if (*nameend) {
821                     /* Don't test has_arg with >, because some C compilers don't
822                        allow it to be used on enums.  */
823                     if (pfound->has_arg)
824                         optarg = nameend + 1;
825                     else {
826                         if (opterr)
827                             fprintf(stderr, _("\
828 %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name);
830                         nextchar += strlen(nextchar);
831                         return '?';
832                     }
833                 } else if (pfound->has_arg == 1) {
834                     if (optind < argc)
835                         optarg = argv[optind++];
836                     else {
837                         if (opterr)
838                             fprintf(stderr,
839                                     _
840                                     ("%s: option `%s' requires an argument\n"),
841                                     argv[0], argv[optind - 1]);
842                         nextchar += strlen(nextchar);
843                         return optstring[0] == ':' ? ':' : '?';
844                     }
845                 }
846                 nextchar += strlen(nextchar);
847                 if (longind != NULL)
848                     *longind = option_index;
849                 if (pfound->flag) {
850                     *(pfound->flag) = pfound->val;
851                     return 0;
852                 }
853                 return pfound->val;
854             }
855             nextchar = NULL;
856             return 'W'; /* Let the application handle it.   */
857         }
858         if (temp[1] == ':') {
859             if (temp[2] == ':') {
860                 /* This is an option that accepts an argument optionally.  */
861                 if (*nextchar != '\0') {
862                     optarg = nextchar;
863                     optind++;
864                 } else
865                     optarg = NULL;
866                 nextchar = NULL;
867             } else {
868                 /* This is an option that requires an argument.  */
869                 if (*nextchar != '\0') {
870                     optarg = nextchar;
871                     /* If we end this ARGV-element by taking the rest as an arg,
872                        we must advance to the next element now.  */
873                     optind++;
874                 } else if (optind == argc) {
875                     if (opterr) {
876                         /* 1003.2 specifies the format of this message.  */
877                         fprintf(stderr,
878                                 _("%s: option requires an argument -- %c\n"),
879                                 argv[0], c);
880                     }
881                     optopt = c;
882                     if (optstring[0] == ':')
883                         c = ':';
884                     else
885                         c = '?';
886                 } else
887                     /* We already incremented `optind' once;
888                        increment it again when taking next ARGV-elt as argument.  */
889                     optarg = argv[optind++];
890                 nextchar = NULL;
891             }
892         }
893         return c;
894     }
897 #ifdef WIN32
898 int getopt(
899     int argc,
900     char** argv,
901     const char* optstring)
902 #else // WIN32
903 int getopt(
904     argc,
905     argv,
906     optstring)
907     int argc;
908     char     *const *argv;
909     const char *optstring;
910 #endif // WIN32
912     return _getopt_internal(argc, argv, optstring,
913                             (const struct option *) 0, (int *) 0, 0);
916 #endif                          /* Not ELIDE_CODE.  */
917 \f
918 #ifdef TEST
920 /* Compile with -DTEST to make an executable for use in testing
921    the above definition of `getopt'.  */
923 int main(
924     argc,
925     argv)
926     int argc;
927     char    **argv;
929     int       c;
930     int       digit_optind = 0;
932     while (1) {
933         int       this_option_optind = optind ? optind : 1;
935         c = getopt(argc, argv, "abc:d:0123456789");
936         if (c == -1)
937             break;
939         switch (c) {
940         case '0':
941         case '1':
942         case '2':
943         case '3':
944         case '4':
945         case '5':
946         case '6':
947         case '7':
948         case '8':
949         case '9':
950             if (digit_optind != 0 && digit_optind != this_option_optind)
951                 printf("digits occur in two different argv-elements.\n");
952             digit_optind = this_option_optind;
953             printf("option %c\n", c);
954             break;
956         case 'a':
957             printf("option a\n");
958             break;
960         case 'b':
961             printf("option b\n");
962             break;
964         case 'c':
965             printf("option c with value `%s'\n", optarg);
966             break;
968         case '?':
969             break;
971         default:
972             printf("?? getopt returned character code 0%o ??\n", c);
973         }
974     }
976     if (optind < argc) {
977         printf("non-option ARGV-elements: ");
978         while (optind < argc)
979             printf("%s ", argv[optind++]);
980         printf("\n");
981     }
983     exit(0);
986 #endif                          /* TEST */