123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- /* nls.c -- skeletal internationalization code. */
- /* Copyright (C) 1996-2009 Free Software Foundation, Inc.
- This file is part of the GNU Readline Library (Readline), a library
- for reading lines of text with interactive input and history editing.
- 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.
- 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.
- 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 */
- #if defined (HAVE_STDLIB_H)
- # include <stdlib.h>
- #else
- # include "ansi_stdlib.h"
- #endif /* HAVE_STDLIB_H */
- #if defined (HAVE_LOCALE_H)
- # include <locale.h>
- #endif
- #include <ctype.h>
- #include "rldefs.h"
- #include "readline.h"
- #include "rlshell.h"
- #include "rlprivate.h"
- #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),
- readline eight-bit mode is enabled. */
- static char *legal_lang_values[] =
- {
- "iso88591",
- "iso88592",
- "iso88593",
- "iso88594",
- "iso88595",
- "iso88596",
- "iso88597",
- "iso88598",
- "iso88599",
- "iso885910",
- "koi8r",
- 0
- };
- 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;
- /* 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++)
- if (STREQ (t, legal_lang_values[i]))
- {
- _rl_meta_flag = 1;
- _rl_convert_meta_chars_to_ascii = 0;
- _rl_output_meta_chars = 1;
- break;
- }
- xfree (t);
- return (legal_lang_values[i] ? 1 : 0);
- #endif /* !HAVE_SETLOCALE */
- }
- #if !defined (HAVE_SETLOCALE)
- static char *
- normalize_codeset (codeset)
- char *codeset;
- {
- size_t namelen, i;
- int len, all_digits;
- char *wp, *retval;
- codeset = find_codeset (codeset, &namelen);
- if (codeset == 0)
- return (codeset);
- all_digits = 1;
- for (len = 0, i = 0; i < namelen; i++)
- {
- if (ISALNUM ((unsigned char)codeset[i]))
- {
- len++;
- all_digits &= _rl_digit_p (codeset[i]);
- }
- }
- retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1);
- if (retval == 0)
- return ((char *)0);
- wp = retval;
- /* Add `iso' to beginning of an all-digit codeset */
- if (all_digits)
- {
- *wp++ = 'i';
- *wp++ = 's';
- *wp++ = 'o';
- }
- for (i = 0; i < namelen; 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';
- return retval;
- }
- /* Isolate codeset portion of locale specification. */
- static char *
- find_codeset (name, lenp)
- char *name;
- size_t *lenp;
- {
- char *cp, *language, *result;
- cp = language = name;
- result = (char *)0;
- while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',')
- cp++;
- /* This does not make sense: language has to be specified. As
- an exception we allow the variable to contain only the codeset
- name. Perhaps there are funny codeset names. */
- if (language == cp)
- {
- *lenp = strlen (language);
- result = language;
- }
- else
- {
- /* Next is the territory. */
- if (*cp == '_')
- do
- ++cp;
- while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_');
- /* Now, finally, is the codeset. */
- result = cp;
- if (*cp == '.')
- do
- ++cp;
- while (*cp && *cp != '@');
- if (cp - result > 2)
- {
- result++;
- *lenp = cp - result;
- }
- else
- {
- *lenp = strlen (language);
- result = language;
- }
- }
- return result;
- }
- #endif /* !HAVE_SETLOCALE */
|