[PATCH] kernel32: Respect the LANG environment variable on Mac OS.

Ken Thomases ken at codeweavers.com
Wed Dec 9 13:34:38 CST 2009


On Dec 3, 2009, at 11:27 AM, Ken Thomases wrote:

> I propose the following (in pseudocode):
>
> mac_formats_locale = CFLocaleGetIdentifier( CFLocaleCopyCurrent() );
> mac_language =  
> CFArrayGetValueAtIndex 
> ( CFBundleCopyLocalizationsForPreferences 
> ( CFLocaleCopyAvailableLocaleIdentifiers(), NULL ), 0 );
> for cat in ( LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME,  
> LC_PAPER, LC_MEASUREMENT, LC_TELEPHONE )
> 	setenv( cat, mac_formats_locale, 0 );
> setenv( "LC_MESSAGES", mac_language, 0 );

I have encountered a problem with my proposal.

The above pseudo-code for determining mac_language is quite likely to  
produce a string like "en" or "zh_Hans" -- that is, a locale specifier  
with no country code.  Setting LC_MESSAGES to a locale string without  
a country code will cause the C library to consider it invalid.   
(That's not a requirement explicitly imposed by the C library, but a  
consequence of what's in /usr/share/locale.  For example, the command  
"locale -a" does not list any locales without country codes.)  When  
that happens, it considers all LC_* variables invalid and defaults to  
the "C" locale.

The code that Wine currently uses avoids this problem because it  
doesn't go through the C library.  Basically, after all of the LANG/ 
setlocale/setup_unix_locales stuff has been done, it overwrites the  
value in lcid_LC_MESSAGES (a Wine variable).

So, I'm making a new proposal: the Mac formats region will be used to  
set LANG unconditionally.  (Passing 1 for the third argument to  
setenv() rather than 0.)  The current code for overwriting  
lcid_LC_MESSAGES will be tweaked.  Instead of looking at whether  
lcid_LC_MESSAGES has been set to something other than lcid_LC_CTYPE,  
it will look at whether LC_ALL or LC_MESSAGES were set in the  
environment.  If they were, it leaves lcid_LC_MESSAGES alone.  If they  
were not, it overwrites it using the existing method.

This retains the precedence order we desire:

LC_ALL
LC_*
Mac OS X settings
LANG

because:

* LANG is just replaced with the Mac OS X region
* If LC_ALL or the LC_* variables are set, they take precedence over  
LANG in the C library (setlocale)
* If LC_ALL or LC_MESSAGES are set, we don't overwrite  
lcid_LC_MESSAGES after the C library has done its thing

Does that sound sensible?

-Ken




More information about the wine-devel mailing list