Annotation of embedaddon/readline/nls.c, revision 1.1.1.2
1.1 misho 1: /* nls.c -- skeletal internationalization code. */
2:
1.1.1.2 ! misho 3: /* Copyright (C) 1996-2017 Free Software Foundation, Inc.
1.1 misho 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",
1.1.1.2 ! misho 77: "utf8",
1.1 misho 78: 0
79: };
80:
81: static char *normalize_codeset PARAMS((char *));
82: #endif /* !HAVE_SETLOCALE */
83:
84: static char *find_codeset PARAMS((char *, size_t *));
85:
86: static char *_rl_get_locale_var PARAMS((const char *));
87:
88: static char *
1.1.1.2 ! misho 89: _rl_get_locale_var (const char *v)
1.1 misho 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
1.1.1.2 ! misho 103: utf8locale (char *lspec)
1.1 misho 104: {
105: char *cp;
106: size_t len;
107:
108: #if HAVE_LANGINFO_CODESET
109: cp = nl_langinfo (CODESET);
110: return (STREQ (cp, "UTF-8") || STREQ (cp, "utf8"));
111: #else
112: cp = find_codeset (lspec, &len);
113:
114: if (cp == 0 || len < 4 || len > 5)
115: return 0;
116: return ((len == 5) ? strncmp (cp, "UTF-8", len) == 0 : strncmp (cp, "utf8", 4) == 0);
117: #endif
118: }
119:
1.1.1.2 ! misho 120: /* Query the right environment variables and call setlocale() to initialize
! 121: the C library locale settings. */
! 122: char *
! 123: _rl_init_locale (void)
1.1 misho 124: {
1.1.1.2 ! misho 125: char *ret, *lspec;
1.1 misho 126:
127: /* Set the LC_CTYPE locale category from environment variables. */
128: lspec = _rl_get_locale_var ("LC_CTYPE");
129: /* Since _rl_get_locale_var queries the right environment variables,
130: we query the current locale settings with setlocale(), and, if
131: that doesn't return anything, we set lspec to the empty string to
132: force the subsequent call to setlocale() to define the `native'
133: environment. */
134: if (lspec == 0 || *lspec == 0)
135: lspec = setlocale (LC_CTYPE, (char *)NULL);
136: if (lspec == 0)
137: lspec = "";
1.1.1.2 ! misho 138: ret = setlocale (LC_CTYPE, lspec); /* ok, since it does not change locale */
! 139:
! 140: _rl_utf8locale = (ret && *ret) ? utf8locale (ret) : 0;
! 141:
! 142: return ret;
! 143: }
! 144:
! 145: /* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
! 146: to decide the defaults for 8-bit character input and output. Returns
! 147: 1 if we set eight-bit mode. */
! 148: int
! 149: _rl_init_eightbit (void)
! 150: {
! 151: /* If we have setlocale(3), just check the current LC_CTYPE category
! 152: value, and go into eight-bit mode if it's not C or POSIX. */
! 153: #if defined (HAVE_SETLOCALE)
! 154: char *lspec, *t;
1.1 misho 155:
1.1.1.2 ! misho 156: t = _rl_init_locale (); /* returns static pointer */
1.1 misho 157:
158: if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0))
159: {
160: _rl_meta_flag = 1;
161: _rl_convert_meta_chars_to_ascii = 0;
162: _rl_output_meta_chars = 1;
163: return (1);
164: }
165: else
166: return (0);
167:
168: #else /* !HAVE_SETLOCALE */
169: char *lspec, *t;
170: int i;
171:
172: /* We don't have setlocale. Finesse it. Check the environment for the
173: appropriate variables and set eight-bit mode if they have the right
174: values. */
175: lspec = _rl_get_locale_var ("LC_CTYPE");
176:
177: if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
178: return (0);
179: for (i = 0; t && legal_lang_values[i]; i++)
180: if (STREQ (t, legal_lang_values[i]))
181: {
182: _rl_meta_flag = 1;
183: _rl_convert_meta_chars_to_ascii = 0;
184: _rl_output_meta_chars = 1;
185: break;
186: }
1.1.1.2 ! misho 187:
! 188: _rl_utf8locale = *t ? STREQ (t, "utf8") : 0;
! 189:
1.1 misho 190: xfree (t);
191: return (legal_lang_values[i] ? 1 : 0);
192: #endif /* !HAVE_SETLOCALE */
193: }
194:
195: #if !defined (HAVE_SETLOCALE)
196: static char *
1.1.1.2 ! misho 197: normalize_codeset (char *codeset)
1.1 misho 198: {
199: size_t namelen, i;
200: int len, all_digits;
201: char *wp, *retval;
202:
203: codeset = find_codeset (codeset, &namelen);
204:
205: if (codeset == 0)
206: return (codeset);
207:
208: all_digits = 1;
209: for (len = 0, i = 0; i < namelen; i++)
210: {
211: if (ISALNUM ((unsigned char)codeset[i]))
212: {
213: len++;
214: all_digits &= _rl_digit_p (codeset[i]);
215: }
216: }
217:
218: retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1);
219: if (retval == 0)
220: return ((char *)0);
221:
222: wp = retval;
223: /* Add `iso' to beginning of an all-digit codeset */
224: if (all_digits)
225: {
226: *wp++ = 'i';
227: *wp++ = 's';
228: *wp++ = 'o';
229: }
230:
231: for (i = 0; i < namelen; i++)
232: if (ISALPHA ((unsigned char)codeset[i]))
233: *wp++ = _rl_to_lower (codeset[i]);
234: else if (_rl_digit_p (codeset[i]))
235: *wp++ = codeset[i];
236: *wp = '\0';
237:
238: return retval;
239: }
240: #endif /* !HAVE_SETLOCALE */
241:
242: /* Isolate codeset portion of locale specification. */
243: static char *
1.1.1.2 ! misho 244: find_codeset (char *name, size_t *lenp)
1.1 misho 245: {
246: char *cp, *language, *result;
247:
248: cp = language = name;
249: result = (char *)0;
250:
251: while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',')
252: cp++;
253:
254: /* This does not make sense: language has to be specified. As
255: an exception we allow the variable to contain only the codeset
256: name. Perhaps there are funny codeset names. */
257: if (language == cp)
258: {
259: *lenp = strlen (language);
260: result = language;
261: }
262: else
263: {
264: /* Next is the territory. */
265: if (*cp == '_')
266: do
267: ++cp;
268: while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_');
269:
270: /* Now, finally, is the codeset. */
271: result = cp;
272: if (*cp == '.')
273: do
274: ++cp;
275: while (*cp && *cp != '@');
276:
277: if (cp - result > 2)
278: {
279: result++;
280: *lenp = cp - result;
281: }
282: else
283: {
284: *lenp = strlen (language);
285: result = language;
286: }
287: }
288:
289: return result;
290: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>