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