| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | /* nls.c -- skeletal internationalization code. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | /* Copyright (C) 1996-2009 Free Software Foundation, Inc.
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    This file is part of the GNU Readline Library (Readline), a library | 
					
						
							|  |  |  |    for reading lines of text with interactive input and history editing.       | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    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 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |    (at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    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 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |    GNU General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #define READLINE_LIBRARY
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_CONFIG_H)
 | 
					
						
							|  |  |  | #  include <config.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #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"
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #include "readline.h"
 | 
					
						
							|  |  |  | #include "rlshell.h"
 | 
					
						
							|  |  |  | #include "rlprivate.h"
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if !defined (HAVE_SETLOCALE)    
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | /* 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", | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  |  "koi8r", | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   0 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | static char *normalize_codeset PARAMS((char *)); | 
					
						
							|  |  |  | static char *find_codeset PARAMS((char *, size_t *)); | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | #endif /* !HAVE_SETLOCALE */
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | /* 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 () | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | /* 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)
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   char *lspec, *t; | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* Set the LC_CTYPE locale category from environment variables. */ | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |   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 */
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   char *lspec, *t; | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |   /* 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. */ | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   lspec = _rl_get_locale_var ("LC_CTYPE"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   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; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   free (t); | 
					
						
							|  |  |  |   return (legal_lang_values[i] ? 1 : 0); | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif /* !HAVE_SETLOCALE */
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | #if !defined (HAVE_SETLOCALE)
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 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++) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |       if (ISALNUM ((unsigned char)codeset[i])) | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 	  len++; | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | 	  all_digits &= _rl_digit_p (codeset[i]); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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++) | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |     if (ISALPHA ((unsigned char)codeset[i])) | 
					
						
							|  |  |  |       *wp++ = _rl_to_lower (codeset[i]); | 
					
						
							|  |  |  |     else if (_rl_digit_p (codeset[i])) | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       *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; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | #endif /* !HAVE_SETLOCALE */
 |