infcall: refactor 'call_function_by_hand_dummy'
[deliverable/binutils-gdb.git] / readline / nls.c
1 /* nls.c -- skeletal internationalization code. */
2
3 /* Copyright (C) 1996-2017 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 "utf8",
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 *
89 _rl_get_locale_var (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 (char *lspec)
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
120 /* Query the right environment variables and call setlocale() to initialize
121 the C library locale settings. */
122 char *
123 _rl_init_locale (void)
124 {
125 char *ret, *lspec;
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 = "";
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;
155
156 t = _rl_init_locale (); /* returns static pointer */
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 }
187
188 _rl_utf8locale = *t ? STREQ (t, "utf8") : 0;
189
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 *
197 normalize_codeset (char *codeset)
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 *
244 find_codeset (char *name, size_t *lenp)
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 }
This page took 0.038282 seconds and 4 git commands to generate.