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