On Nov 30, 2009, at 5:31 PM, Bruno Haible wrote:
This means that a POSIX compliant program has to do the following steps in order to determine the locale for a certain category of settings.
- Inspect the LC_ALL environment variable. If it is set and non-empty, use its value.
- Otherwise: Inspect the LC_xxxx environment variable that matches the specific category. If it is set and non-empty, use its value.
- Otherwise: Inspect the LANG environment variable. If it is set and non-empty, use its value.
- Otherwise: Use the default locale. On MacOS X systems, this means to use user preferences that can be retrieved using the CFLocaleCopyCurrent, CFPreferencesCopyAppValue functions. Note that these settings are similar but not entirely equal to Unix (glibc) conventions (e.g. "zh-Hans" vs. "zh_CN"), therefore some mapping of names has to be done.
By this logic, virtual no end-user program on any given Mac is compliant.
Gettext and POSIX-compliance is one thing. The user-desired behavior for Mac programs is another.
This algorithm is used in all programs that rely on GNU gettext and works perfectly fine:
- By default, no LANG or LC_* environment variable is set, hence the programs obey the user settings.
- For users of Terminal.app, who set these environment variables, the programs obey the environment variables.
It is Terminal.app itself which is setting LANG for all shells it creates, by default. The user is most likely oblivious to this fact.
Ken Thomases wrote:
Mac OS X's Language & Text (formerly known as International) settings in System Preferences don't quite map exactly to Unix LANG or LC_* environment variables, which are a poor intermediary for mapping to Windows settings.
I agree that if you want to map from MacOS X locale names from CF* functions to Win32 locale names, you may want to do so without going through Unix (glibc) conventional names.
It's not about mapping from "MacOS X locale names" (whatever you mean by that) that's the problem. It's the fact that no name or simple string properly represents the full range of settings available in System Preferences.
One problem with trusting the LANG variable is that its UNIX semantics are as a fallback for the LC_* variables, not an override. Given that the user has selected a language and formats in System Preferences, that's like setting all of the various LC_* variables, so LANG should be ignored.
No. If a program ignores LANG while it is set, it is not POSIX compliant, and a user will wonder why it behaves differently than all the POSIX compliant programs on his system.
I would venture to say that the number of Mac users who will wonder that is vanishingly small. Just about the only thing that will get a Mac user wondering is if the behavior of programs deviates from the settings in System Preferences.
I would further venture that the number of POSIX compliant programs on the system with which the user has any familiarity is negligible. By your definition (which I don't question), no Mac applications are compliant.
Allowing LANG to override the user's preference settings would make Wine behave badly when run from Terminal.app if the user's preferred language and formats don't match (e.g. Japanese language, U.S. formats).
- This is a rare case: Normally users run Terminal.app without setting LANG.
This is not a rare case. It's the default case. It will be nearly 100% of the time. Users do not set LANG; Terminal.app does!
- If they do set LANG, POSIX requires the program to obey LANG.
And Wine is applying for POSIX certification? News to me.
If Wine were to rely on LANG, then all users with mismatched language and formats who launch it from Terminal would not get their preferred language.
This would be compliant with POSIX, and with what GNU gettext does for years. No one ever complained about it.
Very, very few Mac users use any program which uses gettext.
If you as a user want to override the language that Wine displays, you can set LC_MESSAGES in your environment rather than LANG. Setting LC_ALL would achieve that, plus override the various other locale categories. Set LANG is the wrong approach, in my opinion.
According to POSIX, if a user sets LC_ALL=foo it is equivalent to unset LC_ALL; LC_CTYPE=foo LC_MESSAGES=foo LC_NUMERIC=foo LC_TIME=foo ... and equivalent to unset LC_ALL LC_CTYPE LC_MESSAGES LC_NUMERIC LC_TIME ...; LANG=foo Every program should treat these three ways to set the locale in the same way. If Wine was to behave differently in the second case than in the third case (by ignoring the LANG setting in the third case, as you propose), it would be buggy.
Buggy in a sense which completely ignores user expectation. That's not the sense in which I'd use that word.
The vast majority of users of Wine on the Mac will expect what I've proposed and be surprised and dismayed by what you've proposed.
-Ken