]> git.mxchange.org Git - flightgear.git/blob - utils/fgcom/fgcom_getopt.c
Tweak tile-manager SGBucket API
[flightgear.git] / utils / fgcom / fgcom_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    Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
6         Free Software Foundation, Inc.
7    This file is part of the GNU C Library.
8
9    The GNU C Library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Lesser General Public
11    License as published by the Free Software Foundation; either
12    version 2.1 of the 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    Lesser General Public License for more details.
18
19    You should have received a copy of the GNU Lesser General Public
20    License along with the GNU C Library; if not, write to the Free
21    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22    02111-1307 USA.  */
23
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 # if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
82 #  include <libintl.h>
83 #  ifndef _
84 #   define _(msgid)     gettext (msgid)
85 #  endif
86 # else
87 #  define _(msgid)      (msgid)
88 # endif
89 # if defined _LIBC && defined USE_IN_LIBIO
90 #  include <wchar.h>
91 # endif
92 #endif
93
94 /* This version of `getopt' appears to the caller like standard Unix `getopt'
95    but it behaves differently for the user, since it allows the user
96    to intersperse the options with the other arguments.
97
98    As `getopt' works, it permutes the elements of ARGV so that,
99    when it is done, all the options precede everything else.  Thus
100    all application programs are extended to handle flexible argument order.
101
102    Setting the environment variable POSIXLY_CORRECT disables permutation.
103    Then the behavior is completely standard.
104
105    GNU application programs can use a third alternative mode in which
106    they can distinguish the relative order of options and other arguments.  */
107
108 #include "fgcom_getopt.h"
109
110 /* For communication from `getopt' to the caller.
111    When `getopt' finds an option that takes an argument,
112    the argument value is returned here.
113    Also, when `ordering' is RETURN_IN_ORDER,
114    each non-option ARGV-element is returned here.  */
115
116 char *optarg;
117
118 /* Index in ARGV of the next element to be scanned.
119    This is used for communication to and from the caller
120    and for communication between successive calls to `getopt'.
121
122    On entry to `getopt', zero means this is the first call; initialize.
123
124    When `getopt' returns -1, this is the index of the first of the
125    non-option elements that the caller should itself scan.
126
127    Otherwise, `optind' communicates from one call to the next
128    how much of ARGV has been scanned so far.  */
129
130 /* 1003.2 says this must be 1 before any call.  */
131 int optind = 1;
132
133 /* Formerly, initialization of getopt depended on optind==0, which
134    causes problems with re-calling getopt as programs generally don't
135    know that. */
136
137 int __getopt_initialized;
138
139 /* The next char to be scanned in the option-element
140    in which the last option character we returned was found.
141    This allows us to pick up the scan where we left off.
142
143    If this is zero, or a null string, it means resume the scan
144    by advancing to the next ARGV-element.  */
145
146 static char *nextchar;
147
148 /* Callers store zero here to inhibit the error message
149    for unrecognized options.  */
150
151 int opterr = 1;
152
153 /* Set to an option character which was unrecognized.
154    This must be initialized on some systems to avoid linking in the
155    system's own getopt implementation.  */
156
157 int optopt = '?';
158
159 /* Describe how to deal with options that follow non-option ARGV-elements.
160
161    If the caller did not specify anything,
162    the default is REQUIRE_ORDER if the environment variable
163    POSIXLY_CORRECT is defined, PERMUTE otherwise.
164
165    REQUIRE_ORDER means don't recognize them as options;
166    stop option processing when the first non-option is seen.
167    This is what Unix does.
168    This mode of operation is selected by either setting the environment
169    variable POSIXLY_CORRECT, or using `+' as the first character
170    of the list of option characters.
171
172    PERMUTE is the default.  We permute the contents of ARGV as we scan,
173    so that eventually all the non-options are at the end.  This allows options
174    to be given in any order, even with programs that were not written to
175    expect this.
176
177    RETURN_IN_ORDER is an option available to programs that were written
178    to expect options and other ARGV-elements in any order and that care about
179    the ordering of the two.  We describe each non-option ARGV-element
180    as if it were the argument of an option with character code 1.
181    Using `-' as the first character of the list of option characters
182    selects this mode of operation.
183
184    The special argument `--' forces an end of option-scanning regardless
185    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
186    `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
187
188 static enum
189 {
190   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
191 } ordering;
192
193 /* Value of POSIXLY_CORRECT environment variable.  */
194 static char *posixly_correct;
195
196 #ifdef  __GNU_LIBRARY__
197 /* We want to avoid inclusion of string.h with non-GNU libraries
198    because there are many ways it can cause trouble.
199    On some systems, it contains special magic macros that don't work
200    in GCC.  */
201 # include <string.h>
202 # define my_index       strchr
203 #else
204
205 # if HAVE_STRING_H || WIN32 /* Pete Wilson mod 7/28/02 */
206 #  include <string.h>
207 # else
208 #  include <strings.h>
209 # endif
210
211 /* Avoid depending on library functions or files
212    whose names are inconsistent.  */
213
214 #ifndef getenv
215 extern char *getenv ();
216 #endif
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__) && !defined strlen
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 # endif /* not __STDC__ */
242 #endif /* __GNUC__ */
243
244 #endif /* not __GNU_LIBRARY__ */
245
246 /* Handle permutation of arguments.  */
247
248 /* Describe the part of ARGV that contains non-options that have
249    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
250    `last_nonopt' is the index after the last of them.  */
251
252 static int first_nonopt;
253 static int last_nonopt;
254
255 #ifdef _LIBC
256 /* Stored original parameters.
257    XXX This is no good solution.  We should rather copy the args so
258    that we can compare them later.  But we must not use malloc(3).  */
259 extern int __libc_argc;
260 extern char **__libc_argv;
261
262 /* Bash 2.0 gives us an environment variable containing flags
263    indicating ARGV elements that should not be considered arguments.  */
264
265 # ifdef USE_NONOPTION_FLAGS
266 /* Defined in getopt_init.c  */
267 extern char *__getopt_nonoption_flags;
268
269 static int nonoption_flags_max_len;
270 static int nonoption_flags_len;
271 # endif
272
273 # ifdef USE_NONOPTION_FLAGS
274 #  define SWAP_FLAGS(ch1, ch2) \
275   if (nonoption_flags_len > 0)                                                \
276     {                                                                         \
277       char __tmp = __getopt_nonoption_flags[ch1];                             \
278       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];          \
279       __getopt_nonoption_flags[ch2] = __tmp;                                  \
280     }
281 # else
282 #  define SWAP_FLAGS(ch1, ch2)
283 # endif
284 #else   /* !_LIBC */
285 # define SWAP_FLAGS(ch1, ch2)
286 #endif  /* _LIBC */
287
288 /* Exchange two adjacent subsequences of ARGV.
289    One subsequence is elements [first_nonopt,last_nonopt)
290    which contains all the non-options that have been skipped so far.
291    The other is elements [last_nonopt,optind), which contains all
292    the options processed since those non-options were skipped.
293
294    `first_nonopt' and `last_nonopt' are relocated so that they describe
295    the new indices of the non-options in ARGV after they are moved.  */
296
297 #if defined __STDC__ && __STDC__
298 static void exchange (char **);
299 #endif
300
301 static void
302 exchange (argv)
303      char **argv;
304 {
305   int bottom = first_nonopt;
306   int middle = last_nonopt;
307   int top = optind;
308   char *tem;
309
310   /* Exchange the shorter segment with the far end of the longer segment.
311      That puts the shorter segment into the right place.
312      It leaves the longer segment in the right place overall,
313      but it consists of two parts that need to be swapped next.  */
314
315 #if defined _LIBC && defined USE_NONOPTION_FLAGS
316   /* First make sure the handling of the `__getopt_nonoption_flags'
317      string can work normally.  Our top argument must be in the range
318      of the string.  */
319   if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
320     {
321       /* We must extend the array.  The user plays games with us and
322          presents new arguments.  */
323       char *new_str = malloc (top + 1);
324       if (new_str == NULL)
325         nonoption_flags_len = nonoption_flags_max_len = 0;
326       else
327         {
328           memset (__mempcpy (new_str, __getopt_nonoption_flags,
329                              nonoption_flags_max_len),
330                   '\0', top + 1 - nonoption_flags_max_len);
331           nonoption_flags_max_len = top + 1;
332           __getopt_nonoption_flags = new_str;
333         }
334     }
335 #endif
336
337   while (top > middle && middle > bottom)
338     {
339       if (top - middle > middle - bottom)
340         {
341           /* Bottom segment is the short one.  */
342           int len = middle - bottom;
343           register int i;
344
345           /* Swap it with the top part of the top segment.  */
346           for (i = 0; i < len; i++)
347             {
348               tem = argv[bottom + i];
349               argv[bottom + i] = argv[top - (middle - bottom) + i];
350               argv[top - (middle - bottom) + i] = tem;
351               SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
352             }
353           /* Exclude the moved bottom segment from further swapping.  */
354           top -= len;
355         }
356       else
357         {
358           /* Top segment is the short one.  */
359           int len = top - middle;
360           register int i;
361
362           /* Swap it with the bottom part of the bottom segment.  */
363           for (i = 0; i < len; i++)
364             {
365               tem = argv[bottom + i];
366               argv[bottom + i] = argv[middle + i];
367               argv[middle + i] = tem;
368               SWAP_FLAGS (bottom + i, middle + i);
369             }
370           /* Exclude the moved top segment from further swapping.  */
371           bottom += len;
372         }
373     }
374
375   /* Update records for the slots the non-options now occupy.  */
376
377   first_nonopt += (optind - last_nonopt);
378   last_nonopt = optind;
379 }
380
381 /* Initialize the internal data when the first call is made.  */
382
383 #if defined __STDC__ && __STDC__
384 static const char *_getopt_initialize (int, char *const *, const char *);
385 #endif
386 static const char *
387 _getopt_initialize (argc, argv, optstring)
388      int argc;
389      char *const *argv;
390      const char *optstring;
391 {
392   /* Start processing options with ARGV-element 1 (since ARGV-element 0
393      is the program name); the sequence of previously skipped
394      non-option ARGV-elements is empty.  */
395
396   first_nonopt = last_nonopt = optind;
397
398   nextchar = NULL;
399
400   posixly_correct = getenv ("POSIXLY_CORRECT");
401
402   /* Determine how to handle the ordering of options and nonoptions.  */
403
404   if (optstring[0] == '-')
405     {
406       ordering = RETURN_IN_ORDER;
407       ++optstring;
408     }
409   else if (optstring[0] == '+')
410     {
411       ordering = REQUIRE_ORDER;
412       ++optstring;
413     }
414   else if (posixly_correct != NULL)
415     ordering = REQUIRE_ORDER;
416   else
417     ordering = PERMUTE;
418
419 #if defined _LIBC && defined USE_NONOPTION_FLAGS
420   if (posixly_correct == NULL
421       && argc == __libc_argc && argv == __libc_argv)
422     {
423       if (nonoption_flags_max_len == 0)
424         {
425           if (__getopt_nonoption_flags == NULL
426               || __getopt_nonoption_flags[0] == '\0')
427             nonoption_flags_max_len = -1;
428           else
429             {
430               const char *orig_str = __getopt_nonoption_flags;
431               int len = nonoption_flags_max_len = strlen (orig_str);
432               if (nonoption_flags_max_len < argc)
433                 nonoption_flags_max_len = argc;
434               __getopt_nonoption_flags =
435                 (char *) malloc (nonoption_flags_max_len);
436               if (__getopt_nonoption_flags == NULL)
437                 nonoption_flags_max_len = -1;
438               else
439                 memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
440                         '\0', nonoption_flags_max_len - len);
441             }
442         }
443       nonoption_flags_len = nonoption_flags_max_len;
444     }
445   else
446     nonoption_flags_len = 0;
447 #endif
448
449   return optstring;
450 }
451
452 /* Scan elements of ARGV (whose length is ARGC) for option characters
453    given in OPTSTRING.
454
455    If an element of ARGV starts with '-', and is not exactly "-" or "--",
456    then it is an option element.  The characters of this element
457    (aside from the initial '-') are option characters.  If `getopt'
458    is called repeatedly, it returns successively each of the option characters
459    from each of the option elements.
460
461    If `getopt' finds another option character, it returns that character,
462    updating `optind' and `nextchar' so that the next call to `getopt' can
463    resume the scan with the following option character or ARGV-element.
464
465    If there are no more option characters, `getopt' returns -1.
466    Then `optind' is the index in ARGV of the first ARGV-element
467    that is not an option.  (The ARGV-elements have been permuted
468    so that those that are not options now come last.)
469
470    OPTSTRING is a string containing the legitimate option characters.
471    If an option character is seen that is not listed in OPTSTRING,
472    return '?' after printing an error message.  If you set `opterr' to
473    zero, the error message is suppressed but we still return '?'.
474
475    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
476    so the following text in the same ARGV-element, or the text of the following
477    ARGV-element, is returned in `optarg'.  Two colons mean an option that
478    wants an optional arg; if there is text in the current ARGV-element,
479    it is returned in `optarg', otherwise `optarg' is set to zero.
480
481    If OPTSTRING starts with `-' or `+', it requests different methods of
482    handling the non-option ARGV-elements.
483    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
484
485    Long-named options begin with `--' instead of `-'.
486    Their names may be abbreviated as long as the abbreviation is unique
487    or is an exact match for some defined option.  If they have an
488    argument, it follows the option name in the same ARGV-element, separated
489    from the option name by a `=', or else the in next ARGV-element.
490    When `getopt' finds a long-named option, it returns 0 if that option's
491    `flag' field is nonzero, the value of the option's `val' field
492    if the `flag' field is zero.
493
494    The elements of ARGV aren't really const, because we permute them.
495    But we pretend they're const in the prototype to be compatible
496    with other systems.
497
498    LONGOPTS is a vector of `struct option' terminated by an
499    element containing a name which is zero.
500
501    LONGIND returns the index in LONGOPT of the long-named option found.
502    It is only valid when a long-named option has been found by the most
503    recent call.
504
505    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
506    long-named options.  */
507
508 int
509 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
510      int argc;
511      char *const *argv;
512      const char *optstring;
513      const struct option *longopts;
514      int *longind;
515      int long_only;
516 {
517   int print_errors = opterr;
518   if (optstring[0] == ':')
519     print_errors = 0;
520
521   if (argc < 1)
522     return -1;
523
524   optarg = NULL;
525
526   if (optind == 0 || !__getopt_initialized)
527     {
528       if (optind == 0)
529         optind = 1;     /* Don't scan ARGV[0], the program name.  */
530       optstring = _getopt_initialize (argc, argv, optstring);
531       __getopt_initialized = 1;
532     }
533
534   /* Test whether ARGV[optind] points to a non-option argument.
535      Either it does not have option syntax, or there is an environment flag
536      from the shell indicating it is not an option.  The later information
537      is only used when the used in the GNU libc.  */
538 #if defined _LIBC && defined USE_NONOPTION_FLAGS
539 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'       \
540                       || (optind < nonoption_flags_len                        \
541                           && __getopt_nonoption_flags[optind] == '1'))
542 #else
543 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
544 #endif
545
546   if (nextchar == NULL || *nextchar == '\0')
547     {
548       /* Advance to the next ARGV-element.  */
549
550       /* Give FIRST_NONOPT and LAST_NONOPT rational values if OPTIND has been
551          moved back by the user (who may also have changed the arguments).  */
552       if (last_nonopt > optind)
553         last_nonopt = optind;
554       if (first_nonopt > optind)
555         first_nonopt = optind;
556
557       if (ordering == PERMUTE)
558         {
559           /* If we have just processed some options following some non-options,
560              exchange them so that the options come first.  */
561
562           if (first_nonopt != last_nonopt && last_nonopt != optind)
563             exchange ((char **) argv);
564           else if (last_nonopt != optind)
565             first_nonopt = optind;
566
567           /* Skip any additional non-options
568              and extend the range of non-options previously skipped.  */
569
570           while (optind < argc && NONOPTION_P)
571             optind++;
572           last_nonopt = optind;
573         }
574
575       /* The special ARGV-element `--' means premature end of options.
576          Skip it like a null option,
577          then exchange with previous non-options as if it were an option,
578          then skip everything else like a non-option.  */
579
580       if (optind != argc && !strcmp (argv[optind], "--"))
581         {
582           optind++;
583
584           if (first_nonopt != last_nonopt && last_nonopt != optind)
585             exchange ((char **) argv);
586           else if (first_nonopt == last_nonopt)
587             first_nonopt = optind;
588           last_nonopt = argc;
589
590           optind = argc;
591         }
592
593       /* If we have done all the ARGV-elements, stop the scan
594          and back over any non-options that we skipped and permuted.  */
595
596       if (optind == argc)
597         {
598           /* Set the next-arg-index to point at the non-options
599              that we previously skipped, so the caller will digest them.  */
600           if (first_nonopt != last_nonopt)
601             optind = first_nonopt;
602           return -1;
603         }
604
605       /* If we have come to a non-option and did not permute it,
606          either stop the scan or describe it to the caller and pass it by.  */
607
608       if (NONOPTION_P)
609         {
610           if (ordering == REQUIRE_ORDER)
611             return -1;
612           optarg = argv[optind++];
613           return 1;
614         }
615
616       /* We have found another option-ARGV-element.
617          Skip the initial punctuation.  */
618
619       nextchar = (argv[optind] + 1
620                   + (longopts != NULL && argv[optind][1] == '-'));
621     }
622
623   /* Decode the current option-ARGV-element.  */
624
625   /* Check whether the ARGV-element is a long option.
626
627      If long_only and the ARGV-element has the form "-f", where f is
628      a valid short option, don't consider it an abbreviated form of
629      a long option that starts with f.  Otherwise there would be no
630      way to give the -f short option.
631
632      On the other hand, if there's a long option "fubar" and
633      the ARGV-element is "-fu", do consider that an abbreviation of
634      the long option, just like "--fu", and not "-f" with arg "u".
635
636      This distinction seems to be the most useful approach.  */
637
638   if (longopts != NULL
639       && (argv[optind][1] == '-'
640           || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
641     {
642       char *nameend;
643       const struct option *p;
644       const struct option *pfound = NULL;
645       int exact = 0;
646       int ambig = 0;
647       int indfound = -1;
648       int option_index;
649
650       for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
651         /* Do nothing.  */ ;
652
653       /* Test all long options for either exact match
654          or abbreviated matches.  */
655       for (p = longopts, option_index = 0; p->name; p++, option_index++)
656         if (!strncmp (p->name, nextchar, nameend - nextchar))
657           {
658             if ((unsigned int) (nameend - nextchar)
659                 == (unsigned int) strlen (p->name))
660               {
661                 /* Exact match found.  */
662                 pfound = p;
663                 indfound = option_index;
664                 exact = 1;
665                 break;
666               }
667             else if (pfound == NULL)
668               {
669                 /* First nonexact match found.  */
670                 pfound = p;
671                 indfound = option_index;
672               }
673             else if (long_only
674                      || pfound->has_arg != p->has_arg
675                      || pfound->flag != p->flag
676                      || pfound->val != p->val)
677               /* Second or later nonexact match found.  */
678               ambig = 1;
679           }
680
681       if (ambig && !exact)
682         {
683           if (print_errors)
684             {
685 #if defined _LIBC && defined USE_IN_LIBIO
686               char *buf;
687
688               __asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
689                           argv[0], argv[optind]);
690
691               if (_IO_fwide (stderr, 0) > 0)
692                 __fwprintf (stderr, L"%s", buf);
693               else
694                 fputs (buf, stderr);
695
696               free (buf);
697 #else
698               fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
699                        argv[0], argv[optind]);
700 #endif
701             }
702           nextchar += strlen (nextchar);
703           optind++;
704           optopt = 0;
705           return '?';
706         }
707
708       if (pfound != NULL)
709         {
710           option_index = indfound;
711           optind++;
712           if (*nameend)
713             {
714               /* Don't test has_arg with >, because some C compilers don't
715                  allow it to be used on enums.  */
716               if (pfound->has_arg)
717                 optarg = nameend + 1;
718               else
719                 {
720                   if (print_errors)
721                     {
722 #if defined _LIBC && defined USE_IN_LIBIO
723                       char *buf;
724 #endif
725
726                       if (argv[optind - 1][1] == '-')
727                         {
728                           /* --option */
729 #if defined _LIBC && defined USE_IN_LIBIO
730                           __asprintf (&buf, _("\
731 %s: option `--%s' doesn't allow an argument\n"),
732                                       argv[0], pfound->name);
733 #else
734                           fprintf (stderr, _("\
735 %s: option `--%s' doesn't allow an argument\n"),
736                                    argv[0], pfound->name);
737 #endif
738                         }
739                       else
740                         {
741                           /* +option or -option */
742 #if defined _LIBC && defined USE_IN_LIBIO
743                           __asprintf (&buf, _("\
744 %s: option `%c%s' doesn't allow an argument\n"),
745                                       argv[0], argv[optind - 1][0],
746                                       pfound->name);
747 #else
748                           fprintf (stderr, _("\
749 %s: option `%c%s' doesn't allow an argument\n"),
750                                    argv[0], argv[optind - 1][0], pfound->name);
751 #endif
752                         }
753
754 #if defined _LIBC && defined USE_IN_LIBIO
755                       if (_IO_fwide (stderr, 0) > 0)
756                         __fwprintf (stderr, L"%s", buf);
757                       else
758                         fputs (buf, stderr);
759
760                       free (buf);
761 #endif
762                     }
763
764                   nextchar += strlen (nextchar);
765
766                   optopt = pfound->val;
767                   return '?';
768                 }
769             }
770           else if (pfound->has_arg == 1)
771             {
772               if (optind < argc)
773                 optarg = argv[optind++];
774               else
775                 {
776                   if (print_errors)
777                     {
778 #if defined _LIBC && defined USE_IN_LIBIO
779                       char *buf;
780
781                       __asprintf (&buf,
782                                   _("%s: option `%s' requires an argument\n"),
783                                   argv[0], argv[optind - 1]);
784
785                       if (_IO_fwide (stderr, 0) > 0)
786                         __fwprintf (stderr, L"%s", buf);
787                       else
788                         fputs (buf, stderr);
789
790                       free (buf);
791 #else
792                       fprintf (stderr,
793                                _("%s: option `%s' requires an argument\n"),
794                                argv[0], argv[optind - 1]);
795 #endif
796                     }
797                   nextchar += strlen (nextchar);
798                   optopt = pfound->val;
799                   return optstring[0] == ':' ? ':' : '?';
800                 }
801             }
802           nextchar += strlen (nextchar);
803           if (longind != NULL)
804             *longind = option_index;
805           if (pfound->flag)
806             {
807               *(pfound->flag) = pfound->val;
808               return 0;
809             }
810           return pfound->val;
811         }
812
813       /* Can't find it as a long option.  If this is not getopt_long_only,
814          or the option starts with '--' or is not a valid short
815          option, then it's an error.
816          Otherwise interpret it as a short option.  */
817       if (!long_only || argv[optind][1] == '-'
818           || my_index (optstring, *nextchar) == NULL)
819         {
820           if (print_errors)
821             {
822 #if defined _LIBC && defined USE_IN_LIBIO
823               char *buf;
824 #endif
825
826               if (argv[optind][1] == '-')
827                 {
828                   /* --option */
829 #if defined _LIBC && defined USE_IN_LIBIO
830                   __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
831                               argv[0], nextchar);
832 #else
833                   fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
834                            argv[0], nextchar);
835 #endif
836                 }
837               else
838                 {
839                   /* +option or -option */
840 #if defined _LIBC && defined USE_IN_LIBIO
841                   __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
842                               argv[0], argv[optind][0], nextchar);
843 #else
844                   fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
845                            argv[0], argv[optind][0], nextchar);
846 #endif
847                 }
848
849 #if defined _LIBC && defined USE_IN_LIBIO
850               if (_IO_fwide (stderr, 0) > 0)
851                 __fwprintf (stderr, L"%s", buf);
852               else
853                 fputs (buf, stderr);
854
855               free (buf);
856 #endif
857             }
858           nextchar = (char *) "";
859           optind++;
860           optopt = 0;
861           return '?';
862         }
863     }
864
865   /* Look at and handle the next short option-character.  */
866
867   {
868     char c = *nextchar++;
869     char *temp = my_index (optstring, c);
870
871     /* Increment `optind' when we start to process its last character.  */
872     if (*nextchar == '\0')
873       ++optind;
874
875     if (temp == NULL || c == ':')
876       {
877         if (print_errors)
878           {
879 #if defined _LIBC && defined USE_IN_LIBIO
880               char *buf;
881 #endif
882
883             if (posixly_correct)
884               {
885                 /* 1003.2 specifies the format of this message.  */
886 #if defined _LIBC && defined USE_IN_LIBIO
887                 __asprintf (&buf, _("%s: illegal option -- %c\n"),
888                             argv[0], c);
889 #else
890                 fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
891 #endif
892               }
893             else
894               {
895 #if defined _LIBC && defined USE_IN_LIBIO
896                 __asprintf (&buf, _("%s: invalid option -- %c\n"),
897                             argv[0], c);
898 #else
899                 fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
900 #endif
901               }
902
903 #if defined _LIBC && defined USE_IN_LIBIO
904             if (_IO_fwide (stderr, 0) > 0)
905               __fwprintf (stderr, L"%s", buf);
906             else
907               fputs (buf, stderr);
908
909             free (buf);
910 #endif
911           }
912         optopt = c;
913         return '?';
914       }
915     /* Convenience. Treat POSIX -W foo same as long option --foo */
916     if (temp[0] == 'W' && temp[1] == ';')
917       {
918         char *nameend;
919         const struct option *p;
920         const struct option *pfound = NULL;
921         int exact = 0;
922         int ambig = 0;
923         int indfound = 0;
924         int option_index;
925
926         /* This is an option that requires an argument.  */
927         if (*nextchar != '\0')
928           {
929             optarg = nextchar;
930             /* If we end this ARGV-element by taking the rest as an arg,
931                we must advance to the next element now.  */
932             optind++;
933           }
934         else if (optind == argc)
935           {
936             if (print_errors)
937               {
938                 /* 1003.2 specifies the format of this message.  */
939 #if defined _LIBC && defined USE_IN_LIBIO
940                 char *buf;
941
942                 __asprintf (&buf, _("%s: option requires an argument -- %c\n"),
943                             argv[0], c);
944
945                 if (_IO_fwide (stderr, 0) > 0)
946                   __fwprintf (stderr, L"%s", buf);
947                 else
948                   fputs (buf, stderr);
949
950                 free (buf);
951 #else
952                 fprintf (stderr, _("%s: option requires an argument -- %c\n"),
953                          argv[0], c);
954 #endif
955               }
956             optopt = c;
957             if (optstring[0] == ':')
958               c = ':';
959             else
960               c = '?';
961             return c;
962           }
963         else
964           /* We already incremented `optind' once;
965              increment it again when taking next ARGV-elt as argument.  */
966           optarg = argv[optind++];
967
968         /* optarg is now the argument, see if it's in the
969            table of longopts.  */
970
971         for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
972           /* Do nothing.  */ ;
973
974         /* Test all long options for either exact match
975            or abbreviated matches.  */
976         for (p = longopts, option_index = 0; p->name; p++, option_index++)
977           if (!strncmp (p->name, nextchar, nameend - nextchar))
978             {
979               if ((unsigned int) (nameend - nextchar) == strlen (p->name))
980                 {
981                   /* Exact match found.  */
982                   pfound = p;
983                   indfound = option_index;
984                   exact = 1;
985                   break;
986                 }
987               else if (pfound == NULL)
988                 {
989                   /* First nonexact match found.  */
990                   pfound = p;
991                   indfound = option_index;
992                 }
993               else
994                 /* Second or later nonexact match found.  */
995                 ambig = 1;
996             }
997         if (ambig && !exact)
998           {
999             if (print_errors)
1000               {
1001 #if defined _LIBC && defined USE_IN_LIBIO
1002                 char *buf;
1003
1004                 __asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
1005                             argv[0], argv[optind]);
1006
1007                 if (_IO_fwide (stderr, 0) > 0)
1008                   __fwprintf (stderr, L"%s", buf);
1009                 else
1010                   fputs (buf, stderr);
1011
1012                 free (buf);
1013 #else
1014                 fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
1015                          argv[0], argv[optind]);
1016 #endif
1017               }
1018             nextchar += strlen (nextchar);
1019             optind++;
1020             return '?';
1021           }
1022         if (pfound != NULL)
1023           {
1024             option_index = indfound;
1025             if (*nameend)
1026               {
1027                 /* Don't test has_arg with >, because some C compilers don't
1028                    allow it to be used on enums.  */
1029                 if (pfound->has_arg)
1030                   optarg = nameend + 1;
1031                 else
1032                   {
1033                     if (print_errors)
1034                       {
1035 #if defined _LIBC && defined USE_IN_LIBIO
1036                         char *buf;
1037
1038                         __asprintf (&buf, _("\
1039 %s: option `-W %s' doesn't allow an argument\n"),
1040                                     argv[0], pfound->name);
1041
1042                         if (_IO_fwide (stderr, 0) > 0)
1043                           __fwprintf (stderr, L"%s", buf);
1044                         else
1045                           fputs (buf, stderr);
1046
1047                         free (buf);
1048 #else
1049                         fprintf (stderr, _("\
1050 %s: option `-W %s' doesn't allow an argument\n"),
1051                                  argv[0], pfound->name);
1052 #endif
1053                       }
1054
1055                     nextchar += strlen (nextchar);
1056                     return '?';
1057                   }
1058               }
1059             else if (pfound->has_arg == 1)
1060               {
1061                 if (optind < argc)
1062                   optarg = argv[optind++];
1063                 else
1064                   {
1065                     if (print_errors)
1066                       {
1067 #if defined _LIBC && defined USE_IN_LIBIO
1068                         char *buf;
1069
1070                         __asprintf (&buf, _("\
1071 %s: option `%s' requires an argument\n"),
1072                                     argv[0], argv[optind - 1]);
1073
1074                         if (_IO_fwide (stderr, 0) > 0)
1075                           __fwprintf (stderr, L"%s", buf);
1076                         else
1077                           fputs (buf, stderr);
1078
1079                         free (buf);
1080 #else
1081                         fprintf (stderr,
1082                                  _("%s: option `%s' requires an argument\n"),
1083                                  argv[0], argv[optind - 1]);
1084 #endif
1085                       }
1086                     nextchar += strlen (nextchar);
1087                     return optstring[0] == ':' ? ':' : '?';
1088                   }
1089               }
1090             nextchar += strlen (nextchar);
1091             if (longind != NULL)
1092               *longind = option_index;
1093             if (pfound->flag)
1094               {
1095                 *(pfound->flag) = pfound->val;
1096                 return 0;
1097               }
1098             return pfound->val;
1099           }
1100           nextchar = NULL;
1101           return 'W';   /* Let the application handle it.   */
1102       }
1103     if (temp[1] == ':')
1104       {
1105         if (temp[2] == ':')
1106           {
1107             /* This is an option that accepts an argument optionally.  */
1108             if (*nextchar != '\0')
1109               {
1110                 optarg = nextchar;
1111                 optind++;
1112               }
1113             else
1114               optarg = NULL;
1115             nextchar = NULL;
1116           }
1117         else
1118           {
1119             /* This is an option that requires an argument.  */
1120             if (*nextchar != '\0')
1121               {
1122                 optarg = nextchar;
1123                 /* If we end this ARGV-element by taking the rest as an arg,
1124                    we must advance to the next element now.  */
1125                 optind++;
1126               }
1127             else if (optind == argc)
1128               {
1129                 if (print_errors)
1130                   {
1131                     /* 1003.2 specifies the format of this message.  */
1132 #if defined _LIBC && defined USE_IN_LIBIO
1133                     char *buf;
1134
1135                     __asprintf (&buf,
1136                                 _("%s: option requires an argument -- %c\n"),
1137                                 argv[0], c);
1138
1139                     if (_IO_fwide (stderr, 0) > 0)
1140                       __fwprintf (stderr, L"%s", buf);
1141                     else
1142                       fputs (buf, stderr);
1143
1144                     free (buf);
1145 #else
1146                     fprintf (stderr,
1147                              _("%s: option requires an argument -- %c\n"),
1148                              argv[0], c);
1149 #endif
1150                   }
1151                 optopt = c;
1152                 if (optstring[0] == ':')
1153                   c = ':';
1154                 else
1155                   c = '?';
1156               }
1157             else
1158               /* We already incremented `optind' once;
1159                  increment it again when taking next ARGV-elt as argument.  */
1160               optarg = argv[optind++];
1161             nextchar = NULL;
1162           }
1163       }
1164     return c;
1165   }
1166 }
1167
1168 int
1169 getopt (argc, argv, optstring)
1170      int argc;
1171      char *const *argv;
1172      const char *optstring;
1173 {
1174   return _getopt_internal (argc, argv, optstring,
1175                            (const struct option *) 0,
1176                            (int *) 0,
1177                            0);
1178 }
1179
1180 extern int getopt_long (int ___argc, char *const *___argv,
1181                         const char *__shortopts,
1182                         const struct option *__longopts, int *__longind)
1183 {
1184         return _getopt_internal(___argc, ___argv, __shortopts, __longopts, __longind, 0);
1185 }
1186
1187
1188 #endif  /* Not ELIDE_CODE.  */
1189
1190
1191 /* Compile with -DTEST to make an executable for use in testing
1192    the above definition of `getopt'.  */
1193
1194 /* #define TEST */        /* Pete Wilson mod 7/28/02 */
1195 #ifdef TEST
1196
1197 #ifndef exit         /* Pete Wilson mod 7/28/02 */
1198   int exit(int);     /* Pete Wilson mod 7/28/02 */
1199 #endif               /* Pete Wilson mod 7/28/02 */
1200
1201 int
1202 main (argc, argv)
1203      int argc;
1204      char **argv;
1205 {
1206   int c;
1207   int digit_optind = 0;
1208
1209   while (1)
1210     {
1211       int this_option_optind = optind ? optind : 1;
1212
1213       c = getopt (argc, argv, "abc:d:0123456789");
1214       if (c == -1)
1215         break;
1216
1217       switch (c)
1218         {
1219         case '0':
1220         case '1':
1221         case '2':
1222         case '3':
1223         case '4':
1224         case '5':
1225         case '6':
1226         case '7':
1227         case '8':
1228         case '9':
1229           if (digit_optind != 0 && digit_optind != this_option_optind)
1230             printf ("digits occur in two different argv-elements.\n");
1231           digit_optind = this_option_optind;
1232           printf ("option %c\n", c);
1233           break;
1234
1235         case 'a':
1236           printf ("option a\n");
1237           break;
1238
1239         case 'b':
1240           printf ("option b\n");
1241           break;
1242
1243         case 'c':
1244           printf ("option c with value `%s'\n", optarg);
1245           break;
1246
1247         case '?':
1248           break;
1249
1250         default:
1251           printf ("?? getopt returned character code 0%o ??\n", c);
1252         }
1253     }
1254
1255   if (optind < argc)
1256     {
1257       printf ("non-option ARGV-elements: ");
1258       while (optind < argc)
1259         printf ("%s ", argv[optind++]);
1260       printf ("\n");
1261     }
1262
1263   exit (0);
1264 }
1265
1266 #endif /* TEST */