]> git.sesse.net Git - vlc/blob - src/extras/getopt.c
- Call dgettext directly with shared libvlc and libtool
[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 /* Overkill. */
34 #include <vlc/vlc.h>
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #if !defined (__STDC__) || !__STDC__
41 /* This is a separate conditional since some stdc systems
42    reject `defined (const)'.  */
43 #ifndef const
44 #define const
45 #endif
46 #endif
47
48 #include <stdio.h>
49
50 /* Comment out all this code if we are using the GNU C Library, and are not
51    actually compiling the library itself.  This code is part of the GNU C
52    Library, but also included in many other GNU distributions.  Compiling
53    and linking in this code is a waste when using the GNU C library
54    (especially if it is a shared library).  Rather than having every GNU
55    program understand `configure --with-gnu-libc' and omit the object files,
56    it is simpler to just do this in the source for each such file.  */
57
58 #define GETOPT_INTERFACE_VERSION 2
59 #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
60 #include <gnu-versions.h>
61 #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
62 #define ELIDE_CODE
63 #endif
64 #endif
65
66 #ifndef ELIDE_CODE
67
68 /* This needs to come after some library #include
69    to get __GNU_LIBRARY__ defined.  */
70 #ifdef  __GNU_LIBRARY__
71 /* Don't include stdlib.h for non-GNU C libraries because some of them
72    contain conflicting prototypes for getopt.  */
73 #include <stdlib.h>
74 #include <unistd.h>
75 #endif /* GNU C library.  */
76
77 #ifdef VMS
78 #include <unixlib.h>
79 #if HAVE_STRING_H - 0
80 #include <string.h>
81 #ifdef STRNCASECMP_IN_STRINGS_H
82 #   include <strings.h>
83 #endif
84 #endif
85 #endif
86
87 #if defined (WIN32) && !defined (__CYGWIN32__) || defined(UNDER_CE)
88 /* It's not Unix, really.  See?  Capital letters.  */
89 #include <windows.h>
90 #define getpid() GetCurrentProcessId()
91 #endif
92
93 #ifndef _
94 /* This is for other GNU distributions with internationalized messages.
95    When compiling libc, the _ macro is predefined.  */
96 #ifdef HAVE_LIBINTL_H
97 #include <libintl.h>
98 #define _(msgid)        gettext (msgid)
99 #else
100 #define _(msgid)        (msgid)
101 #endif
102 #endif
103
104 /* This version of `getopt' appears to the caller like standard Unix `getopt'
105    but it behaves differently for the user, since it allows the user
106    to intersperse the options with the other arguments.
107
108    As `getopt' works, it permutes the elements of ARGV so that,
109    when it is done, all the options precede everything else.  Thus
110    all application programs are extended to handle flexible argument order.
111
112    Setting the environment variable POSIXLY_CORRECT disables permutation.
113    Then the behavior is completely standard.
114
115    GNU application programs can use a third alternative mode in which
116    they can distinguish the relative order of options and other arguments.  */
117
118 #include "getopt.h"
119
120 /* For communication from `getopt' to the caller.
121    When `getopt' finds an option that takes an argument,
122    the argument value is returned here.
123    Also, when `ordering' is RETURN_IN_ORDER,
124    each non-option ARGV-element is returned here.  */
125
126 char *optarg = NULL;
127
128 /* Index in ARGV of the next element to be scanned.
129    This is used for communication to and from the caller
130    and for communication between successive calls to `getopt'.
131
132    On entry to `getopt', zero means this is the first call; initialize.
133
134    When `getopt' returns -1, this is the index of the first of the
135    non-option elements that the caller should itself scan.
136
137    Otherwise, `optind' communicates from one call to the next
138    how much of ARGV has been scanned so far.  */
139
140 /* 1003.2 says this must be 1 before any call.  */
141 int optind = 1;
142
143 /* Formerly, initialization of getopt depended on optind==0, which
144    causes problems with re-calling getopt as programs generally don't
145    know that. */
146
147 int __getopt_initialized = 0;
148
149 /* The next char to be scanned in the option-element
150    in which the last option character we returned was found.
151    This allows us to pick up the scan where we left off.
152
153    If this is zero, or a null string, it means resume the scan
154    by advancing to the next ARGV-element.  */
155
156 static char *nextchar;
157
158 /* Callers store zero here to inhibit the error message
159    for unrecognized options.  */
160
161 int opterr = 1;
162
163 /* Set to an option character which was unrecognized.
164    This must be initialized on some systems to avoid linking in the
165    system's own getopt implementation.  */
166
167 int optopt = '?';
168
169 /* Describe how to deal with options that follow non-option ARGV-elements.
170
171    If the caller did not specify anything,
172    the default is REQUIRE_ORDER if the environment variable
173    POSIXLY_CORRECT is defined, PERMUTE otherwise.
174
175    REQUIRE_ORDER means don't recognize them as options;
176    stop option processing when the first non-option is seen.
177    This is what Unix does.
178    This mode of operation is selected by either setting the environment
179    variable POSIXLY_CORRECT, or using `+' as the first character
180    of the list of option characters.
181
182    PERMUTE is the default.  We permute the contents of ARGV as we scan,
183    so that eventually all the non-options are at the end.  This allows options
184    to be given in any order, even with programs that were not written to
185    expect this.
186
187    RETURN_IN_ORDER is an option available to programs that were written
188    to expect options and other ARGV-elements in any order and that care about
189    the ordering of the two.  We describe each non-option ARGV-element
190    as if it were the argument of an option with character code 1.
191    Using `-' as the first character of the list of option characters
192    selects this mode of operation.
193
194    The special argument `--' forces an end of option-scanning regardless
195    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
196    `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
197
198 static enum
199 {
200         REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
201 }
202 ordering;
203
204 /* Value of POSIXLY_CORRECT environment variable.  */
205 static char *posixly_correct;
206 \f
207 #ifdef  __GNU_LIBRARY__
208 /* We want to avoid inclusion of string.h with non-GNU libraries
209    because there are many ways it can cause trouble.
210    On some systems, it contains special magic macros that don't work
211    in GCC.  */
212 #include <string.h>
213 #define my_index        strchr
214 #else
215
216 /* Avoid depending on library functions or files
217    whose names are inconsistent.  */
218
219 static char *
220      my_index(str, chr)
221      const char *str;
222      int chr;
223 {
224         while (*str)
225         {
226                 if (*str == chr)
227                         return (char *) str;
228                 str++;
229         }
230         return 0;
231 }
232
233 /* If using GCC, we can safely declare strlen this way.
234    If not using GCC, it is ok not to declare it.  */
235 #ifdef __GNUC__
236 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
237    That was relevant to code that was here before.  */
238 #if !defined (__STDC__) || !__STDC__
239 /* gcc with -traditional declares the built-in strlen to return int,
240    and has done so at least since version 2.4.5. -- rms.  */
241 extern int strlen(const char *);
242
243 #endif /* not __STDC__ */
244 #endif /* __GNUC__ */
245
246 #endif /* not __GNU_LIBRARY__ */
247 \f
248 /* Handle permutation of arguments.  */
249
250 /* Describe the part of ARGV that contains non-options that have
251    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
252    `last_nonopt' is the index after the last of them.  */
253
254 static int first_nonopt;
255 static int last_nonopt;
256
257 #ifdef _LIBC
258 /* Bash 2.0 gives us an environment variable containing flags
259    indicating ARGV elements that should not be considered arguments.  */
260
261 static const char *nonoption_flags;
262 static int nonoption_flags_len;
263
264 static int original_argc;
265 static char *const *original_argv;
266
267 /* Make sure the environment variable bash 2.0 puts in the environment
268    is valid for the getopt call we must make sure that the ARGV passed
269    to getopt is that one passed to the process.  */
270 static void store_args(int argc, char *const *argv) __attribute__((unused));
271      static void
272           store_args(int argc, char *const *argv)
273 {
274         /* XXX This is no good solution.  We should rather copy the args so
275            that we can compare them later.  But we must not use malloc(3).  */
276         original_argc = argc;
277         original_argv = argv;
278 }
279 text_set_element(__libc_subinit, store_args);
280 #endif
281
282 /* Exchange two adjacent subsequences of ARGV.
283    One subsequence is elements [first_nonopt,last_nonopt)
284    which contains all the non-options that have been skipped so far.
285    The other is elements [last_nonopt,optind), which contains all
286    the options processed since those non-options were skipped.
287
288    `first_nonopt' and `last_nonopt' are relocated so that they describe
289    the new indices of the non-options in ARGV after they are moved.  */
290
291 #if defined (__STDC__) && __STDC__
292 static void exchange(char **);
293
294 #endif
295
296 static void
297      exchange(argv)
298      char **argv;
299 {
300         int bottom = first_nonopt;
301         int middle = last_nonopt;
302         int top = optind;
303         char *tem;
304
305         /* Exchange the shorter segment with the far end of the longer segment.
306            That puts the shorter segment into the right place.
307            It leaves the longer segment in the right place overall,
308            but it consists of two parts that need to be swapped next.  */
309
310         while (top > middle && middle > bottom)
311         {
312                 if (top - middle > middle - bottom)
313                 {
314                         /* Bottom segment is the short one.  */
315                         int len = middle - bottom;
316                         register int i;
317
318                         /* Swap it with the top part of the top segment.  */
319                         for (i = 0; i < len; i++)
320                         {
321                                 tem = argv[bottom + i];
322                                 argv[bottom + i] = argv[top - (middle - bottom) + i];
323                                 argv[top - (middle - bottom) + i] = tem;
324                         }
325                         /* Exclude the moved bottom segment from further swapping.  */
326                         top -= len;
327                 }
328                 else
329                 {
330                         /* Top segment is the short one.  */
331                         int len = top - middle;
332                         register int i;
333
334                         /* Swap it with the bottom part of the bottom segment.  */
335                         for (i = 0; i < len; i++)
336                         {
337                                 tem = argv[bottom + i];
338                                 argv[bottom + i] = argv[middle + i];
339                                 argv[middle + i] = tem;
340                         }
341                         /* Exclude the moved top segment from further swapping.  */
342                         bottom += len;
343                 }
344         }
345
346         /* Update records for the slots the non-options now occupy.  */
347
348         first_nonopt += (optind - last_nonopt);
349         last_nonopt = optind;
350 }
351
352 /* Initialize the internal data when the first call is made.  */
353
354 #if defined (__STDC__) && __STDC__
355 static const char *_getopt_initialize(int, char *const *, const char *);
356
357 #endif
358 static const char *
359      _getopt_initialize(argc, argv, optstring)
360      int argc;
361      char *const *argv;
362      const char *optstring;
363 {
364         /* Start processing options with ARGV-element 1 (since ARGV-element 0
365            is the program name); the sequence of previously skipped
366            non-option ARGV-elements is empty.  */
367
368         first_nonopt = last_nonopt = optind = 1;
369
370         nextchar = NULL;
371
372         posixly_correct = getenv("POSIXLY_CORRECT");
373
374         /* Determine how to handle the ordering of options and nonoptions.  */
375
376         if (optstring[0] == '-')
377         {
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'\n"),
714                                                 argv[0], nextchar);
715                                 else
716                                         /* +option or -option */
717                                         fprintf(stderr, _("%s: unrecognized option `%c%s'\n"),
718                                         argv[0], argv[optind][0], nextchar);
719                         }
720                         nextchar = (char *) "";
721                         optind++;
722                         optopt = 0;
723                         return '?';
724                 }
725         }
726
727         /* Look at and handle the next short option-character.  */
728
729         {
730                 char c = *nextchar++;
731                 char *temp = my_index(optstring, c);
732
733                 /* Increment `optind' when we start to process its last character.  */
734                 if (*nextchar == '\0')
735                         ++optind;
736
737                 if (temp == NULL || c == ':')
738                 {
739                         if (opterr)
740                         {
741                                 if (posixly_correct)
742                                         /* 1003.2 specifies the format of this message.  */
743                                         fprintf(stderr, _("%s: illegal option -- %c\n"),
744                                                 argv[0], c);
745                                 else
746                                         fprintf(stderr, _("%s: invalid option -- %c\n"),
747                                                 argv[0], c);
748                         }
749                         optopt = c;
750                         return '?';
751                 }
752                 /* Convenience. Treat POSIX -W foo same as long option --foo */
753                 if (temp[0] == 'W' && temp[1] == ';')
754                 {
755                         char *nameend;
756                         const struct option *p;
757                         const struct option *pfound = NULL;
758                         int exact = 0;
759                         int ambig = 0;
760                         int indfound = 0;
761                         int option_index;
762
763                         /* This is an option that requires an argument.  */
764                         if (*nextchar != '\0')
765                         {
766                                 optarg = nextchar;
767                                 /* If we end this ARGV-element by taking the rest as an arg,
768                                    we must advance to the next element now.  */
769                                 optind++;
770                         }
771                         else if (optind == argc)
772                         {
773                                 if (opterr)
774                                 {
775                                         /* 1003.2 specifies the format of this message.  */
776                                         fprintf(stderr, _("%s: option requires an argument -- %c\n"),
777                                                 argv[0], c);
778                                 }
779                                 optopt = c;
780                                 if (optstring[0] == ':')
781                                         c = ':';
782                                 else
783                                         c = '?';
784                                 return c;
785                         }
786                         else
787                                 /* We already incremented `optind' once;
788                                    increment it again when taking next ARGV-elt as argument.  */
789                                 optarg = argv[optind++];
790
791                         /* optarg is now the argument, see if it's in the
792                            table of longopts.  */
793
794                         for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
795                                 /* Do nothing.  */ ;
796
797                         /* Test all long options for either exact match
798                            or abbreviated matches.  */
799                         for (p = longopts, option_index = 0; p->name; p++, option_index++)
800                                 if (!strncmp(p->name, nextchar, nameend - nextchar))
801                                 {
802                                         if ((unsigned int) (nameend - nextchar) == strlen(p->name))
803                                         {
804                                                 /* Exact match found.  */
805                                                 pfound = p;
806                                                 indfound = option_index;
807                                                 exact = 1;
808                                                 break;
809                                         }
810                                         else if (pfound == NULL)
811                                         {
812                                                 /* First nonexact match found.  */
813                                                 pfound = p;
814                                                 indfound = option_index;
815                                         }
816                                         else
817                                                 /* Second or later nonexact match found.  */
818                                                 ambig = 1;
819                                 }
820                         if (ambig && !exact)
821                         {
822                                 if (opterr)
823                                         fprintf(stderr, _("%s: option `-W %s' is ambiguous\n"),
824                                                 argv[0], argv[optind]);
825                                 nextchar += strlen(nextchar);
826                                 optind++;
827                                 return '?';
828                         }
829                         if (pfound != NULL)
830                         {
831                                 option_index = indfound;
832                                 if (*nameend)
833                                 {
834                                         /* Don't test has_arg with >, because some C compilers don't
835                                            allow it to be used on enums.  */
836                                         if (pfound->has_arg)
837                                                 optarg = nameend + 1;
838                                         else
839                                         {
840                                                 if (opterr)
841                                                         fprintf(stderr, _("\
842 %s: option `-W %s' doesn't allow an argument\n"),
843                                                                 argv[0], pfound->name);
844
845                                                 nextchar += strlen(nextchar);
846                                                 return '?';
847                                         }
848                                 }
849                                 else if (pfound->has_arg == 1)
850                                 {
851                                         if (optind < argc)
852                                                 optarg = argv[optind++];
853                                         else
854                                         {
855                                                 if (opterr)
856                                                         fprintf(stderr,
857                                                                 _("%s: option `%s' requires an argument\n"),
858                                                                 argv[0], argv[optind - 1]);
859                                                 nextchar += strlen(nextchar);
860                                                 return optstring[0] == ':' ? ':' : '?';
861                                         }
862                                 }
863                                 nextchar += strlen(nextchar);
864                                 if (longind != NULL)
865                                         *longind = option_index;
866                                 if (pfound->flag)
867                                 {
868                                         *(pfound->flag) = pfound->val;
869                                         return 0;
870                                 }
871                                 return pfound->val;
872                         }
873                         nextchar = NULL;
874                         return 'W';     /* Let the application handle it.   */
875                 }
876                 if (temp[1] == ':')
877                 {
878                         if (temp[2] == ':')
879                         {
880                                 /* This is an option that accepts an argument optionally.  */
881                                 if (*nextchar != '\0')
882                                 {
883                                         optarg = nextchar;
884                                         optind++;
885                                 }
886                                 else
887                                         optarg = NULL;
888                                 nextchar = NULL;
889                         }
890                         else
891                         {
892                                 /* This is an option that requires an argument.  */
893                                 if (*nextchar != '\0')
894                                 {
895                                         optarg = nextchar;
896                                         /* If we end this ARGV-element by taking the rest as an arg,
897                                            we must advance to the next element now.  */
898                                         optind++;
899                                 }
900                                 else if (optind == argc)
901                                 {
902                                         if (opterr)
903                                         {
904                                                 /* 1003.2 specifies the format of this message.  */
905                                                 fprintf(stderr,
906                                                         _("%s: option requires an argument -- %c\n"),
907                                                         argv[0], c);
908                                         }
909                                         optopt = c;
910                                         if (optstring[0] == ':')
911                                                 c = ':';
912                                         else
913                                                 c = '?';
914                                 }
915                                 else
916                                         /* We already incremented `optind' once;
917                                            increment it again when taking next ARGV-elt as argument.  */
918                                         optarg = argv[optind++];
919                                 nextchar = NULL;
920                         }
921                 }
922                 return c;
923         }
924 }
925
926 int
927     getopt(argc, argv, optstring)
928      int argc;
929      char *const *argv;
930      const char *optstring;
931 {
932         return _getopt_internal(argc, argv, optstring,
933                                 (const struct option *) 0,
934                                 (int *) 0,
935                                 0);
936 }
937
938 #endif /* Not ELIDE_CODE.  */
939 \f
940 #ifdef TEST
941
942 /* Compile with -DTEST to make an executable for use in testing
943    the above definition of `getopt'.  */
944
945 int
946     main(argc, argv)
947      int argc;
948      char **argv;
949 {
950         int c;
951         int digit_optind = 0;
952
953         while (1)
954         {
955                 int this_option_optind = optind ? optind : 1;
956
957                 c = getopt(argc, argv, "abc:d:0123456789");
958                 if (c == -1)
959                         break;
960
961                 switch (c)
962                 {
963                         case '0':
964                         case '1':
965                         case '2':
966                         case '3':
967                         case '4':
968                         case '5':
969                         case '6':
970                         case '7':
971                         case '8':
972                         case '9':
973                                 if (digit_optind != 0 && digit_optind != this_option_optind)
974                                         printf("digits occur in two different argv-elements.\n");
975                                 digit_optind = this_option_optind;
976                                 printf("option %c\n", c);
977                                 break;
978
979                         case 'a':
980                                 printf("option a\n");
981                                 break;
982
983                         case 'b':
984                                 printf("option b\n");
985                                 break;
986
987                         case 'c':
988                                 printf("option c with value `%s'\n", optarg);
989                                 break;
990
991                         case '?':
992                                 break;
993
994                         default:
995                                 printf("?? getopt returned character code 0%o ??\n", c);
996                 }
997         }
998
999         if (optind < argc)
1000         {
1001                 printf("non-option ARGV-elements: ");
1002                 while (optind < argc)
1003                         printf("%s ", argv[optind++]);
1004                 printf("\n");
1005         }
1006
1007         exit(0);
1008 }
1009
1010 #endif /* TEST */