X-Git-Url: https://git.deb.at/w?a=blobdiff_plain;f=intl%2Floadmsgcat.c;h=99c51b4c5c2f69e719926ea311093738be42e563;hb=69a912c0db0ac135fff332db4f0b05ad9ed2eec6;hp=bf883a37efafd7a26977c40bd688670b1faef289;hpb=ee5170ade20748797fdde09e370fbb07e585fc9a;p=pkg%2Fabook.git diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c index bf883a3..99c51b4 100644 --- a/intl/loadmsgcat.c +++ b/intl/loadmsgcat.c @@ -1,5 +1,5 @@ /* Load needed message catalogs. - Copyright (C) 1995-1999, 2000-2008 Free Software Foundation, Inc. + Copyright (C) 1995-1999, 2000-2004 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published @@ -13,7 +13,7 @@ You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Tell glibc's to provide a prototype for mempcpy(). @@ -91,14 +91,6 @@ char *alloca (); #ifdef _LIBC # include "../locale/localeinfo.h" -# include -#endif - -/* Handle multi-threaded applications. */ -#ifdef _LIBC -# include -#else -# include "lock.h" #endif /* Provide fallback values for macros that ought to be defined in . @@ -465,12 +457,11 @@ char *alloca (); /* Rename the non ISO C functions. This is required by the standard because some ISO C functions will require linking with this object file and the name space must not be polluted. */ -# define open(name, flags) open_not_cancel_2 (name, flags) -# define close(fd) close_not_cancel_no_status (fd) -# define read(fd, buf, n) read_not_cancel (fd, buf, n) -# define mmap(addr, len, prot, flags, fd, offset) \ - __mmap (addr, len, prot, flags, fd, offset) -# define munmap(addr, len) __munmap (addr, len) +# define open __open +# define close __close +# define read __read +# define mmap __mmap +# define munmap __munmap #endif /* For those losing systems which don't have `alloca' we have to add @@ -773,6 +764,144 @@ get_sysdep_segment_value (const char *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 (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 (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 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 (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 @@ -780,8 +909,7 @@ internal_function _nl_load_domain (struct loaded_l10nfile *domain_file, struct binding *domainbinding) { - __libc_lock_define_initialized_recursive (static, lock) - int fd = -1; + int fd; size_t size; #ifdef _LIBC struct stat64 st; @@ -793,24 +921,8 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, struct loaded_domain *domain; int revision; const char *nullentry; - size_t nullentrylen; - - __libc_lock_lock_recursive (lock); - if (domain_file->decided != 0) - { - /* There are two possibilities: - - + this is the same thread calling again during this 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 - is finished. - */ - goto done; - } - - domain_file->decided = -1; + domain_file->decided = 1; domain_file->data = NULL; /* Note that it would be useless to store domainbinding in domain_file @@ -822,12 +934,12 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, specification the locale file name is different for XPG and CEN syntax. */ if (domain_file->filename == NULL) - goto out; + return; /* Try to open the addressed file. */ fd = open (domain_file->filename, O_RDONLY | O_BINARY); if (fd == -1) - goto out; + return; /* We must know about the size of the file. */ if ( @@ -838,8 +950,11 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, #endif || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0) || __builtin_expect (size < sizeof (struct mo_file_header), 0)) - /* Something went wrong. */ - goto out; + { + /* Something went wrong. */ + close (fd); + return; + } #ifdef HAVE_MMAP /* Now we are ready to load the file. If mmap() is available we try @@ -851,7 +966,6 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, { /* mmap() call was successful. */ close (fd); - fd = -1; use_mmap = 1; } #endif @@ -865,7 +979,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, data = (struct mo_file_header *) malloc (size); if (data == NULL) - goto out; + return; to_read = size; read_ptr = (char *) data; @@ -878,7 +992,8 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, if (nb == -1 && errno == EINTR) continue; #endif - goto out; + close (fd); + return; } read_ptr += nb; to_read -= nb; @@ -886,7 +1001,6 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, while (to_read > 0); close (fd); - fd = -1; } /* Using the magic number we can test whether it really is a message @@ -901,12 +1015,12 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, else #endif free (data); - goto out; + return; } domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain)); if (domain == NULL) - goto out; + return; domain_file->data = domain; domain->data = (char *) data; @@ -976,7 +1090,6 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, ((char *) data + W (domain->must_swap, data->sysdep_segments_offset)); sysdep_segment_values = - (const char **) alloca (n_sysdep_segments * sizeof (const char *)); for (i = 0; i < n_sysdep_segments; i++) { @@ -1208,7 +1321,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, for (i = 0; i < n_inmem_sysdep_strings; i++) { const char *msgid = inmem_orig_sysdep_tab[i].pointer; - nls_uint32 hash_val = __hash_string (msgid); + nls_uint32 hash_val = hash_string (msgid); nls_uint32 idx = hash_val % domain->hash_size; nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); @@ -1259,7 +1372,8 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, /* This is an invalid revision. */ invalid: /* This is an invalid .mo file. */ - free (domain->malloced); + if (domain->malloced) + free (domain->malloced); #ifdef HAVE_MMAP if (use_mmap) munmap ((caddr_t) data, size); @@ -1268,58 +1382,31 @@ _nl_load_domain (struct loaded_l10nfile *domain_file, free (data); free (domain); domain_file->data = NULL; - goto out; + return; } - /* No caches of converted translations so far. */ - domain->conversions = NULL; - domain->nconversions = 0; - gl_rwlock_init (domain->conversions_lock); + /* 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); - /* Get the header entry and look for a plural specification. */ -#ifdef IN_LIBGLOCALE - nullentry = - _nl_find_msg (domain_file, domainbinding, NULL, "", &nullentrylen); -#else - nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen); -#endif + /* Also look for a plural specification. */ EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals); - - out: - if (fd != -1) - close (fd); - - domain_file->decided = 1; - - done: - __libc_lock_unlock_recursive (lock); } #ifdef _LIBC void -internal_function __libc_freeres_fn_section +internal_function _nl_unload_domain (struct loaded_domain *domain) { - size_t i; - if (domain->plural != &__gettext_germanic_plural) - __gettext_free_exp ((struct expression *) domain->plural); - - for (i = 0; i < domain->nconversions; i++) - { - struct converted_domain *convd = &domain->conversions[i]; + __gettext_free_exp (domain->plural); - free (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); - } - free (domain->conversions); - __libc_rwlock_fini (domain->conversions_lock); + _nl_free_domain_conv (domain); - free (domain->malloced); + if (domain->malloced) + free (domain->malloced); # ifdef _POSIX_MAPPED_FILES if (domain->use_mmap)