source: trunk/third/enscript/compat/getopt.c @ 17620

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