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