+2009-12-26 Bruno Haible <bruno@clisp.org>
+
+ * NEWS: Mention the use of the thread-specific locale on MacOS X.
+
2009-12-25 Bruno Haible <bruno@clisp.org>
* Makefile.am (distcheck-hook): Compare fcntl-o.m4 instead of
Version 0.18 - January 2008
* Runtime behaviour:
- On MacOS X and Windows systems, <libintl.h> now extends setlocale() and
- newlocale() so that their determination of the default locale considers
- the choice the user has made in the system control panels.
+ - On MacOS X and Windows systems, <libintl.h> now extends setlocale() and
+ newlocale() so that their determination of the default locale considers
+ the choice the user has made in the system control panels.
+ - On MacOS X systems, the gettext()/dgettext()/... functions now respect the
+ locale of the current thread, if a thread-specific locale has been set.
* PO file format:
There is a new field 'Language' in the header entry. It denotes the language
+2009-12-26 Bruno Haible <bruno@clisp.org>
+
+ * NEWS: Mention the use of the thread-specific locale on MacOS X.
+
2009-05-23 Bruno Haible <bruno@clisp.org>
* configure.ac (AM_INIT_AUTOMAKE): Add 'silent-rules' option.
* On MacOS X and Windows systems, <libintl.h> now extends setlocale() and
newlocale() so that their determination of the default locale considers
the choice the user has made in the system control panels.
+
+* On MacOS X systems, the gettext()/dgettext()/... functions now respect the
+ locale of the current thread, if a thread-specific locale has been set.
\f
Version 0.16.1 - November 2006
+2009-12-26 Bruno Haible <bruno@clisp.org>
+
+ Use the thread-specific locale also on MacOS X.
+ * dcigettext.c (HAVE_NL_LOCALE_NAME): Remove undef.
+ Don't include <langinfo.h>.
+ (HAVE_PER_THREAD_LOCALE): Define on any platform that has 'uselocale'.
+ (DCIGETTEXT, guess_category_value): Use _nl_locale_name_thread_unsafe
+ instead of glibc specific code.
+ * gettextP.h (gl_locale_name_thread_unsafe): New macro.
+ (_nl_locale_name_thread_unsafe): New declaration.
+
2009-12-26 Bruno Haible <bruno@clisp.org>
localename: Fix storage allocation of gl_locale_name_thread's result.
/* Implementation of the internal dcigettext function.
- Copyright (C) 1995-1999, 2000-2008 Free Software Foundation, Inc.
+ Copyright (C) 1995-1999, 2000-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
# include <config.h>
#endif
-/* NL_LOCALE_NAME does not work in glibc-2.4. Ignore it. */
-#undef HAVE_NL_LOCALE_NAME
-
#include <sys/types.h>
#ifdef __GNUC__
#endif
#if !defined _LIBC
-# if HAVE_NL_LOCALE_NAME
-# include <langinfo.h>
-# endif
# include "localcharset.h"
#endif
#endif
/* Whether to support different locales in different threads. */
-#if defined _LIBC || HAVE_NL_LOCALE_NAME || (HAVE_STRUCT___LOCALE_STRUCT___NAMES && defined USE_IN_GETTEXT_TESTS) || defined IN_LIBGLOCALE
+#if defined _LIBC || HAVE_USELOCALE || defined IN_LIBGLOCALE
# define HAVE_PER_THREAD_LOCALE
#endif
# ifdef _LIBC
localename = _strdupa (_current_locale_name (category));
# else
-# if HAVE_NL_LOCALE_NAME
- /* NL_LOCALE_NAME is public glibc API introduced in glibc-2.4. */
- localename = nl_langinfo (NL_LOCALE_NAME (category));
-# else
-# if HAVE_STRUCT___LOCALE_STRUCT___NAMES && defined USE_IN_GETTEXT_TESTS
- /* The __names field is not public glibc API and must therefore not be used
- in code that is installed in public locations. */
- {
- locale_t thread_locale = uselocale (NULL);
- if (thread_locale != LC_GLOBAL_LOCALE)
- localename = thread_locale->__names[category];
- else
- localename = "";
- }
-# endif
-# endif
+ categoryname = category_to_name (category);
+# define CATEGORYNAME_INITIALIZED
+ localename = _nl_locale_name_thread_unsafe (category, categoryname);
+ if (localename == NULL)
+ localename = "";
# endif
# endif
search.localename = localename;
#endif
/* Now determine the symbolic name of CATEGORY and its value. */
+#ifndef CATEGORYNAME_INITIALIZED
categoryname = category_to_name (category);
+#endif
#ifdef IN_LIBGLOCALE
categoryvalue = guess_category_value (category, categoryname, localename);
#else
# ifdef _LIBC
locale = __current_locale_name (category);
# else
-# if HAVE_STRUCT___LOCALE_STRUCT___NAMES && defined USE_IN_GETTEXT_TESTS
- /* The __names field is not public glibc API and must therefore not be used
- in code that is installed in public locations. */
- locale_t thread_locale = uselocale (NULL);
- if (thread_locale != LC_GLOBAL_LOCALE)
- {
- locale = thread_locale->__names[category];
- locale_defaulted = 0;
- }
- else
+ locale_defaulted = 0;
+# if HAVE_USELOCALE
+ locale = _nl_locale_name_thread_unsafe (category, categoryname);
+ if (locale == NULL)
# endif
{
locale = _nl_locale_name_posix (category, categoryname);
- locale_defaulted = 0;
if (locale == NULL)
{
locale = _nl_locale_name_default ();
/* extern const char *_nl_locale_name_from_win32_LANGID (LANGID langid); */
# define gl_locale_name_from_win32_LCID _nl_locale_name_from_win32_LCID
/* extern const char *_nl_locale_name_from_win32_LCID (LCID lcid); */
+# define gl_locale_name_thread_unsafe _nl_locale_name_thread_unsafe
+extern const char *_nl_locale_name_thread_unsafe (int category,
+ const char *categoryname);
# define gl_locale_name_posix _nl_locale_name_posix
extern const char *_nl_locale_name_posix (int category,
const char *categoryname);
+2009-12-26 Bruno Haible <bruno@clisp.org>
+
+ * intl.m4 (gt_INTL_SUBDIR_CORE): Don't check for NL_LOCALE_NAME macro.
+
2009-12-26 Bruno Haible <bruno@clisp.org>
* intl.m4 (gt_INTL_SUBDIR_CORE): Check also for uselocale.
-# intl.m4 serial 16 (gettext-0.18)
+# intl.m4 serial 17 (gettext-0.18)
dnl Copyright (C) 1995-2009 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
AM_ICONV
- dnl glibc >= 2.4 has a NL_LOCALE_NAME macro when _GNU_SOURCE is defined,
- dnl and a _NL_LOCALE_NAME macro always.
- AC_CACHE_CHECK([for NL_LOCALE_NAME macro], [gt_cv_nl_locale_name],
- [AC_TRY_LINK([#include <langinfo.h>
-#include <locale.h>],
- [char* cs = nl_langinfo(_NL_LOCALE_NAME(LC_MESSAGES));
- return !cs;
- ],
- [gt_cv_nl_locale_name=yes],
- [gt_cv_nl_locale_name=no])
- ])
- if test $gt_cv_nl_locale_name = yes; then
- AC_DEFINE([HAVE_NL_LOCALE_NAME], [1],
- [Define if you have <langinfo.h> and it defines the NL_LOCALE_NAME macro if _GNU_SOURCE is defined.])
- fi
-
dnl intl/plural.c is generated from intl/plural.y. It requires bison,
dnl because plural.y uses bison specific features. It requires at least
dnl bison-1.26 because earlier versions generate a plural.c that doesn't
+2009-12-26 Bruno Haible <bruno@clisp.org>
+
+ * configure.ac: Don't define USE_IN_GETTEXT_TESTS. Test for uselocale.
+
2009-12-12 Bruno Haible <bruno@clisp.org>
* woe32dll/export.h: Untabify.
#define DEFAULT_OUTPUT_ALIGNMENT 1
])
AH_BOTTOM([
-/* Indicator for intl/ that it is compiled for testing purposes only. */
-#define USE_IN_GETTEXT_TESTS
-
/* A file name cannot consist of any character possible. INVALID_PATH_CHAR
contains the characters not allowed. */
#if defined _MSC_VER || defined __MINGW32__
gt_LOCALE_JA
dnl Checks for functions for the tests/*.c tests.
-AC_CHECK_FUNCS_ONCE([getrlimit setrlimit])
+AC_CHECK_FUNCS_ONCE([getrlimit setrlimit uselocale])
dnl Prepares the libtool configuration for languages used by the tests.
LT_LANG([C++])
+2009-12-26 Bruno Haible <bruno@clisp.org>
+
+ Enable the gettext-6 and gettext-7 tests also on MacOS X.
+ * Makefile.am (gettext_6_prg_CFLAGS, gettext_7_prg_CFLAGS): Depend on
+ HAVE_NEWLOCALE instead of GLIBC2.
+ (gettext_6_prg_LDADD, gettext_7_prg_LDADD): Likewise. Remove
+ libgettextlib.la.
+ * gettext-6-prg.c: Enable the test also on MacOS X platforms that have
+ uselocale.
+ (LOCALE_DE_ISO8859, LOCALE_FR_ISO8859): New macros.
+ (thread1_execution, thread2_execution): Use them.
+ (check_locale_exists): New function.
+ (main): Check for the locales if an argument is passed.
+ * gettext-7-prg.c: Enable the test also on MacOS X platforms that have
+ uselocale.
+ (LOCALE_DE_ISO8859, LOCALE_DE_UTF8): New macros.
+ (thread1_execution, thread2_execution): Use them.
+ (check_locale_exists): New function.
+ (main): Check for the locales if an argument is passed.
+ * gettext-6: Make the test work also on MacOS X systems. Test the
+ presence of the locales through the program, not through testlocale.
+ * gettext-7: Likewise.
+
2009-12-26 Bruno Haible <bruno@clisp.org>
* gettext-7: Make the test fail when it produced unexpected results.
gettext_5_prg_SOURCES = gettext-5-prg.c
gettext_5_prg_LDADD = ../gnulib-lib/libgettextlib.la $(LDADD)
gettext_6_prg_SOURCES = gettext-6-prg.c
-gettext_6_prg_CFLAGS = $(gettext_6_prg_CFLAGS_@GLIBC2@)
-gettext_6_prg_CFLAGS_yes = -DUSE_POSIX_THREADS
-gettext_6_prg_LDADD = $(gettext_6_prg_LDADD_@GLIBC2@)
-gettext_6_prg_LDADD_yes = ../gnulib-lib/libgettextlib.la $(LDADD) -lpthread
+gettext_6_prg_CFLAGS = $(gettext_6_prg_CFLAGS_@HAVE_NEWLOCALE@)
+gettext_6_prg_CFLAGS_1 = -DUSE_POSIX_THREADS
+gettext_6_prg_LDADD = $(gettext_6_prg_LDADD_@HAVE_NEWLOCALE@)
+gettext_6_prg_LDADD_1 = $(LDADD) -lpthread
gettext_7_prg_SOURCES = gettext-7-prg.c
-gettext_7_prg_CFLAGS = $(gettext_7_prg_CFLAGS_@GLIBC2@)
-gettext_7_prg_CFLAGS_yes = -DUSE_POSIX_THREADS
-gettext_7_prg_LDADD = $(gettext_7_prg_LDADD_@GLIBC2@)
-gettext_7_prg_LDADD_yes = ../gnulib-lib/libgettextlib.la $(LDADD) -lpthread
+gettext_7_prg_CFLAGS = $(gettext_7_prg_CFLAGS_@HAVE_NEWLOCALE@)
+gettext_7_prg_CFLAGS_1 = -DUSE_POSIX_THREADS
+gettext_7_prg_LDADD = $(gettext_7_prg_LDADD_@HAVE_NEWLOCALE@)
+gettext_7_prg_LDADD_1 = $(LDADD) -lpthread
gettext_8_prg_SOURCES = gettext-8-prg.c
gettext_8_prg_LDADD = ../gnulib-lib/libgettextlib.la $(LDADD)
cake_SOURCES = plural-1-prg.c setlocale.c
tmpfiles=""
trap 'rm -fr $tmpfiles' 1 2 3 15
-# This test works only on glibc systems.
+# This test works only on glibc and MacOS X systems.
+: ${host_os=unknown}
: ${GLIBC2=no}
-test "$GLIBC2" = yes || {
- echo "Skipping test: not a glibc system"
+{ case "$host_os" in
+ *-gnu*) test "$GLIBC2" = yes ;;
+ darwin*) true ;;
+ *) false ;;
+ esac
+} || {
+ echo "Skipping test: not a glibc or Mac OS X system"
exit 77
}
# This test works only on systems that have a de_DE and fr_FR locale installed.
-LC_ALL=de_DE ./testlocale || {
+missing_locale=`./gettext-6-prg 1`
+if test -n "$missing_locale"; then
if test -f /usr/bin/localedef; then
- echo "Skipping test: locale de_DE not installed"
+ echo "Skipping test: locale ${missing_locale} not installed"
else
- echo "Skipping test: locale de_DE not supported"
+ echo "Skipping test: locale ${missing_locale} not supported"
fi
exit 77
-}
-LC_ALL=fr_FR ./testlocale || {
- if test -f /usr/bin/localedef; then
- echo "Skipping test: locale fr_FR not installed"
- else
- echo "Skipping test: locale fr_FR not supported"
- fi
- exit 77
-}
+fi
tmpfiles="$tmpfiles de_DE fr_FR"
test -d de_DE || mkdir de_DE
case $? in
0) ;;
77)
- echo "Skipping test: not a glibc 2.3 system"
+ echo "Skipping test: not a glibc >= 2.3 or MacOS X >= 10.5 system"
rm -fr $tmpfiles; exit 77
;;
esac
/* Test program, used by the gettext-6 test.
- Copyright (C) 2005-2007 Free Software Foundation, Inc.
+ Copyright (C) 2005-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 General Public License as published by
#include <stdio.h>
#include <string.h>
-#if USE_POSIX_THREADS && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3))
+#if USE_POSIX_THREADS && (__GLIBC__ >= 2 || (defined __APPLE__ && defined __MACH__)) && HAVE_USELOCALE
#include <pthread.h>
#undef _LIBINTL_H
#include "libgnuintl.h"
+/* Name of German and French locale in ISO-8859-1 or ISO-8859-15 encoding. */
+#if __GLIBC__ >= 2
+# define LOCALE_DE_ISO8859 "de_DE.ISO-8859-1"
+# define LOCALE_FR_ISO8859 "fr_FR.ISO-8859-1"
+#elif defined __APPLE__ && defined __MACH__ /* MacOS X */
+# define LOCALE_DE_ISO8859 "de_DE.ISO8859-1"
+# define LOCALE_FR_ISO8859 "fr_FR.ISO8859-1"
+#else
+# define LOCALE_DE_ISO8859 "de_DE"
+# define LOCALE_FR_ISO8859 "fr_FR"
+#endif
+
/* Set to 1 if the program is not behaving correctly. */
int result;
char *s;
waitfor (1);
- uselocale (newlocale (LC_ALL_MASK, "de_DE", NULL));
+ uselocale (newlocale (LC_ALL_MASK, LOCALE_DE_ISO8859, NULL));
setto (2);
waitfor (1);
char *s;
waitfor (2);
- uselocale (newlocale (LC_ALL_MASK, "fr_FR", NULL));
+ uselocale (newlocale (LC_ALL_MASK, LOCALE_FR_ISO8859, NULL));
setto (1);
waitfor (2);
return NULL;
}
+static void
+check_locale_exists (const char *name)
+{
+ if (newlocale (LC_ALL_MASK, name, NULL) == NULL)
+ {
+ printf ("%s\n", name);
+ exit (1);
+ }
+}
+
int
-main (void)
+main (int argc, char *argv[])
{
+ int arg;
pthread_t thread1;
pthread_t thread2;
+ arg = (argc > 1 ? atoi (argv[1]) : 0);
+ switch (arg)
+ {
+ case 1:
+ /* Check for the existence of the first locale. */
+ check_locale_exists (LOCALE_DE_ISO8859);
+ /* Check for the existence of the second locale. */
+ check_locale_exists (LOCALE_FR_ISO8859);
+ return 0;
+ default:
+ break;
+ }
+
unsetenv ("LANGUAGE");
unsetenv ("OUTPUT_CHARSET");
textdomain ("tstthread");
tmpfiles=""
trap 'rm -fr $tmpfiles' 1 2 3 15
-# This test works only on glibc systems.
+# This test works only on glibc and MacOS X systems.
+: ${host_os=unknown}
: ${GLIBC2=no}
-test "$GLIBC2" = yes || {
- echo "Skipping test: not a glibc system"
+{ case "$host_os" in
+ *-gnu*) test "$GLIBC2" = yes ;;
+ darwin*) true ;;
+ *) false ;;
+ esac
+} || {
+ echo "Skipping test: not a glibc or Mac OS X system"
exit 77
}
# This test works only on systems that have a de_DE.ISO-8859-1 and
# de_DE.UTF-8 locale installed.
-LC_ALL=de_DE.ISO-8859-1 ./testlocale || {
+missing_locale=`./gettext-7-prg 1`
+if test -n "$missing_locale"; then
if test -f /usr/bin/localedef; then
- echo "Skipping test: locale de_DE.ISO-8859-1 not installed"
+ echo "Skipping test: locale ${missing_locale} not installed"
else
- echo "Skipping test: locale de_DE.ISO-8859-1 not supported"
+ echo "Skipping test: locale ${missing_locale} not supported"
fi
exit 77
-}
-LC_ALL=de_DE.UTF-8 ./testlocale || {
- if test -f /usr/bin/localedef; then
- echo "Skipping test: locale de_DE.UTF-8 not installed"
- else
- echo "Skipping test: locale de_DE.UTF-8 not supported"
- fi
- exit 77
-}
+fi
tmpfiles="$tmpfiles de_DE"
test -d de_DE || mkdir de_DE
case $? in
0) ;;
77)
- echo "Skipping test: not a glibc 2.3 system"
+ echo "Skipping test: not a glibc >= 2.3 or MacOS X >= 10.5 system"
rm -fr $tmpfiles; exit 77
;;
*)
/* Test program, used by the gettext-7 test.
- Copyright (C) 2005-2007 Free Software Foundation, Inc.
+ Copyright (C) 2005-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 General Public License as published by
#include <stdio.h>
#include <string.h>
-#if USE_POSIX_THREADS && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3))
+#if USE_POSIX_THREADS && (__GLIBC__ >= 2 || (defined __APPLE__ && defined __MACH__)) && HAVE_USELOCALE
#include <pthread.h>
#undef _LIBINTL_H
#include "libgnuintl.h"
+/* Name of German locale in ISO-8859-1 or ISO-8859-15 encoding. */
+#if __GLIBC__ >= 2
+# define LOCALE_DE_ISO8859 "de_DE.ISO-8859-1"
+#elif defined __APPLE__ && defined __MACH__ /* MacOS X */
+# define LOCALE_DE_ISO8859 "de_DE.ISO8859-1"
+#else
+# define LOCALE_DE_ISO8859 "de_DE"
+#endif
+
+/* Name of German locale in UTF-8 encoding. */
+#define LOCALE_DE_UTF8 "de_DE.UTF-8"
+
/* Set to 1 if the program is not behaving correctly. */
int result;
char *s;
waitfor (1);
- uselocale (newlocale (LC_ALL_MASK, "de_DE.ISO-8859-1", NULL));
+ uselocale (newlocale (LC_ALL_MASK, LOCALE_DE_ISO8859, NULL));
setto (2);
/* Here we expect output in ISO-8859-1. */
char *s;
waitfor (2);
- uselocale (newlocale (LC_ALL_MASK, "de_DE.UTF-8", NULL));
+ uselocale (newlocale (LC_ALL_MASK, LOCALE_DE_UTF8, NULL));
setto (1);
/* Here we expect output in UTF-8. */
return NULL;
}
+static void
+check_locale_exists (const char *name)
+{
+ if (newlocale (LC_ALL_MASK, name, NULL) == NULL)
+ {
+ printf ("%s\n", name);
+ exit (1);
+ }
+}
+
int
-main (void)
+main (int argc, char *argv[])
{
+ int arg;
pthread_t thread1;
pthread_t thread2;
+ arg = (argc > 1 ? atoi (argv[1]) : 0);
+ switch (arg)
+ {
+ case 1:
+ /* Check for the existence of the first locale. */
+ check_locale_exists (LOCALE_DE_ISO8859);
+ /* Check for the existence of the second locale. */
+ check_locale_exists (LOCALE_DE_UTF8);
+ return 0;
+ default:
+ break;
+ }
+
unsetenv ("LANGUAGE");
unsetenv ("OUTPUT_CHARSET");
textdomain ("tstthread");