bug-gnulib
[Top][All Lists]
Advanced

[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'."




reply via email to

[Prev in Thread] Current Thread [Next in Thread]