+2005-01-01 Bruno Haible <bruno@clisp.org>
+
+ * dcigettext.c (guess_category_value): Let the environment variables
+ LC_ALL, LC_xxx, LANG take precedence over the system-dependent language
+ preference list.
+ * gettextP.h (_nl_language_preferences): Remove declaration.
+ (_nl_language_preferences_default): New declaration.
+ (_nl_locale_name_posix, _nl_locale_name_default): New declarations.
+ * langprefs.c (_nl_language_preferences_default): Renamed from
+ _nl_language_preferences. Remove handling of getenv("LANGUAGE").
+ * localename.c (_nl_locale_name_posix, _nl_locale_name_default): New
+ functions, extracted from _nl_locale_name.
+ (_nl_locale_name): Use them.
+
2004-09-06 Bruno Haible <bruno@clisp.org>
* localename.c (_nl_locale_name): Add code for MacOS X versions that
/* Implementation of the internal dcigettext function.
- Copyright (C) 1995-1999, 2000-2004 Free Software Foundation, Inc.
+ Copyright (C) 1995-1999, 2000-2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published
}
#endif
-/* Guess value of current locale from value of the environment variables. */
+/* Guess value of current locale from value of the environment variables
+ or system-dependent defaults. */
static const char *
internal_function
guess_category_value (int category, const char *categoryname)
{
const char *language;
- const char *retval;
-
- /* The highest priority value is the `LANGUAGE' environment
- variable. But we don't use the value if the currently selected
- locale is the C locale. This is a GNU extension. */
-#ifdef _LIBC
- language = getenv ("LANGUAGE");
- if (language != NULL && language[0] == '\0')
- language = NULL;
-#else
- language = _nl_language_preferences ();
+ const char *locale;
+#ifndef _LIBC
+ const char *language_default;
+ int locale_defaulted;
#endif
- /* We have to proceed with the POSIX methods of looking to `LC_ALL',
+ /* We use the settings in the following order:
+ 1. The value of the environment variable 'LANGUAGE'. This is a GNU
+ extension. Its value can be a colon-separated list of locale names.
+ 2. The value of the environment variable 'LC_ALL', 'LC_xxx', or 'LANG'.
+ More precisely, the first among these that is set to a non-empty value.
+ This is how POSIX specifies it. The value is a single locale name.
+ 3. A system-dependent preference list of languages. Its value can be a
+ colon-separated list of locale names.
+ 4. A system-dependent default locale name.
+ This way:
+ - System-dependent settings can be overridden by environment variables.
+ - If the system provides both a list of languages and a default locale,
+ the former is used. */
+
+ /* Fetch the locale name, through the POSIX method of looking to `LC_ALL',
`LC_xxx', and `LANG'. On some systems this can be done by the
`setlocale' function itself. */
#ifdef _LIBC
- retval = __current_locale_name (category);
+ locale = __current_locale_name (category);
#else
- retval = _nl_locale_name (category, categoryname);
+ locale = _nl_locale_name_posix (category, categoryname);
+ locale_defaulted = 0;
+ if (locale == NULL)
+ {
+ locale = _nl_locale_name_default ();
+ locale_defaulted = 1;
+ }
#endif
- /* Ignore LANGUAGE if the locale is set to "C" because
+ /* Ignore LANGUAGE and its system-dependent analogon if the locale is set
+ to "C" because
1. "C" locale usually uses the ASCII encoding, and most international
messages use non-ASCII characters. These characters get displayed
as question marks (if using glibc's iconv()) or as invalid 8-bit
characters to ASCII). In any case, the output is ugly.
2. The precise output of some programs in the "C" locale is specified
by POSIX and should not depend on environment variables like
- "LANGUAGE". We allow such programs to use gettext(). */
- return language != NULL && strcmp (retval, "C") != 0 ? language : retval;
+ "LANGUAGE" or system-dependent information. We allow such programs
+ to use gettext(). */
+ if (strcmp (locale, "C") == 0)
+ return locale;
+
+ /* The highest priority value is the value of the 'LANGUAGE' environment
+ variable. */
+ language = getenv ("LANGUAGE");
+ if (language != NULL && language[0] != '\0')
+ return language;
+#ifndef _LIBC
+ /* The next priority value is the locale name, if not defaulted. */
+ if (locale_defaulted)
+ {
+ /* The next priority value is the default language preferences list. */
+ language_default = _nl_language_preferences_default ();
+ if (language_default != NULL)
+ return language_default;
+ }
+ /* The least priority value is the locale name, if defaulted. */
+#endif
+ return locale;
}
/* @@ begin of epilog @@ */
/* Header describing internals of libintl library.
- Copyright (C) 1995-1999, 2000-2004 Free Software Foundation, Inc.
+ Copyright (C) 1995-1999, 2000-2005 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@cygnus.com>, 1995.
This program is free software; you can redistribute it and/or modify it
extern int _nl_msg_cat_cntr;
#ifndef _LIBC
-const char *_nl_language_preferences (void);
+const char *_nl_language_preferences_default (void);
+const char *_nl_locale_name_posix (int category, const char *categoryname);
+const char *_nl_locale_name_default (void);
const char *_nl_locale_name (int category, const char *categoryname);
#endif
/* Determine the user's language preferences.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004-2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published
/* Determine the user's language preferences, as a colon separated list of
locale names in XPG syntax
language[_territory[.codeset]][@modifier]
- The result must not be freed; it is statically allocated. */
+ The result must not be freed; it is statically allocated.
+ The LANGUAGE environment variable does not need to be considered; it is
+ already taken into account by the caller. */
const char *
-_nl_language_preferences (void)
+_nl_language_preferences_default (void)
{
- const char *language;
-
- language = getenv ("LANGUAGE");
- if (language != NULL && language[0] != '\0')
- return language;
-
#if HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.2 or newer */
{
/* Cache the preferences list, since CoreFoundation calls are expensive. */
/* Determine the current selected locale.
- Copyright (C) 1995-1999, 2000-2004 Free Software Foundation, Inc.
+ Copyright (C) 1995-1999, 2000-2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published
The result must not be freed; it is statically allocated. */
const char *
-_nl_locale_name (int category, const char *categoryname)
+_nl_locale_name_posix (int category, const char *categoryname)
{
/* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'.
On some systems this can be done by the 'setlocale' function itself. */
if (retval != NULL && retval[0] != '\0')
return retval;
- /* We use C as the default domain. POSIX says this is
- implementation defined. */
-# if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined(WIN32))
+ return NULL;
+#endif
+}
+
+const char *
+_nl_locale_name_default (void)
+{
+ /* POSIX:2001 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:2001 does not require
+ such a facility. */
+#if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined(WIN32))
+
+ /* The system does not have a way of setting the locale, other than the
+ POSIX specified environment variables. We use C as default locale. */
return "C";
-# else
+#else
/* Return an XPG style locale name language[_territory][@modifier].
Don't even bother determining the codeset; it's not useful in this
context, because message catalogs are not specific to a single
codeset. */
-# if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
+# if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
/* MacOS X 10.2 or newer */
{
/* Cache the locale name, since CoreFoundation calls are expensive. */
if (cached_localename == NULL)
{
char namebuf[256];
-# if HAVE_CFLOCALECOPYCURRENT /* MacOS X 10.3 or newer */
+# if HAVE_CFLOCALECOPYCURRENT /* MacOS X 10.3 or newer */
CFLocaleRef locale = CFLocaleCopyCurrent ();
CFStringRef name = CFLocaleGetIdentifier (locale);
kCFStringEncodingASCII))
cached_localename = strdup (namebuf);
CFRelease (locale);
-# elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.2 or newer */
+# elif HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.2 or newer */
CFTypeRef value =
CFPreferencesCopyAppValue (CFSTR ("AppleLocale"),
kCFPreferencesCurrentApplication);
&& CFStringGetCString ((CFStringRef)value, namebuf, sizeof(namebuf),
kCFStringEncodingASCII))
cached_localename = strdup (namebuf);
-# endif
+# endif
if (cached_localename == NULL)
cached_localename = "C";
}
return cached_localename;
}
-# endif
+# endif
-# if defined(WIN32) /* WIN32 */
+# if defined(WIN32) /* WIN32 */
{
LCID lcid;
LANGID langid;
default: return "C";
}
}
-# endif
# endif
#endif
}
+
+const char *
+_nl_locale_name (int category, const char *categoryname)
+{
+ const char *retval;
+
+ retval = _nl_locale_name_posix (category, categoryname);
+ if (retval != NULL)
+ return retval;
+
+ return _nl_locale_name_default ();
+}