]> git.ipfire.org Git - thirdparty/bash.git/blame - locale.c
Imported from ../bash-2.04.tar.gz.
[thirdparty/bash.git] / locale.c
CommitLineData
ccc6cda3
JA
1/* locale.c - Miscellaneous internationalization functions. */
2
3/* Copyright (C) 1996 Free Software Foundation, Inc.
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file COPYING. If not, write to the Free Software
bb70624e 19 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
ccc6cda3
JA
20
21#include "config.h"
22
23#include "bashtypes.h"
24
25#if defined (HAVE_UNISTD_H)
26# include <unistd.h>
27#endif
28
29#include "bashintl.h"
30#include "bashansi.h"
31#include <stdio.h>
32#include <ctype.h>
33
34#include "shell.h"
35
36/* The current locale when the program begins */
37static char *default_locale;
38
39/* The current domain for textdomain(3). */
40static char *default_domain;
41static char *default_dir;
42
43/* tracks the value of LC_ALL; used to override values for other locale
44 categories */
45static char *lc_all;
46
47/* Set the value of default_locale and make the current locale the
48 system default locale. This should be called very early in main(). */
49void
50set_default_locale ()
51{
52#if defined (HAVE_SETLOCALE)
53 default_locale = setlocale (LC_ALL, "");
54 if (default_locale)
55 default_locale = savestring (default_locale);
56#endif /* HAVE_SETLOCALE */
57}
58
59/* Set default values for LC_CTYPE, LC_COLLATE, and LC_MESSAGES if they
60 are not specified in the environment, but LANG or LC_ALL is. This
61 should be called from main() after parsing the environment. */
62void
63set_default_locale_vars ()
64{
65 char *val;
66
67#if defined (HAVE_SETLOCALE)
68 val = get_string_value ("LC_CTYPE");
69 if (val == 0 && lc_all && *lc_all)
70 setlocale (LC_CTYPE, lc_all);
71
72# if defined (LC_COLLATE)
73 val = get_string_value ("LC_COLLATE");
74 if (val == 0 && lc_all && *lc_all)
75 setlocale (LC_COLLATE, lc_all);
76# endif /* LC_COLLATE */
77
78# if defined (LC_MESSAGES)
79 val = get_string_value ("LC_MESSAGES");
80 if (val == 0 && lc_all && *lc_all)
81 setlocale (LC_MESSAGES, lc_all);
82# endif /* LC_MESSAGES */
83
bb70624e
JA
84# if defined (LC_NUMERIC)
85 val = get_string_value ("LC_NUMERIC");
86 if (val == 0 && lc_all && *lc_all)
87 setlocale (LC_NUMERIC, lc_all);
88# endif /* LC_NUMERIC */
89
ccc6cda3
JA
90#endif /* HAVE_SETLOCALE */
91
92 val = get_string_value ("TEXTDOMAIN");
93 if (val && *val)
94 {
95 FREE (default_domain);
96 default_domain = savestring (val);
97 textdomain (default_domain);
98 }
99
100 val = get_string_value ("TEXTDOMAINDIR");
101 if (val && *val)
102 {
103 FREE (default_dir);
104 default_dir = savestring (val);
105 bindtextdomain (default_domain, default_dir);
106 }
107}
108
109/* Set one of the locale categories (specified by VAR) to VALUE. Returns 1
110 if successful, 0 otherwise. */
111int
112set_locale_var (var, value)
113 char *var, *value;
114{
115 if (var[0] == 'T' && var[10] == 0) /* TEXTDOMAIN */
116 {
117 FREE (default_domain);
118 default_domain = value ? savestring (value) : (char *)NULL;
119 textdomain (default_domain);
120 return (1);
121 }
122 else if (var[0] == 'T') /* TEXTDOMAINDIR */
123 {
124 FREE (default_dir);
125 default_dir = value ? savestring (value) : (char *)NULL;
126 bindtextdomain (default_domain, default_dir);
127 return (1);
128 }
129
130 /* var[0] == 'L' && var[1] == 'C' && var[2] == '_' */
131
132 else if (var[3] == 'A') /* LC_ALL */
133 {
134 FREE (lc_all);
e8ce775d
JA
135 if (value)
136 lc_all = savestring (value);
137 else if (default_locale)
138 lc_all = savestring (default_locale);
139 else
140 {
141 lc_all = xmalloc (1);
142 lc_all[0] = '\0';
143 }
ccc6cda3 144#if defined (HAVE_SETLOCALE)
bb70624e 145 return (setlocale (LC_ALL, lc_all) != 0);
ccc6cda3
JA
146#else
147 return (1);
148#endif
149 }
150
151#if defined (HAVE_SETLOCALE)
152 else if (var[3] == 'C' && var[4] == 'T') /* LC_CTYPE */
153 {
154 if (lc_all == 0 || *lc_all == '\0')
bb70624e 155 return (setlocale (LC_CTYPE, value ? value : "") != 0);
ccc6cda3
JA
156 }
157 else if (var[3] == 'C' && var[4] == 'O') /* LC_COLLATE */
158 {
159# if defined (LC_COLLATE)
160 if (lc_all == 0 || *lc_all == '\0')
bb70624e 161 return (setlocale (LC_COLLATE, value ? value : "") != 0);
ccc6cda3
JA
162# endif /* LC_COLLATE */
163 }
164 else if (var[3] == 'M' && var[4] == 'E') /* LC_MESSAGES */
165 {
166# if defined (LC_MESSAGES)
167 if (lc_all == 0 || *lc_all == '\0')
bb70624e 168 return (setlocale (LC_MESSAGES, value ? value : "") != 0);
ccc6cda3
JA
169# endif /* LC_MESSAGES */
170 }
bb70624e
JA
171 else if (var[3] = 'N' && var[4] == 'U') /* LC_NUMERIC */
172 {
173# if defined (LC_NUMERIC)
174 if (lc_all == 0 || *lc_all == '\0')
175 return (setlocale (LC_NUMERIC, value ? value : "") != 0);
176# endif /* LC_NUMERIC */
177 }
ccc6cda3
JA
178#endif /* HAVE_SETLOCALE */
179
180 return (0);
181}
182
b72432fd 183#if 0
ccc6cda3
JA
184/* Called when LANG is assigned a value. Sets LC_ALL if that has not
185 already been set. */
b72432fd
JA
186#else
187/* This no longer does anything; we rely on the C library for correct
188 behavior. */
189#endif
ccc6cda3
JA
190int
191set_lang (var, value)
192 char *var, *value;
193{
b72432fd 194#if 0
ccc6cda3 195 return ((lc_all == 0) ? set_locale_var ("LC_ALL", value) : 0);
b72432fd
JA
196#else
197 return 0;
198#endif
ccc6cda3
JA
199}
200
201/* Get the value of one of the locale variables (LC_MESSAGES, LC_CTYPE) */
202char *
203get_locale_var (var)
204 char *var;
205{
206 char *locale;
207
208 locale = lc_all;
209
210 if (locale == 0)
211 locale = get_string_value (var);
212 if (locale == 0)
213 locale = default_locale;
214
215 return (locale);
216}
217
218/* Translate the contents of STRING, a $"..." quoted string, according
219 to the current locale. In the `C' or `POSIX' locale, or if gettext()
220 is not available, the passed string is returned unchanged. The
221 length of the translated string is returned in LENP, if non-null. */
222char *
223localetrans (string, len, lenp)
224 char *string;
225 int len, *lenp;
226{
227 char *locale, *t;
228#if defined (HAVE_GETTEXT)
229 char *translated;
230 int tlen;
231#endif
232
233 /* Don't try to translate null strings. */
234 if (string == 0 || *string == 0)
235 {
236 if (lenp)
237 *lenp = 0;
238 return ((char *)NULL);
239 }
240
241 t = xmalloc (len + 1);
242
243 locale = get_locale_var ("LC_MESSAGES");
244
245 /* If we don't have setlocale() or the current locale is `C' or `POSIX',
246 just return the string. If we don't have gettext(), there's no use
247 doing anything else. */
248#if defined (HAVE_GETTEXT)
249 if (locale == 0 || locale[0] == '\0' ||
250 (locale[0] == 'C' && locale[1] == '\0') || STREQ (locale, "POSIX"))
251#endif
252 {
253 strcpy (t, string);
254 if (lenp)
255 *lenp = len;
256 return (t);
257 }
258
259#if defined (HAVE_GETTEXT)
260 /* Now try to translate it. */
261 translated = gettext (string);
262 if (translated == string) /* gettext returns its argument if untranslatable */
263 {
264 strcpy (t, string);
265 if (lenp)
266 *lenp = len;
267 }
268 else
269 {
270 free (t);
271 tlen = strlen (translated);
272 t = xmalloc (tlen + 1);
273 strcpy (t, translated);
274 if (lenp)
275 *lenp = tlen;
276 }
277 return (t);
278#endif /* HAVE_GETTEXT */
279}