(linenum→info "unix/slp.c:2238")

glibc/2.7/locale/uselocale.c

    1: /* uselocale -- fetch and set the current per-thread locale
    2:    Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc.
    3:    This file is part of the GNU C Library.
    4: 
    5:    The GNU C Library is free software; you can redistribute it and/or
    6:    modify it under the terms of the GNU Lesser General Public
    7:    License as published by the Free Software Foundation; either
    8:    version 2.1 of the License, or (at your option) any later version.
    9: 
   10:    The GNU C Library is distributed in the hope that it will be useful,
   11:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13:    Lesser General Public License for more details.
   14: 
   15:    You should have received a copy of the GNU Lesser General Public
   16:    License along with the GNU C Library; if not, write to the Free
   17:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   18:    02111-1307 USA.  */
   19: 
   20: #include <locale.h>
   21: #include "localeinfo.h"
   22: #include <ctype.h>
   23: 
   24: /* Switch the current thread's locale to DATASET.
   25:    If DATASET is null, instead just return the current setting.
   26:    The special value LC_GLOBAL_LOCALE is the initial setting
   27:    for all threads, and means the thread uses the global
   28:    setting controlled by `setlocale'.  */
   29: locale_t
   30: __uselocale (locale_t newloc)
   31: {
   32:   locale_t oldloc = _NL_CURRENT_LOCALE;
   33: 
   34:   if (newloc != NULL)
   35:     {
   36:       const locale_t locobj
   37:         = newloc == LC_GLOBAL_LOCALE ? &_nl_global_locale : newloc;
   38:       __libc_tsd_set (LOCALE, locobj);
   39: 
   40: #ifdef NL_CURRENT_INDIRECT
   41:       /* Now we must update all the per-category thread-local variables to
   42:          point into the new current locale for this thread.  The magic
   43:          symbols _nl_current_LC_FOO_used are defined to meaningless values
   44:          if _nl_current_LC_FOO was linked in.  By using weak references to
   45:          both symbols and testing the address of _nl_current_LC_FOO_used,
   46:          we can avoid accessing the _nl_current_LC_FOO thread-local
   47:          variable at all when no code referring to it was linked in.  We
   48:          need the special bogus symbol because while TLS symbols can be
   49:          weak, there is no reasonable way to test for the default-zero
   50:          value as with a heap symbol (taking the address would just use
   51:          some bogus offset from our thread pointer).  */
   52: 
   53: # define DEFINE_CATEGORY(category, category_name, items, a) \
   54:       {                                                                       \
   55:         extern char _nl_current_##category##_used;                           \
   56:         weak_extern (_nl_current_##category##_used)                          \
   57:         weak_extern (_nl_current_##category)                                 \
   58:         if (&_nl_current_##category##_used != 0)                             \
   59:           _nl_current_##category = &locobj->__locales[category];             \
   60:       }
   61: # include "categories.def"
   62: # undef DEFINE_CATEGORY
   63: #endif
   64: 
   65:       /* Update the special tsd cache of some locale data.  */
   66:       __libc_tsd_set (CTYPE_B, (void *) locobj->__ctype_b);
   67:       __libc_tsd_set (CTYPE_TOLOWER, (void *) locobj->__ctype_tolower);
   68:       __libc_tsd_set (CTYPE_TOUPPER, (void *) locobj->__ctype_toupper);
   69:     }
   70: 
   71:   return oldloc == &_nl_global_locale ? LC_GLOBAL_LOCALE : oldloc;
   72: }
   73: libc_hidden_def (__uselocale)
   74: weak_alias (__uselocale, uselocale)
Syntax (Markdown)