[prev in list] [next in list] [prev in thread] [next in thread] 

List:       bash-bug
Subject:    Re: setting locales
From:       Roman Rakus <rrakus () redhat ! com>
Date:       2008-07-09 14:09:52
Message-ID: 4874C6B0.70701 () redhat ! com
[Download RAW message or body]

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.

["bash-3.2-locale.patch" (text/x-patch)]

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" (text/x-vcard)]

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic