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