[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: setting locales
From: |
Roman Rakus |
Subject: |
Re: setting locales |
Date: |
Wed, 09 Jul 2008 16:09:52 +0200 |
User-agent: |
Thunderbird 2.0.0.14 (X11/20080501) |
Chet Ramey wrote:
In file locale.c, function get_locale_var, locale =
default_locale; /* system-dependent; not really portable. should it
be "C"? */
default_locale contains string returned by calling
setlocale(LC_ALL,NULL); and we then use this string to assign locale for
LC_'every_other' and this is not right way. Why we simple don't call
setlocale(LC_ALL,default_locale)? The final code will be shorter and
more readable...
Bash does most of the locale-setting itself for two reasons.
1. setlocale() calls getenv() to obtain the values for the variables it's
interested in. Not all systems allow getenv() to be replaced or
interposed, so setlocale() would see stale data.
2. Users expect shell variables to affect the locale for the shell. Since
setlocale() looks in the environment, these changes would not be
applied.
In any event, calling setlocale(LC_ALL, default_locale) is rarely the right
thing to do, since it doesn't allow users to mix locales between categories
(e.g., LC_COLLATE=C; LC_CTYPE=C; LC_MESSAGES=de_DE.UTF-8).
Chet
Yeah, I got your point. Nevertheless I do this small patch, which parse
default_locale and try to find if category is set.
diff -up bash-3.2/locale.c.rr bash-3.2/locale.c
--- bash-3.2/locale.c.rr 2006-07-27 15:38:43.000000000 +0200
+++ bash-3.2/locale.c 2008-07-08 13:43:51.000000000 +0200
@@ -264,6 +264,41 @@ set_default_lang ()
set_lang ("LANG", v);
}
+/* Try to find value of locale variable in default_locale.
+ Return found value or NULL. */
+char *
+find_var_in_default (var)
+ char *var;
+{
+ char *begin = strstr (default_locale, var);
+
+ if (begin)
+ { /* var is in default */
+ int size = 0;
+ char *end = NULL;
+ char *value = NULL;
+
+ begin = index (begin, '=');
+ if (!begin)
+ return (char *) NULL; /* Bad syntax of locale string */
+
+ begin++; /* value begins behind '=' */
+ end = index (begin, ';'); /* here may ends value of var */
+ size = end ? end - begin : strlen (begin);
+
+ value = (char *) malloc (size + 1);
+ if(!value)
+ return (char *) NULL; /* malloc error */
+
+ value = strncpy (value, begin, size);
+ value[size] = '\0';
+ return value;
+ }
+
+ return (char *) NULL; /* var isn't in default */
+}
+
+
/* Get the value of one of the locale variables (LC_MESSAGES, LC_CTYPE).
The precedence is as POSIX.2 specifies: LC_ALL has precedence over
the specific locale variables, and LANG, if set, is used as the default. */
@@ -280,6 +315,8 @@ get_locale_var (var)
if (locale == 0 || *locale == 0)
locale = lang;
if (locale == 0 || *locale == 0)
+ locale = find_var_in_default(var);
+ if (locale == 0 || *locale == 0)
locale = default_locale; /* system-dependent; not really portable.
should it be "C"? */
return (locale);
rrakus.vcf
Description: Vcard