#include <stdlib.h>
#include <locale.h>
+#include <string.h>
#if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
-# include <string.h>
# include <CoreFoundation/CFString.h>
# if HAVE_CFLOCALECOPYCURRENT
# include <CoreFoundation/CFLocale.h>
# define WIN32_NATIVE
#endif
-#ifdef WIN32_NATIVE
+#if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
/* List of language codes, sorted by value:
#endif
-#ifdef WIN32_NATIVE
+#if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
/* Canonicalize a Win32 native locale name to a Unix locale name.
NAME is a sufficiently large buffer.
#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
return setlocale (category, NULL);
#else
+ /* On other systems we ignore what setlocale reports and instead look at the
+ environment variables directly. This is necessary
+ 1. on systems which have a facility for customizing the default locale
+ (MacOS X, native Windows, Cygwin) and where the system's setlocale()
+ function ignores this default locale (MacOS X, Cygwin), in two cases:
+ a. when the user missed to use the setlocale() override from libintl
+ (for example by not including <libintl.h>),
+ b. when setlocale supports only the "C" locale, such as on Cygwin
+ 1.5.x. In this case even the override from libintl cannot help.
+ 2. on all systems where setlocale supports only the "C" locale. */
+ /* Strictly speaking, it is a POSIX violation to look at the environment
+ variables regardless whether setlocale has been called or not. POSIX
+ says:
+ "For C-language programs, the POSIX locale shall be the
+ default locale when the setlocale() function is not called."
+ But we assume that all programs that use internationalized APIs call
+ setlocale (LC_ALL, ""). */
+ return gl_locale_name_environ (category, categoryname);
+#endif
+}
+
+const char *
+gl_locale_name_environ (int category, const char *categoryname)
+{
const char *retval;
/* Setting of LC_ALL overrides all other. */
/* Last possibility is the LANG environment variable. */
retval = getenv ("LANG");
if (retval != NULL && retval[0] != '\0')
- return retval;
+ {
+#if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
+ /* MacOS X 10.2 or newer.
+ Ignore invalid LANG value set by the Terminal application. */
+ if (strcmp (retval, "UTF-8") != 0)
+#endif
+#if defined __CYGWIN__
+ /* Cygwin.
+ Ignore dummy LANG value set by ~/.profile. */
+ if (strcmp (retval, "C.UTF-8") != 0)
+#endif
+ return retval;
+ }
return NULL;
-#endif
}
const char *
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. */
+ such a facility.
+
+ The systems with such a facility are MacOS X and Windows: They provide a
+ GUI that allows the user to choose a locale.
+ - On MacOS X, by default, none of LC_* or LANG are set. Starting with
+ MacOS X 10.4 or 10.5, LANG is set for processes launched by the
+ 'Terminal' application (but sometimes to an incorrect value "UTF-8").
+ When no environment variable is set, setlocale (LC_ALL, "") uses the
+ "C" locale.
+ - On native Windows, by default, none of LC_* or LANG are set.
+ When no environment variable is set, setlocale (LC_ALL, "") uses the
+ locale chosen by the user.
+ - On Cygwin 1.5.x, by default, none of LC_* or LANG are set.
+ When no environment variable is set, setlocale (LC_ALL, "") uses the
+ "C" locale.
+ - On Cygwin 1.7, by default, LANG is set to "C.UTF-8" when the default
+ ~/.profile is executed.
+ When no environment variable is set, setlocale (LC_ALL, "") uses the
+ "C.UTF-8" locale, which operates in the same way as the "C" locale.
+ */
-#if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined(WIN32_NATIVE))
+#if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined WIN32_NATIVE || defined __CYGWIN__)
/* The system does not have a way of setting the locale, other than the
POSIX specified environment variables. We use C as default locale. */
# endif
-# if defined(WIN32_NATIVE) /* WIN32, not Cygwin */
+# if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
{
LCID lcid;