source: git/old_modgen/modgen/getopt.c @ 2bf04b

spielwiese
Last change on this file since 2bf04b was 2bf04b, checked in by Hans Schoenemann <hannes@…>, 8 years ago
format
  • Property mode set to 100644
File size: 33.7 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   Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
6           Free Software Foundation, Inc.
7   This file is part of the GNU C Library.
8
9   The GNU C Library is free software; you can redistribute it and/or
10   modify it under the terms of the GNU Lesser General Public
11   License as published by the Free Software Foundation; either
12   version 2.1 of the License, or (at your option) any later version.
13
14   The GNU C Library is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   Lesser General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public
20   License along with the GNU C Library; if not, write to the Free
21   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22   02111-1307 USA.  */
23
24/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
25   Ditto for AIX 3.2 and <stdlib.h>.  */
26#ifndef _NO_PROTO
27# define _NO_PROTO
28#endif
29
30
31# include <config.h>
32
33
34#ifndef HAVE_GETOPT_LONG
35
36#if !defined __STDC__ || !__STDC__
37/* This is a separate conditional since some stdc systems
38   reject `defined (const)'.  */
39# ifndef const
40#  define const
41# endif
42#endif
43
44#include <stdio.h>
45
46/* Comment out all this code if we are using the GNU C Library, and are not
47   actually compiling the library itself.  This code is part of the GNU C
48   Library, but also included in many other GNU distributions.  Compiling
49   and linking in this code is a waste when using the GNU C library
50   (especially if it is a shared library).  Rather than having every GNU
51   program understand `configure --with-gnu-libc' and omit the object files,
52   it is simpler to just do this in the source for each such file.  */
53
54#define GETOPT_INTERFACE_VERSION 2
55#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
56# include <gnu-versions.h>
57# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
58#  define ELIDE_CODE
59# endif
60#endif
61
62#ifndef ELIDE_CODE
63
64
65/* This needs to come after some library #include
66   to get __GNU_LIBRARY__ defined.  */
67#ifdef        __GNU_LIBRARY__
68/* Don't include stdlib.h for non-GNU C libraries because some of them
69   contain conflicting prototypes for getopt.  */
70# include <stdlib.h>
71# include <unistd.h>
72#endif        /* GNU C library.  */
73
74#ifdef VMS
75# include <unixlib.h>
76# if HAVE_STRING_H - 0
77#  include <string.h>
78# endif
79#endif
80
81#ifndef _
82/* This is for other GNU distributions with internationalized messages.  */
83# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
84#  include <libintl.h>
85#  ifndef _
86#   define _(msgid)        gettext (msgid)
87#  endif
88# else
89#  define _(msgid)        (msgid)
90# endif
91#endif
92
93/* This version of `getopt' appears to the caller like standard Unix `getopt'
94   but it behaves differently for the user, since it allows the user
95   to intersperse the options with the other arguments.
96
97   As `getopt' works, it permutes the elements of ARGV so that,
98   when it is done, all the options precede everything else.  Thus
99   all application programs are extended to handle flexible argument order.
100
101   Setting the environment variable POSIXLY_CORRECT disables permutation.
102   Then the behavior is completely standard.
103
104   GNU application programs can use a third alternative mode in which
105   they can distinguish the relative order of options and other arguments.  */
106
107#include "my_getopt.h"
108
109/* For communication from `getopt' to the caller.
110   When `getopt' finds an option that takes an argument,
111   the argument value is returned here.
112   Also, when `ordering' is RETURN_IN_ORDER,
113   each non-option ARGV-element is returned here.  */
114
115char *optarg;
116
117/* Index in ARGV of the next element to be scanned.
118   This is used for communication to and from the caller
119   and for communication between successive calls to `getopt'.
120
121   On entry to `getopt', zero means this is the first call; initialize.
122
123   When `getopt' returns -1, this is the index of the first of the
124   non-option elements that the caller should itself scan.
125
126   Otherwise, `optind' communicates from one call to the next
127   how much of ARGV has been scanned so far.  */
128
129/* 1003.2 says this must be 1 before any call.  */
130int optind = 1;
131
132/* Formerly, initialization of getopt depended on optind==0, which
133   causes problems with re-calling getopt as programs generally don't
134   know that. */
135
136int __getopt_initialized;
137
138/* The next char to be scanned in the option-element
139   in which the last option character we returned was found.
140   This allows us to pick up the scan where we left off.
141
142   If this is zero, or a null string, it means resume the scan
143   by advancing to the next ARGV-element.  */
144
145static char *nextchar;
146
147/* Callers store zero here to inhibit the error message
148   for unrecognized options.  */
149
150int opterr = 1;
151
152/* Set to an option character which was unrecognized.
153   This must be initialized on some systems to avoid linking in the
154   system's own getopt implementation.  */
155
156int optopt = '?';
157
158/* Describe how to deal with options that follow non-option ARGV-elements.
159
160   If the caller did not specify anything,
161   the default is REQUIRE_ORDER if the environment variable
162   POSIXLY_CORRECT is defined, PERMUTE otherwise.
163
164   REQUIRE_ORDER means don't recognize them as options;
165   stop option processing when the first non-option is seen.
166   This is what Unix does.
167   This mode of operation is selected by either setting the environment
168   variable POSIXLY_CORRECT, or using `+' as the first character
169   of the list of option characters.
170
171   PERMUTE is the default.  We permute the contents of ARGV as we scan,
172   so that eventually all the non-options are at the end.  This allows options
173   to be given in any order, even with programs that were not written to
174   expect this.
175
176   RETURN_IN_ORDER is an option available to programs that were written
177   to expect options and other ARGV-elements in any order and that care about
178   the ordering of the two.  We describe each non-option ARGV-element
179   as if it were the argument of an option with character code 1.
180   Using `-' as the first character of the list of option characters
181   selects this mode of operation.
182
183   The special argument `--' forces an end of option-scanning regardless
184   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
185   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
186
187static enum
188{
189  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
190} ordering;
191
192/* Value of POSIXLY_CORRECT environment variable.  */
193static char *posixly_correct;
194
195#ifdef        __GNU_LIBRARY__
196/* We want to avoid inclusion of string.h with non-GNU libraries
197   because there are many ways it can cause trouble.
198   On some systems, it contains special magic macros that don't work
199   in GCC.  */
200# include <string.h>
201# define my_index        strchr
202#else
203
204# if HAVE_STRING_H
205#  include <string.h>
206# else
207#  include <strings.h>
208# endif
209
210/* Avoid depending on library functions or files
211   whose names are inconsistent.  */
212
213#ifndef getenv
214extern char *getenv ();
215#endif
216
217static char *
218my_index (str, chr)
219     const char *str;
220     int chr;
221{
222  while (*str)
223    {
224      if (*str == chr)
225        return (char *) str;
226      str++;
227    }
228  return 0;
229}
230
231/* If using GCC, we can safely declare strlen this way.
232   If not using GCC, it is ok not to declare it.  */
233#ifdef __GNUC__
234/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
235   That was relevant to code that was here before.  */
236# if (!defined __STDC__ || !__STDC__) && !defined strlen
237/* gcc with -traditional declares the built-in strlen to return int,
238   and has done so at least since version 2.4.5. -- rms.  */
239extern int strlen (const char *);
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
251static int first_nonopt;
252static int last_nonopt;
253
254#ifdef _LIBC
255/* Stored original parameters.
256   XXX This is no good solution.  We should rather copy the args so
257   that we can compare them later.  But we must not use malloc(3).  */
258extern int __libc_argc;
259extern char **__libc_argv;
260
261/* Bash 2.0 gives us an environment variable containing flags
262   indicating ARGV elements that should not be considered arguments.  */
263
264# ifdef USE_NONOPTION_FLAGS
265/* Defined in getopt_init.c  */
266extern char *__getopt_nonoption_flags;
267
268static int nonoption_flags_max_len;
269static int nonoption_flags_len;
270# endif
271
272# ifdef USE_NONOPTION_FLAGS
273#  define SWAP_FLAGS(ch1, ch2) \
274  if (nonoption_flags_len > 0)                                                      \
275    {                                                                              \
276      char __tmp = __getopt_nonoption_flags[ch1];                              \
277      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];              \
278      __getopt_nonoption_flags[ch2] = __tmp;                                      \
279    }
280# else
281#  define SWAP_FLAGS(ch1, ch2)
282# endif
283#else        /* !_LIBC */
284# define SWAP_FLAGS(ch1, ch2)
285#endif        /* _LIBC */
286
287/* Exchange two adjacent subsequences of ARGV.
288   One subsequence is elements [first_nonopt,last_nonopt)
289   which contains all the non-options that have been skipped so far.
290   The other is elements [last_nonopt,optind), which contains all
291   the options processed since those non-options were skipped.
292
293   `first_nonopt' and `last_nonopt' are relocated so that they describe
294   the new indices of the non-options in ARGV after they are moved.  */
295
296#if defined __STDC__ && __STDC__
297static void exchange (char **);
298#endif
299
300static void
301exchange (argv)
302     char **argv;
303{
304  int bottom = first_nonopt;
305  int middle = last_nonopt;
306  int top = optind;
307  char *tem;
308
309  /* Exchange the shorter segment with the far end of the longer segment.
310     That puts the shorter segment into the right place.
311     It leaves the longer segment in the right place overall,
312     but it consists of two parts that need to be swapped next.  */
313
314#if defined _LIBC && defined USE_NONOPTION_FLAGS
315  /* First make sure the handling of the `__getopt_nonoption_flags'
316     string can work normally.  Our top argument must be in the range
317     of the string.  */
318  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
319    {
320      /* We must extend the array.  The user plays games with us and
321         presents new arguments.  */
322      char *new_str = malloc (top + 1);
323      if (new_str == NULL)
324        nonoption_flags_len = nonoption_flags_max_len = 0;
325      else
326        {
327          memset (__mempcpy (new_str, __getopt_nonoption_flags,
328                             nonoption_flags_max_len),
329                  '\0', top + 1 - nonoption_flags_max_len);
330          nonoption_flags_max_len = top + 1;
331          __getopt_nonoption_flags = new_str;
332        }
333    }
334#endif
335
336  while (top > middle && middle > bottom)
337    {
338      if (top - middle > middle - bottom)
339        {
340          /* Bottom segment is the short one.  */
341          int len = middle - bottom;
342          register int i;
343
344          /* Swap it with the top part of the top segment.  */
345          for (i = 0; i < len; i++)
346            {
347              tem = argv[bottom + i];
348              argv[bottom + i] = argv[top - (middle - bottom) + i];
349              argv[top - (middle - bottom) + i] = tem;
350              SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
351            }
352          /* Exclude the moved bottom segment from further swapping.  */
353          top -= len;
354        }
355      else
356        {
357          /* Top segment is the short one.  */
358          int len = top - middle;
359          register int i;
360
361          /* Swap it with the bottom part of the bottom segment.  */
362          for (i = 0; i < len; i++)
363            {
364              tem = argv[bottom + i];
365              argv[bottom + i] = argv[middle + i];
366              argv[middle + i] = tem;
367              SWAP_FLAGS (bottom + i, middle + i);
368            }
369          /* Exclude the moved top segment from further swapping.  */
370          bottom += len;
371        }
372    }
373
374  /* Update records for the slots the non-options now occupy.  */
375
376  first_nonopt += (optind - last_nonopt);
377  last_nonopt = optind;
378}
379
380/* Initialize the internal data when the first call is made.  */
381
382#if defined __STDC__ && __STDC__
383static const char *_getopt_initialize (int, char *const *, const char *);
384#endif
385static const char *
386_getopt_initialize (argc, argv, optstring)
387     int argc;
388     char *const *argv;
389     const char *optstring;
390{
391  /* Start processing options with ARGV-element 1 (since ARGV-element 0
392     is the program name); the sequence of previously skipped
393     non-option ARGV-elements is empty.  */
394
395  first_nonopt = last_nonopt = optind;
396
397  nextchar = NULL;
398
399  posixly_correct = getenv ("POSIXLY_CORRECT");
400
401  /* Determine how to handle the ordering of options and nonoptions.  */
402
403  if (optstring[0] == '-')
404    {
405      ordering = RETURN_IN_ORDER;
406      ++optstring;
407    }
408  else if (optstring[0] == '+')
409    {
410      ordering = REQUIRE_ORDER;
411      ++optstring;
412    }
413  else if (posixly_correct != NULL)
414    ordering = REQUIRE_ORDER;
415  else
416    ordering = PERMUTE;
417
418#if defined _LIBC && defined USE_NONOPTION_FLAGS
419  if (posixly_correct == NULL
420      && argc == __libc_argc && argv == __libc_argv)
421    {
422      if (nonoption_flags_max_len == 0)
423        {
424          if (__getopt_nonoption_flags == NULL
425              || __getopt_nonoption_flags[0] == '\0')
426            nonoption_flags_max_len = -1;
427          else
428            {
429              const char *orig_str = __getopt_nonoption_flags;
430              int len = nonoption_flags_max_len = strlen (orig_str);
431              if (nonoption_flags_max_len < argc)
432                nonoption_flags_max_len = argc;
433              __getopt_nonoption_flags =
434                (char *) malloc (nonoption_flags_max_len);
435              if (__getopt_nonoption_flags == NULL)
436                nonoption_flags_max_len = -1;
437              else
438                memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
439                        '\0', nonoption_flags_max_len - len);
440            }
441        }
442      nonoption_flags_len = nonoption_flags_max_len;
443    }
444  else
445    nonoption_flags_len = 0;
446#endif
447
448  return optstring;
449}
450
451/* Scan elements of ARGV (whose length is ARGC) for option characters
452   given in OPTSTRING.
453
454   If an element of ARGV starts with '-', and is not exactly "-" or "--",
455   then it is an option element.  The characters of this element
456   (aside from the initial '-') are option characters.  If `getopt'
457   is called repeatedly, it returns successively each of the option characters
458   from each of the option elements.
459
460   If `getopt' finds another option character, it returns that character,
461   updating `optind' and `nextchar' so that the next call to `getopt' can
462   resume the scan with the following option character or ARGV-element.
463
464   If there are no more option characters, `getopt' returns -1.
465   Then `optind' is the index in ARGV of the first ARGV-element
466   that is not an option.  (The ARGV-elements have been permuted
467   so that those that are not options now come last.)
468
469   OPTSTRING is a string containing the legitimate option characters.
470   If an option character is seen that is not listed in OPTSTRING,
471   return '?' after printing an error message.  If you set `opterr' to
472   zero, the error message is suppressed but we still return '?'.
473
474   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
475   so the following text in the same ARGV-element, or the text of the following
476   ARGV-element, is returned in `optarg'.  Two colons mean an option that
477   wants an optional arg; if there is text in the current ARGV-element,
478   it is returned in `optarg', otherwise `optarg' is set to zero.
479
480   If OPTSTRING starts with `-' or `+', it requests different methods of
481   handling the non-option ARGV-elements.
482   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
483
484   Long-named options begin with `--' instead of `-'.
485   Their names may be abbreviated as long as the abbreviation is unique
486   or is an exact match for some defined option.  If they have an
487   argument, it follows the option name in the same ARGV-element, separated
488   from the option name by a `=', or else the in next ARGV-element.
489   When `getopt' finds a long-named option, it returns 0 if that option's
490   `flag' field is nonzero, the value of the option's `val' field
491   if the `flag' field is zero.
492
493   The elements of ARGV aren't really const, because we permute them.
494   But we pretend they're const in the prototype to be compatible
495   with other systems.
496
497   LONGOPTS is a vector of `struct option' terminated by an
498   element containing a name which is zero.
499
500   LONGIND returns the index in LONGOPT of the long-named option found.
501   It is only valid when a long-named option has been found by the most
502   recent call.
503
504   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
505   long-named options.  */
506
507int
508_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
509     int argc;
510     char *const *argv;
511     const char *optstring;
512     const struct option *longopts;
513     int *longind;
514     int long_only;
515{
516  int print_errors = opterr;
517  if (optstring[0] == ':')
518    print_errors = 0;
519
520  if (argc < 1)
521    return -1;
522
523  optarg = NULL;
524
525  if (optind == 0 || !__getopt_initialized)
526    {
527      if (optind == 0)
528        optind = 1;        /* Don't scan ARGV[0], the program name.  */
529      optstring = _getopt_initialize (argc, argv, optstring);
530      __getopt_initialized = 1;
531    }
532
533  /* Test whether ARGV[optind] points to a non-option argument.
534     Either it does not have option syntax, or there is an environment flag
535     from the shell indicating it is not an option.  The later information
536     is only used when the used in the GNU libc.  */
537#if defined _LIBC && defined USE_NONOPTION_FLAGS
538# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'              \
539                      || (optind < nonoption_flags_len                              \
540                          && __getopt_nonoption_flags[optind] == '1'))
541#else
542# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
543#endif
544
545  if (nextchar == NULL || *nextchar == '\0')
546    {
547      /* Advance to the next ARGV-element.  */
548
549      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
550         moved back by the user (who may also have changed the arguments).  */
551      if (last_nonopt > optind)
552        last_nonopt = optind;
553      if (first_nonopt > optind)
554        first_nonopt = optind;
555
556      if (ordering == PERMUTE)
557        {
558          /* If we have just processed some options following some non-options,
559             exchange them so that the options come first.  */
560
561          if (first_nonopt != last_nonopt && last_nonopt != optind)
562            exchange ((char **) argv);
563          else if (last_nonopt != optind)
564            first_nonopt = optind;
565
566          /* Skip any additional non-options
567             and extend the range of non-options previously skipped.  */
568
569          while (optind < argc && NONOPTION_P)
570            optind++;
571          last_nonopt = optind;
572        }
573
574      /* The special ARGV-element `--' means premature end of options.
575         Skip it like a null option,
576         then exchange with previous non-options as if it were an option,
577         then skip everything else like a non-option.  */
578
579      if (optind != argc && !strcmp (argv[optind], "--"))
580        {
581          optind++;
582
583          if (first_nonopt != last_nonopt && last_nonopt != optind)
584            exchange ((char **) argv);
585          else if (first_nonopt == last_nonopt)
586            first_nonopt = optind;
587          last_nonopt = argc;
588
589          optind = argc;
590        }
591
592      /* If we have done all the ARGV-elements, stop the scan
593         and back over any non-options that we skipped and permuted.  */
594
595      if (optind == argc)
596        {
597          /* Set the next-arg-index to point at the non-options
598             that we previously skipped, so the caller will digest them.  */
599          if (first_nonopt != last_nonopt)
600            optind = first_nonopt;
601          return -1;
602        }
603
604      /* If we have come to a non-option and did not permute it,
605         either stop the scan or describe it to the caller and pass it by.  */
606
607      if (NONOPTION_P)
608        {
609          if (ordering == REQUIRE_ORDER)
610            return -1;
611          optarg = argv[optind++];
612          return 1;
613        }
614
615      /* We have found another option-ARGV-element.
616         Skip the initial punctuation.  */
617
618      nextchar = (argv[optind] + 1
619                  + (longopts != NULL && argv[optind][1] == '-'));
620    }
621
622  /* Decode the current option-ARGV-element.  */
623
624  /* Check whether the ARGV-element is a long option.
625
626     If long_only and the ARGV-element has the form "-f", where f is
627     a valid short option, don't consider it an abbreviated form of
628     a long option that starts with f.  Otherwise there would be no
629     way to give the -f short option.
630
631     On the other hand, if there's a long option "fubar" and
632     the ARGV-element is "-fu", do consider that an abbreviation of
633     the long option, just like "--fu", and not "-f" with arg "u".
634
635     This distinction seems to be the most useful approach.  */
636
637  if (longopts != NULL
638      && (argv[optind][1] == '-'
639          || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
640    {
641      char *nameend;
642      const struct option *p;
643      const struct option *pfound = NULL;
644      int exact = 0;
645      int ambig = 0;
646      int indfound = -1;
647      int option_index;
648
649      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
650        /* Do nothing.  */ ;
651
652      /* Test all long options for either exact match
653         or abbreviated matches.  */
654      for (p = longopts, option_index = 0; p->name; p++, option_index++)
655        if (!strncmp (p->name, nextchar, nameend - nextchar))
656          {
657            if ((unsigned int) (nameend - nextchar)
658                == (unsigned int) strlen (p->name))
659              {
660                /* Exact match found.  */
661                pfound = p;
662                indfound = option_index;
663                exact = 1;
664                break;
665              }
666            else if (pfound == NULL)
667              {
668                /* First nonexact match found.  */
669                pfound = p;
670                indfound = option_index;
671              }
672            else if (long_only
673                     || pfound->has_arg != p->has_arg
674                     || pfound->flag != p->flag
675                     || pfound->val != p->val)
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 */
1058#endif
Note: See TracBrowser for help on using the repository browser.