Annotation of embedaddon/readline/nls.c, revision 1.1
1.1 ! misho 1: /* nls.c -- skeletal internationalization code. */
! 2:
! 3: /* Copyright (C) 1996-2009 Free Software Foundation, Inc.
! 4:
! 5: This file is part of the GNU Readline Library (Readline), a library
! 6: for reading lines of text with interactive input and history editing.
! 7:
! 8: Readline is free software: you can redistribute it and/or modify
! 9: it under the terms of the GNU General Public License as published by
! 10: the Free Software Foundation, either version 3 of the License, or
! 11: (at your option) any later version.
! 12:
! 13: Readline is distributed in the hope that it will be useful,
! 14: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 16: GNU General Public License for more details.
! 17:
! 18: You should have received a copy of the GNU General Public License
! 19: along with Readline. If not, see <http://www.gnu.org/licenses/>.
! 20: */
! 21:
! 22: #define READLINE_LIBRARY
! 23:
! 24: #if defined (HAVE_CONFIG_H)
! 25: # include <config.h>
! 26: #endif
! 27:
! 28: #include <sys/types.h>
! 29:
! 30: #include <stdio.h>
! 31:
! 32: #if defined (HAVE_UNISTD_H)
! 33: # include <unistd.h>
! 34: #endif /* HAVE_UNISTD_H */
! 35:
! 36: #if defined (HAVE_STDLIB_H)
! 37: # include <stdlib.h>
! 38: #else
! 39: # include "ansi_stdlib.h"
! 40: #endif /* HAVE_STDLIB_H */
! 41:
! 42: #if defined (HAVE_LOCALE_H)
! 43: # include <locale.h>
! 44: #endif
! 45:
! 46: #if defined (HAVE_LANGINFO_CODESET)
! 47: # include <langinfo.h>
! 48: #endif
! 49:
! 50: #include <ctype.h>
! 51:
! 52: #include "rldefs.h"
! 53: #include "readline.h"
! 54: #include "rlshell.h"
! 55: #include "rlprivate.h"
! 56:
! 57: static int utf8locale PARAMS((char *));
! 58:
! 59: #if !defined (HAVE_SETLOCALE)
! 60: /* A list of legal values for the LANG or LC_CTYPE environment variables.
! 61: If a locale name in this list is the value for the LC_ALL, LC_CTYPE,
! 62: or LANG environment variable (using the first of those with a value),
! 63: readline eight-bit mode is enabled. */
! 64: static char *legal_lang_values[] =
! 65: {
! 66: "iso88591",
! 67: "iso88592",
! 68: "iso88593",
! 69: "iso88594",
! 70: "iso88595",
! 71: "iso88596",
! 72: "iso88597",
! 73: "iso88598",
! 74: "iso88599",
! 75: "iso885910",
! 76: "koi8r",
! 77: 0
! 78: };
! 79:
! 80: static char *normalize_codeset PARAMS((char *));
! 81: #endif /* !HAVE_SETLOCALE */
! 82:
! 83: static char *find_codeset PARAMS((char *, size_t *));
! 84:
! 85: static char *_rl_get_locale_var PARAMS((const char *));
! 86:
! 87: static char *
! 88: _rl_get_locale_var (v)
! 89: const char *v;
! 90: {
! 91: char *lspec;
! 92:
! 93: lspec = sh_get_env_value ("LC_ALL");
! 94: if (lspec == 0 || *lspec == 0)
! 95: lspec = sh_get_env_value (v);
! 96: if (lspec == 0 || *lspec == 0)
! 97: lspec = sh_get_env_value ("LANG");
! 98:
! 99: return lspec;
! 100: }
! 101:
! 102: static int
! 103: utf8locale (lspec)
! 104: char *lspec;
! 105: {
! 106: char *cp;
! 107: size_t len;
! 108:
! 109: #if HAVE_LANGINFO_CODESET
! 110: cp = nl_langinfo (CODESET);
! 111: return (STREQ (cp, "UTF-8") || STREQ (cp, "utf8"));
! 112: #else
! 113: cp = find_codeset (lspec, &len);
! 114:
! 115: if (cp == 0 || len < 4 || len > 5)
! 116: return 0;
! 117: return ((len == 5) ? strncmp (cp, "UTF-8", len) == 0 : strncmp (cp, "utf8", 4) == 0);
! 118: #endif
! 119: }
! 120:
! 121: /* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
! 122: to decide the defaults for 8-bit character input and output. Returns
! 123: 1 if we set eight-bit mode. */
! 124: int
! 125: _rl_init_eightbit ()
! 126: {
! 127: /* If we have setlocale(3), just check the current LC_CTYPE category
! 128: value, and go into eight-bit mode if it's not C or POSIX. */
! 129: #if defined (HAVE_SETLOCALE)
! 130: char *lspec, *t;
! 131:
! 132: /* Set the LC_CTYPE locale category from environment variables. */
! 133: lspec = _rl_get_locale_var ("LC_CTYPE");
! 134: /* Since _rl_get_locale_var queries the right environment variables,
! 135: we query the current locale settings with setlocale(), and, if
! 136: that doesn't return anything, we set lspec to the empty string to
! 137: force the subsequent call to setlocale() to define the `native'
! 138: environment. */
! 139: if (lspec == 0 || *lspec == 0)
! 140: lspec = setlocale (LC_CTYPE, (char *)NULL);
! 141: if (lspec == 0)
! 142: lspec = "";
! 143: t = setlocale (LC_CTYPE, lspec);
! 144:
! 145: if (t && *t)
! 146: _rl_utf8locale = utf8locale (t);
! 147:
! 148: if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0))
! 149: {
! 150: _rl_meta_flag = 1;
! 151: _rl_convert_meta_chars_to_ascii = 0;
! 152: _rl_output_meta_chars = 1;
! 153: return (1);
! 154: }
! 155: else
! 156: return (0);
! 157:
! 158: #else /* !HAVE_SETLOCALE */
! 159: char *lspec, *t;
! 160: int i;
! 161:
! 162: /* We don't have setlocale. Finesse it. Check the environment for the
! 163: appropriate variables and set eight-bit mode if they have the right
! 164: values. */
! 165: lspec = _rl_get_locale_var ("LC_CTYPE");
! 166:
! 167: if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
! 168: return (0);
! 169: for (i = 0; t && legal_lang_values[i]; i++)
! 170: if (STREQ (t, legal_lang_values[i]))
! 171: {
! 172: _rl_meta_flag = 1;
! 173: _rl_convert_meta_chars_to_ascii = 0;
! 174: _rl_output_meta_chars = 1;
! 175: break;
! 176: }
! 177: xfree (t);
! 178: return (legal_lang_values[i] ? 1 : 0);
! 179:
! 180: #endif /* !HAVE_SETLOCALE */
! 181: }
! 182:
! 183: #if !defined (HAVE_SETLOCALE)
! 184: static char *
! 185: normalize_codeset (codeset)
! 186: char *codeset;
! 187: {
! 188: size_t namelen, i;
! 189: int len, all_digits;
! 190: char *wp, *retval;
! 191:
! 192: codeset = find_codeset (codeset, &namelen);
! 193:
! 194: if (codeset == 0)
! 195: return (codeset);
! 196:
! 197: all_digits = 1;
! 198: for (len = 0, i = 0; i < namelen; i++)
! 199: {
! 200: if (ISALNUM ((unsigned char)codeset[i]))
! 201: {
! 202: len++;
! 203: all_digits &= _rl_digit_p (codeset[i]);
! 204: }
! 205: }
! 206:
! 207: retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1);
! 208: if (retval == 0)
! 209: return ((char *)0);
! 210:
! 211: wp = retval;
! 212: /* Add `iso' to beginning of an all-digit codeset */
! 213: if (all_digits)
! 214: {
! 215: *wp++ = 'i';
! 216: *wp++ = 's';
! 217: *wp++ = 'o';
! 218: }
! 219:
! 220: for (i = 0; i < namelen; i++)
! 221: if (ISALPHA ((unsigned char)codeset[i]))
! 222: *wp++ = _rl_to_lower (codeset[i]);
! 223: else if (_rl_digit_p (codeset[i]))
! 224: *wp++ = codeset[i];
! 225: *wp = '\0';
! 226:
! 227: return retval;
! 228: }
! 229: #endif /* !HAVE_SETLOCALE */
! 230:
! 231: /* Isolate codeset portion of locale specification. */
! 232: static char *
! 233: find_codeset (name, lenp)
! 234: char *name;
! 235: size_t *lenp;
! 236: {
! 237: char *cp, *language, *result;
! 238:
! 239: cp = language = name;
! 240: result = (char *)0;
! 241:
! 242: while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',')
! 243: cp++;
! 244:
! 245: /* This does not make sense: language has to be specified. As
! 246: an exception we allow the variable to contain only the codeset
! 247: name. Perhaps there are funny codeset names. */
! 248: if (language == cp)
! 249: {
! 250: *lenp = strlen (language);
! 251: result = language;
! 252: }
! 253: else
! 254: {
! 255: /* Next is the territory. */
! 256: if (*cp == '_')
! 257: do
! 258: ++cp;
! 259: while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_');
! 260:
! 261: /* Now, finally, is the codeset. */
! 262: result = cp;
! 263: if (*cp == '.')
! 264: do
! 265: ++cp;
! 266: while (*cp && *cp != '@');
! 267:
! 268: if (cp - result > 2)
! 269: {
! 270: result++;
! 271: *lenp = cp - result;
! 272: }
! 273: else
! 274: {
! 275: *lenp = strlen (language);
! 276: result = language;
! 277: }
! 278: }
! 279:
! 280: return result;
! 281: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>