diff options
author | Ulrich Drepper <drepper@redhat.com> | 2005-04-04 22:37:38 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2005-04-04 22:37:38 +0000 |
commit | 4e82c610255f6a186c20c73e74f8e71dcda98efc (patch) | |
tree | b55a3e6692a0261c576330950793bde88524e0e1 /intl/loadmsgcat.c | |
parent | 7a50b1f6d1bd959ae5dfb5539d9cd8935eb8d926 (diff) | |
download | glibc-4e82c610255f6a186c20c73e74f8e71dcda98efc.tar.gz glibc-4e82c610255f6a186c20c73e74f8e71dcda98efc.tar.xz glibc-4e82c610255f6a186c20c73e74f8e71dcda98efc.zip |
* intl/tst-gettext3.c: New file.
* intl/tst-gettext3.sh: New file. * intl/Makefile (distribute): Add tst-gettext3.sh. (test-srcs): Add tst-gettext3. (tests): Depend on tst-gettext3.out. (tst-gettext3.out): New rule. (CFLAGS-tst-gettext3.c): New variable. Fix bug exposed by tst-gettext3. * intl/gettextP.h (struct converted_domain): New type. (struct loaded_domain): Remove the conv, conv_tab fields. Add conversions, nconversions fields. (_nl_init_domain_conv): Remove declaration. (_nl_free_domain_conv): Remove declaration. (_nl_find_msg): Add convert argument. * intl/dcigettext.c (DCIGETTEXT): Call _nl_find_msg with convert=1. (_nl_find_msg): Add convert argument. When a conversion to a different charset is needed, create a new converted_domain element, instead of throwing away the old converted translations. (get_output_charset): New function. * intl/loadmsgcat.c (_nl_init_domain_conv): Remove function. (_nl_free_domain_conv): Remove function. (_nl_load_domain): Initialize the conversions array to empty. Use _nl_find_msg instead of _nl_init_domain_conv to retrieve the header entry. (_nl_unload_domain): Free the conversions array and its contents. * intl/gettextP.h (struct loaded_domain): Remove codeset_cntr field. (struct binding): Likewise. * intl/bindtextdom.c (set_binding_values): Drop codeset_cntr modifications.
Diffstat (limited to 'intl/loadmsgcat.c')
-rw-r--r-- | intl/loadmsgcat.c | 172 |
1 files changed, 23 insertions, 149 deletions
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c index efefc69a43..1f55531097 100644 --- a/intl/loadmsgcat.c +++ b/intl/loadmsgcat.c @@ -1,5 +1,5 @@ /* Load needed message catalogs. - Copyright (C) 1995-2004 Free Software Foundation, Inc. + Copyright (C) 1995-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 @@ -752,146 +752,6 @@ get_sysdep_segment_value (name) return NULL; } -/* 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, CODESET); -# else -# if HAVE_ICONV - extern const char *locale_charset PARAMS ((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, ""); - if (__gconv_open (outcharset, charset, &domain->conv, - GCONV_AVOID_NOCONV) - != __GCONV_OK) - domain->conv = (__gconv_t) -1; -# else -# if HAVE_ICONV - /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5, - we want to use transliteration. */ -# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \ - || _LIBICONV_VERSION >= 0x0105 - if (strchr (outcharset, '/') == NULL) - { - char *tmp; - - len = strlen (outcharset); - tmp = (char *) alloca (len + 10 + 1); - memcpy (tmp, outcharset, len); - memcpy (tmp + len, "//TRANSLIT", 10 + 1); - outcharset = tmp; - - domain->conv = iconv_open (outcharset, charset); - - freea (outcharset); - } - else -# endif - domain->conv = iconv_open (outcharset, charset); -# 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 @@ -913,6 +773,7 @@ _nl_load_domain (domain_file, domainbinding) struct loaded_domain *domain; int revision; const char *nullentry; + size_t nullentrylen; __libc_lock_lock_recursive (lock); if (domain_file->decided != 0) @@ -920,8 +781,8 @@ _nl_load_domain (domain_file, domainbinding) /* There are two possibilities: + is is the same thread calling again during this - initialization via _nl_init_domain_conv and _nl_find_msg. We - have initialized everything this call needs. + initialization via _nl_find_msg. We have initialized + everything this call needs. + this is another thread which tried to initialize this object. Not necessary anymore since if the lock is available this @@ -1388,12 +1249,12 @@ _nl_load_domain (domain_file, domainbinding) goto out; } - /* 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); + /* No caches of converted translations so far. */ + domain->conversions = NULL; + domain->nconversions = 0; - /* Also look for a plural specification. */ + /* Get the header entry and look for a plural specification. */ + nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen); EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals); out: @@ -1412,10 +1273,23 @@ internal_function __libc_freeres_fn_section _nl_unload_domain (domain) struct loaded_domain *domain; { + size_t i; + if (domain->plural != &__gettext_germanic_plural) __gettext_free_exp (domain->plural); - _nl_free_domain_conv (domain); + for (i = 0; i < domain->nconversions; i++) + { + struct converted_domain *convd = &domain->conversions[i]; + + free ((char *) convd->encoding); + if (convd->conv_tab != NULL && convd->conv_tab != (char **) -1) + free (convd->conv_tab); + if (convd->conv != (__gconv_t) -1) + __gconv_close (convd->conv); + } + if (domain->conversions != NULL) + free (domain->conversions); if (domain->malloced) free (domain->malloced); |