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