mark unused arguments in the same way throughout the code
[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!
5
6    Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
7    Free Software Foundation, Inc.
8
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.
11
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.
16
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.
21
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
32
33
34 #if !defined WIN32 && (!defined (__STDC__) || !__STDC__)
35 /* This is a separate conditional since some stdc systems
36    reject `defined (const)'.  */
37 #ifndef const
38 #define const
39 #endif
40 #endif
41
42
43 #ifdef HAVE_CONFIG_H
44 #include "../rrd_config.h"
45 #endif
46
47 #include "rrd_i18n.h"
48
49
50 #include <stdio.h>
51
52 /* Comment out all this code if we are using the GNU C Library, and are not
53    actually compiling the library itself.  This code is part of the GNU C
54    Library, but also included in many other GNU distributions.  Compiling
55    and linking in this code is a waste when using the GNU C library
56    (especially if it is a shared library).  Rather than having every GNU
57    program understand `configure --with-gnu-libc' and omit the object files,
58    it is simpler to just do this in the source for each such file.  */
59
60 #define GETOPT_INTERFACE_VERSION 2
61 #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
62 #include <gnu-versions.h>
63 #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
64 #define ELIDE_CODE
65 #endif
66 #endif
67
68 #ifndef ELIDE_CODE
69
70
71 /* This needs to come after some library #include
72    to get __GNU_LIBRARY__ defined.  */
73 #ifdef  __GNU_LIBRARY__
74 /* Don't include stdlib.h for non-GNU C libraries because some of them
75    contain conflicting prototypes for getopt.  */
76 #include <stdlib.h>
77 #include <unistd.h>
78 #endif                          /* GNU C library.  */
79
80 #ifdef VMS
81 #include <unixlib.h>
82 #if HAVE_STRING_H - 0
83 #include <string.h>
84 #endif
85 #endif
86
87 #if defined (_WIN32) && !defined (__CYGWIN32__)
88 /* It's not Unix, really.  See?  Capital letters.  */
89 #include <windows.h>
90 #define getpid() GetCurrentProcessId()
91 #endif
92
93 /* This version of `getopt' appears to the caller like standard Unix `getopt'
94    but it behaves differently for the user, since it allows the user
95    to intersperse the options with the other arguments.
96
97    As `getopt' works, it permutes the elements of ARGV so that,
98    when it is done, all the options precede everything else.  Thus
99    all application programs are extended to handle flexible argument order.
100
101    Setting the environment variable POSIXLY_CORRECT disables permutation.
102    Then the behavior is completely standard.
103
104    GNU application programs can use a third alternative mode in which
105    they can distinguish the relative order of options and other arguments.  */
106
107 #include "rrd_getopt.h"
108
109 /* For communication from `getopt' to the caller.
110    When `getopt' finds an option that takes an argument,
111    the argument value is returned here.
112    Also, when `ordering' is RETURN_IN_ORDER,
113    each non-option ARGV-element is returned here.  */
114
115 /*
116  * On some versions of Solaris, opterr and friends are defined in core libc
117  * rather than in a separate getopt module.  Define these variables only
118  * if configure found they aren't there by default.  (We assume that testing
119  * opterr is sufficient for all of these except optreset.)
120  */
121 #ifndef HAVE_INT_OPTERR
122
123 char     *optarg = NULL;
124
125 /* Index in ARGV of the next element to be scanned.
126    This is used for communication to and from the caller
127    and for communication between successive calls to `getopt'.
128
129    On entry to `getopt', zero means this is the first call; initialize.
130
131    When `getopt' returns -1, this is the index of the first of the
132    non-option elements that the caller should itself scan.
133
134    Otherwise, `optind' communicates from one call to the next
135    how much of ARGV has been scanned so far.  */
136
137 /* Callers store zero here to inhibit the error message
138    for unrecognized options.  */
139
140 int       opterr = 1;
141
142 /* Set to an option character which was unrecognized.
143    This must be initialized on some systems to avoid linking in the
144    system's own getopt implementation.  */
145
146 int       optopt = '?';
147
148 /* 1003.2 says this must be 1 before any call.  */
149 int       optind = 1;
150
151 #else
152  extern int      opterr;
153  extern int      optind;
154  extern int      optopt;
155  extern char     *optarg;
156 #endif
157
158
159 /* Formerly, initialization of getopt depended on optind==0, which
160    causes problems with re-calling getopt as programs generally don't
161    know that. */
162
163 int       __getopt_initialized = 0;
164
165 /* The next char to be scanned in the option-element
166    in which the last option character we returned was found.
167    This allows us to pick up the scan where we left off.
168
169    If this is zero, or a null string, it means resume the scan
170    by advancing to the next ARGV-element.  */
171
172 static char *nextchar;
173
174
175 /* Describe how to deal with options that follow non-option ARGV-elements.
176
177    If the caller did not specify anything,
178    the default is REQUIRE_ORDER if the environment variable
179    POSIXLY_CORRECT is defined, PERMUTE otherwise.
180
181    REQUIRE_ORDER means don't recognize them as options;
182    stop option processing when the first non-option is seen.
183    This is what Unix does.
184    This mode of operation is selected by either setting the environment
185    variable POSIXLY_CORRECT, or using `+' as the first character
186    of the list of option characters.
187
188    PERMUTE is the default.  We permute the contents of ARGV as we scan,
189    so that eventually all the non-options are at the end.  This allows options
190    to be given in any order, even with programs that were not written to
191    expect this.
192
193    RETURN_IN_ORDER is an option available to programs that were written
194    to expect options and other ARGV-elements in any order and that care about
195    the ordering of the two.  We describe each non-option ARGV-element
196    as if it were the argument of an option with character code 1.
197    Using `-' as the first character of the list of option characters
198    selects this mode of operation.
199
200    The special argument `--' forces an end of option-scanning regardless
201    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
202    `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
203
204 static enum {
205     REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
206 } ordering;
207
208 /* Value of POSIXLY_CORRECT environment variable.  */
209 static char *posixly_correct;
210 \f
211 /* we must include string as there are warnings without it ... */
212 #include <string.h>
213
214 #ifdef  __GNU_LIBRARY__
215 /* We want to avoid inclusion of string.h with non-GNU libraries
216    because there are many ways it can cause trouble.
217    On some systems, it contains special magic macros that don't work
218    in GCC.  */
219 #define my_index        strchr
220 #else
221
222 /* Avoid depending on library functions or files
223    whose names are inconsistent.  */
224
225 char     *getenv(
226     );
227
228 static char* my_index(const char* str, int chr)
229 {
230     while (*str) {
231         if (*str == chr)
232             return (char *) str;
233         str++;
234     }
235     return 0;
236 }
237
238 /* If using GCC, we can safely declare strlen this way.
239    If not using GCC, it is ok not to declare it.  */
240 #ifdef __GNUC__
241 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
242    That was relevant to code that was here before.  */
243 #if !defined (__STDC__) || !__STDC__
244 /* gcc with -traditional declares the built-in strlen to return int,
245    and has done so at least since version 2.4.5. -- rms.  */
246 extern int strlen(
247     const char *);
248 #endif                          /* not __STDC__ */
249 #endif                          /* __GNUC__ */
250
251 #endif                          /* not __GNU_LIBRARY__ */
252 \f
253 /* Handle permutation of arguments.  */
254
255 /* Describe the part of ARGV that contains non-options that have
256    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
257    `last_nonopt' is the index after the last of them.  */
258
259 static int first_nonopt;
260 static int last_nonopt;
261
262 #ifdef _LIBC
263 /* Bash 2.0 gives us an environment variable containing flags
264    indicating ARGV elements that should not be considered arguments.  */
265
266 static const char *nonoption_flags;
267 static int nonoption_flags_len;
268
269 static int original_argc;
270 static char *const *original_argv;
271
272 /* Make sure the environment variable bash 2.0 puts in the environment
273    is valid for the getopt call we must make sure that the ARGV passed
274    to getopt is that one passed to the process.  */
275 static void store_args(
276     int argc,
277     char *const *argv);
278
279 static void store_args(
280     int argc,
281     char *const *argv)
282 {
283     /* XXX This is no good solution.  We should rather copy the args so
284        that we can compare them later.  But we must not use malloc(3).  */
285     original_argc = argc;
286     original_argv = argv;
287 }
288
289 text_set_element(__libc_subinit, store_args);
290 #endif
291
292 /* Exchange two adjacent subsequences of ARGV.
293    One subsequence is elements [first_nonopt,last_nonopt)
294    which contains all the non-options that have been skipped so far.
295    The other is elements [last_nonopt,optind), which contains all
296    the options processed since those non-options were skipped.
297
298    `first_nonopt' and `last_nonopt' are relocated so that they describe
299    the new indices of the non-options in ARGV after they are moved.  */
300
301 #if defined (__STDC__) && __STDC__
302 static void exchange(
303     char **);
304 #endif
305
306 static void exchange(char** argv)
307 {
308     int       bottom = first_nonopt;
309     int       middle = last_nonopt;
310     int       top = optind;
311     char     *tem;
312
313     /* Exchange the shorter segment with the far end of the longer segment.
314        That puts the shorter segment into the right place.
315        It leaves the longer segment in the right place overall,
316        but it consists of two parts that need to be swapped next.  */
317
318     while (top > middle && middle > bottom) {
319         if (top - middle > middle - bottom) {
320             /* Bottom segment is the short one.  */
321             int       len = middle - bottom;
322             register int i;
323
324             /* Swap it with the top part of the top segment.  */
325             for (i = 0; i < len; i++) {
326                 tem = argv[bottom + i];
327                 argv[bottom + i] = argv[top - (middle - bottom) + i];
328                 argv[top - (middle - bottom) + i] = tem;
329             }
330             /* Exclude the moved bottom segment from further swapping.  */
331             top -= len;
332         } else {
333             /* Top segment is the short one.  */
334             int       len = top - middle;
335             register int i;
336
337             /* Swap it with the bottom part of the bottom segment.  */
338             for (i = 0; i < len; i++) {
339                 tem = argv[bottom + i];
340                 argv[bottom + i] = argv[middle + i];
341                 argv[middle + i] = tem;
342             }
343             /* Exclude the moved top segment from further swapping.  */
344             bottom += len;
345         }
346     }
347
348     /* Update records for the slots the non-options now occupy.  */
349
350     first_nonopt += (optind - last_nonopt);
351     last_nonopt = optind;
352 }
353
354 /* Initialize the internal data when the first call is made.  */
355
356 #if defined (__STDC__) && __STDC__
357 static const char *_getopt_initialize(
358     int,
359     char *const *,
360     const char *);
361 #endif
362 static const char* _getopt_initialize(int argc,
363                                       char** argv,
364                                       const char* optstring)
365 {
366     /* Start processing options with ARGV-element 1 (since ARGV-element 0
367        is the program name); the sequence of previously skipped
368        non-option ARGV-elements is empty.  */
369
370     first_nonopt = last_nonopt = optind = 1;
371
372     nextchar = NULL;
373
374     posixly_correct = getenv("POSIXLY_CORRECT");
375
376     /* Determine how to handle the ordering of options and nonoptions.  */
377
378     if (optstring[0] == '-') {
379         ordering = RETURN_IN_ORDER;
380         ++optstring;
381     } else if (optstring[0] == '+') {
382         ordering = REQUIRE_ORDER;
383         ++optstring;
384     } else if (posixly_correct != NULL)
385         ordering = REQUIRE_ORDER;
386     else
387         ordering = PERMUTE;
388
389 #ifdef _LIBC
390     if (posixly_correct == NULL
391         && argc == original_argc && argv == original_argv) {
392         /* Bash 2.0 puts a special variable in the environment for each
393            command it runs, specifying which ARGV elements are the results of
394            file name wildcard expansion and therefore should not be
395            considered as options.  */
396         char      var[100];
397
398         sprintf(var, "_%d_GNU_nonoption_argv_flags_", getpid());
399         nonoption_flags = getenv(var);
400         if (nonoption_flags == NULL)
401             nonoption_flags_len = 0;
402         else
403             nonoption_flags_len = strlen(nonoption_flags);
404     } else
405         nonoption_flags_len = 0;
406 #endif
407
408     return optstring;
409 }
410 \f
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(int argc,
468                      char** argv,
469                      const char *optstring,
470                      const struct option *longopts,
471                      int* longind,
472                      int long_only)
473 {
474     optarg = NULL;
475
476     if (!__getopt_initialized || optind == 0) {
477         optstring = _getopt_initialize(argc, argv, optstring);
478         optind = 1;     /* Don't scan ARGV[0], the program name.  */
479         __getopt_initialized = 1;
480     }
481
482     /* Test whether ARGV[optind] points to a non-option argument.
483        Either it does not have option syntax, or there is an environment flag
484        from the shell indicating it is not an option.  The later information
485        is only used when the used in the GNU libc.  */
486 #ifdef _LIBC
487 #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'        \
488                      || (optind < nonoption_flags_len                         \
489                          && nonoption_flags[optind] == '1'))
490 #else
491 #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
492 #endif
493
494     if (nextchar == NULL || *nextchar == '\0') {
495         /* Advance to the next ARGV-element.  */
496
497         /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
498            moved back by the user (who may also have changed the arguments).  */
499         if (last_nonopt > optind)
500             last_nonopt = optind;
501         if (first_nonopt > optind)
502             first_nonopt = optind;
503
504         if (ordering == PERMUTE) {
505             /* If we have just processed some options following some non-options,
506                exchange them so that the options come first.  */
507
508             if (first_nonopt != last_nonopt && last_nonopt != optind)
509                 exchange((char **) argv);
510             else if (last_nonopt != optind)
511                 first_nonopt = optind;
512
513             /* Skip any additional non-options
514                and extend the range of non-options previously skipped.  */
515
516             while (optind < argc && NONOPTION_P)
517                 optind++;
518             last_nonopt = optind;
519         }
520
521         /* The special ARGV-element `--' means premature end of options.
522            Skip it like a null option,
523            then exchange with previous non-options as if it were an option,
524            then skip everything else like a non-option.  */
525
526         if (optind != argc && !strcmp(argv[optind], "--")) {
527             optind++;
528
529             if (first_nonopt != last_nonopt && last_nonopt != optind)
530                 exchange((char **) argv);
531             else if (first_nonopt == last_nonopt)
532                 first_nonopt = optind;
533             last_nonopt = argc;
534
535             optind = argc;
536         }
537
538         /* If we have done all the ARGV-elements, stop the scan
539            and back over any non-options that we skipped and permuted.  */
540
541         if (optind == argc) {
542             /* Set the next-arg-index to point at the non-options
543                that we previously skipped, so the caller will digest them.  */
544             if (first_nonopt != last_nonopt)
545                 optind = first_nonopt;
546             return -1;
547         }
548
549         /* If we have come to a non-option and did not permute it,
550            either stop the scan or describe it to the caller and pass it by.  */
551
552         if (NONOPTION_P) {
553             if (ordering == REQUIRE_ORDER)
554                 return -1;
555             optarg = argv[optind++];
556             return 1;
557         }
558
559         /* We have found another option-ARGV-element.
560            Skip the initial punctuation.  */
561
562         nextchar = (argv[optind] + 1
563                     + (longopts != NULL && argv[optind][1] == '-'));
564     }
565
566     /* Decode the current option-ARGV-element.  */
567
568     /* Check whether the ARGV-element is a long option.
569
570        If long_only and the ARGV-element has the form "-f", where f is
571        a valid short option, don't consider it an abbreviated form of
572        a long option that starts with f.  Otherwise there would be no
573        way to give the -f short option.
574
575        On the other hand, if there's a long option "fubar" and
576        the ARGV-element is "-fu", do consider that an abbreviation of
577        the long option, just like "--fu", and not "-f" with arg "u".
578
579        This distinction seems to be the most useful approach.  */
580
581     if (longopts != NULL
582         && (argv[optind][1] == '-' || (long_only && (argv[optind][2]
583                                                      || !my_index(optstring,
584                                                                   argv[optind]
585                                                                   [1]))))) {
586         char     *nameend;
587         const struct option *p;
588         const struct option *pfound = NULL;
589         int       exact = 0;
590         int       ambig = 0;
591         int       indfound = -1;
592         int       option_index;
593
594         for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
595             /* Do nothing.  */ ;
596
597         /* Test all long options for either exact match
598            or abbreviated matches.  */
599         for (p = longopts, option_index = 0; p->name; p++, option_index++)
600             if (!strncmp(p->name, nextchar, nameend - nextchar)) {
601                 if ((unsigned int) (nameend - nextchar)
602                     == (unsigned int) strlen(p->name)) {
603                     /* Exact match found.  */
604                     pfound = p;
605                     indfound = option_index;
606                     exact = 1;
607                     break;
608                 } else if (pfound == NULL) {
609                     /* First nonexact match found.  */
610                     pfound = p;
611                     indfound = option_index;
612                 } else
613                     /* Second or later nonexact match found.  */
614                     ambig = 1;
615             }
616
617         if (ambig && !exact) {
618             if (opterr)
619                 fprintf(stderr, _("%s: option `%s' is ambiguous\n"),
620                         argv[0], argv[optind]);
621             nextchar += strlen(nextchar);
622             optind++;
623             optopt = 0;
624             return '?';
625         }
626
627         if (pfound != NULL) {
628             option_index = indfound;
629             optind++;
630             if (*nameend) {
631                 /* Don't test has_arg with >, because some C compilers don't
632                    allow it to be used on enums.  */
633                 if (pfound->has_arg)
634                     optarg = nameend + 1;
635                 else {
636                     if (opterr) {
637                         if (argv[optind - 1][1] == '-')
638                             /* --option */
639                             fprintf(stderr,
640                                     _
641                                     ("%s: option `--%s' doesn't allow an argument\n"),
642                                     argv[0], pfound->name);
643                         else
644                             /* +option or -option */
645                             fprintf(stderr,
646                                     _
647                                     ("%s: option `%c%s' doesn't allow an argument\n"),
648                                     argv[0], argv[optind - 1][0],
649                                     pfound->name);
650                     }
651                     nextchar += strlen(nextchar);
652
653                     optopt = pfound->val;
654                     return '?';
655                 }
656             } else if (pfound->has_arg == 1) {
657                 if (optind < argc)
658                     optarg = argv[optind++];
659                 else {
660                     if (opterr)
661                         fprintf(stderr,
662                                 _("%s: option `%s' requires an argument\n"),
663                                 argv[0], argv[optind - 1]);
664                     nextchar += strlen(nextchar);
665                     optopt = pfound->val;
666                     return optstring[0] == ':' ? ':' : '?';
667                 }
668             }
669             nextchar += strlen(nextchar);
670             if (longind != NULL)
671                 *longind = option_index;
672             if (pfound->flag) {
673                 *(pfound->flag) = pfound->val;
674                 return 0;
675             }
676             return pfound->val;
677         }
678
679         /* Can't find it as a long option.  If this is not getopt_long_only,
680            or the option starts with '--' or is not a valid short
681            option, then it's an error.
682            Otherwise interpret it as a short option.  */
683         if (!long_only || argv[optind][1] == '-'
684             || my_index(optstring, *nextchar) == NULL) {
685             if (opterr) {
686                 if (argv[optind][1] == '-')
687                     /* --option */
688                     fprintf(stderr, _("%s: unrecognized option `--%s'\n"),
689                             argv[0], nextchar);
690                 else
691                     /* +option or -option */
692                     fprintf(stderr, _("%s: unrecognized option `%c%s'\n"),
693                             argv[0], argv[optind][0], nextchar);
694             }
695             nextchar = (char *) "";
696             optind++;
697             optopt = 0;
698             return '?';
699         }
700     }
701
702     /* Look at and handle the next short option-character.  */
703
704     {
705         char      c = *nextchar++;
706         char     *temp = my_index(optstring, c);
707
708         /* Increment `optind' when we start to process its last character.  */
709         if (*nextchar == '\0')
710             ++optind;
711
712         if (temp == NULL || c == ':') {
713             if (opterr) {
714                 if (posixly_correct)
715                     /* 1003.2 specifies the format of this message.  */
716                     fprintf(stderr, _("%s: illegal option -- %c\n"),
717                             argv[0], c);
718                 else
719                     fprintf(stderr, _("%s: invalid option -- %c\n"),
720                             argv[0], c);
721             }
722             optopt = c;
723             return '?';
724         }
725         /* Convenience. Treat POSIX -W foo same as long option --foo */
726         if (temp[0] == 'W' && temp[1] == ';') {
727             char     *nameend;
728             const struct option *p;
729             const struct option *pfound = NULL;
730             int       exact = 0;
731             int       ambig = 0;
732             int       indfound = 0;
733             int       option_index;
734
735             /* This is an option that requires an argument.  */
736             if (*nextchar != '\0') {
737                 optarg = nextchar;
738                 /* If we end this ARGV-element by taking the rest as an arg,
739                    we must advance to the next element now.  */
740                 optind++;
741             } else if (optind == argc) {
742                 if (opterr) {
743                     /* 1003.2 specifies the format of this message.  */
744                     fprintf(stderr,
745                             _("%s: option requires an argument -- %c\n"),
746                             argv[0], c);
747                 }
748                 optopt = c;
749                 if (optstring[0] == ':')
750                     c = ':';
751                 else
752                     c = '?';
753                 return c;
754             } else
755                 /* We already incremented `optind' once;
756                    increment it again when taking next ARGV-elt as argument.  */
757                 optarg = argv[optind++];
758
759             /* optarg is now the argument, see if it's in the
760                table of longopts.  */
761
762             for (nextchar = nameend = optarg; *nameend && *nameend != '=';
763                  nameend++)
764                 /* Do nothing.  */ ;
765
766             /* Test all long options for either exact match
767                or abbreviated matches.  */
768             for (p = longopts, option_index = 0; p->name; p++, option_index++)
769                 if (!strncmp(p->name, nextchar, nameend - nextchar)) {
770                     if ((unsigned int) (nameend - nextchar) ==
771                         strlen(p->name)) {
772                         /* Exact match found.  */
773                         pfound = p;
774                         indfound = option_index;
775                         exact = 1;
776                         break;
777                     } else if (pfound == NULL) {
778                         /* First nonexact match found.  */
779                         pfound = p;
780                         indfound = option_index;
781                     } else
782                         /* Second or later nonexact match found.  */
783                         ambig = 1;
784                 }
785             if (ambig && !exact) {
786                 if (opterr)
787                     fprintf(stderr, _("%s: option `-W %s' is ambiguous\n"),
788                             argv[0], argv[optind]);
789                 nextchar += strlen(nextchar);
790                 optind++;
791                 return '?';
792             }
793             if (pfound != NULL) {
794                 option_index = indfound;
795                 if (*nameend) {
796                     /* Don't test has_arg with >, because some C compilers don't
797                        allow it to be used on enums.  */
798                     if (pfound->has_arg)
799                         optarg = nameend + 1;
800                     else {
801                         if (opterr)
802                             fprintf(stderr, _("\
803 %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name);
804
805                         nextchar += strlen(nextchar);
806                         return '?';
807                     }
808                 } else if (pfound->has_arg == 1) {
809                     if (optind < argc)
810                         optarg = argv[optind++];
811                     else {
812                         if (opterr)
813                             fprintf(stderr,
814                                     _
815                                     ("%s: option `%s' requires an argument\n"),
816                                     argv[0], argv[optind - 1]);
817                         nextchar += strlen(nextchar);
818                         return optstring[0] == ':' ? ':' : '?';
819                     }
820                 }
821                 nextchar += strlen(nextchar);
822                 if (longind != NULL)
823                     *longind = option_index;
824                 if (pfound->flag) {
825                     *(pfound->flag) = pfound->val;
826                     return 0;
827                 }
828                 return pfound->val;
829             }
830             nextchar = NULL;
831             return 'W'; /* Let the application handle it.   */
832         }
833         if (temp[1] == ':') {
834             if (temp[2] == ':') {
835                 /* This is an option that accepts an argument optionally.  */
836                 if (*nextchar != '\0') {
837                     optarg = nextchar;
838                     optind++;
839                 } else
840                     optarg = NULL;
841                 nextchar = NULL;
842             } else {
843                 /* This is an option that requires an argument.  */
844                 if (*nextchar != '\0') {
845                     optarg = nextchar;
846                     /* If we end this ARGV-element by taking the rest as an arg,
847                        we must advance to the next element now.  */
848                     optind++;
849                 } else if (optind == argc) {
850                     if (opterr) {
851                         /* 1003.2 specifies the format of this message.  */
852                         fprintf(stderr,
853                                 _("%s: option requires an argument -- %c\n"),
854                                 argv[0], c);
855                     }
856                     optopt = c;
857                     if (optstring[0] == ':')
858                         c = ':';
859                     else
860                         c = '?';
861                 } else
862                     /* We already incremented `optind' once;
863                        increment it again when taking next ARGV-elt as argument.  */
864                     optarg = argv[optind++];
865                 nextchar = NULL;
866             }
867         }
868         return c;
869     }
870 }
871
872 int getopt(
873     int argc,
874     char** argv,
875     const char* optstring)
876 {
877     return _getopt_internal(argc, argv, optstring,
878                             (const struct option *) 0, (int *) 0, 0);
879 }
880
881 #endif                          /* Not ELIDE_CODE.  */
882 \f
883 #ifdef TEST
884
885 /* Compile with -DTEST to make an executable for use in testing
886    the above definition of `getopt'.  */
887
888 int main(
889     argc,
890     argv)
891     int argc;
892     char    **argv;
893 {
894     int       c;
895     int       digit_optind = 0;
896
897     while (1) {
898         int       this_option_optind = optind ? optind : 1;
899
900         c = getopt(argc, argv, "abc:d:0123456789");
901         if (c == -1)
902             break;
903
904         switch (c) {
905         case '0':
906         case '1':
907         case '2':
908         case '3':
909         case '4':
910         case '5':
911         case '6':
912         case '7':
913         case '8':
914         case '9':
915             if (digit_optind != 0 && digit_optind != this_option_optind)
916                 printf("digits occur in two different argv-elements.\n");
917             digit_optind = this_option_optind;
918             printf("option %c\n", c);
919             break;
920
921         case 'a':
922             printf("option a\n");
923             break;
924
925         case 'b':
926             printf("option b\n");
927             break;
928
929         case 'c':
930             printf("option c with value `%s'\n", optarg);
931             break;
932
933         case '?':
934             break;
935
936         default:
937             printf("?? getopt returned character code 0%o ??\n", c);
938         }
939     }
940
941     if (optind < argc) {
942         printf("non-option ARGV-elements: ");
943         while (optind < argc)
944             printf("%s ", argv[optind++]);
945         printf("\n");
946     }
947
948     exit(0);
949 }
950
951 #endif                          /* TEST */