Imported from ../bash-4.0-rc1.tar.gz.
[platform/upstream/bash.git] / lib / readline / nls.c
index fad5201..7f10f01 100644 (file)
@@ -1,30 +1,34 @@
 /* nls.c -- skeletal internationalization code. */
 
-/* Copyright (C) 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2009 Free Software Foundation, Inc.
 
-   This file is part of the GNU Readline Library, a library for
-   reading lines of text with interactive input and history editing.
+   This file is part of the GNU Readline Library (Readline), a library
+   for reading lines of text with interactive input and history editing.      
 
-   The GNU Readline Library 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 1, or
+   Readline 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 3 of the License, or
    (at your option) any later version.
 
-   The GNU Readline Library is distributed in the hope that it will be
-   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   Readline is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
-   The GNU General Public License is often shipped with GNU software, and
-   is generally kept in a file called COPYING or LICENSE.  If you do not
-   have a copy of the license, write to the Free Software Foundation,
-   675 Mass Ave, Cambridge, MA 02139, USA. */
+   You should have received a copy of the GNU General Public License
+   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #define READLINE_LIBRARY
 
 #if defined (HAVE_CONFIG_H)
 #  include <config.h>
 #endif
 
+#include <sys/types.h>
+
+#include <stdio.h>
+
 #if defined (HAVE_UNISTD_H)
 #  include <unistd.h>
 #endif /* HAVE_UNISTD_H */
 #include <ctype.h>
 
 #include "rldefs.h"
+#include "readline.h"
+#include "rlshell.h"
+#include "rlprivate.h"
 
-extern int _rl_convert_meta_chars_to_ascii;
-extern int _rl_output_meta_chars;
-extern int _rl_meta_flag;
-    
+#if !defined (HAVE_SETLOCALE)    
 /* A list of legal values for the LANG or LC_CTYPE environment variables.
    If a locale name in this list is the value for the LC_ALL, LC_CTYPE,
    or LANG environment variable (using the first of those with a value),
@@ -63,25 +67,74 @@ static char *legal_lang_values[] =
  "iso88598",
  "iso88599",
  "iso885910",
- "koi8r",   
+ "koi8r",
   0
 };
 
-static char *normalize_codeset ();
-static char *find_codeset ();
+static char *normalize_codeset PARAMS((char *));
+static char *find_codeset PARAMS((char *, size_t *));
+#endif /* !HAVE_SETLOCALE */
 
+static char *_rl_get_locale_var PARAMS((const char *));
+
+static char *
+_rl_get_locale_var (v)
+     const char *v;
+{
+  char *lspec;
+
+  lspec = sh_get_env_value ("LC_ALL");
+  if (lspec == 0 || *lspec == 0)
+    lspec = sh_get_env_value (v);
+  if (lspec == 0 || *lspec == 0)
+    lspec = sh_get_env_value ("LANG");
+
+  return lspec;
+}
+  
 /* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
    to decide the defaults for 8-bit character input and output.  Returns
    1 if we set eight-bit mode. */
 int
 _rl_init_eightbit ()
 {
+/* If we have setlocale(3), just check the current LC_CTYPE category
+   value, and go into eight-bit mode if it's not C or POSIX. */
+#if defined (HAVE_SETLOCALE)
+  char *lspec, *t;
+
+  /* Set the LC_CTYPE locale category from environment variables. */
+  lspec = _rl_get_locale_var ("LC_CTYPE");
+  /* Since _rl_get_locale_var queries the right environment variables,
+     we query the current locale settings with setlocale(), and, if
+     that doesn't return anything, we set lspec to the empty string to
+     force the subsequent call to setlocale() to define the `native'
+     environment. */
+  if (lspec == 0 || *lspec == 0)
+    lspec = setlocale (LC_CTYPE, (char *)NULL);
+  if (lspec == 0)
+    lspec = "";
+  t = setlocale (LC_CTYPE, lspec);
+
+  if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0))
+    {
+      _rl_meta_flag = 1;
+      _rl_convert_meta_chars_to_ascii = 0;
+      _rl_output_meta_chars = 1;
+      return (1);
+    }
+  else
+    return (0);
+
+#else /* !HAVE_SETLOCALE */
   char *lspec, *t;
   int i;
 
-  lspec = getenv ("LC_ALL");
-  if (lspec == 0) lspec = getenv ("LC_CTYPE");
-  if (lspec == 0) lspec = getenv ("LANG");
+  /* We don't have setlocale.  Finesse it.  Check the environment for the
+     appropriate variables and set eight-bit mode if they have the right
+     values. */
+  lspec = _rl_get_locale_var ("LC_CTYPE");
+
   if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
     return (0);
   for (i = 0; t && legal_lang_values[i]; i++)
@@ -90,15 +143,15 @@ _rl_init_eightbit ()
        _rl_meta_flag = 1;
        _rl_convert_meta_chars_to_ascii = 0;
        _rl_output_meta_chars = 1;
-#if defined (HAVE_SETLOCALE)
-       setlocale (LC_CTYPE, lspec);
-#endif
        break;
       }
   free (t);
   return (legal_lang_values[i] ? 1 : 0);
+
+#endif /* !HAVE_SETLOCALE */
 }
 
+#if !defined (HAVE_SETLOCALE)
 static char *
 normalize_codeset (codeset)
      char *codeset;
@@ -115,10 +168,10 @@ normalize_codeset (codeset)
   all_digits = 1;
   for (len = 0, i = 0; i < namelen; i++)
     {
-      if (isalnum (codeset[i]))
+      if (ISALNUM ((unsigned char)codeset[i]))
        {
          len++;
-         all_digits &= isdigit (codeset[i]);
+         all_digits &= _rl_digit_p (codeset[i]);
        }
     }
 
@@ -136,9 +189,9 @@ normalize_codeset (codeset)
     }
 
   for (i = 0; i < namelen; i++)
-    if (isalpha (codeset[i]))
-      *wp++ = (isupper (codeset[i])) ? tolower (codeset[i]) : codeset[i];
-    else if (isdigit (codeset[i]))
+    if (ISALPHA ((unsigned char)codeset[i]))
+      *wp++ = _rl_to_lower (codeset[i]);
+    else if (_rl_digit_p (codeset[i]))
       *wp++ = codeset[i];
   *wp = '\0';
 
@@ -196,3 +249,4 @@ find_codeset (name, lenp)
 
   return result;
 }
+#endif /* !HAVE_SETLOCALE */