X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Flocalename.c;h=3ab88228a266426b2e16099669c22e0323da7556;hb=5bddd6312f3041adf1580f0c791dcb05c0d3ae92;hp=4b77c95fae1e6f4473457357e49c4796a81cce2c;hpb=85de14f614534603cf01144192cae044df638e22;p=gnulib.git diff --git a/lib/localename.c b/lib/localename.c index 4b77c95fa..3ab88228a 100644 --- a/lib/localename.c +++ b/lib/localename.c @@ -1,5 +1,5 @@ /* Determine name of the currently selected locale. - Copyright (C) 1995-1999, 2000-2009 Free Software Foundation, Inc. + Copyright (C) 1995-2011 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 @@ -2507,7 +2507,7 @@ gl_locale_name_from_win32_LCID (LCID lcid) #endif -#if defined __APPLE__ && defined __MACH__ && HAVE_USELOCALE /* MacOS X */ +#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,15 +2592,22 @@ struniq (const char *string) #endif +#if defined IN_LIBINTL || HAVE_USELOCALE + +/* 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 (int category, const char *categoryname) +gl_locale_name_thread_unsafe (int category, const char *categoryname) { -#if HAVE_USELOCALE +# if HAVE_USELOCALE { locale_t thread_locale = uselocale (NULL); if (thread_locale != LC_GLOBAL_LOCALE) { -# if __GLIBC__ >= 2 +# if __GLIBC__ >= 2 && !defined __UCLIBC__ /* Work around an incorrect definition of the _NL_LOCALE_NAME macro in glibc < 2.12. See . */ @@ -2611,19 +2618,31 @@ gl_locale_name_thread (int category, const char *categoryname) nl_langinfo (_NL_LOCALE_NAME (category)). */ name = thread_locale->__names[category]; return name; -# endif -# if defined __APPLE__ && defined __MACH__ /* MacOS X */ +# endif +# if defined __APPLE__ && defined __MACH__ /* MacOS X */ /* The locale name is found deep in an undocumented data structure. Since it's stored in a buffer of size 32 and newlocale() rejects locale names of length > 31, we can assume that it is NUL terminated in this buffer. But we need to make a copy of the locale name, of indefinite extent. */ - struct _xlocale + struct _xlocale_part1_v0 /* used in MacOS X 10.5 */ { int32_t __refcount; void (*__free_extra)(void *); __darwin_mbstate_t __mbs[10]; int64_t __magic; + }; + struct _xlocale_part1_v1 /* used in MacOS X >= 10.6.0 */ + { + int32_t __refcount; + void (*__free_extra)(void *); + __darwin_mbstate_t __mbs[10]; + /*pthread_lock_t*/ int __lock; + int64_t __magic; + }; + struct _xlocale_part2 + { + int64_t __magic; unsigned char __collate_load_error; unsigned char __collate_substitute_nontrivial; unsigned char _messages_using_locale; @@ -2682,37 +2701,66 @@ gl_locale_name_thread (int category, const char *categoryname) char *_time_locale_buf; /* more */ }; - struct _xlocale *tlp = (struct _xlocale *) thread_locale; + struct _xlocale_part2 *tlp; + if (((struct _xlocale_part1_v0 *) thread_locale)->__magic + == 0x786C6F63616C6530LL) + /* MacOS X 10.5 */ + tlp = + (struct _xlocale_part2 *) + &((struct _xlocale_part1_v0 *) thread_locale)->__magic; + else if (((struct _xlocale_part1_v1 *) thread_locale)->__magic + == 0x786C6F63616C6530LL) + /* MacOS X >= 10.6.0 */ + tlp = + (struct _xlocale_part2 *) + &((struct _xlocale_part1_v1 *) thread_locale)->__magic; + else + /* Unsupported version of MacOS X: The internals of 'struct _xlocale' + have changed again. */ + return ""; switch (category) { case LC_CTYPE: - return struniq (tlp->__lc_ctype->__ctype_encoding); + return tlp->__lc_ctype->__ctype_encoding; case LC_NUMERIC: return tlp->_numeric_using_locale - ? struniq (tlp->__lc_numeric->_numeric_locale_buf) + ? tlp->__lc_numeric->_numeric_locale_buf : "C"; case LC_TIME: return tlp->_time_using_locale - ? struniq (tlp->__lc_time->_time_locale_buf) + ? tlp->__lc_time->_time_locale_buf : "C"; case LC_COLLATE: return !tlp->__collate_load_error - ? struniq (tlp->__lc_collate->__encoding) + ? tlp->__lc_collate->__encoding : "C"; case LC_MONETARY: return tlp->_monetary_using_locale - ? struniq (tlp->__lc_monetary->_monetary_locale_buf) + ? tlp->__lc_monetary->_monetary_locale_buf : "C"; case LC_MESSAGES: return tlp->_messages_using_locale - ? struniq (tlp->__lc_messages->_messages_locale_buf) + ? tlp->__lc_messages->_messages_locale_buf : "C"; default: /* We shouldn't get here. */ return ""; } -# endif +# endif } } +# endif + return NULL; +} + +#endif + +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; } @@ -2723,7 +2771,7 @@ gl_locale_name_thread (int category, const char *categoryname) However it does not specify the exact format. Neither do SUSV2 and ISO C 99. So we can use this feature only on selected systems (e.g. those using GNU C Library). */ -#if defined _LIBC || (defined __GLIBC__ && __GLIBC__ >= 2) +#if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined __UCLIBC__) # define HAVE_LOCALE_NULL #endif @@ -2846,7 +2894,7 @@ gl_locale_name_default (void) CFLocaleRef locale = CFLocaleCopyCurrent (); CFStringRef name = CFLocaleGetIdentifier (locale); - if (CFStringGetCString (name, namebuf, sizeof(namebuf), + if (CFStringGetCString (name, namebuf, sizeof (namebuf), kCFStringEncodingASCII)) { gl_locale_name_canonicalize (namebuf); @@ -2859,7 +2907,8 @@ gl_locale_name_default (void) kCFPreferencesCurrentApplication); if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID () - && CFStringGetCString ((CFStringRef)value, namebuf, sizeof(namebuf), + && CFStringGetCString ((CFStringRef)value, + namebuf, sizeof (namebuf), kCFStringEncodingASCII)) { gl_locale_name_canonicalize (namebuf);