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