+2018-12-16 Bruno Haible <bruno@clisp.org>
+
+ localename: Fix test failure on OpenBSD >= 6.2.
+ * m4/intl-thread-locale.m4 (gt_INTL_THREAD_LOCALE_NAME): Test for fake
+ locale system. Define HAVE_FAKE_LOCALES in this case.
+ * lib/localename.c (HAVE_GOOD_USELOCALE): New macro. Use it instead of
+ HAVE_USELOCALE.
+ * tests/test-localename.c (HAVE_GOOD_USELOCALE): New macro. Use it
+ instead of HAVE_NEWLOCALE && HAVE_USELOCALE.
+ * doc/posix-functions/uselocale.texi: Mention OpenBSD problem. Update
+ platforms list.
+ * doc/posix-functions/newlocale.texi: Likewise.
+ * doc/posix-functions/duplocale.texi: Update platforms list.
+ * doc/posix-functions/freelocale.texi: Likewise.
+
2018-12-16 Bruno Haible <bruno@clisp.org>
duplocale tests: Re-enable the test on platforms without <monetary.h>.
@itemize
@item
This function is missing on many platforms:
-Mac OS X 10.3, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 4.4.
+Mac OS X 10.3, FreeBSD 9.0, NetBSD 5.0, OpenBSD 6.1, Minix 3.1.8, AIX 6.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 4.4.
@end itemize
@itemize
@item
This function is missing on many platforms:
-Mac OS X 10.3, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 4.4.
+Mac OS X 10.3, FreeBSD 9.0, NetBSD 5.0, OpenBSD 6.1, Minix 3.1.8, AIX 6.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 4.4.
@end itemize
@itemize
@item
This function is missing on many platforms:
-Mac OS X 10.3, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 4.4.
+Mac OS X 10.3, FreeBSD 9.0, NetBSD 5.0, OpenBSD 6.1, Minix 3.1.8, AIX 6.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 4.4.
+@item
+This function is useless because the @code{locale_t} type contains basically
+no information on some platforms:
+OpenBSD 6.3.
@end itemize
@itemize
@item
This function is missing on many platforms:
-Mac OS X 10.3, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 4.4.
+Mac OS X 10.3, FreeBSD 9.0, NetBSD 5.0, OpenBSD 6.1, Minix 3.1.8, AIX 6.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 4.4.
+@item
+This function is useless because the @code{locale_t} type contains basically
+no information on some platforms:
+OpenBSD 6.3.
@end itemize
#include "flexmember.h"
-#if HAVE_USELOCALE
+/* We cannot support uselocale() on platforms where the locale_t type is fake.
+ See intl-thread-locale.m4 for details. */
+#if HAVE_USELOCALE && !HAVE_FAKE_LOCALES
+# define HAVE_GOOD_USELOCALE 1
+#endif
+
+#if HAVE_GOOD_USELOCALE
/* Mac OS X 10.5 defines the locale_t type in <xlocale.h>. */
# if defined __APPLE__ && defined __MACH__
# include <xlocale.h>
#endif
-#if HAVE_USELOCALE /* glibc, Mac OS X, FreeBSD >= 9.1, AIX >= 7,
- Solaris 11 OpenIndiana, or Solaris >= 11.4 */
+#if HAVE_GOOD_USELOCALE /* glibc, Mac OS X, FreeBSD >= 9.1, AIX >= 7,
+ Solaris 11 OpenIndiana, or Solaris >= 11.4 */
/* Simple hash set of strings. We don't want to drag in lots of hash table
code here. */
#endif
-#if HAVE_USELOCALE && HAVE_NAMELESS_LOCALES
+#if HAVE_GOOD_USELOCALE && HAVE_NAMELESS_LOCALES
/* The 'locale_t' object does not contain the names of the locale categories.
We have to associate them with the object through a hash table.
#endif
-#if defined IN_LIBINTL || HAVE_USELOCALE
+#if defined IN_LIBINTL || HAVE_GOOD_USELOCALE
/* Like gl_locale_name_thread, except that the result is not in storage of
indefinite extent. */
const char *
gl_locale_name_thread_unsafe (int category, const char *categoryname)
{
-# if HAVE_USELOCALE
+# if HAVE_GOOD_USELOCALE
{
locale_t thread_locale = uselocale (NULL);
if (thread_locale != LC_GLOBAL_LOCALE)
const char *
gl_locale_name_thread (int category, const char *categoryname)
{
-#if HAVE_USELOCALE
+#if HAVE_GOOD_USELOCALE
const char *name = gl_locale_name_thread_unsafe (category, categoryname);
if (name != NULL)
return struniq (name);
-# intl-thread-locale.m4 serial 2
+# intl-thread-locale.m4 serial 3
dnl Copyright (C) 2015-2018 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
AC_CHECK_FUNCS_ONCE([uselocale])
+ dnl On OpenBSD >= 6.2, the locale_t type and the uselocale(), newlocale(),
+ dnl duplocale(), freelocale() functions exist but are effectively useless,
+ dnl because the locale_t value depends only on the LC_CTYPE category of the
+ dnl locale and furthermore contains only one bit of information (it
+ dnl distinguishes the "C" locale from the *.UTF-8 locales). See
+ dnl <https://cvsweb.openbsd.org/src/lib/libc/locale/newlocale.c?rev=1.1&content-type=text/x-cvsweb-markup>.
+ dnl In the setlocale() implementation they have thought about the programs
+ dnl that use the API ("Even though only LC_CTYPE has any effect in the
+ dnl OpenBSD base system, store complete information about the global locale,
+ dnl such that third-party software can access it"), but for uselocale()
+ dnl they did not think about the programs.
+ dnl In this situation, even the HAVE_NAMELESS_LOCALES support does not work.
+ dnl So, define HAVE_FAKE_LOCALES and disable all locale_t support.
+ if test $ac_cv_func_uselocale = yes; then
+ AC_CHECK_HEADERS_ONCE([xlocale.h])
+ AC_CACHE_CHECK([for fake locale system (OpenBSD)],
+ [gt_cv_locale_fake],
+ [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <locale.h>
+#if HAVE_XLOCALE_H
+# include <xlocale.h>
+#endif
+int main ()
+{
+ locale_t loc1, loc2;
+ if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) return 1;
+ if (setlocale (LC_ALL, "fr_FR.UTF-8") == NULL) return 1;
+ loc1 = newlocale (LC_ALL_MASK, "de_DE.UTF-8", (locale_t)0);
+ loc2 = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", (locale_t)0);
+ return !(loc1 == loc2);
+}]])],
+ [gt_cv_locale_fake=yes],
+ [gt_cv_locale_fake=no],
+ [dnl Guess the locale system is fake only on OpenBSD.
+ case "$host_os" in
+ openbsd*) gt_cv_locale_fake="guessing yes" ;;
+ *) gt_cv_locale_fake="guessing no" ;;
+ esac
+ ])
+ ])
+ else
+ gt_cv_locale_fake=no
+ fi
+ case "$gt_cv_locale_fake" in
+ *yes)
+ AC_DEFINE([HAVE_FAKE_LOCALES], [1],
+ [Define if the locale_t type contains insufficient information, as on OpenBSD.])
+ ;;
+ esac
+
if test $ac_cv_func_uselocale = yes; then
AC_CACHE_CHECK([for Solaris 11.4 locale system],
[gt_cv_locale_solaris114],
#include "macros.h"
+#if HAVE_NEWLOCALE && HAVE_USELOCALE && !HAVE_FAKE_LOCALES
+# define HAVE_GOOD_USELOCALE 1
+#endif
+
-#if HAVE_NEWLOCALE && HAVE_USELOCALE
+#if HAVE_GOOD_USELOCALE
static struct { int cat; int mask; const char *string; } const categories[] =
{
/* Get into a defined state, */
setlocale (LC_ALL, "en_US.UTF-8");
-#if HAVE_NEWLOCALE && HAVE_USELOCALE
+#if HAVE_GOOD_USELOCALE
uselocale (LC_GLOBAL_LOCALE);
#endif
ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
}
-#if HAVE_NEWLOCALE && HAVE_USELOCALE
+#if HAVE_GOOD_USELOCALE
/* Check that gl_locale_name considers the thread locale. */
{
locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
/* Get into a defined state, */
setlocale (LC_ALL, "en_US.UTF-8");
-#if HAVE_NEWLOCALE && HAVE_USELOCALE
+#if HAVE_GOOD_USELOCALE
/* Check that gl_locale_name_thread returns NULL when no thread locale is
set. */
uselocale (LC_GLOBAL_LOCALE);
/* Get into a defined state, */
setlocale (LC_ALL, "en_US.UTF-8");
-#if HAVE_NEWLOCALE && HAVE_USELOCALE
+#if HAVE_GOOD_USELOCALE
uselocale (LC_GLOBAL_LOCALE);
#endif
ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
}
-#if HAVE_NEWLOCALE && HAVE_USELOCALE
+#if HAVE_GOOD_USELOCALE
/* Check that gl_locale_name_posix ignores the thread locale. */
{
locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
/* Get into a defined state, */
setlocale (LC_ALL, "en_US.UTF-8");
-#if HAVE_NEWLOCALE && HAVE_USELOCALE
+#if HAVE_GOOD_USELOCALE
uselocale (LC_GLOBAL_LOCALE);
#endif
name = gl_locale_name_environ (LC_MESSAGES, "LC_MESSAGES");
ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
-#if HAVE_NEWLOCALE && HAVE_USELOCALE
+#if HAVE_GOOD_USELOCALE
/* Check that gl_locale_name_environ ignores the thread locale. */
{
locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);
ASSERT (strcmp (name, "C") == 0);
#endif
-#if HAVE_NEWLOCALE && HAVE_USELOCALE
+#if HAVE_GOOD_USELOCALE
/* Check that gl_locale_name_default ignores the thread locale. */
{
locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL);