diff options
author | Ulrich Drepper <drepper@redhat.com> | 2005-04-28 18:21:03 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2005-04-28 18:21:03 +0000 |
commit | 8406a53a2502e0896878bfc2fd5f5726be39604a (patch) | |
tree | ae3cd0feeb2f071e4e713184ab99f624bdaf7270 /intl/dcigettext.c | |
parent | 572028fa7e0d679b537c66f10d44fa8bb94bde50 (diff) |
* sysdeps/i386/i686/memcmp.S: Move misplaced END.
2005-03-27 Bruno Haible <bruno@clisp.org>
Make it possible for multiple threads to use gettext() in different
locales.
* intl/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.
* intl/tst-gettext4.c: New file.
* intl/tst-gettext4.sh: New file.
* intl/tst-gettext4-de.po: New file.
* intl/tst-gettext4-fr.po: New file.
* intl/tst-gettext5.c: New file.
* intl/tst-gettext5.sh: New file.
* intl/Makefile (distribute): Add tst-gettext4.sh, tst-gettext4-de.po,
tst-gettext4-fr.po, tst-gettext5.sh.
(multithread-test-srcs): New variable.
(test-srcs): Add its contents.
(tests): Depend on tst-gettext4.out, tst-gettext5.out.
(tst-gettext4.out, tst-gettext5.out): New rules.
(CFLAGS-tst-gettext4.c, CFLAGS-tst-gettext5.c): New variables.
Add rule for linking the multithread-test-srcs with the appropriate
thread-library.
2005-04-28 Ulrich Drepper <drepper@redhat.com>
* po/rw.po: New file. From translation team.
Diffstat (limited to 'intl/dcigettext.c')
-rw-r--r-- | intl/dcigettext.c | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/intl/dcigettext.c b/intl/dcigettext.c index c73c719d94..f294dedf2f 100644 --- a/intl/dcigettext.c +++ b/intl/dcigettext.c @@ -172,6 +172,11 @@ static void *mempcpy PARAMS ((void *dest, const void *src, size_t n)); # define PATH_MAX _POSIX_PATH_MAX #endif +/* Whether to support different locales in different threads. */ +#if defined _LIBC || HAVE_NL_LOCALE_NAME +# define HAVE_PER_THREAD_LOCALE +#endif + /* This is the type used for the search tree where known translations are stored. */ struct known_translation_t @@ -182,6 +187,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; @@ -226,10 +236,16 @@ transcmp (p1, 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; @@ -408,6 +424,9 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) 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; @@ -442,6 +461,12 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) memcpy (search->msgid, msgid1, msgid_len); search->domainname = domainname; search->category = category; +# ifdef HAVE_PER_THREAD_LOCALE +# ifdef _LIBC + localename = __current_locale_name (category); +# endif + search->localename = localename; +# endif /* Since tfind/tsearch manage a balanced tree, concurrent tfind and tsearch calls can be fatal. */ @@ -629,19 +654,33 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) 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; |