summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2005-05-02 10:20:19 +0000
committerBruno Haible <bruno@clisp.org>2009-06-23 12:12:32 +0200
commit0d156eb3ade89fb685d0d42d42635b8fcd98ba96 (patch)
tree6e75af7486447c8af7f2b9651c9887263ff82cdd
parent884a809d4e8a17b611c8e014a4ccd54a2a88bf15 (diff)
downloadexternal_gettext-0d156eb3ade89fb685d0d42d42635b8fcd98ba96.zip
external_gettext-0d156eb3ade89fb685d0d42d42635b8fcd98ba96.tar.gz
external_gettext-0d156eb3ade89fb685d0d42d42635b8fcd98ba96.tar.bz2
Make it possible for multiple threads to use gettext() in different locales.
-rw-r--r--gettext-runtime/intl/ChangeLog13
-rw-r--r--gettext-runtime/intl/dcigettext.c88
-rw-r--r--gettext-tools/ChangeLog5
-rw-r--r--gettext-tools/configure.ac7
-rw-r--r--gettext-tools/tests/ChangeLog17
-rw-r--r--gettext-tools/tests/Makefile.am17
6 files changed, 132 insertions, 15 deletions
diff --git a/gettext-runtime/intl/ChangeLog b/gettext-runtime/intl/ChangeLog
index 9ee195e..0c6ef59 100644
--- a/gettext-runtime/intl/ChangeLog
+++ b/gettext-runtime/intl/ChangeLog
@@ -1,3 +1,16 @@
+2005-03-20 Bruno Haible <bruno@clisp.org>
+
+ Make it possible for multiple threads to use gettext() in different
+ locales.
+ * dcigettext.c (HAVE_PER_THREAD_LOCALE): New macro.
+ (struct known_translation_t): If HAVE_PER_THREAD_LOCALE, add localename
+ field.
+ (transcmp): If HAVE_PER_THREAD_LOCALE, compare localename fields.
+ (DCIGETTEXT): If HAVE_PER_THREAD_LOCALE, fill the localename field in
+ search and newp.
+ (guess_category_value): If HAVE_PER_THREAD_LOCALE, look at the thread's
+ locale.
+
2005-03-19 Bruno Haible <bruno@clisp.org>
* gettextP.h (struct loaded_domain): Remove codeset_cntr field.
diff --git a/gettext-runtime/intl/dcigettext.c b/gettext-runtime/intl/dcigettext.c
index 63534b8..f5a8915 100644
--- a/gettext-runtime/intl/dcigettext.c
+++ b/gettext-runtime/intl/dcigettext.c
@@ -216,6 +216,11 @@ static void *mempcpy (void *dest, const void *src, size_t n);
# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL)
#endif
+/* Whether to support different locales in different threads. */
+#if defined _LIBC || (HAVE_STRUCT___LOCALE_STRUCT___NAMES && defined USE_IN_GETTEXT_TESTS)
+# define HAVE_PER_THREAD_LOCALE
+#endif
+
/* This is the type used for the search tree where known translations
are stored. */
struct known_translation_t
@@ -226,6 +231,11 @@ struct known_translation_t
/* The category. */
int category;
+#ifdef HAVE_PER_THREAD_LOCALE
+ /* Name of the relevant locale category, or "" for the global locale. */
+ const char *localename;
+#endif
+
/* State of the catalog counter at the point the string was found. */
int counter;
@@ -267,10 +277,16 @@ transcmp (const void *p1, const void *p2)
{
result = strcmp (s1->domainname, s2->domainname);
if (result == 0)
- /* We compare the category last (though this is the cheapest
- operation) since it is hopefully always the same (namely
- LC_MESSAGES). */
- result = s1->category - s2->category;
+ {
+#ifdef HAVE_PER_THREAD_LOCALE
+ result = strcmp (s1->localename, s2->localename);
+ if (result == 0)
+#endif
+ /* We compare the category last (though this is the cheapest
+ operation) since it is hopefully always the same (namely
+ LC_MESSAGES). */
+ result = s1->category - s2->category;
+ }
}
return result;
@@ -447,6 +463,9 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
struct known_translation_t *search;
struct known_translation_t **foundp = NULL;
size_t msgid_len;
+# ifdef HAVE_PER_THREAD_LOCALE
+ const char *localename;
+# endif
#endif
size_t domainname_len;
@@ -487,6 +506,24 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
memcpy (search->msgid, msgid1, msgid_len);
search->domainname = domainname;
search->category = category;
+# ifdef HAVE_PER_THREAD_LOCALE
+# ifdef _LIBC
+ localename = __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)
+ localename = thread_locale->__names[category];
+ else
+ localename = "";
+ }
+# endif
+# endif
+ search->localename = localename;
+# endif
foundp = (struct known_translation_t **) tfind (search, &root, transcmp);
freea (search);
@@ -649,19 +686,33 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
if (foundp == NULL)
{
/* Create a new entry and add it to the search tree. */
+ size_t size;
struct known_translation_t *newp;
- newp = (struct known_translation_t *)
- malloc (offsetof (struct known_translation_t, msgid)
- + msgid_len + domainname_len + 1);
+ size = offsetof (struct known_translation_t, msgid)
+ + msgid_len + domainname_len + 1;
+# ifdef HAVE_PER_THREAD_LOCALE
+ size += strlen (localename) + 1;
+# endif
+ newp = (struct known_translation_t *) malloc (size);
if (newp != NULL)
{
char *new_domainname;
+# ifdef HAVE_PER_THREAD_LOCALE
+ char *new_localename;
+# endif
new_domainname = mempcpy (newp->msgid, msgid1, msgid_len);
memcpy (new_domainname, domainname, domainname_len + 1);
+# ifdef HAVE_PER_THREAD_LOCALE
+ new_localename = new_domainname + domainname_len + 1;
+ strcpy (new_localename, localename);
+# endif
newp->domainname = new_domainname;
newp->category = category;
+# ifdef HAVE_PER_THREAD_LOCALE
+ newp->localename = new_localename;
+# endif
newp->counter = _nl_msg_cat_cntr;
newp->domain = domain;
newp->translation = retval;
@@ -1286,12 +1337,25 @@ guess_category_value (int category, const char *categoryname)
#ifdef _LIBC
locale = __current_locale_name (category);
#else
- locale = _nl_locale_name_posix (category, categoryname);
- locale_defaulted = 0;
- if (locale == NULL)
+# 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 = _nl_locale_name_default ();
- locale_defaulted = 1;
+ locale = thread_locale->__names[category];
+ locale_defaulted = 0;
+ }
+ else
+# endif
+ {
+ locale = _nl_locale_name_posix (category, categoryname);
+ locale_defaulted = 0;
+ if (locale == NULL)
+ {
+ locale = _nl_locale_name_default ();
+ locale_defaulted = 1;
+ }
}
#endif
diff --git a/gettext-tools/ChangeLog b/gettext-tools/ChangeLog
index 766ef8e..d0b39d0 100644
--- a/gettext-tools/ChangeLog
+++ b/gettext-tools/ChangeLog
@@ -1,3 +1,8 @@
+2005-03-20 Bruno Haible <bruno@clisp.org>
+
+ * configure.ac: Test for field __names in struct __locale_struct.
+ Also define USE_IN_GETTEXT_TESTS.
+
2005-04-11 Bruno Haible <bruno@clisp.org>
* gettext-0.14.4 released.
diff --git a/gettext-tools/configure.ac b/gettext-tools/configure.ac
index b44a95e..61af08b 100644
--- a/gettext-tools/configure.ac
+++ b/gettext-tools/configure.ac
@@ -115,6 +115,10 @@ gt_TYPE_SSIZE_T
AC_TYPE_PID_T
AC_TYPE_MODE_T
gt_TYPE_SIG_ATOMIC_T
+gl_GLIBC21
+if test $GLIBC21 = yes; then
+ AC_CHECK_MEMBERS([struct __locale_struct.__names], , , [#include <xlocale.h>])
+fi
dnl Checks for library functions.
gl_ALLOCSA
@@ -168,6 +172,9 @@ AH_TOP([
#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__
diff --git a/gettext-tools/tests/ChangeLog b/gettext-tools/tests/ChangeLog
index 93e9706..7b45ca8 100644
--- a/gettext-tools/tests/ChangeLog
+++ b/gettext-tools/tests/ChangeLog
@@ -1,3 +1,20 @@
+2005-03-20 Bruno Haible <bruno@clisp.org>
+
+ * gettext-6: New file.
+ * gettext-6-prg.c: New file.
+ * gettext-6-1.po: New file.
+ * gettext-6-2.po: New file.
+ * gettext-7: New file.
+ * gettext-7-prg.c: New file.
+ * gettext-7.po: New file.
+ * Makefile.am (TESTS): Add gettext-6, gettext-7.
+ (EXTRA_DIST): Add gettext-6-1.po, gettext-6-2.po, gettext-7.po.
+ (noinst_PROGRAMS): Add gettext-6-prg, gettext-7-prg.
+ (gettext_6_prg_SOURCES, gettext_6_prg_CFLAGS, gettext_6_prg_LDADD): New
+ variables.
+ (gettext_7_prg_SOURCES, gettext_7_prg_CFLAGS, gettext_7_prg_LDADD): New
+ variables.
+
2005-03-19 Bruno Haible <bruno@clisp.org>
* gettext-3: New file.
diff --git a/gettext-tools/tests/Makefile.am b/gettext-tools/tests/Makefile.am
index 41850c6..5422701 100644
--- a/gettext-tools/tests/Makefile.am
+++ b/gettext-tools/tests/Makefile.am
@@ -20,7 +20,7 @@
AUTOMAKE_OPTIONS = 1.5 gnits no-dependencies
EXTRA_DIST =
-TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 \
+TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 gettext-6 gettext-7 \
msgattrib-1 msgattrib-2 msgattrib-3 msgattrib-4 msgattrib-5 \
msgattrib-6 msgattrib-7 msgattrib-8 msgattrib-9 msgattrib-10 \
msgattrib-11 msgattrib-12 msgattrib-13 msgattrib-14 \
@@ -111,7 +111,8 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 \
EXTRA_DIST += $(TESTS) \
test.mo xg-c-1.ok.po mex-test2.ok msguniq-a.in msguniq-a.inp \
msguniq-a.out qttest_pl.po qttest_pl.qm ChangeLog.0 gettext-3-1.po \
- gettext-3-2.po gettext-4.po gettext-5.po
+ gettext-3-2.po gettext-4.po gettext-5.po gettext-6-1.po \
+ gettext-6-2.po gettext-7.po
XGETTEXT = ../src/xgettext
@@ -172,7 +173,7 @@ DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
LDADD = $(LDADD_@USE_INCLUDED_LIBINTL@) @INTL_MACOSX_LIBS@
LDADD_yes = ../intl/libintl.la
LDADD_no = ../intl/libgnuintl.la @LTLIBINTL@
-noinst_PROGRAMS = tstgettext tstngettext testlocale gettext-3-prg gettext-4-prg gettext-5-prg cake fc3 fc4 fc5
+noinst_PROGRAMS = tstgettext tstngettext testlocale gettext-3-prg gettext-4-prg gettext-5-prg gettext-6-prg gettext-7-prg cake fc3 fc4 fc5
tstgettext_SOURCES = tstgettext.c setlocale.c
tstgettext_CFLAGS = -DINSTALLDIR=\".\"
tstgettext_LDADD = ../lib/libgettextlib.la $(LDADD)
@@ -186,6 +187,16 @@ gettext_4_prg_SOURCES = gettext-4-prg.c
gettext_4_prg_LDADD = ../lib/libgettextlib.la $(LDADD)
gettext_5_prg_SOURCES = gettext-5-prg.c
gettext_5_prg_LDADD = ../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 = ../lib/libgettextlib.la $(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 = ../lib/libgettextlib.la $(LDADD) -lpthread
cake_SOURCES = plural-1-prg.c setlocale.c
cake_LDADD = ../lib/libgettextlib.la $(LDADD)
fc3_SOURCES = format-c-3-prg.c setlocale.c