source: trunk/third/readline/nls.c @ 15410

Revision 15410, 5.4 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15409, which included commits to RCS files with non-trunk default branches.
Line 
1/* nls.c -- skeletal internationalization code. */
2
3/* Copyright (C) 1996 Free Software Foundation, Inc.
4
5   This file is part of the GNU Readline Library, a library for
6   reading lines of text with interactive input and history editing.
7
8   The GNU Readline Library is free software; you can redistribute it
9   and/or modify it under the terms of the GNU General Public License
10   as published by the Free Software Foundation; either version 2, or
11   (at your option) any later version.
12
13   The GNU Readline Library is distributed in the hope that it will be
14   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   The GNU General Public License is often shipped with GNU software, and
19   is generally kept in a file called COPYING or LICENSE.  If you do not
20   have a copy of the license, write to the Free Software Foundation,
21   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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#include <ctype.h>
47
48#include "rldefs.h"
49#include "readline.h"
50#include "rlshell.h"
51#include "rlprivate.h"
52
53#if !defined (HAVE_SETLOCALE)   
54/* A list of legal values for the LANG or LC_CTYPE environment variables.
55   If a locale name in this list is the value for the LC_ALL, LC_CTYPE,
56   or LANG environment variable (using the first of those with a value),
57   readline eight-bit mode is enabled. */
58static char *legal_lang_values[] =
59{
60 "iso88591",
61 "iso88592",
62 "iso88593",
63 "iso88594",
64 "iso88595",
65 "iso88596",
66 "iso88597",
67 "iso88598",
68 "iso88599",
69 "iso885910",
70 "koi8r",
71  0
72};
73
74static char *normalize_codeset __P((char *));
75static char *find_codeset __P((char *, size_t *));
76#endif /* !HAVE_SETLOCALE */
77
78/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
79   to decide the defaults for 8-bit character input and output.  Returns
80   1 if we set eight-bit mode. */
81int
82_rl_init_eightbit ()
83{
84/* If we have setlocale(3), just check the current LC_CTYPE category
85   value, and go into eight-bit mode if it's not C or POSIX. */
86#if defined (HAVE_SETLOCALE)
87  char *t;
88
89  /* Set the LC_CTYPE locale category from environment variables. */
90  t = setlocale (LC_CTYPE, "");
91  if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0))
92    {
93      _rl_meta_flag = 1;
94      _rl_convert_meta_chars_to_ascii = 0;
95      _rl_output_meta_chars = 1;
96      return (1);
97    }
98  else
99    return (0);
100
101#else /* !HAVE_SETLOCALE */
102  char *lspec, *t;
103  int i;
104
105  /* We don't have setlocale.  Finesse it.  Check the environment for the
106     appropriate variables and set eight-bit mode if they have the right
107     values. */
108  lspec = get_env_value ("LC_ALL");
109  if (lspec == 0) lspec = get_env_value ("LC_CTYPE");
110  if (lspec == 0) lspec = get_env_value ("LANG");
111  if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
112    return (0);
113  for (i = 0; t && legal_lang_values[i]; i++)
114    if (STREQ (t, legal_lang_values[i]))
115      {
116        _rl_meta_flag = 1;
117        _rl_convert_meta_chars_to_ascii = 0;
118        _rl_output_meta_chars = 1;
119        break;
120      }
121  free (t);
122  return (legal_lang_values[i] ? 1 : 0);
123
124#endif /* !HAVE_SETLOCALE */
125}
126
127#if !defined (HAVE_SETLOCALE)
128static char *
129normalize_codeset (codeset)
130     char *codeset;
131{
132  size_t namelen, i;
133  int len, all_digits;
134  char *wp, *retval;
135
136  codeset = find_codeset (codeset, &namelen);
137
138  if (codeset == 0)
139    return (codeset);
140
141  all_digits = 1;
142  for (len = 0, i = 0; i < namelen; i++)
143    {
144      if (isalnum (codeset[i]))
145        {
146          len++;
147          all_digits &= isdigit (codeset[i]);
148        }
149    }
150
151  retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1);
152  if (retval == 0)
153    return ((char *)0);
154
155  wp = retval;
156  /* Add `iso' to beginning of an all-digit codeset */
157  if (all_digits)
158    {
159      *wp++ = 'i';
160      *wp++ = 's';
161      *wp++ = 'o';
162    }
163
164  for (i = 0; i < namelen; i++)
165    if (isalpha (codeset[i]))
166      *wp++ = (isupper (codeset[i])) ? tolower (codeset[i]) : codeset[i];
167    else if (isdigit (codeset[i]))
168      *wp++ = codeset[i];
169  *wp = '\0';
170
171  return retval;
172}
173
174/* Isolate codeset portion of locale specification. */
175static char *
176find_codeset (name, lenp)
177     char *name;
178     size_t *lenp;
179{
180  char *cp, *language, *result;
181
182  cp = language = name;
183  result = (char *)0;
184
185  while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',')
186    cp++;
187
188  /* This does not make sense: language has to be specified.  As
189     an exception we allow the variable to contain only the codeset
190     name.  Perhaps there are funny codeset names.  */
191  if (language == cp)
192    {
193      *lenp = strlen (language);
194      result = language;
195    }
196  else
197    {
198      /* Next is the territory. */
199      if (*cp == '_')
200        do
201          ++cp;
202        while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_');
203
204      /* Now, finally, is the codeset. */
205      result = cp;
206      if (*cp == '.')
207        do
208          ++cp;
209        while (*cp && *cp != '@');
210
211      if (cp - result > 2)
212        {
213          result++;
214          *lenp = cp - result;
215        }
216      else
217        {
218          *lenp = strlen (language);
219          result = language;
220        }
221    }
222
223  return result;
224}
225#endif /* !HAVE_SETLOCALE */
Note: See TracBrowser for help on using the repository browser.