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