bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

localename: improvements for MacOS X and Cygwin


From: Bruno Haible
Subject: localename: improvements for MacOS X and Cygwin
Date: Tue, 22 Dec 2009 01:34:55 +0100
User-agent: KMail/1.9.9

This patch changes localename.[hc]. It
  - Introduces a function gl_locale_name_environ used by related code in 
libintl.
  - Tweaks the behaviour on MacOS X.
  - On Cygwin, respects the locale set by the user in the Windows "Control 
Panel".

In parallel to this, I'm adding to libintl for MacOS X and Cygwin a setlocale()
override that inquires the locale set by the user in the Windows "Control 
Panel".
Although an override of setlocale() might be in gnulib scope, I think things are
simpler if this override is only offered by libintl, not also by gnulib.


2009-12-21  Bruno Haible  <address@hidden>

        localename: Improvements for MacOS X and Cygwin.
        * lib/localename.h (gl_locale_name_environ): New declaration.
        * lib/localename.c (gl_locale_name_environ): New function, extracted 
from
        gl_locale_name_posix. Ignore dummy LANG values on MacOS X and Cygwin.
        (gl_locale_name_posix): Invoke it.
        (gl_locale_name_default): Add comments. Use Windows native API also on
        Cygwin.

--- lib/localename.h.orig       2009-12-22 01:27:31.000000000 +0100
+++ lib/localename.h    2009-12-22 01:23:02.000000000 +0100
@@ -1,5 +1,5 @@
 /* Determine name of the currently selected locale.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009 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
@@ -52,6 +52,11 @@
    The result must not be freed; it is statically allocated.  */
 extern const char * gl_locale_name_posix (int category, const char 
*categoryname);
 
+/* Determine the default locale's name, as specified by environment
+   variables.
+   The result must not be freed; it is statically allocated.  */
+extern const char * gl_locale_name_environ (int category, const char 
*categoryname);
+
 /* Determine the default locale's name.  This is the current locale's name,
    if not specified by setlocale() calls or by environment variables.  This
    locale name is usually determined by systems settings that the user can
--- lib/localename.c.orig       2009-12-22 01:27:31.000000000 +0100
+++ lib/localename.c    2009-12-22 01:23:22.000000000 +0100
@@ -31,9 +31,9 @@
 
 #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>
@@ -46,7 +46,7 @@
 # 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:
@@ -1394,7 +1394,7 @@
 #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.
@@ -2518,6 +2518,30 @@
 #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.  */
@@ -2531,10 +2555,21 @@
   /* 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 *
@@ -2547,9 +2582,28 @@
       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.  */
@@ -2603,7 +2657,7 @@
 
 # endif
 
-# if defined(WIN32_NATIVE) /* WIN32, not Cygwin */
+# if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
   {
     LCID lcid;
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]