mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 12:30:06 +00:00
* 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.
This commit is contained in:
parent
572028fa7e
commit
8406a53a25
33
ChangeLog
33
ChangeLog
@ -1,5 +1,38 @@
|
|||||||
2005-04-28 Ulrich Drepper <drepper@redhat.com>
|
2005-04-28 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
* scripts/config.guess: Update from upstream.
|
* scripts/config.guess: Update from upstream.
|
||||||
* scripts/config.sub: Likewise.
|
* scripts/config.sub: Likewise.
|
||||||
|
|
||||||
|
@ -30,9 +30,17 @@ distribute = gmo.h gettextP.h hash-string.h loadinfo.h locale.alias \
|
|||||||
tst-translit.sh translit.po \
|
tst-translit.sh translit.po \
|
||||||
tst-gettext2.sh tstlang1.po tstlang2.po \
|
tst-gettext2.sh tstlang1.po tstlang2.po \
|
||||||
tst-codeset.sh tstcodeset.po \
|
tst-codeset.sh tstcodeset.po \
|
||||||
tst-gettext3.sh
|
tst-gettext3.sh \
|
||||||
|
tst-gettext4.sh tst-gettext4-de.po tst-gettext4-fr.po \
|
||||||
|
tst-gettext5.sh
|
||||||
|
|
||||||
|
include ../Makeconfig
|
||||||
|
|
||||||
|
multithread-test-srcs := tst-gettext4 tst-gettext5
|
||||||
test-srcs := tst-gettext tst-translit tst-gettext2 tst-codeset tst-gettext3
|
test-srcs := tst-gettext tst-translit tst-gettext2 tst-codeset tst-gettext3
|
||||||
|
ifeq ($(have-thread-library),yes)
|
||||||
|
test-srcs += $(multithread-test-srcs)
|
||||||
|
endif
|
||||||
tests = tst-ngettext
|
tests = tst-ngettext
|
||||||
|
|
||||||
before-compile = $(objpfx)msgs.h
|
before-compile = $(objpfx)msgs.h
|
||||||
@ -42,8 +50,6 @@ install-others = $(inst_msgcatdir)/locale.alias
|
|||||||
generated = msgs.h mtrace-tst-gettext tst-gettext.mtrace
|
generated = msgs.h mtrace-tst-gettext tst-gettext.mtrace
|
||||||
generated-dirs := domaindir localedir
|
generated-dirs := domaindir localedir
|
||||||
|
|
||||||
include ../Makeconfig
|
|
||||||
|
|
||||||
ifneq (no,$(BISON))
|
ifneq (no,$(BISON))
|
||||||
plural.c: plural.y
|
plural.c: plural.y
|
||||||
$(BISON) $(BISONFLAGS) $@ $^
|
$(BISON) $(BISONFLAGS) $@ $^
|
||||||
@ -60,6 +66,9 @@ ifeq (yes,$(build-shared))
|
|||||||
ifneq ($(strip $(MSGFMT)),:)
|
ifneq ($(strip $(MSGFMT)),:)
|
||||||
tests: $(objpfx)tst-translit.out $(objpfx)tst-gettext2.out \
|
tests: $(objpfx)tst-translit.out $(objpfx)tst-gettext2.out \
|
||||||
$(objpfx)tst-codeset.out $(objpfx)tst-gettext3.out
|
$(objpfx)tst-codeset.out $(objpfx)tst-gettext3.out
|
||||||
|
ifeq ($(have-thread-library),yes)
|
||||||
|
tests: $(objpfx)tst-gettext4.out $(objpfx)tst-gettext5.out
|
||||||
|
endif
|
||||||
ifneq (no,$(PERL))
|
ifneq (no,$(PERL))
|
||||||
tests: $(objpfx)mtrace-tst-gettext
|
tests: $(objpfx)mtrace-tst-gettext
|
||||||
endif
|
endif
|
||||||
@ -77,6 +86,10 @@ $(objpfx)tst-codeset.out: tst-codeset.sh $(objpfx)tst-codeset
|
|||||||
$(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
|
$(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
|
||||||
$(objpfx)tst-gettext3.out: tst-gettext3.sh $(objpfx)tst-gettext3
|
$(objpfx)tst-gettext3.out: tst-gettext3.sh $(objpfx)tst-gettext3
|
||||||
$(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
|
$(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
|
||||||
|
$(objpfx)tst-gettext4.out: tst-gettext4.sh $(objpfx)tst-gettext4
|
||||||
|
$(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
|
||||||
|
$(objpfx)tst-gettext5.out: tst-gettext5.sh $(objpfx)tst-gettext5
|
||||||
|
$(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -89,11 +102,26 @@ CFLAGS-tst-translit.c = -DOBJPFX=\"$(objpfx)\"
|
|||||||
CFLAGS-tst-gettext2.c = -DOBJPFX=\"$(objpfx)\"
|
CFLAGS-tst-gettext2.c = -DOBJPFX=\"$(objpfx)\"
|
||||||
CFLAGS-tst-codeset.c = -DOBJPFX=\"$(objpfx)\"
|
CFLAGS-tst-codeset.c = -DOBJPFX=\"$(objpfx)\"
|
||||||
CFLAGS-tst-gettext3.c = -DOBJPFX=\"$(objpfx)\"
|
CFLAGS-tst-gettext3.c = -DOBJPFX=\"$(objpfx)\"
|
||||||
|
CFLAGS-tst-gettext4.c = -DOBJPFX=\"$(objpfx)\"
|
||||||
|
CFLAGS-tst-gettext5.c = -DOBJPFX=\"$(objpfx)\"
|
||||||
|
|
||||||
|
ifeq ($(have-thread-library),yes)
|
||||||
|
ifeq (yes,$(build-shared))
|
||||||
|
$(addprefix $(objpfx),$(multithread-test-srcs)): $(shared-thread-library)
|
||||||
|
else
|
||||||
|
$(addprefix $(objpfx),$(multithread-test-srcs)): $(static-thread-library)
|
||||||
|
endif
|
||||||
|
ifeq (yes,$(build-bounded))
|
||||||
|
$(multithread-test-srcs:%=$(objpfx)%-bp): $(bounded-thread-library)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
$(objpfx)tst-translit.out: $(objpfx)tst-gettext.out
|
$(objpfx)tst-translit.out: $(objpfx)tst-gettext.out
|
||||||
$(objpfx)tst-gettext2.out: $(objpfx)tst-gettext.out
|
$(objpfx)tst-gettext2.out: $(objpfx)tst-gettext.out
|
||||||
$(objpfx)tst-codeset.out: $(objpfx)tst-gettext.out
|
$(objpfx)tst-codeset.out: $(objpfx)tst-gettext.out
|
||||||
$(objpfx)tst-gettext3.out: $(objpfx)tst-gettext.out
|
$(objpfx)tst-gettext3.out: $(objpfx)tst-gettext.out
|
||||||
|
$(objpfx)tst-gettext4.out: $(objpfx)tst-gettext.out
|
||||||
|
$(objpfx)tst-gettext5.out: $(objpfx)tst-gettext.out
|
||||||
|
|
||||||
CPPFLAGS += -D'LOCALEDIR="$(msgcatdir)"' \
|
CPPFLAGS += -D'LOCALEDIR="$(msgcatdir)"' \
|
||||||
-D'LOCALE_ALIAS_PATH="$(msgcatdir)"'
|
-D'LOCALE_ALIAS_PATH="$(msgcatdir)"'
|
||||||
|
@ -172,6 +172,11 @@ static void *mempcpy PARAMS ((void *dest, const void *src, size_t n));
|
|||||||
# define PATH_MAX _POSIX_PATH_MAX
|
# define PATH_MAX _POSIX_PATH_MAX
|
||||||
#endif
|
#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
|
/* This is the type used for the search tree where known translations
|
||||||
are stored. */
|
are stored. */
|
||||||
struct known_translation_t
|
struct known_translation_t
|
||||||
@ -182,6 +187,11 @@ struct known_translation_t
|
|||||||
/* The category. */
|
/* The category. */
|
||||||
int 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. */
|
/* State of the catalog counter at the point the string was found. */
|
||||||
int counter;
|
int counter;
|
||||||
|
|
||||||
@ -226,10 +236,16 @@ transcmp (p1, p2)
|
|||||||
{
|
{
|
||||||
result = strcmp (s1->domainname, s2->domainname);
|
result = strcmp (s1->domainname, s2->domainname);
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
/* We compare the category last (though this is the cheapest
|
{
|
||||||
operation) since it is hopefully always the same (namely
|
#ifdef HAVE_PER_THREAD_LOCALE
|
||||||
LC_MESSAGES). */
|
result = strcmp (s1->localename, s2->localename);
|
||||||
result = s1->category - s2->category;
|
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;
|
return result;
|
||||||
@ -408,6 +424,9 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
|
|||||||
struct known_translation_t *search;
|
struct known_translation_t *search;
|
||||||
struct known_translation_t **foundp = NULL;
|
struct known_translation_t **foundp = NULL;
|
||||||
size_t msgid_len;
|
size_t msgid_len;
|
||||||
|
# ifdef HAVE_PER_THREAD_LOCALE
|
||||||
|
const char *localename;
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
size_t domainname_len;
|
size_t domainname_len;
|
||||||
|
|
||||||
@ -442,6 +461,12 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
|
|||||||
memcpy (search->msgid, msgid1, msgid_len);
|
memcpy (search->msgid, msgid1, msgid_len);
|
||||||
search->domainname = domainname;
|
search->domainname = domainname;
|
||||||
search->category = category;
|
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
|
/* Since tfind/tsearch manage a balanced tree, concurrent tfind and
|
||||||
tsearch calls can be fatal. */
|
tsearch calls can be fatal. */
|
||||||
@ -629,19 +654,33 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
|
|||||||
if (foundp == NULL)
|
if (foundp == NULL)
|
||||||
{
|
{
|
||||||
/* Create a new entry and add it to the search tree. */
|
/* Create a new entry and add it to the search tree. */
|
||||||
|
size_t size;
|
||||||
struct known_translation_t *newp;
|
struct known_translation_t *newp;
|
||||||
|
|
||||||
newp = (struct known_translation_t *)
|
size = offsetof (struct known_translation_t, msgid)
|
||||||
malloc (offsetof (struct known_translation_t, msgid)
|
+ msgid_len + domainname_len + 1;
|
||||||
+ 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)
|
if (newp != NULL)
|
||||||
{
|
{
|
||||||
char *new_domainname;
|
char *new_domainname;
|
||||||
|
# ifdef HAVE_PER_THREAD_LOCALE
|
||||||
|
char *new_localename;
|
||||||
|
# endif
|
||||||
|
|
||||||
new_domainname = mempcpy (newp->msgid, msgid1, msgid_len);
|
new_domainname = mempcpy (newp->msgid, msgid1, msgid_len);
|
||||||
memcpy (new_domainname, domainname, domainname_len + 1);
|
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->domainname = new_domainname;
|
||||||
newp->category = category;
|
newp->category = category;
|
||||||
|
# ifdef HAVE_PER_THREAD_LOCALE
|
||||||
|
newp->localename = new_localename;
|
||||||
|
# endif
|
||||||
newp->counter = _nl_msg_cat_cntr;
|
newp->counter = _nl_msg_cat_cntr;
|
||||||
newp->domain = domain;
|
newp->domain = domain;
|
||||||
newp->translation = retval;
|
newp->translation = retval;
|
||||||
|
8
intl/tst-gettext4-de.po
Normal file
8
intl/tst-gettext4-de.po
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||||
|
"Content-Transfer-Encoding: 8-bit\n"
|
||||||
|
|
||||||
|
msgid "beauty"
|
||||||
|
msgstr "Schönheit"
|
8
intl/tst-gettext4-fr.po
Normal file
8
intl/tst-gettext4-fr.po
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||||
|
"Content-Transfer-Encoding: 8-bit\n"
|
||||||
|
|
||||||
|
msgid "beauty"
|
||||||
|
msgstr "beauté"
|
151
intl/tst-gettext4.c
Normal file
151
intl/tst-gettext4.c
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/* Test that gettext() in multithreaded applications works correctly if
|
||||||
|
different threads operate in different locales with the same encoding.
|
||||||
|
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Bruno Haible <bruno@clisp.org>, 2005.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <libintl.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Set to 1 if the program is not behaving correctly. */
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/* Denotes which thread should run next. */
|
||||||
|
int flipflop;
|
||||||
|
/* Lock and wait queue used to switch between the threads. */
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
pthread_cond_t waitqueue;
|
||||||
|
|
||||||
|
/* Waits until the flipflop has a given value.
|
||||||
|
Before the call, the lock is unlocked. After the call, it is locked. */
|
||||||
|
static void
|
||||||
|
waitfor (int value)
|
||||||
|
{
|
||||||
|
if (pthread_mutex_lock (&lock))
|
||||||
|
exit (10);
|
||||||
|
while (flipflop != value)
|
||||||
|
if (pthread_cond_wait (&waitqueue, &lock))
|
||||||
|
exit (11);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sets the flipflop to a given value.
|
||||||
|
Before the call, the lock is locked. After the call, it is unlocked. */
|
||||||
|
static void
|
||||||
|
setto (int value)
|
||||||
|
{
|
||||||
|
flipflop = value;
|
||||||
|
if (pthread_cond_signal (&waitqueue))
|
||||||
|
exit (20);
|
||||||
|
if (pthread_mutex_unlock (&lock))
|
||||||
|
exit (21);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
thread1_execution (void *arg)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
waitfor (1);
|
||||||
|
uselocale (newlocale (LC_ALL_MASK, "de_DE.ISO-8859-1", NULL));
|
||||||
|
setto (2);
|
||||||
|
|
||||||
|
waitfor (1);
|
||||||
|
s = gettext ("beauty");
|
||||||
|
puts (s);
|
||||||
|
if (strcmp (s, "Sch\366nheit"))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "thread 1 call 1 returned: %s\n", s);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
setto (2);
|
||||||
|
|
||||||
|
waitfor (1);
|
||||||
|
s = gettext ("beauty");
|
||||||
|
puts (s);
|
||||||
|
if (strcmp (s, "Sch\366nheit"))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "thread 1 call 2 returned: %s\n", s);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
setto (2);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
thread2_execution (void *arg)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
waitfor (2);
|
||||||
|
uselocale (newlocale (LC_ALL_MASK, "fr_FR.ISO-8859-1", NULL));
|
||||||
|
setto (1);
|
||||||
|
|
||||||
|
waitfor (2);
|
||||||
|
s = gettext ("beauty");
|
||||||
|
puts (s);
|
||||||
|
if (strcmp (s, "beaut\351"))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "thread 2 call 1 returned: %s\n", s);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
setto (1);
|
||||||
|
|
||||||
|
waitfor (2);
|
||||||
|
s = gettext ("beauty");
|
||||||
|
puts (s);
|
||||||
|
if (strcmp (s, "beaut\351"))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "thread 2 call 2 returned: %s\n", s);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
setto (1);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
pthread_t thread1;
|
||||||
|
pthread_t thread2;
|
||||||
|
|
||||||
|
unsetenv ("LANGUAGE");
|
||||||
|
unsetenv ("OUTPUT_CHARSET");
|
||||||
|
textdomain ("multithread");
|
||||||
|
bindtextdomain ("multithread", OBJPFX "domaindir");
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
flipflop = 1;
|
||||||
|
if (pthread_mutex_init (&lock, NULL))
|
||||||
|
exit (2);
|
||||||
|
if (pthread_cond_init (&waitqueue, NULL))
|
||||||
|
exit (2);
|
||||||
|
if (pthread_create (&thread1, NULL, &thread1_execution, NULL))
|
||||||
|
exit (2);
|
||||||
|
if (pthread_create (&thread2, NULL, &thread2_execution, NULL))
|
||||||
|
exit (2);
|
||||||
|
if (pthread_join (thread2, NULL))
|
||||||
|
exit (3);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
48
intl/tst-gettext4.sh
Executable file
48
intl/tst-gettext4.sh
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# Test that gettext() in multithreaded applications works correctly if
|
||||||
|
# different threads operate in different locales with the same encoding.
|
||||||
|
# Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
|
||||||
|
# This file is part of the GNU C Library.
|
||||||
|
#
|
||||||
|
|
||||||
|
# The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
# The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with the GNU C Library; if not, write to the Free
|
||||||
|
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
# 02111-1307 USA.
|
||||||
|
|
||||||
|
common_objpfx=$1
|
||||||
|
objpfx=$2
|
||||||
|
|
||||||
|
LC_ALL=C
|
||||||
|
export LC_ALL
|
||||||
|
|
||||||
|
# Generate the test data.
|
||||||
|
test -d ${objpfx}domaindir || mkdir ${objpfx}domaindir
|
||||||
|
# Create the domain directories.
|
||||||
|
test -d ${objpfx}domaindir/de_DE || mkdir ${objpfx}domaindir/de_DE
|
||||||
|
test -d ${objpfx}domaindir/de_DE/LC_MESSAGES || mkdir ${objpfx}domaindir/de_DE/LC_MESSAGES
|
||||||
|
test -d ${objpfx}domaindir/fr_FR || mkdir ${objpfx}domaindir/fr_FR
|
||||||
|
test -d ${objpfx}domaindir/fr_FR/LC_MESSAGES || mkdir ${objpfx}domaindir/fr_FR/LC_MESSAGES
|
||||||
|
# Populate them.
|
||||||
|
msgfmt -o ${objpfx}domaindir/de_DE/LC_MESSAGES/multithread.mo tst-gettext4-de.po
|
||||||
|
msgfmt -o ${objpfx}domaindir/fr_FR/LC_MESSAGES/multithread.mo tst-gettext4-fr.po
|
||||||
|
|
||||||
|
GCONV_PATH=${common_objpfx}iconvdata
|
||||||
|
export GCONV_PATH
|
||||||
|
LOCPATH=${common_objpfx}localedata
|
||||||
|
export LOCPATH
|
||||||
|
|
||||||
|
${common_objpfx}elf/ld.so --library-path $common_objpfx \
|
||||||
|
${objpfx}tst-gettext4 > ${objpfx}tst-gettext4.out
|
||||||
|
|
||||||
|
exit $?
|
156
intl/tst-gettext5.c
Normal file
156
intl/tst-gettext5.c
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/* Test that gettext() in multithreaded applications works correctly if
|
||||||
|
different threads operate in different locales referring to the same
|
||||||
|
catalog file but with different encodings.
|
||||||
|
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Bruno Haible <bruno@clisp.org>, 2005.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <libintl.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Set to 1 if the program is not behaving correctly. */
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/* Denotes which thread should run next. */
|
||||||
|
int flipflop;
|
||||||
|
/* Lock and wait queue used to switch between the threads. */
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
pthread_cond_t waitqueue;
|
||||||
|
|
||||||
|
/* Waits until the flipflop has a given value.
|
||||||
|
Before the call, the lock is unlocked. After the call, it is locked. */
|
||||||
|
static void
|
||||||
|
waitfor (int value)
|
||||||
|
{
|
||||||
|
if (pthread_mutex_lock (&lock))
|
||||||
|
exit (10);
|
||||||
|
while (flipflop != value)
|
||||||
|
if (pthread_cond_wait (&waitqueue, &lock))
|
||||||
|
exit (11);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sets the flipflop to a given value.
|
||||||
|
Before the call, the lock is locked. After the call, it is unlocked. */
|
||||||
|
static void
|
||||||
|
setto (int value)
|
||||||
|
{
|
||||||
|
flipflop = value;
|
||||||
|
if (pthread_cond_signal (&waitqueue))
|
||||||
|
exit (20);
|
||||||
|
if (pthread_mutex_unlock (&lock))
|
||||||
|
exit (21);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
thread1_execution (void *arg)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
waitfor (1);
|
||||||
|
uselocale (newlocale (LC_ALL_MASK, "de_DE.ISO-8859-1", NULL));
|
||||||
|
setto (2);
|
||||||
|
|
||||||
|
/* Here we expect output in ISO-8859-1. */
|
||||||
|
|
||||||
|
waitfor (1);
|
||||||
|
s = gettext ("cheese");
|
||||||
|
puts (s);
|
||||||
|
if (strcmp (s, "K\344se"))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "thread 1 call 1 returned: %s\n", s);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
setto (2);
|
||||||
|
|
||||||
|
waitfor (1);
|
||||||
|
s = gettext ("cheese");
|
||||||
|
puts (s);
|
||||||
|
if (strcmp (s, "K\344se"))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "thread 1 call 2 returned: %s\n", s);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
setto (2);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
thread2_execution (void *arg)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
waitfor (2);
|
||||||
|
uselocale (newlocale (LC_ALL_MASK, "de_DE.UTF-8", NULL));
|
||||||
|
setto (1);
|
||||||
|
|
||||||
|
/* Here we expect output in UTF-8. */
|
||||||
|
|
||||||
|
waitfor (2);
|
||||||
|
s = gettext ("cheese");
|
||||||
|
puts (s);
|
||||||
|
if (strcmp (s, "K\303\244se"))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "thread 2 call 1 returned: %s\n", s);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
setto (1);
|
||||||
|
|
||||||
|
waitfor (2);
|
||||||
|
s = gettext ("cheese");
|
||||||
|
puts (s);
|
||||||
|
if (strcmp (s, "K\303\244se"))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "thread 2 call 2 returned: %s\n", s);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
setto (1);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
pthread_t thread1;
|
||||||
|
pthread_t thread2;
|
||||||
|
|
||||||
|
unsetenv ("LANGUAGE");
|
||||||
|
unsetenv ("OUTPUT_CHARSET");
|
||||||
|
textdomain ("codeset");
|
||||||
|
bindtextdomain ("codeset", OBJPFX "domaindir");
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
flipflop = 1;
|
||||||
|
if (pthread_mutex_init (&lock, NULL))
|
||||||
|
exit (2);
|
||||||
|
if (pthread_cond_init (&waitqueue, NULL))
|
||||||
|
exit (2);
|
||||||
|
if (pthread_create (&thread1, NULL, &thread1_execution, NULL))
|
||||||
|
exit (2);
|
||||||
|
if (pthread_create (&thread2, NULL, &thread2_execution, NULL))
|
||||||
|
exit (2);
|
||||||
|
if (pthread_join (thread2, NULL))
|
||||||
|
exit (3);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
46
intl/tst-gettext5.sh
Executable file
46
intl/tst-gettext5.sh
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# Test that gettext() in multithreaded applications works correctly if
|
||||||
|
# different threads operate in different locales referring to the same
|
||||||
|
# catalog file but with different encodings.
|
||||||
|
# Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
|
||||||
|
# This file is part of the GNU C Library.
|
||||||
|
#
|
||||||
|
|
||||||
|
# The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
# The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with the GNU C Library; if not, write to the Free
|
||||||
|
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
# 02111-1307 USA.
|
||||||
|
|
||||||
|
common_objpfx=$1
|
||||||
|
objpfx=$2
|
||||||
|
|
||||||
|
LC_ALL=C
|
||||||
|
export LC_ALL
|
||||||
|
|
||||||
|
# Generate the test data.
|
||||||
|
test -d ${objpfx}domaindir || mkdir ${objpfx}domaindir
|
||||||
|
# Create the domain directories.
|
||||||
|
test -d ${objpfx}domaindir/de_DE || mkdir ${objpfx}domaindir/de_DE
|
||||||
|
test -d ${objpfx}domaindir/de_DE/LC_MESSAGES || mkdir ${objpfx}domaindir/de_DE/LC_MESSAGES
|
||||||
|
# Populate them.
|
||||||
|
msgfmt -o ${objpfx}domaindir/de_DE/LC_MESSAGES/codeset.mo tstcodeset.po
|
||||||
|
|
||||||
|
GCONV_PATH=${common_objpfx}iconvdata
|
||||||
|
export GCONV_PATH
|
||||||
|
LOCPATH=${common_objpfx}localedata
|
||||||
|
export LOCPATH
|
||||||
|
|
||||||
|
${common_objpfx}elf/ld.so --library-path $common_objpfx \
|
||||||
|
${objpfx}tst-gettext5 > ${objpfx}tst-gettext5.out
|
||||||
|
|
||||||
|
exit $?
|
@ -1,5 +1,5 @@
|
|||||||
/* Compare two memory blocks for differences in the first COUNT bytes.
|
/* Compare two memory blocks for differences in the first COUNT bytes.
|
||||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -350,6 +350,7 @@ L(set):
|
|||||||
sbbl $-1, %eax
|
sbbl $-1, %eax
|
||||||
popl %esi
|
popl %esi
|
||||||
RETURN
|
RETURN
|
||||||
|
END (BP_SYM (memcmp))
|
||||||
|
|
||||||
.section .rodata
|
.section .rodata
|
||||||
ALIGN (2)
|
ALIGN (2)
|
||||||
@ -387,7 +388,6 @@ L(table_32bytes) :
|
|||||||
.long L(30bytes) - . + 0x78
|
.long L(30bytes) - . + 0x78
|
||||||
.long L(31bytes) - . + 0x7c
|
.long L(31bytes) - . + 0x7c
|
||||||
|
|
||||||
END (BP_SYM (memcmp))
|
|
||||||
|
|
||||||
#undef bcmp
|
#undef bcmp
|
||||||
weak_alias (BP_SYM (memcmp), BP_SYM (bcmp))
|
weak_alias (BP_SYM (memcmp), BP_SYM (bcmp))
|
||||||
|
Loading…
Reference in New Issue
Block a user