Back to index

glibc  2.9
lc-ctype.c
Go to the documentation of this file.
00001 /* Define current locale data for LC_CTYPE category.
00002    Copyright (C) 1995,1996,1997,1998,1999,2000,2002,2003,2005,2008
00003        Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include "localeinfo.h"
00022 #include <ctype.h>
00023 #include <endian.h>
00024 #include <stdint.h>
00025 
00026 _NL_CURRENT_DEFINE (LC_CTYPE);
00027 
00028 /* We are called after loading LC_CTYPE data to load it into
00029    the variables used by the ctype.h macros.  */
00030 
00031 
00032 
00033 void
00034 _nl_postload_ctype (void)
00035 {
00036 #define current(type,x,offset) \
00037   ((const type *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_##x) + offset)
00038 
00039   const union locale_data_value *const ctypes
00040     = _nl_global_locale.__locales[LC_CTYPE]->values;
00041 
00042 /* These thread-local variables are defined in ctype-info.c.
00043    The declarations here must match those in localeinfo.h.
00044 
00045    These point into arrays of 384, so they can be indexed by any `unsigned
00046    char' value [0,255]; by EOF (-1); or by any `signed char' value
00047    [-128,-1).  ISO C requires that the ctype functions work for `unsigned
00048    char' values and for EOF; we also support negative `signed char' values
00049    for broken old programs.  The case conversion arrays are of `int's
00050    rather than `unsigned char's because tolower (EOF) must be EOF, which
00051    doesn't fit into an `unsigned char'.  But today more important is that
00052    the arrays are also used for multi-byte character sets.
00053 
00054    First we update the special members of _nl_global_locale as newlocale
00055    would.  This is necessary for uselocale (LC_GLOBAL_LOCALE) to find these
00056    values properly.  */
00057 
00058   _nl_global_locale.__ctype_b = (const unsigned short int *)
00059     ctypes[_NL_ITEM_INDEX (_NL_CTYPE_CLASS)].string + 128;
00060   _nl_global_locale.__ctype_tolower = (const int *)
00061     ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOLOWER)].string + 128;
00062   _nl_global_locale.__ctype_toupper = (const int *)
00063     ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOUPPER)].string + 128;
00064 
00065   /* Next we must set the thread-local caches if and only if this thread is
00066      in fact using the global locale.  */
00067   if (_NL_CURRENT_LOCALE == &_nl_global_locale)
00068     {
00069       __libc_tsd_set (const uint16_t *, CTYPE_B,
00070                     (void *) _nl_global_locale.__ctype_b);
00071       __libc_tsd_set (const int32_t *, CTYPE_TOUPPER,
00072                     (void *) _nl_global_locale.__ctype_toupper);
00073       __libc_tsd_set (const int32_t *, CTYPE_TOLOWER,
00074                     (void *) _nl_global_locale.__ctype_tolower);
00075     }
00076 
00077 #include <shlib-compat.h>
00078 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
00079   /* We must use the exported names to access these so we are sure to
00080      be accessing the main executable's copy if it has COPY relocs.  */
00081 
00082   extern __const unsigned short int *__ctype_b; /* Characteristics.  */
00083   extern __const __int32_t *__ctype_tolower; /* Case conversions.  */
00084   extern __const __int32_t *__ctype_toupper; /* Case conversions.  */
00085 
00086   extern const uint32_t *__ctype32_b;
00087   extern const uint32_t *__ctype32_toupper;
00088   extern const uint32_t *__ctype32_tolower;
00089 
00090   /* We need the .symver declarations these macros generate so that
00091      our references are explicitly bound to the versioned symbol names
00092      rather than the unadorned names that are not exported.  When the
00093      linker sees these bound to local symbols (as the unexported names are)
00094      then it doesn't generate a proper relocation to the global symbols.
00095      We need those relocations so that a versioned definition with a COPY
00096      reloc in an executable will override the libc.so definition.  */
00097 
00098 compat_symbol (libc, __ctype_b, __ctype_b, GLIBC_2_0);
00099 compat_symbol (libc, __ctype_tolower, __ctype_tolower, GLIBC_2_0);
00100 compat_symbol (libc, __ctype_toupper, __ctype_toupper, GLIBC_2_0);
00101 compat_symbol (libc, __ctype32_b, __ctype32_b, GLIBC_2_0);
00102 compat_symbol (libc, __ctype32_tolower, __ctype32_tolower, GLIBC_2_2);
00103 compat_symbol (libc, __ctype32_toupper, __ctype32_toupper, GLIBC_2_2);
00104 
00105   __ctype_b = current (uint16_t, CLASS, 128);
00106   __ctype_toupper = current (int32_t, TOUPPER, 128);
00107   __ctype_tolower = current (int32_t, TOLOWER, 128);
00108   __ctype32_b = current (uint32_t, CLASS32, 0);
00109   __ctype32_toupper = current (uint32_t, TOUPPER32, 0);
00110   __ctype32_tolower = current (uint32_t, TOLOWER32, 0);
00111 #endif
00112 }