]> git.saurik.com Git - bison.git/blobdiff - lib/getopt.c
* src/system.h: Don't use #ifdef/#ifndef on HAVE_ values, only
[bison.git] / lib / getopt.c
index d176d3e7e720a406de82663db4740418355998de..dc07cb36f7db2a87727abad15f48dd40da38b4e9 100644 (file)
@@ -1,14 +1,15 @@
 /* Getopt for GNU.
 /* Getopt for GNU.
-   NOTE: The canonical source of this file is maintained with the GNU
-   C Library.  Bugs can be reported to bug-glibc@gnu.org.
-
-   Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to drepper@gnu.org
+   before changing it!
+   Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002
        Free Software Foundation, Inc.
        Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
 
 
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 2, or (at your option) any
-   later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
-#else
-# if !defined __STDC__ || !__STDC__
-/* This is a separate conditional since some stdc systems
-   reject `defined (const)'.  */
-#  ifndef const
-#   define const
-#  endif
-# endif
 #endif
 
 #include <stdio.h>
 #endif
 
 #include <stdio.h>
 #ifndef ELIDE_CODE
 
 
 #ifndef ELIDE_CODE
 
 
-/* This needs to come after some library #include
-   to get __GNU_LIBRARY__ defined.  */
-#ifdef __GNU_LIBRARY__
-/* Don't include stdlib.h for non-GNU C libraries because some of them
-   contain conflicting prototypes for getopt.  */
+#if HAVE_STDLIB_H || defined __GNU_LIBRARY__
 # include <stdlib.h>
 # include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H || defined __GNU_LIBRARY__
 # include <unistd.h>
 # include <unistd.h>
-#endif /* GNU C library.  */
+#endif
 
 #ifdef VMS
 # include <unixlib.h>
 
 #ifdef VMS
 # include <unixlib.h>
 #endif
 
 #ifndef _
 #endif
 
 #ifndef _
-/* This is for other GNU distributions with internationalized messages.
-   When compiling libc, the _ macro is predefined.  */
-# ifdef HAVE_LIBINTL_H
+/* This is for other GNU distributions with internationalized messages.  */
+# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
 #  include <libintl.h>
 #  include <libintl.h>
-#  define _(msgid)     gettext (msgid)
+#  ifndef _
+#   define _(msgid)    gettext (msgid)
+#  endif
 # else
 #  define _(msgid)     (msgid)
 # endif
 # else
 #  define _(msgid)     (msgid)
 # endif
@@ -187,30 +179,18 @@ static enum
 /* Value of POSIXLY_CORRECT environment variable.  */
 static char *posixly_correct;
 \f
 /* Value of POSIXLY_CORRECT environment variable.  */
 static char *posixly_correct;
 \f
-#ifdef __GNU_LIBRARY__
-/* We want to avoid inclusion of string.h with non-GNU libraries
-   because there are many ways it can cause trouble.
-   On some systems, it contains special magic macros that don't work
-   in GCC.  */
+#if HAVE_STRING_H || defined __GNU_LIBRARY__
 # include <string.h>
 # include <string.h>
-# define my_index      strchr
 #else
 #else
-
-# if HAVE_STRING_H
-#  include <string.h>
-# else
+# if HAVE_STRINGS_H
 #  include <strings.h>
 # endif
 #  include <strings.h>
 # endif
-
-/* Avoid depending on library functions or files
-   whose names are inconsistent.  */
-
-#ifndef getenv
-extern char *getenv ();
 #endif
 
 #endif
 
+#if !HAVE_STRCHR && !defined strchr && !defined __GNU_LIBRARY__
+# define strchr my_strchr
 static char *
 static char *
-my_index (str, chr)
+strchr (str, chr)
      const char *str;
      int chr;
 {
      const char *str;
      int chr;
 {
@@ -222,20 +202,11 @@ my_index (str, chr)
     }
   return 0;
 }
     }
   return 0;
 }
+#endif
 
 
-/* If using GCC, we can safely declare strlen this way.
-   If not using GCC, it is ok not to declare it.  */
-#ifdef __GNUC__
-/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
-   That was relevant to code that was here before.  */
-# if (!defined __STDC__ || !__STDC__) && !defined strlen
-/* gcc with -traditional declares the built-in strlen to return int,
-   and has done so at least since version 2.4.5. -- rms.  */
-extern int strlen (const char *);
-# endif /* not __STDC__ */
-#endif /* __GNUC__ */
-
-#endif /* not __GNU_LIBRARY__ */
+#if !HAVE_DECL_GETENV && !defined getenv && !defined __GNU_LIBRARY__
+char *getenv ();
+#endif
 \f
 /* Handle permutation of arguments.  */
 
 \f
 /* Handle permutation of arguments.  */
 
@@ -250,11 +221,13 @@ static int last_nonopt;
 /* Bash 2.0 gives us an environment variable containing flags
    indicating ARGV elements that should not be considered arguments.  */
 
 /* Bash 2.0 gives us an environment variable containing flags
    indicating ARGV elements that should not be considered arguments.  */
 
+#ifdef USE_NONOPTION_FLAGS
 /* Defined in getopt_init.c  */
 extern char *__getopt_nonoption_flags;
 
 static int nonoption_flags_max_len;
 static int nonoption_flags_len;
 /* Defined in getopt_init.c  */
 extern char *__getopt_nonoption_flags;
 
 static int nonoption_flags_max_len;
 static int nonoption_flags_len;
+#endif
 
 static int original_argc;
 static char *const *original_argv;
 
 static int original_argc;
 static char *const *original_argv;
@@ -275,13 +248,17 @@ store_args_and_env (int argc, char *const *argv)
 text_set_element (__libc_subinit, store_args_and_env);
 # endif /* text_set_element */
 
 text_set_element (__libc_subinit, store_args_and_env);
 # endif /* text_set_element */
 
-# define SWAP_FLAGS(ch1, ch2) \
+# ifdef USE_NONOPTION_FLAGS
+#  define SWAP_FLAGS(ch1, ch2) \
   if (nonoption_flags_len > 0)                                               \
     {                                                                        \
       char __tmp = __getopt_nonoption_flags[ch1];                            \
       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];         \
       __getopt_nonoption_flags[ch2] = __tmp;                                 \
     }
   if (nonoption_flags_len > 0)                                               \
     {                                                                        \
       char __tmp = __getopt_nonoption_flags[ch1];                            \
       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];         \
       __getopt_nonoption_flags[ch2] = __tmp;                                 \
     }
+# else
+#  define SWAP_FLAGS(ch1, ch2)
+# endif
 #else  /* !_LIBC */
 # define SWAP_FLAGS(ch1, ch2)
 #endif /* _LIBC */
 #else  /* !_LIBC */
 # define SWAP_FLAGS(ch1, ch2)
 #endif /* _LIBC */
@@ -313,7 +290,7 @@ exchange (argv)
      It leaves the longer segment in the right place overall,
      but it consists of two parts that need to be swapped next.  */
 
      It leaves the longer segment in the right place overall,
      but it consists of two parts that need to be swapped next.  */
 
-#ifdef _LIBC
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
   /* First make sure the handling of the `__getopt_nonoption_flags'
      string can work normally.  Our top argument must be in the range
      of the string.  */
   /* First make sure the handling of the `__getopt_nonoption_flags'
      string can work normally.  Our top argument must be in the range
      of the string.  */
@@ -417,7 +394,7 @@ _getopt_initialize (argc, argv, optstring)
   else
     ordering = PERMUTE;
 
   else
     ordering = PERMUTE;
 
-#ifdef _LIBC
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
   if (posixly_correct == NULL
       && argc == original_argc && argv == original_argv)
     {
   if (posixly_correct == NULL
       && argc == original_argc && argv == original_argv)
     {
@@ -515,6 +492,13 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
      int *longind;
      int long_only;
 {
      int *longind;
      int long_only;
 {
+  int print_errors = opterr;
+  if (optstring[0] == ':')
+    print_errors = 0;
+
+  if (argc < 1)
+    return -1;
+
   optarg = NULL;
 
   if (optind == 0 || !__getopt_initialized)
   optarg = NULL;
 
   if (optind == 0 || !__getopt_initialized)
@@ -529,7 +513,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
      Either it does not have option syntax, or there is an environment flag
      from the shell indicating it is not an option.  The later information
      is only used when the used in the GNU libc.  */
      Either it does not have option syntax, or there is an environment flag
      from the shell indicating it is not an option.  The later information
      is only used when the used in the GNU libc.  */
-#ifdef _LIBC
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'              \
                      || (optind < nonoption_flags_len                        \
                          && __getopt_nonoption_flags[optind] == '1'))
 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'              \
                      || (optind < nonoption_flags_len                        \
                          && __getopt_nonoption_flags[optind] == '1'))
@@ -631,7 +615,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 
   if (longopts != NULL
       && (argv[optind][1] == '-'
 
   if (longopts != NULL
       && (argv[optind][1] == '-'
-         || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+         || (long_only && (argv[optind][2] || !strchr (optstring, argv[optind][1])))))
     {
       char *nameend;
       const struct option *p;
     {
       char *nameend;
       const struct option *p;
@@ -664,14 +648,17 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                pfound = p;
                indfound = option_index;
              }
                pfound = p;
                indfound = option_index;
              }
-           else
+           else if (long_only
+                    || pfound->has_arg != p->has_arg
+                    || pfound->flag != p->flag
+                    || pfound->val != p->val)
              /* Second or later nonexact match found.  */
              ambig = 1;
          }
 
       if (ambig && !exact)
        {
              /* Second or later nonexact match found.  */
              ambig = 1;
          }
 
       if (ambig && !exact)
        {
-         if (opterr)
+         if (print_errors)
            fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
                     argv[0], argv[optind]);
          nextchar += strlen (nextchar);
            fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
                     argv[0], argv[optind]);
          nextchar += strlen (nextchar);
@@ -692,7 +679,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                optarg = nameend + 1;
              else
                {
                optarg = nameend + 1;
              else
                {
-                 if (opterr)
+                 if (print_errors)
                    {
                      if (argv[optind - 1][1] == '-')
                        /* --option */
                    {
                      if (argv[optind - 1][1] == '-')
                        /* --option */
@@ -718,7 +705,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                optarg = argv[optind++];
              else
                {
                optarg = argv[optind++];
              else
                {
-                 if (opterr)
+                 if (print_errors)
                    fprintf (stderr,
                           _("%s: option `%s' requires an argument\n"),
                           argv[0], argv[optind - 1]);
                    fprintf (stderr,
                           _("%s: option `%s' requires an argument\n"),
                           argv[0], argv[optind - 1]);
@@ -743,9 +730,9 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
         option, then it's an error.
         Otherwise interpret it as a short option.  */
       if (!long_only || argv[optind][1] == '-'
         option, then it's an error.
         Otherwise interpret it as a short option.  */
       if (!long_only || argv[optind][1] == '-'
-         || my_index (optstring, *nextchar) == NULL)
+         || strchr (optstring, *nextchar) == NULL)
        {
        {
-         if (opterr)
+         if (print_errors)
            {
              if (argv[optind][1] == '-')
                /* --option */
            {
              if (argv[optind][1] == '-')
                /* --option */
@@ -767,7 +754,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 
   {
     char c = *nextchar++;
 
   {
     char c = *nextchar++;
-    char *temp = my_index (optstring, c);
+    char *temp = strchr (optstring, c);
 
     /* Increment `optind' when we start to process its last character.  */
     if (*nextchar == '\0')
 
     /* Increment `optind' when we start to process its last character.  */
     if (*nextchar == '\0')
@@ -775,7 +762,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 
     if (temp == NULL || c == ':')
       {
 
     if (temp == NULL || c == ':')
       {
-       if (opterr)
+       if (print_errors)
          {
            if (posixly_correct)
              /* 1003.2 specifies the format of this message.  */
          {
            if (posixly_correct)
              /* 1003.2 specifies the format of this message.  */
@@ -809,7 +796,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
          }
        else if (optind == argc)
          {
          }
        else if (optind == argc)
          {
-           if (opterr)
+           if (print_errors)
              {
                /* 1003.2 specifies the format of this message.  */
                fprintf (stderr, _("%s: option requires an argument -- %c\n"),
              {
                /* 1003.2 specifies the format of this message.  */
                fprintf (stderr, _("%s: option requires an argument -- %c\n"),
@@ -858,7 +845,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
            }
        if (ambig && !exact)
          {
            }
        if (ambig && !exact)
          {
-           if (opterr)
+           if (print_errors)
              fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
                       argv[0], argv[optind]);
            nextchar += strlen (nextchar);
              fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
                       argv[0], argv[optind]);
            nextchar += strlen (nextchar);
@@ -876,7 +863,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                  optarg = nameend + 1;
                else
                  {
                  optarg = nameend + 1;
                else
                  {
-                   if (opterr)
+                   if (print_errors)
                      fprintf (stderr, _("\
 %s: option `-W %s' doesn't allow an argument\n"),
                               argv[0], pfound->name);
                      fprintf (stderr, _("\
 %s: option `-W %s' doesn't allow an argument\n"),
                               argv[0], pfound->name);
@@ -891,7 +878,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
                  optarg = argv[optind++];
                else
                  {
                  optarg = argv[optind++];
                else
                  {
-                   if (opterr)
+                   if (print_errors)
                      fprintf (stderr,
                               _("%s: option `%s' requires an argument\n"),
                               argv[0], argv[optind - 1]);
                      fprintf (stderr,
                               _("%s: option `%s' requires an argument\n"),
                               argv[0], argv[optind - 1]);
@@ -938,12 +925,12 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
              }
            else if (optind == argc)
              {
              }
            else if (optind == argc)
              {
-               if (opterr)
+               if (print_errors)
                  {
                    /* 1003.2 specifies the format of this message.  */
                    fprintf (stderr,
                  {
                    /* 1003.2 specifies the format of this message.  */
                    fprintf (stderr,
-                          _("%s: option requires an argument -- %c\n"),
-                          argv[0], c);
+                            _("%s: option requires an argument -- %c\n"),
+                            argv[0], c);
                  }
                optopt = c;
                if (optstring[0] == ':')
                  }
                optopt = c;
                if (optstring[0] == ':')