intl patches (19)
Bruno Haible
haible@ilog.fr
Mon Apr 9 06:22:00 GMT 2001
There is a bug in intl: bind_textdomain_codeset() has no effect when
gettext() has already been called on the same domain. Example:
printf ("%s\n", gettext ("cheese"));
bind_textdomain_codeset ("domain", "UTF-8");
printf ("%s\n", gettext ("cheese"));
But applications like vim rely on bind_textdomain_codeset() having an
effect on later gettext() calls.
There is currently no workaround for this bug, because applications cannot
turn off gettext's caching mechanisms.
Here is a fix. The patch
- increments a domain-specific counter when bind_textdomain_codeset()
changes the codeset for a domain. The counter works like a timestamp.
- stores the domain-specific counter in the 'struct loaded_domain' when
it is created,
- compares the two counters when a message is to be fetched through
the catalog, and if the one in the 'struct loaded_domain' is too old,
the previous iconv() results are abandoned, and a new __gconv_t/iconv_t
descriptor is fetched,
- stops storing the domainbinding in 'struct loaded_l10nfile', because
this domainbinding can be NULL before bind_textdomain_codeset() but will
be != NULL after bind_textdomain_codeset(), thus the older (stored)
value may be invalid.
- adds a new test 'tst-codeset' to verify the bug is fixed.
Bruno
2001-04-07 Bruno Haible <haible@clisp.cons.org>
* intl/gettextP.h (struct loaded_domain): Add codeset_cntr field.
(struct binding): Add codeset_cntr field.
(_nl_load_domain): Add domainbinding argument.
(_nl_init_domain_conv, _nl_free_domain_conv): New declarations.
(_nl_find_msg): New declaration, moved here from loadinfo.h.
* intl/loadinfo.h (struct loaded_l10nfile): Remove domainbinding field.
(_nl_make_l10nflist): Remove domainbinding argument.
(_nl_find_msg): Move declaration to gettextP.h.
* intl/bindtextdom.c (set_binding_values): Initialize ->codeset_cntr
to 0. Increment it when ->codeset is changed.
* intl/dcigettext.c (DCIGETTEXT): Pass binding to _nl_find_msg.
(_nl_find_msg): Add domainbinding argument. Reinitialize the converter
if domainbinding->codeset_cntr has been incremented.
* intl/finddomain.c (_nl_find_domain): Don't pass domainbinding to
_nl_make_l10nflist(). Pass it to _nl_load_domain() instead.
* intl/l10nflist.c (_nl_make_l10nflist): Remove domainbinding argument.
* intl/loadmsgcat.c (_nl_init_domain_conv): New function, extracted
from _nl_load_domain. Append //TRANSLIT also when using libiconv.
(_nl_free_domain_conv): New function, extracted from _nl_unload_domain.
(_nl_load_domain): Add domainbinding argument. Call
_nl_init_domain_conv.
(_nl_unload_domain): Call _nl_free_domain_conv.
* intl/Makefile (distribute): Add tst-codeset.sh, tstcodeset.po.
(test-srcs): Add tst-codeset.
(tests): Depend on tst-codeset.out.
(tst-codeset.out): New rule.
(CFLAGS-tst-codeset.c): New variable.
* intl/tst-codeset.sh: New file.
* intl/tstcodeset.po: New file.
* intl/tst-codeset.c: New file.
* locale/findlocale.c (_nl_find_locale): Update _nl_make_l10nflist
calls.
*** glibc-20010315/intl/gettextP.h.bak Sun Mar 18 00:19:31 2001
--- glibc-20010315/intl/gettextP.h Sat Apr 7 22:28:54 2001
***************
*** 129,134 ****
--- 129,135 ----
struct string_desc *trans_tab;
nls_uint32 hash_size;
nls_uint32 *hash_tab;
+ int codeset_cntr;
#ifdef _LIBC
__gconv_t conv;
#else
***************
*** 156,161 ****
--- 157,163 ----
{
struct binding *next;
char *dirname;
+ int codeset_cntr; /* Incremented each time codeset changes. */
char *codeset;
char domainname[ZERO];
};
***************
*** 170,179 ****
const char *__domainname,
struct binding *__domainbinding))
internal_function;
! void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain))
internal_function;
void _nl_unload_domain PARAMS ((struct loaded_domain *__domain))
internal_function;
#ifdef _LIBC
extern char *__gettext PARAMS ((const char *__msgid));
--- 172,193 ----
const char *__domainname,
struct binding *__domainbinding))
internal_function;
! void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain,
! struct binding *__domainbinding))
internal_function;
void _nl_unload_domain PARAMS ((struct loaded_domain *__domain))
internal_function;
+ const char *_nl_init_domain_conv PARAMS ((struct loaded_l10nfile *__domain_file,
+ struct loaded_domain *__domain,
+ struct binding *__domainbinding))
+ internal_function;
+ void _nl_free_domain_conv PARAMS ((struct loaded_domain *__domain))
+ internal_function;
+
+ char *_nl_find_msg PARAMS ((struct loaded_l10nfile *domain_file,
+ struct binding *domainbinding,
+ const char *msgid, size_t *lengthp))
+ internal_function;
#ifdef _LIBC
extern char *__gettext PARAMS ((const char *__msgid));
*** glibc-20010315/intl/loadinfo.h.bak Sat Mar 17 19:45:29 2001
--- glibc-20010315/intl/loadinfo.h Sat Apr 7 22:28:54 2001
***************
*** 64,70 ****
struct loaded_l10nfile
{
const char *filename;
- struct binding *domainbinding;
int decided;
const void *data;
--- 64,69 ----
***************
*** 89,96 ****
const char *normalized_codeset,
const char *modifier, const char *special,
const char *sponsor, const char *revision,
! const char *filename,
! struct binding *domainbinding, int do_allocate));
extern const char *_nl_expand_alias PARAMS ((const char *name));
--- 88,94 ----
const char *normalized_codeset,
const char *modifier, const char *special,
const char *sponsor, const char *revision,
! const char *filename, int do_allocate));
extern const char *_nl_expand_alias PARAMS ((const char *name));
***************
*** 108,116 ****
extern char *_nl_find_language PARAMS ((const char *name));
-
- extern char *_nl_find_msg PARAMS ((struct loaded_l10nfile *domain_file,
- const char *msgid, size_t *lengthp))
- internal_function;
-
#endif /* loadinfo.h */
--- 106,109 ----
*** glibc-20010315/intl/bindtextdom.c.bak Sat Mar 17 18:23:23 2001
--- glibc-20010315/intl/bindtextdom.c Sat Apr 7 22:28:54 2001
***************
*** 218,223 ****
--- 218,224 ----
free (binding->codeset);
binding->codeset = result;
+ binding->codeset_cntr++;
modified = 1;
}
}
***************
*** 281,286 ****
--- 282,289 ----
/* The default value. */
new_binding->dirname = (char *) _nl_default_dirname;
+ new_binding->codeset_cntr = 0;
+
if (codesetp)
{
const char *codeset = *codesetp;
***************
*** 301,306 ****
--- 304,310 ----
memcpy (result, codeset, len);
#endif
codeset = result;
+ new_binding->codeset_cntr++;
}
*codesetp = codeset;
new_binding->codeset = (char *) codeset;
*** glibc-20010315/intl/dcigettext.c.bak Sun Mar 18 00:26:39 2001
--- glibc-20010315/intl/dcigettext.c Sat Apr 7 22:28:54 2001
***************
*** 598,604 ****
if (domain != NULL)
{
! retval = _nl_find_msg (domain, msgid1, &retlen);
if (retval == NULL)
{
--- 598,604 ----
if (domain != NULL)
{
! retval = _nl_find_msg (domain, binding, msgid1, &retlen);
if (retval == NULL)
{
***************
*** 606,613 ****
for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
{
! retval = _nl_find_msg (domain->successor[cnt], msgid1,
! &retlen);
if (retval != NULL)
{
--- 606,613 ----
for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
{
! retval = _nl_find_msg (domain->successor[cnt], binding,
! msgid1, &retlen);
if (retval != NULL)
{
***************
*** 676,683 ****
char *
internal_function
! _nl_find_msg (domain_file, msgid, lengthp)
struct loaded_l10nfile *domain_file;
const char *msgid;
size_t *lengthp;
{
--- 676,684 ----
char *
internal_function
! _nl_find_msg (domain_file, domainbinding, msgid, lengthp)
struct loaded_l10nfile *domain_file;
+ struct binding *domainbinding;
const char *msgid;
size_t *lengthp;
{
***************
*** 687,693 ****
size_t resultlen;
if (domain_file->decided == 0)
! _nl_load_domain (domain_file);
if (domain_file->data == NULL)
return NULL;
--- 688,694 ----
size_t resultlen;
if (domain_file->decided == 0)
! _nl_load_domain (domain_file, domainbinding);
if (domain_file->data == NULL)
return NULL;
***************
*** 766,771 ****
--- 767,782 ----
resultlen = W (domain->must_swap, domain->trans_tab[act].length) + 1;
#if defined _LIBC || HAVE_ICONV
+ if (domain->codeset_cntr
+ != (domainbinding != NULL ? domainbinding->codeset_cntr : 0))
+ {
+ /* The domain's codeset has changed through bind_textdomain_codeset()
+ since the message catalog was initialized or last accessed. We
+ have to reinitialize the converter. */
+ _nl_free_domain_conv (domain);
+ _nl_init_domain_conv (domain_file, domain, domainbinding);
+ }
+
if (
# ifdef _LIBC
domain->conv != (__gconv_t) -1
*** glibc-20010315/intl/finddomain.c.bak Sat Mar 17 17:42:23 2001
--- glibc-20010315/intl/finddomain.c Sat Apr 7 22:28:54 2001
***************
*** 107,121 ****
be one data set in the list of loaded domains. */
retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
strlen (dirname) + 1, 0, locale, NULL, NULL,
! NULL, NULL, NULL, NULL, NULL, domainname,
! domainbinding, 0);
if (retval != NULL)
{
/* We know something about this locale. */
int cnt;
if (retval->decided == 0)
! _nl_load_domain (retval);
if (retval->data != NULL)
return retval;
--- 107,120 ----
be one data set in the list of loaded domains. */
retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
strlen (dirname) + 1, 0, locale, NULL, NULL,
! NULL, NULL, NULL, NULL, NULL, domainname, 0);
if (retval != NULL)
{
/* We know something about this locale. */
int cnt;
if (retval->decided == 0)
! _nl_load_domain (retval, domainbinding);
if (retval->data != NULL)
return retval;
***************
*** 123,129 ****
for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
{
if (retval->successor[cnt]->decided == 0)
! _nl_load_domain (retval->successor[cnt]);
if (retval->successor[cnt]->data != NULL)
break;
--- 122,128 ----
for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
{
if (retval->successor[cnt]->decided == 0)
! _nl_load_domain (retval->successor[cnt], domainbinding);
if (retval->successor[cnt]->data != NULL)
break;
***************
*** 164,184 ****
retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
strlen (dirname) + 1, mask, language, territory,
codeset, normalized_codeset, modifier, special,
! sponsor, revision, domainname, domainbinding,
! 1);
if (retval == NULL)
/* This means we are out of core. */
return NULL;
if (retval->decided == 0)
! _nl_load_domain (retval);
if (retval->data == NULL)
{
int cnt;
for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
{
if (retval->successor[cnt]->decided == 0)
! _nl_load_domain (retval->successor[cnt]);
if (retval->successor[cnt]->data != NULL)
break;
}
--- 163,182 ----
retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
strlen (dirname) + 1, mask, language, territory,
codeset, normalized_codeset, modifier, special,
! sponsor, revision, domainname, 1);
if (retval == NULL)
/* This means we are out of core. */
return NULL;
if (retval->decided == 0)
! _nl_load_domain (retval, domainbinding);
if (retval->data == NULL)
{
int cnt;
for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
{
if (retval->successor[cnt]->decided == 0)
! _nl_load_domain (retval->successor[cnt], domainbinding);
if (retval->successor[cnt]->data != NULL)
break;
}
*** glibc-20010315/intl/l10nflist.c.bak Sat Mar 17 19:45:29 2001
--- glibc-20010315/intl/l10nflist.c Sat Apr 7 22:28:54 2001
***************
*** 175,181 ****
struct loaded_l10nfile *
_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
territory, codeset, normalized_codeset, modifier, special,
! sponsor, revision, filename, domainbinding, do_allocate)
struct loaded_l10nfile **l10nfile_list;
const char *dirlist;
size_t dirlist_len;
--- 175,181 ----
struct loaded_l10nfile *
_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
territory, codeset, normalized_codeset, modifier, special,
! sponsor, revision, filename, do_allocate)
struct loaded_l10nfile **l10nfile_list;
const char *dirlist;
size_t dirlist_len;
***************
*** 189,195 ****
const char *sponsor;
const char *revision;
const char *filename;
- struct binding *domainbinding;
int do_allocate;
{
char *abs_filename;
--- 189,194 ----
***************
*** 310,316 ****
return NULL;
retval->filename = abs_filename;
- retval->domainbinding = domainbinding;
retval->decided = (__argz_count (dirlist, dirlist_len) != 1
|| ((mask & XPG_CODESET) != 0
&& (mask & XPG_NORM_CODESET) != 0));
--- 309,314 ----
***************
*** 346,353 ****
= _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt,
language, territory, codeset,
normalized_codeset, modifier, special,
! sponsor, revision, filename, domainbinding,
! 1);
}
retval->successor[entries] = NULL;
--- 344,350 ----
= _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt,
language, territory, codeset,
normalized_codeset, modifier, special,
! sponsor, revision, filename, 1);
}
retval->successor[entries] = NULL;
*** glibc-20010315/intl/loadmsgcat.c.bak Sat Mar 17 23:39:33 2001
--- glibc-20010315/intl/loadmsgcat.c Sat Apr 7 22:28:55 2001
***************
*** 207,218 ****
#endif
/* Load the message catalogs specified by FILENAME. If it is no valid
message catalog do nothing. */
void
internal_function
! _nl_load_domain (domain_file)
struct loaded_l10nfile *domain_file;
{
int fd;
size_t size;
--- 207,352 ----
#endif
+ /* Initialize the codeset dependent parts of an opened message catalog.
+ Return the header entry. */
+ const char *
+ internal_function
+ _nl_init_domain_conv (domain_file, domain, domainbinding)
+ struct loaded_l10nfile *domain_file;
+ struct loaded_domain *domain;
+ struct binding *domainbinding;
+ {
+ /* Find out about the character set the file is encoded with.
+ This can be found (in textual form) in the entry "". If this
+ entry does not exist or if this does not contain the `charset='
+ information, we will assume the charset matches the one the
+ current locale and we don't have to perform any conversion. */
+ char *nullentry;
+ size_t nullentrylen;
+
+ /* Preinitialize fields, to avoid recursion during _nl_find_msg. */
+ domain->codeset_cntr =
+ (domainbinding != NULL ? domainbinding->codeset_cntr : 0);
+ #ifdef _LIBC
+ domain->conv = (__gconv_t) -1;
+ #else
+ # if HAVE_ICONV
+ domain->conv = (iconv_t) -1;
+ # endif
+ #endif
+ domain->conv_tab = NULL;
+
+ /* Get the header entry. */
+ nullentry = _nl_find_msg (domain_file, domainbinding, "", &nullentrylen);
+
+ if (nullentry != NULL)
+ {
+ #if defined _LIBC || HAVE_ICONV
+ const char *charsetstr;
+
+ charsetstr = strstr (nullentry, "charset=");
+ if (charsetstr != NULL)
+ {
+ size_t len;
+ char *charset;
+ const char *outcharset;
+
+ charsetstr += strlen ("charset=");
+ len = strcspn (charsetstr, " \t\n");
+
+ charset = (char *) alloca (len + 1);
+ # if defined _LIBC || HAVE_MEMPCPY
+ *((char *) mempcpy (charset, charsetstr, len)) = '\0';
+ # else
+ memcpy (charset, charsetstr, len);
+ charset[len] = '\0';
+ # endif
+
+ /* The output charset should normally be determined by the
+ locale. But sometimes the locale is not used or not correctly
+ set up, so we provide a possibility for the user to override
+ this. Moreover, the value specified through
+ bind_textdomain_codeset overrides both. */
+ if (domainbinding != NULL && domainbinding->codeset != NULL)
+ outcharset = domainbinding->codeset;
+ else
+ {
+ outcharset = getenv ("OUTPUT_CHARSET");
+ if (outcharset == NULL || outcharset[0] == '\0')
+ {
+ # ifdef _LIBC
+ outcharset = (*_nl_current[LC_CTYPE])->values[_NL_ITEM_INDEX (CODESET)].string;
+ # else
+ # if HAVE_ICONV
+ extern const char *locale_charset (void);
+ outcharset = locale_charset ();
+ # endif
+ # endif
+ }
+ }
+
+ # ifdef _LIBC
+ /* We always want to use transliteration. */
+ outcharset = norm_add_slashes (outcharset, "TRANSLIT");
+ charset = norm_add_slashes (charset, NULL);
+ if (__gconv_open (outcharset, charset, &domain->conv,
+ GCONV_AVOID_NOCONV)
+ != __GCONV_OK)
+ domain->conv = (__gconv_t) -1;
+ # else
+ # if HAVE_ICONV
+ /* When using GNU libiconv, we want to use transliteration. */
+ # if _LIBICONV_VERSION
+ len = strlen (outcharset);
+ {
+ char *tmp = (char *) alloca (len + 10 + 1);
+ memcpy (tmp, outcharset, len);
+ memcpy (tmp + len, "//TRANSLIT", 10 + 1);
+ outcharset = tmp;
+ }
+ # endif
+ domain->conv = iconv_open (outcharset, charset);
+ # if _LIBICONV_VERSION
+ freea (outcharset);
+ # endif
+ # endif
+ # endif
+
+ freea (charset);
+ }
+ #endif /* _LIBC || HAVE_ICONV */
+ }
+
+ return nullentry;
+ }
+
+ /* Frees the codeset dependent parts of an opened message catalog. */
+ void
+ internal_function
+ _nl_free_domain_conv (domain)
+ struct loaded_domain *domain;
+ {
+ if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1)
+ free (domain->conv_tab);
+
+ #ifdef _LIBC
+ if (domain->conv != (__gconv_t) -1)
+ __gconv_close (domain->conv);
+ #else
+ # if HAVE_ICONV
+ if (domain->conv != (iconv_t) -1)
+ iconv_close (domain->conv);
+ # endif
+ #endif
+ }
+
/* Load the message catalogs specified by FILENAME. If it is no valid
message catalog do nothing. */
void
internal_function
! _nl_load_domain (domain_file, domainbinding)
struct loaded_l10nfile *domain_file;
+ struct binding *domainbinding;
{
int fd;
size_t size;
***************
*** 224,235 ****
struct mo_file_header *data = (struct mo_file_header *) -1;
int use_mmap = 0;
struct loaded_domain *domain;
! char *nullentry;
! size_t nullentrylen;
domain_file->decided = 1;
domain_file->data = NULL;
/* If the record does not represent a valid locale the FILENAME
might be NULL. This can happen when according to the given
specification the locale file name is different for XPG and CEN
--- 358,372 ----
struct mo_file_header *data = (struct mo_file_header *) -1;
int use_mmap = 0;
struct loaded_domain *domain;
! const char *nullentry;
domain_file->decided = 1;
domain_file->data = NULL;
+ /* Note that it would be useless to store domainbinding in domain_file
+ because domainbinding might be == NULL now but != NULL later (after
+ a call to bind_textdomain_codeset). */
+
/* If the record does not represent a valid locale the FILENAME
might be NULL. This can happen when according to the given
specification the locale file name is different for XPG and CEN
***************
*** 355,439 ****
return;
}
! /* Now find out about the character set the file is encoded with.
! This can be found (in textual form) in the entry "". If this
! entry does not exist or if this does not contain the `charset='
! information, we will assume the charset matches the one the
! current locale and we don't have to perform any conversion. */
! #ifdef _LIBC
! domain->conv = (__gconv_t) -1;
! #else
! # if HAVE_ICONV
! domain->conv = (iconv_t) -1;
! # endif
! #endif
! domain->conv_tab = NULL;
! nullentry = _nl_find_msg (domain_file, "", &nullentrylen);
! if (nullentry != NULL)
! {
! #if defined _LIBC || HAVE_ICONV
! const char *charsetstr;
!
! charsetstr = strstr (nullentry, "charset=");
! if (charsetstr != NULL)
! {
! size_t len;
! char *charset;
! const char *outcharset;
!
! charsetstr += strlen ("charset=");
! len = strcspn (charsetstr, " \t\n");
!
! charset = (char *) alloca (len + 1);
! # if defined _LIBC || HAVE_MEMPCPY
! *((char *) mempcpy (charset, charsetstr, len)) = '\0';
! # else
! memcpy (charset, charsetstr, len);
! charset[len] = '\0';
! # endif
!
! /* The output charset should normally be determined by the
! locale. But sometimes the locale is not used or not correctly
! set up, so we provide a possibility for the user to override
! this. Moreover, the value specified through
! bind_textdomain_codeset overrides both. */
! if (domain_file->domainbinding != NULL
! && domain_file->domainbinding->codeset != NULL)
! outcharset = domain_file->domainbinding->codeset;
! else
! {
! outcharset = getenv ("OUTPUT_CHARSET");
! if (outcharset == NULL || outcharset[0] == '\0')
! {
! # ifdef _LIBC
! outcharset = (*_nl_current[LC_CTYPE])->values[_NL_ITEM_INDEX (CODESET)].string;
! # else
! # if HAVE_ICONV
! extern const char *locale_charset (void);
! outcharset = locale_charset ();
! # endif
! # endif
! }
! }
!
! # ifdef _LIBC
! /* We always want to use transliteration. */
! outcharset = norm_add_slashes (outcharset, "TRANSLIT");
! charset = norm_add_slashes (charset, NULL);
! if (__gconv_open (outcharset, charset, &domain->conv,
! GCONV_AVOID_NOCONV)
! != __GCONV_OK)
! domain->conv = (__gconv_t) -1;
! # else
! # if HAVE_ICONV
! domain->conv = iconv_open (outcharset, charset);
! # endif
! # endif
!
! freea (charset);
! }
! #endif /* _LIBC || HAVE_ICONV */
! }
/* Also look for a plural specification. */
if (nullentry != NULL)
--- 492,501 ----
return;
}
! /* Now initialize the character set converter from the character set
! the file is encoded with (found in the header entry) to the domain's
! specified character set or the locale's character set. */
! nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding);
/* Also look for a plural specification. */
if (nullentry != NULL)
***************
*** 498,508 ****
if (domain->plural != &germanic_plural)
__gettext_free_exp (domain->plural);
! if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1)
! free (domain->conv_tab);
!
! if (domain->conv != (__gconv_t) -1)
! __gconv_close (domain->conv);
# ifdef _POSIX_MAPPED_FILES
if (domain->use_mmap)
--- 560,566 ----
if (domain->plural != &germanic_plural)
__gettext_free_exp (domain->plural);
! _nl_free_domain_conv (domain);
# ifdef _POSIX_MAPPED_FILES
if (domain->use_mmap)
*** glibc-20010315/intl/Makefile.bak Sat Apr 7 21:46:54 2001
--- glibc-20010315/intl/Makefile Sat Apr 7 22:21:44 2001
***************
*** 25,34 ****
finddomain loadmsgcat localealias textdomain \
l10nflist explodename plural
distribute = gettext.h gettextP.h hash-string.h loadinfo.h locale.alias \
! plural.y po2test.sed tst-gettext.sh tst-translit.sh \
! translit.po tst-gettext2.sh tstlang1.po tstlang2.po
! test-srcs := tst-gettext tst-translit tst-gettext2
tests = tst-ngettext
before-compile = $(objpfx)msgs.h
--- 25,34 ----
finddomain loadmsgcat localealias textdomain \
l10nflist explodename plural
distribute = gettext.h gettextP.h hash-string.h loadinfo.h locale.alias \
! plural.y po2test.sed tst-gettext.sh tst-translit.sh tst-codeset.sh \
! translit.po tst-gettext2.sh tstlang1.po tstlang2.po tstcodeset.po
! test-srcs := tst-gettext tst-translit tst-gettext2 tst-codeset
tests = tst-ngettext
before-compile = $(objpfx)msgs.h
***************
*** 54,60 ****
ifeq (no,$(cross-compiling))
ifeq (yes,$(build-shared))
ifneq ($(strip $(MSGFMT)),:)
! tests: $(objpfx)tst-translit.out $(objpfx)tst-gettext2.out
endif
ifneq (no,$(PERL))
tests: $(objpfx)mtrace-tst-gettext
--- 54,61 ----
ifeq (no,$(cross-compiling))
ifeq (yes,$(build-shared))
ifneq ($(strip $(MSGFMT)),:)
! tests: $(objpfx)tst-translit.out $(objpfx)tst-gettext2.out \
! $(objpfx)tst-codeset.out
endif
ifneq (no,$(PERL))
tests: $(objpfx)mtrace-tst-gettext
***************
*** 68,73 ****
--- 69,76 ----
$(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
$(objpfx)tst-gettext2.out: tst-gettext2.sh $(objpfx)tst-gettext2
$(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
+ $(objpfx)tst-codeset.out: tst-codeset.sh $(objpfx)tst-codeset
+ $(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
endif
endif
***************
*** 78,83 ****
--- 81,87 ----
CFLAGS-tst-gettext.c = -DTESTSTRS_H=\"$(objpfx)msgs.h\"
CFLAGS-tst-gettext2.c = -DOBJPFX=\"$(objpfx)\"
CFLAGS-tst-translit.c = -DOBJPFX=\"$(objpfx)\"
+ CFLAGS-tst-codeset.c = -DOBJPFX=\"$(objpfx)\"
$(objpfx)tst-translit.out: $(objpfx)tst-gettext.out
*** glibc-20010315/intl/tst-codeset.sh.bak Sat Apr 7 21:48:27 2001
--- glibc-20010315/intl/tst-codeset.sh Sat Apr 7 22:18:19 2001
***************
*** 0 ****
--- 1,42 ----
+ #! /bin/sh
+ # Test of bind_textdomain_codeset.
+ # Copyright (C) 2001 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 Library General Public License as
+ # published by the Free Software Foundation; either version 2 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
+ # Library General Public License for more details.
+ #
+ # You should have received a copy of the GNU Library General Public
+ # License along with the GNU C Library; see the file COPYING.LIB. If
+ # not, write to the Free Software Foundation, Inc.,
+ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ common_objpfx=$1
+ objpfx=$2
+
+ GCONV_PATH=${common_objpfx}iconvdata
+ export GCONV_PATH
+ LOCPATH=${common_objpfx}localedata
+ export LOCPATH
+ 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
+
+ ${common_objpfx}elf/ld.so --library-path $common_objpfx \
+ ${objpfx}tst-codeset > ${objpfx}tst-codeset.out
+
+ exit $?
*** glibc-20010315/intl/tstcodeset.po.bak Sat Apr 7 22:02:38 2001
--- glibc-20010315/intl/tstcodeset.po Sat Apr 7 22:02:26 2001
***************
*** 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 "cheese"
+ msgstr "Käse"
*** glibc-20010315/intl/tst-codeset.c.bak Sat Apr 7 22:18:42 2001
--- glibc-20010315/intl/tst-codeset.c Sat Apr 7 22:27:36 2001
***************
*** 0 ****
--- 1,56 ----
+ /* Test of bind_textdomain_codeset.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Bruno Haible <haible@clisp.cons.org>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. 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 <stdio.h>
+ #include <stdlib.h>
+
+ int
+ main (void)
+ {
+ char *s;
+ int result = 0;
+
+ unsetenv ("LANGUAGE");
+ unsetenv ("OUTPUT_CHARSET");
+ setlocale (LC_ALL, "de_DE.ISO-8859-1");
+ textdomain ("codeset");
+ bindtextdomain ("codeset", OBJPFX "domaindir");
+
+ /* Here we expect output in ISO-8859-1. */
+ s = gettext ("cheese");
+ if (strcmp (s, "K\344se"))
+ {
+ printf ("call 1 returned: %s\n", s);
+ result = 1;
+ }
+
+ bind_textdomain_codeset ("codeset", "UTF-8");
+
+ /* Here we expect output in UTF-8. */
+ s = gettext ("cheese");
+ if (strcmp (s, "K\303\244se"))
+ {
+ printf ("call 2 returned: %s\n", s);
+ result = 1;
+ }
+
+ return result;
+ }
*** glibc-20010315/locale/findlocale.c.bak Mon Nov 27 23:28:39 2000
--- glibc-20010315/locale/findlocale.c Sat Apr 7 22:30:29 2001
***************
*** 121,127 ****
language, territory, codeset,
normalized_codeset, modifier, special,
sponsor, revision,
! _nl_category_names[category], NULL, 0);
if (locale_file == NULL)
{
--- 121,127 ----
language, territory, codeset,
normalized_codeset, modifier, special,
sponsor, revision,
! _nl_category_names[category], 0);
if (locale_file == NULL)
{
***************
*** 132,138 ****
language, territory, codeset,
normalized_codeset, modifier, special,
sponsor, revision,
! _nl_category_names[category], NULL, 1);
if (locale_file == NULL)
/* This means we are out of core. */
return NULL;
--- 132,138 ----
language, territory, codeset,
normalized_codeset, modifier, special,
sponsor, revision,
! _nl_category_names[category], 1);
if (locale_file == NULL)
/* This means we are out of core. */
return NULL;
More information about the Libc-alpha
mailing list