Annotation of embedaddon/readline/nls.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>