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