Ken Thomases wrote:
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
LGTM
Chip