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