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



Reply via email to