[PATCH] kernel32: Respect the LANG environment variable on Mac OS.

Bruno Haible bruno at clisp.org
Mon Nov 30 17:31:03 CST 2009


Hi,

As the author of the support for GNU gettext in MacOS X [1], I can explain the
relation between the POSIX notion of locale and the MacOS X user preferences.

POSIX:2008 [2] says:
  "All implementations shall define a locale as the default locale, to be
   invoked when no environment variables are set, or set to the empty string.
   This default locale can be the POSIX locale or any other implementation-
   defined locale. Some implementations may provide facilities for local
   installation administrators to set the default locale, customizing it for
   each location. POSIX.1-2008 does not require such a facility."

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.
  1) Inspect the LC_ALL environment variable. If it is set and non-empty,
     use its value.
  2) Otherwise: Inspect the LC_xxxx environment variable that matches the
     specific category. If it is set and non-empty, use its value.
  3) Otherwise: Inspect the LANG environment variable. If it is set and
     non-empty, use its value.
  4) 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.

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.

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.

> 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.

> 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).

1. This is a rare case: Normally users run Terminal.app without setting LANG.
2. If they do set LANG, POSIX requires the program to obey LANG.

> 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.

> 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.

Bruno


[1] http://git.savannah.gnu.org/gitweb/?p=gettext.git;a=blob;f=gettext-runtime/intl/localename.c;h=9f4c18191debaa968a95de925386f66616657fbc;hb=HEAD
[2] http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html



More information about the wine-devel mailing list