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