aboutsummaryrefslogtreecommitdiffstats
path: root/intl/loadmsgcat.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2006-11-21 11:00:14 +0000
committerWerner Koch <[email protected]>2006-11-21 11:00:14 +0000
commite50c5f39cc2ea399eead30ef451d7d5e24c13fe6 (patch)
tree37f73eb8abf85a3a6505a5a7c30b1e4c8e8d85d5 /intl/loadmsgcat.c
parentMade some PIN pads work. (diff)
downloadgnupg-e50c5f39cc2ea399eead30ef451d7d5e24c13fe6.tar.gz
gnupg-e50c5f39cc2ea399eead30ef451d7d5e24c13fe6.zip
No more warnings for AMD64 (at least when cross-compiling). Thus tehre is a
good chance that gpg2 will now work. Other cleanups. Updated gettext.
Diffstat (limited to 'intl/loadmsgcat.c')
-rw-r--r--intl/loadmsgcat.c249
1 files changed, 81 insertions, 168 deletions
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
index 99c51b4c5..2520c8c21 100644
--- a/intl/loadmsgcat.c
+++ b/intl/loadmsgcat.c
@@ -1,5 +1,5 @@
/* Load needed message catalogs.
- Copyright (C) 1995-1999, 2000-2004 Free Software Foundation, Inc.
+ Copyright (C) 1995-1999, 2000-2005 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA. */
/* Tell glibc's <string.h> to provide a prototype for mempcpy().
@@ -91,6 +91,14 @@ char *alloca ();
#ifdef _LIBC
# include "../locale/localeinfo.h"
+# include <not-cancel.h>
+#endif
+
+/* Handle multi-threaded applications. */
+#ifdef _LIBC
+# include <bits/libc-lock.h>
+#else
+# include "lock.h"
#endif
/* Provide fallback values for macros that ought to be defined in <inttypes.h>.
@@ -457,11 +465,12 @@ 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 __open
-# define close __close
-# define read __read
-# define mmap __mmap
-# define munmap __munmap
+# 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)
#endif
/* For those losing systems which don't have `alloca' we have to add
@@ -764,144 +773,6 @@ 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
@@ -909,7 +780,8 @@ internal_function
_nl_load_domain (struct loaded_l10nfile *domain_file,
struct binding *domainbinding)
{
- int fd;
+ __libc_lock_define_initialized_recursive (static, lock)
+ int fd = -1;
size_t size;
#ifdef _LIBC
struct stat64 st;
@@ -921,8 +793,24 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
struct loaded_domain *domain;
int revision;
const char *nullentry;
+ size_t nullentrylen;
- domain_file->decided = 1;
+ __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->data = NULL;
/* Note that it would be useless to store domainbinding in domain_file
@@ -934,12 +822,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)
- return;
+ goto out;
/* Try to open the addressed file. */
fd = open (domain_file->filename, O_RDONLY | O_BINARY);
if (fd == -1)
- return;
+ goto out;
/* We must know about the size of the file. */
if (
@@ -950,11 +838,8 @@ _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. */
- close (fd);
- return;
- }
+ /* Something went wrong. */
+ goto out;
#ifdef HAVE_MMAP
/* Now we are ready to load the file. If mmap() is available we try
@@ -966,6 +851,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
{
/* mmap() call was successful. */
close (fd);
+ fd = -1;
use_mmap = 1;
}
#endif
@@ -979,7 +865,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
data = (struct mo_file_header *) malloc (size);
if (data == NULL)
- return;
+ goto out;
to_read = size;
read_ptr = (char *) data;
@@ -992,8 +878,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
if (nb == -1 && errno == EINTR)
continue;
#endif
- close (fd);
- return;
+ goto out;
}
read_ptr += nb;
to_read -= nb;
@@ -1001,6 +886,7 @@ _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
@@ -1015,12 +901,12 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
else
#endif
free (data);
- return;
+ goto out;
}
domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
if (domain == NULL)
- return;
+ goto out;
domain_file->data = domain;
domain->data = (char *) data;
@@ -1321,7 +1207,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));
@@ -1382,28 +1268,55 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
free (data);
free (domain);
domain_file->data = NULL;
- return;
+ 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. */
+#ifdef IN_LIBGLOCALE
+ nullentry =
+ _nl_find_msg (domain_file, domainbinding, NULL, "", &nullentrylen);
+#else
+ nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
+#endif
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
+internal_function __libc_freeres_fn_section
_nl_unload_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 (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);