[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: localename and thread locale
From: |
Bruno Haible |
Subject: |
Re: localename and thread locale |
Date: |
Sat, 26 Dec 2009 14:35:53 +0100 |
User-agent: |
KMail/1.9.9 |
Hi,
I wrote:
> +/* Determine the current per-thread locale's name, as specified by
> uselocale()
> + calls.
> + CATEGORY is a locale category abbreviation, as defined in <locale.h>,
> + but not LC_ALL. E.g. LC_MESSAGES.
> + CATEGORYNAME is the name of CATEGORY as a string, e.g. "LC_MESSAGES".
> + Return the locale category's name, canonicalized into XPG syntax
> + address@hidden
> + or NULL if no locale has been specified for the current thread.
> + The codeset part in the result is not reliable; the locale_charset()
> + should be used for codeset information instead.
> + The result must not be freed; it is statically allocated. */
> +extern const char * gl_locale_name_thread (int category, const char
> *categoryname);
It turns out that the result was not safely stored on glibc systems. So, on
glibc systems, one needs an 'struniq' call on the name returned by libc, in
order to move it into safe storage. Whereas on MacOS X it appears to be
unnecessary, but I cannot prove it from looking at the MacOS X libc sources.
So I leave in the 'struniq' calls on this platform as well.
2009-12-26 Bruno Haible <address@hidden>
localename: Fix storage allocation of gl_locale_name_thread's result.
* lib/localename.c (SIZE_BITS, string_hash, struct hash_node,
HASH_TABLE_SIZE, struniq_hash_table, struniq_lock, struniq): Define on
all platforms that have 'uselocale'.
(gl_locale_name_thread_unsafe): New function, extracted from
gl_locale_name_thread.
(gl_locale_name_thread): Call struniq on all platforms that have
'uselocale'.
*** lib/localename.c.orig Sat Dec 26 14:29:32 2009
--- lib/localename.c Sat Dec 26 14:28:00 2009
***************
*** 2507,2513 ****
#endif
! #if defined __APPLE__ && defined __MACH__ && HAVE_USELOCALE /* MacOS X */
/* Simple hash set of strings. We don't want to drag in lots of hash table
code here. */
--- 2507,2513 ----
#endif
! #if HAVE_USELOCALE /* glibc or MacOS X */
/* Simple hash set of strings. We don't want to drag in lots of hash table
code here. */
***************
*** 2592,2599 ****
#endif
const char *
! gl_locale_name_thread (int category, const char *categoryname)
{
#if HAVE_USELOCALE
{
--- 2592,2604 ----
#endif
+ /* Like gl_locale_name_thread, except that the result is not in storage of
+ indefinite extent. */
+ #if !defined IN_LIBINTL
+ static
+ #endif
const char *
! gl_locale_name_thread_unsafe (int category, const char *categoryname)
{
#if HAVE_USELOCALE
{
***************
*** 2686,2711 ****
switch (category)
{
case LC_CTYPE:
! return struniq (tlp->__lc_ctype->__ctype_encoding);
case LC_NUMERIC:
return tlp->_numeric_using_locale
! ? struniq (tlp->__lc_numeric->_numeric_locale_buf)
: "C";
case LC_TIME:
return tlp->_time_using_locale
! ? struniq (tlp->__lc_time->_time_locale_buf)
: "C";
case LC_COLLATE:
return !tlp->__collate_load_error
! ? struniq (tlp->__lc_collate->__encoding)
: "C";
case LC_MONETARY:
return tlp->_monetary_using_locale
! ? struniq (tlp->__lc_monetary->_monetary_locale_buf)
: "C";
case LC_MESSAGES:
return tlp->_messages_using_locale
! ? struniq (tlp->__lc_messages->_messages_locale_buf)
: "C";
default: /* We shouldn't get here. */
return "";
--- 2691,2716 ----
switch (category)
{
case LC_CTYPE:
! return tlp->__lc_ctype->__ctype_encoding;
case LC_NUMERIC:
return tlp->_numeric_using_locale
! ? tlp->__lc_numeric->_numeric_locale_buf
: "C";
case LC_TIME:
return tlp->_time_using_locale
! ? tlp->__lc_time->_time_locale_buf
: "C";
case LC_COLLATE:
return !tlp->__collate_load_error
! ? tlp->__lc_collate->__encoding
: "C";
case LC_MONETARY:
return tlp->_monetary_using_locale
! ? tlp->__lc_monetary->_monetary_locale_buf
: "C";
case LC_MESSAGES:
return tlp->_messages_using_locale
! ? tlp->__lc_messages->_messages_locale_buf
: "C";
default: /* We shouldn't get here. */
return "";
***************
*** 2717,2722 ****
--- 2722,2738 ----
return NULL;
}
+ const char *
+ gl_locale_name_thread (int category, const char *categoryname)
+ {
+ #if HAVE_USELOCALE
+ const char *name = gl_locale_name_thread_unsafe (category, categoryname);
+ if (name != NULL)
+ return struniq (name);
+ #endif
+ return NULL;
+ }
+
/* XPG3 defines the result of 'setlocale (category, NULL)' as:
"Directs 'setlocale()' to query 'category' and return the current
setting of 'local'."