Bruno Haible
2018-05-03 03:42:17 UTC
On a recent mingw (both 32-bit and 64-bit), I'm seeing this test failure:
FAIL: test-localename
=====================
../../tests/test-localename.c:158: assertion 'strcmp (name, "de_DE.UTF-8") == 0' failed
Once this is worked around, there is another one here:
/* Check that gl_locale_name_thread always returns NULL. */
ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
It is due to the localename.c change from 2014-07-15 [1]. While the general
approach (to call GetThreadLocale only as a fallback, because GetThreadLocale
does not consider changes made by 'setlocale') is reasonable, the exact
placement of the new code is odd: Fixing the test failures in the tests
(attached: fix-tests.diff) makes the code even stranger.
[1] https://lists.gnu.org/archive/html/bug-gnulib/2014-07/msg00003.html
The better fix is this one:
2018-05-02 Bruno Haible <***@clisp.org>
localename: Fix test failures on mingw.
* lib/localename.c (gl_locale_name_thread): Remove code specific to
native Windows.
(gl_locale_name_posix): Move code specific to native Windows here.
* tests/test-localename.c (test_locale_name, test_locale_name_posix):
Accept result without charset suffix, as it appears on mingw.
diff --git a/lib/localename.c b/lib/localename.c
index 74c8ee0..f7a7fa5 100644
--- a/lib/localename.c
+++ b/lib/localename.c
@@ -2786,7 +2786,27 @@ gl_locale_name_thread (int category, const char *categoryname)
const char *name = gl_locale_name_thread_unsafe (category, categoryname);
if (name != NULL)
return struniq (name);
-#elif defined WINDOWS_NATIVE
+#endif
+ /* On WINDOWS_NATIVE, don't use GetThreadLocale() here, because when
+ SetThreadLocale has not been called - which is a very frequent case -
+ the value of GetThreadLocale() ignores past calls to 'setlocale'. */
+ return NULL;
+}
+
+/* XPG3 defines the result of 'setlocale (category, NULL)' as:
+ "Directs 'setlocale()' to query 'category' and return the current
+ setting of 'local'."
+ However it does not specify the exact format. Neither do SUSV2 and
+ ISO C 99. So we can use this feature only on selected systems (e.g.
+ those using GNU C Library). */
+#if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__)
+# define HAVE_LOCALE_NULL
+#endif
+
+const char *
+gl_locale_name_posix (int category, const char *categoryname)
+{
+#if defined WINDOWS_NATIVE
if (LC_MIN <= category && category <= LC_MAX)
{
char *locname = setlocale (category, NULL);
@@ -2796,8 +2816,8 @@ gl_locale_name_thread (int category, const char *categoryname)
separated list of locales. We need only one, so we take the
one corresponding to LC_CTYPE, as the most important for
character translations. */
- if (strchr (locname, ';'))
- locname = setlocale (LC_CTYPE, NULL);
+ if (category == LC_ALL && strchr (locname, ';'))
+ locname = setlocale (LC_CTYPE, NULL);
/* Convert locale name to LCID. We don't want to use
LocaleNameToLCID because (a) it is only available since Vista,
@@ -2808,22 +2828,6 @@ gl_locale_name_thread (int category, const char *categoryname)
return gl_locale_name_from_win32_LCID (lcid);
}
#endif
- return NULL;
-}
-
-/* XPG3 defines the result of 'setlocale (category, NULL)' as:
- "Directs 'setlocale()' to query 'category' and return the current
- setting of 'local'."
- However it does not specify the exact format. Neither do SUSV2 and
- ISO C 99. So we can use this feature only on selected systems (e.g.
- those using GNU C Library). */
-#if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__)
-# define HAVE_LOCALE_NULL
-#endif
-
-const char *
-gl_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 defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
diff --git a/tests/test-localename.c b/tests/test-localename.c
index c0952a1..7e866c7 100644
--- a/tests/test-localename.c
+++ b/tests/test-localename.c
@@ -155,7 +155,16 @@ test_locale_name (void)
if (setlocale (LC_ALL, "") != NULL)
{
name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
+#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
+ /* On native Windows, here,
+ gl_locale_name_thread (LC_CTYPE, "LC_CTYPE")
+ returns NULL and
+ gl_locale_name_posix (LC_CTYPE, "LC_CTYPE")
+ returns either "de_DE" or "de_DE.UTF-8". */
+ ASSERT (strcmp (name, "de_DE") == 0 || strcmp (name, "de_DE.UTF-8") == 0);
+#else
ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
+#endif
name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
}
@@ -575,7 +584,11 @@ test_locale_name_posix (void)
if (setlocale (LC_ALL, "") != NULL)
{
name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
+#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
+ ASSERT (strcmp (name, "de_DE") == 0 || strcmp (name, "de_DE.UTF-8") == 0);
+#else
ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
+#endif
name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
}
FAIL: test-localename
=====================
../../tests/test-localename.c:158: assertion 'strcmp (name, "de_DE.UTF-8") == 0' failed
Once this is worked around, there is another one here:
/* Check that gl_locale_name_thread always returns NULL. */
ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
It is due to the localename.c change from 2014-07-15 [1]. While the general
approach (to call GetThreadLocale only as a fallback, because GetThreadLocale
does not consider changes made by 'setlocale') is reasonable, the exact
placement of the new code is odd: Fixing the test failures in the tests
(attached: fix-tests.diff) makes the code even stranger.
[1] https://lists.gnu.org/archive/html/bug-gnulib/2014-07/msg00003.html
The better fix is this one:
2018-05-02 Bruno Haible <***@clisp.org>
localename: Fix test failures on mingw.
* lib/localename.c (gl_locale_name_thread): Remove code specific to
native Windows.
(gl_locale_name_posix): Move code specific to native Windows here.
* tests/test-localename.c (test_locale_name, test_locale_name_posix):
Accept result without charset suffix, as it appears on mingw.
diff --git a/lib/localename.c b/lib/localename.c
index 74c8ee0..f7a7fa5 100644
--- a/lib/localename.c
+++ b/lib/localename.c
@@ -2786,7 +2786,27 @@ gl_locale_name_thread (int category, const char *categoryname)
const char *name = gl_locale_name_thread_unsafe (category, categoryname);
if (name != NULL)
return struniq (name);
-#elif defined WINDOWS_NATIVE
+#endif
+ /* On WINDOWS_NATIVE, don't use GetThreadLocale() here, because when
+ SetThreadLocale has not been called - which is a very frequent case -
+ the value of GetThreadLocale() ignores past calls to 'setlocale'. */
+ return NULL;
+}
+
+/* XPG3 defines the result of 'setlocale (category, NULL)' as:
+ "Directs 'setlocale()' to query 'category' and return the current
+ setting of 'local'."
+ However it does not specify the exact format. Neither do SUSV2 and
+ ISO C 99. So we can use this feature only on selected systems (e.g.
+ those using GNU C Library). */
+#if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__)
+# define HAVE_LOCALE_NULL
+#endif
+
+const char *
+gl_locale_name_posix (int category, const char *categoryname)
+{
+#if defined WINDOWS_NATIVE
if (LC_MIN <= category && category <= LC_MAX)
{
char *locname = setlocale (category, NULL);
@@ -2796,8 +2816,8 @@ gl_locale_name_thread (int category, const char *categoryname)
separated list of locales. We need only one, so we take the
one corresponding to LC_CTYPE, as the most important for
character translations. */
- if (strchr (locname, ';'))
- locname = setlocale (LC_CTYPE, NULL);
+ if (category == LC_ALL && strchr (locname, ';'))
+ locname = setlocale (LC_CTYPE, NULL);
/* Convert locale name to LCID. We don't want to use
LocaleNameToLCID because (a) it is only available since Vista,
@@ -2808,22 +2828,6 @@ gl_locale_name_thread (int category, const char *categoryname)
return gl_locale_name_from_win32_LCID (lcid);
}
#endif
- return NULL;
-}
-
-/* XPG3 defines the result of 'setlocale (category, NULL)' as:
- "Directs 'setlocale()' to query 'category' and return the current
- setting of 'local'."
- However it does not specify the exact format. Neither do SUSV2 and
- ISO C 99. So we can use this feature only on selected systems (e.g.
- those using GNU C Library). */
-#if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__)
-# define HAVE_LOCALE_NULL
-#endif
-
-const char *
-gl_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 defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
diff --git a/tests/test-localename.c b/tests/test-localename.c
index c0952a1..7e866c7 100644
--- a/tests/test-localename.c
+++ b/tests/test-localename.c
@@ -155,7 +155,16 @@ test_locale_name (void)
if (setlocale (LC_ALL, "") != NULL)
{
name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
+#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
+ /* On native Windows, here,
+ gl_locale_name_thread (LC_CTYPE, "LC_CTYPE")
+ returns NULL and
+ gl_locale_name_posix (LC_CTYPE, "LC_CTYPE")
+ returns either "de_DE" or "de_DE.UTF-8". */
+ ASSERT (strcmp (name, "de_DE") == 0 || strcmp (name, "de_DE.UTF-8") == 0);
+#else
ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
+#endif
name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
}
@@ -575,7 +584,11 @@ test_locale_name_posix (void)
if (setlocale (LC_ALL, "") != NULL)
{
name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
+#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
+ ASSERT (strcmp (name, "de_DE") == 0 || strcmp (name, "de_DE.UTF-8") == 0);
+#else
ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
+#endif
name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
}