nls.c revision 26497
121308Sache/* nls.c -- skeletal internationalization code. */ 221308Sache 321308Sache/* Copyright (C) 1996 Free Software Foundation, Inc. 421308Sache 521308Sache This file is part of the GNU Readline Library, a library for 621308Sache reading lines of text with interactive input and history editing. 721308Sache 821308Sache The GNU Readline Library is free software; you can redistribute it 921308Sache and/or modify it under the terms of the GNU General Public License 1021308Sache as published by the Free Software Foundation; either version 1, or 1121308Sache (at your option) any later version. 1221308Sache 1321308Sache The GNU Readline Library is distributed in the hope that it will be 1421308Sache useful, but WITHOUT ANY WARRANTY; without even the implied warranty 1521308Sache of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1621308Sache GNU General Public License for more details. 1721308Sache 1821308Sache The GNU General Public License is often shipped with GNU software, and 1921308Sache is generally kept in a file called COPYING or LICENSE. If you do not 2021308Sache have a copy of the license, write to the Free Software Foundation, 2121308Sache 675 Mass Ave, Cambridge, MA 02139, USA. */ 2221308Sache#define READLINE_LIBRARY 2321308Sache 2421308Sache#if defined (HAVE_CONFIG_H) 2521308Sache# include <config.h> 2621308Sache#endif 2721308Sache 2826497Sache#include <sys/types.h> 2926497Sache 3021308Sache#if defined (HAVE_UNISTD_H) 3121308Sache# include <unistd.h> 3221308Sache#endif /* HAVE_UNISTD_H */ 3321308Sache 3421308Sache#if defined (HAVE_STDLIB_H) 3521308Sache# include <stdlib.h> 3621308Sache#else 3721308Sache# include "ansi_stdlib.h" 3821308Sache#endif /* HAVE_STDLIB_H */ 3921308Sache 4021308Sache#if defined (HAVE_LOCALE_H) 4121308Sache# include <locale.h> 4221308Sache#endif 4321308Sache 4421308Sache#include <ctype.h> 4521308Sache 4621308Sache#include "rldefs.h" 4721308Sache 4821308Sacheextern int _rl_convert_meta_chars_to_ascii; 4921308Sacheextern int _rl_output_meta_chars; 5021308Sacheextern int _rl_meta_flag; 5126497Sache 5226497Sache/* Functions imported from shell.c */ 5326497Sacheextern char *get_env_value (); 5426497Sache 5526497Sache#if !defined (HAVE_SETLOCALE) 5621308Sache/* A list of legal values for the LANG or LC_CTYPE environment variables. 5721308Sache If a locale name in this list is the value for the LC_ALL, LC_CTYPE, 5821308Sache or LANG environment variable (using the first of those with a value), 5921308Sache readline eight-bit mode is enabled. */ 6021308Sachestatic char *legal_lang_values[] = 6121308Sache{ 6221308Sache "iso88591", 6321308Sache "iso88592", 6421308Sache "iso88593", 6521308Sache "iso88594", 6621308Sache "iso88595", 6721308Sache "iso88596", 6821308Sache "iso88597", 6921308Sache "iso88598", 7021308Sache "iso88599", 7121308Sache "iso885910", 7221308Sache "koi8r", 7321308Sache 0 7421308Sache}; 7521308Sache 7621308Sachestatic char *normalize_codeset (); 7721308Sachestatic char *find_codeset (); 7826497Sache#endif /* !HAVE_SETLOCALE */ 7921308Sache 8021308Sache/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value 8121308Sache to decide the defaults for 8-bit character input and output. Returns 8221308Sache 1 if we set eight-bit mode. */ 8321308Sacheint 8421308Sache_rl_init_eightbit () 8521308Sache{ 8626497Sache/* If we have setlocale(3), just check the current LC_CTYPE category 8726497Sache value, and go into eight-bit mode if it's not C or POSIX. */ 8826497Sache#if defined (HAVE_SETLOCALE) 8926497Sache char *t; 9026497Sache 9126497Sache /* Set the LC_CTYPE locale category from environment variables. */ 9226497Sache t = setlocale (LC_CTYPE, ""); 9326497Sache if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0)) 9426497Sache { 9526497Sache _rl_meta_flag = 1; 9626497Sache _rl_convert_meta_chars_to_ascii = 0; 9726497Sache _rl_output_meta_chars = 1; 9826497Sache return (1); 9926497Sache } 10026497Sache else 10126497Sache return (0); 10226497Sache 10326497Sache#else /* !HAVE_SETLOCALE */ 10421308Sache char *lspec, *t; 10521308Sache int i; 10621308Sache 10726497Sache /* We don't have setlocale. Finesse it. Check the environment for the 10826497Sache appropriate variables and set eight-bit mode if they have the right 10926497Sache values. */ 11026497Sache lspec = get_env_value ("LC_ALL"); 11126497Sache if (lspec == 0) lspec = get_env_value ("LC_CTYPE"); 11226497Sache if (lspec == 0) lspec = get_env_value ("LANG"); 11321308Sache if (lspec == 0 || (t = normalize_codeset (lspec)) == 0) 11421308Sache return (0); 11521308Sache for (i = 0; t && legal_lang_values[i]; i++) 11621308Sache if (STREQ (t, legal_lang_values[i])) 11721308Sache { 11821308Sache _rl_meta_flag = 1; 11921308Sache _rl_convert_meta_chars_to_ascii = 0; 12021308Sache _rl_output_meta_chars = 1; 12121308Sache break; 12221308Sache } 12321308Sache free (t); 12421308Sache return (legal_lang_values[i] ? 1 : 0); 12526497Sache 12626497Sache#endif /* !HAVE_SETLOCALE */ 12721308Sache} 12821308Sache 12926497Sache#if !defined (HAVE_SETLOCALE) 13021308Sachestatic char * 13121308Sachenormalize_codeset (codeset) 13221308Sache char *codeset; 13321308Sache{ 13421308Sache size_t namelen, i; 13521308Sache int len, all_digits; 13621308Sache char *wp, *retval; 13721308Sache 13821308Sache codeset = find_codeset (codeset, &namelen); 13921308Sache 14021308Sache if (codeset == 0) 14121308Sache return (codeset); 14221308Sache 14321308Sache all_digits = 1; 14421308Sache for (len = 0, i = 0; i < namelen; i++) 14521308Sache { 14621308Sache if (isalnum (codeset[i])) 14721308Sache { 14821308Sache len++; 14921308Sache all_digits &= isdigit (codeset[i]); 15021308Sache } 15121308Sache } 15221308Sache 15321308Sache retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1); 15421308Sache if (retval == 0) 15521308Sache return ((char *)0); 15621308Sache 15721308Sache wp = retval; 15821308Sache /* Add `iso' to beginning of an all-digit codeset */ 15921308Sache if (all_digits) 16021308Sache { 16121308Sache *wp++ = 'i'; 16221308Sache *wp++ = 's'; 16321308Sache *wp++ = 'o'; 16421308Sache } 16521308Sache 16621308Sache for (i = 0; i < namelen; i++) 16721308Sache if (isalpha (codeset[i])) 16821308Sache *wp++ = (isupper (codeset[i])) ? tolower (codeset[i]) : codeset[i]; 16921308Sache else if (isdigit (codeset[i])) 17021308Sache *wp++ = codeset[i]; 17121308Sache *wp = '\0'; 17221308Sache 17321308Sache return retval; 17421308Sache} 17521308Sache 17621308Sache/* Isolate codeset portion of locale specification. */ 17721308Sachestatic char * 17821308Sachefind_codeset (name, lenp) 17921308Sache char *name; 18021308Sache size_t *lenp; 18121308Sache{ 18221308Sache char *cp, *language, *result; 18321308Sache 18421308Sache cp = language = name; 18521308Sache result = (char *)0; 18621308Sache 18721308Sache while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',') 18821308Sache cp++; 18921308Sache 19021308Sache /* This does not make sense: language has to be specified. As 19121308Sache an exception we allow the variable to contain only the codeset 19221308Sache name. Perhaps there are funny codeset names. */ 19321308Sache if (language == cp) 19421308Sache { 19521308Sache *lenp = strlen (language); 19621308Sache result = language; 19721308Sache } 19821308Sache else 19921308Sache { 20021308Sache /* Next is the territory. */ 20121308Sache if (*cp == '_') 20221308Sache do 20321308Sache ++cp; 20421308Sache while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_'); 20521308Sache 20621308Sache /* Now, finally, is the codeset. */ 20721308Sache result = cp; 20821308Sache if (*cp == '.') 20921308Sache do 21021308Sache ++cp; 21121308Sache while (*cp && *cp != '@'); 21221308Sache 21321308Sache if (cp - result > 2) 21421308Sache { 21521308Sache result++; 21621308Sache *lenp = cp - result; 21721308Sache } 21821308Sache else 21921308Sache { 22021308Sache *lenp = strlen (language); 22121308Sache result = language; 22221308Sache } 22321308Sache } 22421308Sache 22521308Sache return result; 22621308Sache} 22726497Sache#endif /* !HAVE_SETLOCALE */ 228