mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
gettext: Upgrade to version 0.18
* configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.18. * po/Makefile.in.in: Upgrade to gettext-0.18. Keep option --previous of msgmerge. * intl/: Upgrade to gettext-0.18. * m4/gettext.m4: Upgrade to gettext-0.18.1. * m4/iconv.m4: Upgrade to gettext-0.18.1. * m4/lib-ld.m4: Upgrade to gettext-0.18.1. * m4/lib-link.m4: Upgrade to gettext-0.18.1. * m4/lib-prefix.m4: Upgrade to gettext-0.18.1. * m4/nls.m4: Upgrade to gettext-0.18.1. * m4/po.m4: Upgrade to gettext-0.18.1. * m4/progtest.m4: Upgrade to gettext-0.18.1. * m4/codeset.m4: Upgrade to gettext-0.18.1. * m4/fcntl-o.m4: New file, from gettext-0.18.1. * m4/glibc2.m4: Upgrade to gettext-0.18.1. * m4/glibc21.m4: Upgrade to gettext-0.18.1. * m4/intdiv0.m4: Upgrade to gettext-0.18.1. * m4/intl.m4: Upgrade to gettext-0.18.1. * m4/intldir.m4: Upgrade to gettext-0.18.1. * m4/intlmacosx.m4: Upgrade to gettext-0.18.1. * m4/intmax.m4: Upgrade to gettext-0.18.1. * m4/inttypes_h.m4: Upgrade to gettext-0.18.1. * m4/inttypes-pri.m4: Upgrade to gettext-0.18.1. * m4/lcmessage.m4: Upgrade to gettext-0.18.1. * m4/lock.m4: Upgrade to gettext-0.18.1. * m4/longlong.m4: Upgrade to gettext-0.18.1. * m4/printf-posix.m4: Upgrade to gettext-0.18.1. * m4/size_max.m4: Upgrade to gettext-0.18.1. * m4/stdint_h.m4: Upgrade to gettext-0.18.1. * m4/threadlib.m4: New file, from gettext-0.18.1. * m4/uintmax_t.m4: Upgrade to gettext-0.18.1. * m4/visibility.m4: Upgrade to gettext-0.18.1. * m4/wchar_t.m4: Upgrade to gettext-0.18.1. * m4/wint_t.m4: Upgrade to gettext-0.18.1. * m4/xsize.m4: Upgrade to gettext-0.18.1. * m4/Makefile.am (EXTRA_DIST): Add the new files.
This commit is contained in:
parent
0fee571260
commit
4032aa8be8
85 changed files with 16677 additions and 6457 deletions
|
@ -1,5 +1,5 @@
|
|||
/* Implementation of the internal dcigettext function.
|
||||
Copyright (C) 1995-1999, 2000-2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1999, 2000-2009 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
|
||||
|
@ -27,9 +27,6 @@
|
|||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* NL_LOCALE_NAME does not work in glibc-2.4. Ignore it. */
|
||||
#undef HAVE_NL_LOCALE_NAME
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
@ -90,8 +87,8 @@ extern int errno;
|
|||
# include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#if !defined _LIBC && HAVE_NL_LOCALE_NAME
|
||||
# include <langinfo.h>
|
||||
#if !defined _LIBC
|
||||
# include "localcharset.h"
|
||||
#endif
|
||||
|
||||
#include "gettextP.h"
|
||||
|
@ -125,16 +122,6 @@ extern int errno;
|
|||
((int) &((struct { char dummy1; TYPE dummy2; } *) 0)->dummy2)
|
||||
#endif
|
||||
|
||||
/* The internal variables in the standalone libintl.a must have different
|
||||
names than the internal variables in GNU libc, otherwise programs
|
||||
using libintl.a cannot be linked statically. */
|
||||
#if !defined _LIBC
|
||||
# define _nl_default_default_domain libintl_nl_default_default_domain
|
||||
# define _nl_current_default_domain libintl_nl_current_default_domain
|
||||
# define _nl_default_dirname libintl_nl_default_dirname
|
||||
# define _nl_domain_bindings libintl_nl_domain_bindings
|
||||
#endif
|
||||
|
||||
/* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */
|
||||
#ifndef offsetof
|
||||
# define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
|
||||
|
@ -170,6 +157,22 @@ static void *mempcpy (void *dest, const void *src, size_t n);
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* Use a replacement if the system does not provide the `tsearch' function
|
||||
family. */
|
||||
#if HAVE_TSEARCH || defined _LIBC
|
||||
# include <search.h>
|
||||
#else
|
||||
# define tsearch libintl_tsearch
|
||||
# define tfind libintl_tfind
|
||||
# define tdelete libintl_tdelete
|
||||
# define twalk libintl_twalk
|
||||
# include "tsearch.h"
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
# define tsearch __tsearch
|
||||
#endif
|
||||
|
||||
/* Amount to increase buffer size by in each try. */
|
||||
#define PATH_INCR 32
|
||||
|
||||
|
@ -225,7 +228,7 @@ static void *mempcpy (void *dest, const void *src, size_t n);
|
|||
#endif
|
||||
|
||||
/* Whether to support different locales in different threads. */
|
||||
#if defined _LIBC || HAVE_NL_LOCALE_NAME || (HAVE_STRUCT___LOCALE_STRUCT___NAMES && defined USE_IN_GETTEXT_TESTS) || defined IN_LIBGLOCALE
|
||||
#if defined _LIBC || HAVE_USELOCALE || defined IN_LIBGLOCALE
|
||||
# define HAVE_PER_THREAD_LOCALE
|
||||
#endif
|
||||
|
||||
|
@ -260,22 +263,19 @@ struct known_translation_t
|
|||
size_t translation_length;
|
||||
|
||||
/* Pointer to the string in question. */
|
||||
char msgid[ZERO];
|
||||
union
|
||||
{
|
||||
char appended[ZERO]; /* used if domain != NULL */
|
||||
const char *ptr; /* used if domain == NULL */
|
||||
}
|
||||
msgid;
|
||||
};
|
||||
|
||||
/* Root of the search tree with known translations. We can use this
|
||||
only if the system provides the `tsearch' function family. */
|
||||
#if defined HAVE_TSEARCH || defined _LIBC
|
||||
# include <search.h>
|
||||
|
||||
gl_rwlock_define_initialized (static, tree_lock)
|
||||
|
||||
/* Root of the search tree with known translations. */
|
||||
static void *root;
|
||||
|
||||
# ifdef _LIBC
|
||||
# define tsearch __tsearch
|
||||
# endif
|
||||
|
||||
/* Function to compare two entries in the table of known translations. */
|
||||
static int
|
||||
transcmp (const void *p1, const void *p2)
|
||||
|
@ -287,7 +287,8 @@ transcmp (const void *p1, const void *p2)
|
|||
s1 = (const struct known_translation_t *) p1;
|
||||
s2 = (const struct known_translation_t *) p2;
|
||||
|
||||
result = strcmp (s1->msgid, s2->msgid);
|
||||
result = strcmp (s1->domain != NULL ? s1->msgid.appended : s1->msgid.ptr,
|
||||
s2->domain != NULL ? s2->msgid.appended : s2->msgid.ptr);
|
||||
if (result == 0)
|
||||
{
|
||||
result = strcmp (s1->domainname, s2->domainname);
|
||||
|
@ -312,7 +313,6 @@ transcmp (const void *p1, const void *p2)
|
|||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Name of the default domain used for gettext(3) prior any call to
|
||||
textdomain(3). The default value for this is "messages". */
|
||||
|
@ -501,13 +501,10 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
char *retval;
|
||||
size_t retlen;
|
||||
int saved_errno;
|
||||
#if defined HAVE_TSEARCH || defined _LIBC
|
||||
struct known_translation_t *search;
|
||||
struct known_translation_t search;
|
||||
struct known_translation_t **foundp = NULL;
|
||||
size_t msgid_len;
|
||||
# if defined HAVE_PER_THREAD_LOCALE && !defined IN_LIBGLOCALE
|
||||
#if defined HAVE_PER_THREAD_LOCALE && !defined IN_LIBGLOCALE
|
||||
const char *localename;
|
||||
# endif
|
||||
#endif
|
||||
size_t domainname_len;
|
||||
|
||||
|
@ -524,6 +521,14 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
: n == 1 ? (char *) msgid1 : (char *) msgid2);
|
||||
#endif
|
||||
|
||||
/* Preserve the `errno' value. */
|
||||
saved_errno = errno;
|
||||
|
||||
#ifdef _LIBC
|
||||
__libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
|
||||
__libc_rwlock_rdlock (__libc_setlocale_lock);
|
||||
#endif
|
||||
|
||||
gl_rwlock_rdlock (_nl_state_lock);
|
||||
|
||||
/* If DOMAINNAME is NULL, we are interested in the default domain. If
|
||||
|
@ -538,54 +543,37 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
category = LC_MESSAGES;
|
||||
#endif
|
||||
|
||||
#if defined HAVE_TSEARCH || defined _LIBC
|
||||
msgid_len = strlen (msgid1) + 1;
|
||||
|
||||
/* Try to find the translation among those which we found at
|
||||
some time. */
|
||||
search = (struct known_translation_t *)
|
||||
alloca (offsetof (struct known_translation_t, msgid) + msgid_len);
|
||||
memcpy (search->msgid, msgid1, msgid_len);
|
||||
search->domainname = domainname;
|
||||
search->category = category;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
# ifndef IN_LIBGLOCALE
|
||||
# ifdef _LIBC
|
||||
localename = __current_locale_name (category);
|
||||
# else
|
||||
# if HAVE_NL_LOCALE_NAME
|
||||
/* NL_LOCALE_NAME is public glibc API introduced in glibc-2.4. */
|
||||
localename = nl_langinfo (NL_LOCALE_NAME (category));
|
||||
# else
|
||||
# if HAVE_STRUCT___LOCALE_STRUCT___NAMES && defined USE_IN_GETTEXT_TESTS
|
||||
/* The __names field is not public glibc API and must therefore not be used
|
||||
in code that is installed in public locations. */
|
||||
{
|
||||
locale_t thread_locale = uselocale (NULL);
|
||||
if (thread_locale != LC_GLOBAL_LOCALE)
|
||||
localename = thread_locale->__names[category];
|
||||
else
|
||||
localename = "";
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
search->localename = localename;
|
||||
# ifdef IN_LIBGLOCALE
|
||||
search->encoding = encoding;
|
||||
search.domain = NULL;
|
||||
search.msgid.ptr = msgid1;
|
||||
search.domainname = domainname;
|
||||
search.category = category;
|
||||
#ifdef HAVE_PER_THREAD_LOCALE
|
||||
# ifndef IN_LIBGLOCALE
|
||||
# ifdef _LIBC
|
||||
localename = _strdupa (_current_locale_name (category));
|
||||
# else
|
||||
categoryname = category_to_name (category);
|
||||
# define CATEGORYNAME_INITIALIZED
|
||||
localename = _nl_locale_name_thread_unsafe (category, categoryname);
|
||||
if (localename == NULL)
|
||||
localename = "";
|
||||
# endif
|
||||
# endif
|
||||
search.localename = localename;
|
||||
# ifdef IN_LIBGLOCALE
|
||||
search.encoding = encoding;
|
||||
# endif
|
||||
|
||||
/* Since tfind/tsearch manage a balanced tree, concurrent tfind and
|
||||
tsearch calls can be fatal. */
|
||||
gl_rwlock_rdlock (tree_lock);
|
||||
|
||||
foundp = (struct known_translation_t **) tfind (search, &root, transcmp);
|
||||
foundp = (struct known_translation_t **) tfind (&search, &root, transcmp);
|
||||
|
||||
gl_rwlock_unlock (tree_lock);
|
||||
|
||||
freea (search);
|
||||
if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr)
|
||||
{
|
||||
/* Now deal with plural. */
|
||||
|
@ -596,13 +584,14 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
retval = (char *) (*foundp)->translation;
|
||||
|
||||
gl_rwlock_unlock (_nl_state_lock);
|
||||
# ifdef _LIBC
|
||||
__libc_rwlock_unlock (__libc_setlocale_lock);
|
||||
# endif
|
||||
__set_errno (saved_errno);
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Preserve the `errno' value. */
|
||||
saved_errno = errno;
|
||||
|
||||
/* See whether this is a SUID binary or not. */
|
||||
DETERMINE_SECURE;
|
||||
|
||||
|
@ -671,7 +660,9 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
#endif
|
||||
|
||||
/* Now determine the symbolic name of CATEGORY and its value. */
|
||||
#ifndef CATEGORYNAME_INITIALIZED
|
||||
categoryname = category_to_name (category);
|
||||
#endif
|
||||
#ifdef IN_LIBGLOCALE
|
||||
categoryvalue = guess_category_value (category, categoryname, localename);
|
||||
#else
|
||||
|
@ -683,8 +674,8 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
+ domainname_len + 5);
|
||||
ADD_BLOCK (block_list, xdomainname);
|
||||
|
||||
stpcpy (mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
|
||||
domainname, domainname_len),
|
||||
stpcpy ((char *) mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
|
||||
domainname, domainname_len),
|
||||
".mo");
|
||||
|
||||
/* Creating working area. */
|
||||
|
@ -773,40 +764,43 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
/* Found the translation of MSGID1 in domain DOMAIN:
|
||||
starting at RETVAL, RETLEN bytes. */
|
||||
FREE_BLOCKS (block_list);
|
||||
#if defined HAVE_TSEARCH || defined _LIBC
|
||||
if (foundp == NULL)
|
||||
{
|
||||
/* Create a new entry and add it to the search tree. */
|
||||
size_t msgid_len;
|
||||
size_t size;
|
||||
struct known_translation_t *newp;
|
||||
|
||||
msgid_len = strlen (msgid1) + 1;
|
||||
size = offsetof (struct known_translation_t, msgid)
|
||||
+ msgid_len + domainname_len + 1;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
#ifdef HAVE_PER_THREAD_LOCALE
|
||||
size += strlen (localename) + 1;
|
||||
# endif
|
||||
#endif
|
||||
newp = (struct known_translation_t *) malloc (size);
|
||||
if (newp != NULL)
|
||||
{
|
||||
char *new_domainname;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
#ifdef HAVE_PER_THREAD_LOCALE
|
||||
char *new_localename;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
new_domainname = mempcpy (newp->msgid, msgid1, msgid_len);
|
||||
new_domainname =
|
||||
(char *) mempcpy (newp->msgid.appended, msgid1,
|
||||
msgid_len);
|
||||
memcpy (new_domainname, domainname, domainname_len + 1);
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
#ifdef HAVE_PER_THREAD_LOCALE
|
||||
new_localename = new_domainname + domainname_len + 1;
|
||||
strcpy (new_localename, localename);
|
||||
# endif
|
||||
#endif
|
||||
newp->domainname = new_domainname;
|
||||
newp->category = category;
|
||||
# ifdef HAVE_PER_THREAD_LOCALE
|
||||
#ifdef HAVE_PER_THREAD_LOCALE
|
||||
newp->localename = new_localename;
|
||||
# endif
|
||||
# ifdef IN_LIBGLOCALE
|
||||
#endif
|
||||
#ifdef IN_LIBGLOCALE
|
||||
newp->encoding = encoding;
|
||||
# endif
|
||||
#endif
|
||||
newp->counter = _nl_msg_cat_cntr;
|
||||
newp->domain = domain;
|
||||
newp->translation = retval;
|
||||
|
@ -834,7 +828,7 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
(*foundp)->translation = retval;
|
||||
(*foundp)->translation_length = retlen;
|
||||
}
|
||||
#endif
|
||||
|
||||
__set_errno (saved_errno);
|
||||
|
||||
/* Now deal with plural. */
|
||||
|
@ -842,6 +836,9 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
retval = plural_lookup (domain, n, retval, retlen);
|
||||
|
||||
gl_rwlock_unlock (_nl_state_lock);
|
||||
#ifdef _LIBC
|
||||
__libc_rwlock_unlock (__libc_setlocale_lock);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
@ -851,6 +848,9 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
|
|||
/* Return the untranslated MSGID. */
|
||||
FREE_BLOCKS (block_list);
|
||||
gl_rwlock_unlock (_nl_state_lock);
|
||||
#ifdef _LIBC
|
||||
__libc_rwlock_unlock (__libc_setlocale_lock);
|
||||
#endif
|
||||
#ifndef _LIBC
|
||||
if (!ENABLE_SECURE)
|
||||
{
|
||||
|
@ -1005,12 +1005,17 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
|
|||
# ifndef IN_LIBGLOCALE
|
||||
const char *encoding = get_output_charset (domainbinding);
|
||||
# endif
|
||||
size_t nconversions;
|
||||
struct converted_domain *convd;
|
||||
size_t i;
|
||||
|
||||
/* Protect against reallocation of the table. */
|
||||
gl_rwlock_rdlock (domain->conversions_lock);
|
||||
|
||||
/* Search whether a table with converted translations for this
|
||||
encoding has already been allocated. */
|
||||
size_t nconversions = domain->nconversions;
|
||||
struct converted_domain *convd = NULL;
|
||||
size_t i;
|
||||
nconversions = domain->nconversions;
|
||||
convd = NULL;
|
||||
|
||||
for (i = nconversions; i > 0; )
|
||||
{
|
||||
|
@ -1022,134 +1027,165 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
|
|||
}
|
||||
}
|
||||
|
||||
gl_rwlock_unlock (domain->conversions_lock);
|
||||
|
||||
if (convd == NULL)
|
||||
{
|
||||
/* Allocate a table for the converted translations for this
|
||||
encoding. */
|
||||
struct converted_domain *new_conversions =
|
||||
(struct converted_domain *)
|
||||
(domain->conversions != NULL
|
||||
? realloc (domain->conversions,
|
||||
(nconversions + 1) * sizeof (struct converted_domain))
|
||||
: malloc ((nconversions + 1) * sizeof (struct converted_domain)));
|
||||
/* We have to allocate a new conversions table. */
|
||||
gl_rwlock_wrlock (domain->conversions_lock);
|
||||
nconversions = domain->nconversions;
|
||||
|
||||
if (__builtin_expect (new_conversions == NULL, 0))
|
||||
/* Nothing we can do, no more memory. We cannot use the
|
||||
translation because it might be encoded incorrectly. */
|
||||
return (char *) -1;
|
||||
/* Maybe in the meantime somebody added the translation.
|
||||
Recheck. */
|
||||
for (i = nconversions; i > 0; )
|
||||
{
|
||||
i--;
|
||||
if (strcmp (domain->conversions[i].encoding, encoding) == 0)
|
||||
{
|
||||
convd = &domain->conversions[i];
|
||||
goto found_convd;
|
||||
}
|
||||
}
|
||||
|
||||
domain->conversions = new_conversions;
|
||||
{
|
||||
/* Allocate a table for the converted translations for this
|
||||
encoding. */
|
||||
struct converted_domain *new_conversions =
|
||||
(struct converted_domain *)
|
||||
(domain->conversions != NULL
|
||||
? realloc (domain->conversions,
|
||||
(nconversions + 1) * sizeof (struct converted_domain))
|
||||
: malloc ((nconversions + 1) * sizeof (struct converted_domain)));
|
||||
|
||||
/* Copy the 'encoding' string to permanent storage. */
|
||||
encoding = strdup (encoding);
|
||||
if (__builtin_expect (encoding == NULL, 0))
|
||||
/* Nothing we can do, no more memory. We cannot use the
|
||||
translation because it might be encoded incorrectly. */
|
||||
return (char *) -1;
|
||||
if (__builtin_expect (new_conversions == NULL, 0))
|
||||
{
|
||||
/* Nothing we can do, no more memory. We cannot use the
|
||||
translation because it might be encoded incorrectly. */
|
||||
unlock_fail:
|
||||
gl_rwlock_unlock (domain->conversions_lock);
|
||||
return (char *) -1;
|
||||
}
|
||||
|
||||
convd = &new_conversions[nconversions];
|
||||
convd->encoding = encoding;
|
||||
domain->conversions = new_conversions;
|
||||
|
||||
/* 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. */
|
||||
/* Copy the 'encoding' string to permanent storage. */
|
||||
encoding = strdup (encoding);
|
||||
if (__builtin_expect (encoding == NULL, 0))
|
||||
/* Nothing we can do, no more memory. We cannot use the
|
||||
translation because it might be encoded incorrectly. */
|
||||
goto unlock_fail;
|
||||
|
||||
convd = &new_conversions[nconversions];
|
||||
convd->encoding = encoding;
|
||||
|
||||
/* 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
|
||||
convd->conv = (__gconv_t) -1;
|
||||
convd->conv = (__gconv_t) -1;
|
||||
# else
|
||||
# if HAVE_ICONV
|
||||
convd->conv = (iconv_t) -1;
|
||||
convd->conv = (iconv_t) -1;
|
||||
# endif
|
||||
# endif
|
||||
{
|
||||
char *nullentry;
|
||||
size_t nullentrylen;
|
||||
{
|
||||
char *nullentry;
|
||||
size_t nullentrylen;
|
||||
|
||||
/* Get the header entry. This is a recursion, but it doesn't
|
||||
reallocate domain->conversions because we pass
|
||||
encoding = NULL or convert = 0, respectively. */
|
||||
nullentry =
|
||||
/* Get the header entry. This is a recursion, but it doesn't
|
||||
reallocate domain->conversions because we pass
|
||||
encoding = NULL or convert = 0, respectively. */
|
||||
nullentry =
|
||||
# ifdef IN_LIBGLOCALE
|
||||
_nl_find_msg (domain_file, domainbinding, NULL, "",
|
||||
&nullentrylen);
|
||||
_nl_find_msg (domain_file, domainbinding, NULL, "",
|
||||
&nullentrylen);
|
||||
# else
|
||||
_nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
|
||||
_nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
|
||||
# endif
|
||||
|
||||
if (nullentry != NULL)
|
||||
{
|
||||
const char *charsetstr;
|
||||
if (nullentry != NULL)
|
||||
{
|
||||
const char *charsetstr;
|
||||
|
||||
charsetstr = strstr (nullentry, "charset=");
|
||||
if (charsetstr != NULL)
|
||||
{
|
||||
size_t len;
|
||||
char *charset;
|
||||
const char *outcharset;
|
||||
charsetstr = strstr (nullentry, "charset=");
|
||||
if (charsetstr != NULL)
|
||||
{
|
||||
size_t len;
|
||||
char *charset;
|
||||
const char *outcharset;
|
||||
|
||||
charsetstr += strlen ("charset=");
|
||||
len = strcspn (charsetstr, " \t\n");
|
||||
charsetstr += strlen ("charset=");
|
||||
len = strcspn (charsetstr, " \t\n");
|
||||
|
||||
charset = (char *) alloca (len + 1);
|
||||
charset = (char *) alloca (len + 1);
|
||||
# if defined _LIBC || HAVE_MEMPCPY
|
||||
*((char *) mempcpy (charset, charsetstr, len)) = '\0';
|
||||
*((char *) mempcpy (charset, charsetstr, len)) = '\0';
|
||||
# else
|
||||
memcpy (charset, charsetstr, len);
|
||||
charset[len] = '\0';
|
||||
memcpy (charset, charsetstr, len);
|
||||
charset[len] = '\0';
|
||||
# endif
|
||||
|
||||
outcharset = encoding;
|
||||
outcharset = encoding;
|
||||
|
||||
# ifdef _LIBC
|
||||
/* We always want to use transliteration. */
|
||||
outcharset = norm_add_slashes (outcharset, "TRANSLIT");
|
||||
charset = norm_add_slashes (charset, "");
|
||||
int r = __gconv_open (outcharset, charset, &convd->conv,
|
||||
GCONV_AVOID_NOCONV);
|
||||
if (__builtin_expect (r != __GCONV_OK, 0))
|
||||
{
|
||||
/* If the output encoding is the same there is
|
||||
nothing to do. Otherwise do not use the
|
||||
translation at all. */
|
||||
if (__builtin_expect (r != __GCONV_NOCONV, 1))
|
||||
return NULL;
|
||||
/* We always want to use transliteration. */
|
||||
outcharset = norm_add_slashes (outcharset, "TRANSLIT");
|
||||
charset = norm_add_slashes (charset, "");
|
||||
int r = __gconv_open (outcharset, charset, &convd->conv,
|
||||
GCONV_AVOID_NOCONV);
|
||||
if (__builtin_expect (r != __GCONV_OK, 0))
|
||||
{
|
||||
/* If the output encoding is the same there is
|
||||
nothing to do. Otherwise do not use the
|
||||
translation at all. */
|
||||
if (__builtin_expect (r != __GCONV_NULCONV, 1))
|
||||
{
|
||||
gl_rwlock_unlock (domain->conversions_lock);
|
||||
free ((char *) encoding);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
convd->conv = (__gconv_t) -1;
|
||||
}
|
||||
convd->conv = (__gconv_t) -1;
|
||||
}
|
||||
# else
|
||||
# if HAVE_ICONV
|
||||
/* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
|
||||
we want to use transliteration. */
|
||||
/* 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;
|
||||
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;
|
||||
len = strlen (outcharset);
|
||||
tmp = (char *) alloca (len + 10 + 1);
|
||||
memcpy (tmp, outcharset, len);
|
||||
memcpy (tmp + len, "//TRANSLIT", 10 + 1);
|
||||
outcharset = tmp;
|
||||
|
||||
convd->conv = iconv_open (outcharset, charset);
|
||||
convd->conv = iconv_open (outcharset, charset);
|
||||
|
||||
freea (outcharset);
|
||||
}
|
||||
else
|
||||
freea (outcharset);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
convd->conv = iconv_open (outcharset, charset);
|
||||
convd->conv = iconv_open (outcharset, charset);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
freea (charset);
|
||||
}
|
||||
}
|
||||
freea (charset);
|
||||
}
|
||||
}
|
||||
}
|
||||
convd->conv_tab = NULL;
|
||||
/* Here domain->conversions is still == new_conversions. */
|
||||
domain->nconversions++;
|
||||
}
|
||||
convd->conv_tab = NULL;
|
||||
/* Here domain->conversions is still == new_conversions. */
|
||||
domain->nconversions++;
|
||||
|
||||
found_convd:
|
||||
gl_rwlock_unlock (domain->conversions_lock);
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -1171,13 +1207,29 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
|
|||
handle this case by converting RESULTLEN bytes, including
|
||||
NULs. */
|
||||
|
||||
if (convd->conv_tab == NULL
|
||||
&& ((convd->conv_tab =
|
||||
/* This lock primarily protects the memory management variables
|
||||
freemem, freemem_size. It also protects write accesses to
|
||||
convd->conv_tab. It's not worth using a separate lock (such
|
||||
as domain->conversions_lock) for this purpose, because when
|
||||
modifying convd->conv_tab, we also need to lock freemem,
|
||||
freemem_size for most of the time. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
if (__builtin_expect (convd->conv_tab == NULL, 0))
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
if (convd->conv_tab == NULL)
|
||||
{
|
||||
convd->conv_tab =
|
||||
(char **) calloc (nstrings + domain->n_sysdep_strings,
|
||||
sizeof (char *)))
|
||||
== NULL))
|
||||
/* Mark that we didn't succeed allocating a table. */
|
||||
convd->conv_tab = (char **) -1;
|
||||
sizeof (char *));
|
||||
if (convd->conv_tab != NULL)
|
||||
goto not_translated_yet;
|
||||
/* Mark that we didn't succeed allocating a table. */
|
||||
convd->conv_tab = (char **) -1;
|
||||
}
|
||||
__libc_lock_unlock (lock);
|
||||
}
|
||||
|
||||
if (__builtin_expect (convd->conv_tab == (char **) -1, 0))
|
||||
/* Nothing we can do, no more memory. We cannot use the
|
||||
|
@ -1191,7 +1243,6 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
|
|||
/* We use a bit more efficient memory handling.
|
||||
We allocate always larger blocks which get used over
|
||||
time. This is faster than many small allocations. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
# define INITIAL_BLOCK_SIZE 4080
|
||||
static unsigned char *freemem;
|
||||
static size_t freemem_size;
|
||||
|
@ -1200,13 +1251,17 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
|
|||
unsigned char *outbuf;
|
||||
int malloc_count;
|
||||
# ifndef _LIBC
|
||||
transmem_block_t *transmem_list = NULL;
|
||||
transmem_block_t *transmem_list;
|
||||
# endif
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
not_translated_yet:
|
||||
|
||||
inbuf = (const unsigned char *) result;
|
||||
outbuf = freemem + sizeof (size_t);
|
||||
# ifndef _LIBC
|
||||
transmem_list = NULL;
|
||||
# endif
|
||||
|
||||
malloc_count = 0;
|
||||
while (1)
|
||||
|
@ -1483,20 +1538,13 @@ guess_category_value (int category, const char *categoryname)
|
|||
# ifdef _LIBC
|
||||
locale = __current_locale_name (category);
|
||||
# else
|
||||
# if HAVE_STRUCT___LOCALE_STRUCT___NAMES && defined USE_IN_GETTEXT_TESTS
|
||||
/* The __names field is not public glibc API and must therefore not be used
|
||||
in code that is installed in public locations. */
|
||||
locale_t thread_locale = uselocale (NULL);
|
||||
if (thread_locale != LC_GLOBAL_LOCALE)
|
||||
{
|
||||
locale = thread_locale->__names[category];
|
||||
locale_defaulted = 0;
|
||||
}
|
||||
else
|
||||
locale_defaulted = 0;
|
||||
# if HAVE_USELOCALE
|
||||
locale = _nl_locale_name_thread_unsafe (category, categoryname);
|
||||
if (locale == NULL)
|
||||
# endif
|
||||
{
|
||||
locale = _nl_locale_name_posix (category, categoryname);
|
||||
locale_defaulted = 0;
|
||||
if (locale == NULL)
|
||||
{
|
||||
locale = _nl_locale_name_default ();
|
||||
|
@ -1584,7 +1632,6 @@ get_output_charset (struct binding *domainbinding)
|
|||
return _NL_CURRENT (LC_CTYPE, CODESET);
|
||||
# else
|
||||
# if HAVE_ICONV
|
||||
extern const char *locale_charset (void);
|
||||
return locale_charset ();
|
||||
# endif
|
||||
# endif
|
||||
|
@ -1617,6 +1664,10 @@ mempcpy (void *dest, const void *src, size_t n)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !_LIBC && !HAVE_TSEARCH
|
||||
# include "tsearch.c"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _LIBC
|
||||
/* If we want to free all resources we have to do some work at
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue