On Dec 2, 2009, at 11:25 PM, Gert van den Berg wrote:
What I meant is that LC_* (not LC_ALL) don't have a setting that says "the locale is say en_ZA" it only has we have number (LC_NUMERIC) from en_ZA, times (LC_TIME) from en_UK, sort things (LC_COLLATE) according to en_AU, determine whether something is a letter / number and how to change their case (LC_CTYPE) according to UTF-8, ect. LANG is only setting that really maps to Wine / Windows' sCountry and Locale settings. (if all LC_* variables are set, LANG only determine things not in any of the LC_* variables) LC_* does not have anything to determine the actual UI language either.
What I meant above, is that you should be able to get the equivalent effect (to the POSIX default) by setting everything to LANG's setting and then changing them from the LC_* variables. E.g. if LANG is fr_FR (not sure if that is an actual name) and LC_TIME is en_US, set environment up for French, change settings affected by LC_TIME to US English. Setting LANG to French and all individual settings to en_US, shoulld reslut in a system where the country is France, Locale code is 0x040c, UI is French, but date / time / number / currency settings, etc. is that of en_US.
I don't think that setting LC_ALL (or LANG) has any meaning beyond what one gets from the individual LC_* variables, but I could be mistaken.
I understand that you're suggesting it should or that you can imagine a semantic meaning to setting all of the LC_* variables to one thing and LANG to another, but I don't think it actually works that way.
In other words, I don't believe the C library has any notion of "the locale is en_ZA" in the sense you mean. It only has the various categories.
Currently, Wine uses the LC_MESSAGES category to determine sCountry and Locale.
Considering how OS X seem to set variables, that might work as well... My interpretation of your proposed logic for OS X: Set up everything to OS X setting, overwrite everything if LANG is set, overwrite further settings from LC_*, overwrite everything from LC_ALL if that is set. (the slow unoptimized way that might result in some settings being overwritten 4 times before settling on a value...)
Resulting order: LC_ALL LC_* LANG OS X settings.
That's not quite what I proposed. 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 );
The 0 as the third argument to setenv() means don't replace any existing definition. In this way, any LC_* environment variables set in the original environment would take precedence over the System Preferences settings. (LC_PAPER, LC_MEASUREMENT, and LC_TELEPHONE would only be used if actually defined, which they currently aren't on Mac OS X.)
The above would all precede the call to setlocale( LC_ALL, "" ) so that it would influence how the C library locale gets initialized. We would remove the post-setlocale override of lcid_LC_MESSAGES.
This results in the order I previously described:
LC_ALL LC_* from the original environment Mac OS X settings LANG
The Mac OS X settings have to take precedence over LANG for the reasons I've previously described. (Terminal.app sets it automatically to a value that doesn't/can't quite represent the user's actual preferences. As it happens, Terminal.app isn't doing this for you because Mac OS X doesn't support en_ZA in the Unix locale definitions in /usr/share/locale.)
As near as I can tell, Wine only probes the locale information by invoking setlocale(<category>, NULL). It doesn't directly examine the environment variables. Furthermore, it only queries using the individual categories, not LC_ALL. It uses setlocale(LC_ALL, "") once to tell the C library to initialize itself from the environment.
So, I'm not sure how setting all of the LC_* variables to a given value can be different from setting LC_ALL to that value.
Interpreting it as above, settings LC_ALL is equivalent to setting all LC_ variables and setting LANG to LC_ALL's value.
No. LANG is irrelevant if all LC_* variables are set. It's only use is to supply the locale for a category if LC_ALL or the specific LC_whatever is not set. If you set all of the LC_whatevers, then LANG is unused.
Regards, Ken