source: src/router/proftpd/lib/getopt.c @ 17876

Last change on this file since 17876 was 17876, checked in by BrainSlayer, 20 months ago

update proftp

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