Back to index

glibc  2.9
uselocale.c File Reference
#include <locale.h>
#include "localeinfo.h"
#include <ctype.h>

Go to the source code of this file.


locale_t __uselocale (locale_t newloc)

Function Documentation

locale_t __uselocale ( locale_t  newloc)

Definition at line 30 of file uselocale.c.

  locale_t oldloc = _NL_CURRENT_LOCALE;

  if (newloc != NULL)
      const locale_t locobj
       = newloc == LC_GLOBAL_LOCALE ? &_nl_global_locale : newloc;
      __libc_tsd_set (__locale_t, LOCALE, locobj);

      /* Now we must update all the per-category thread-local variables to
        point into the new current locale for this thread.  The magic
        symbols _nl_current_LC_FOO_used are defined to meaningless values
        if _nl_current_LC_FOO was linked in.  By using weak references to
        both symbols and testing the address of _nl_current_LC_FOO_used,
        we can avoid accessing the _nl_current_LC_FOO thread-local
        variable at all when no code referring to it was linked in.  We
        need the special bogus symbol because while TLS symbols can be
        weak, there is no reasonable way to test for the default-zero
        value as with a heap symbol (taking the address would just use
        some bogus offset from our thread pointer).  */

# define DEFINE_CATEGORY(category, category_name, items, a) \
      {                                                                     \
       extern char _nl_current_##category##_used;                           \
       weak_extern (_nl_current_##category##_used)                          \
       weak_extern (_nl_current_##category)                                 \
       if (&_nl_current_##category##_used != 0)                      \
         _nl_current_##category = &locobj->__locales[category];             \
# include "categories.def"
# undef       DEFINE_CATEGORY

      /* Update the special tsd cache of some locale data.  */
      __libc_tsd_set (const uint16_t *, CTYPE_B, (void *) locobj->__ctype_b);
      __libc_tsd_set (const int32_t *, CTYPE_TOLOWER,
                    (void *) locobj->__ctype_tolower);
      __libc_tsd_set (const int32_t *, CTYPE_TOUPPER,
                    (void *) locobj->__ctype_toupper);

  return oldloc == &_nl_global_locale ? LC_GLOBAL_LOCALE : oldloc;

Here is the caller graph for this function: