
1: /* Define current locale data for LC_CTYPE category. 2: Copyright (C) 1995,1996,1997,1998,1999,2000,2002,2003,2005 3: Free Software Foundation, Inc. 4: This file is part of the GNU C Library. 5: 6: The GNU C Library is free software; you can redistribute it and/or 7: modify it under the terms of the GNU Lesser General Public 8: License as published by the Free Software Foundation; either 9: version 2.1 of the License, or (at your option) any later version. 10: 11: The GNU C Library is distributed in the hope that it will be useful, 12: but WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: Lesser General Public License for more details. 15: 16: You should have received a copy of the GNU Lesser General Public 17: License along with the GNU C Library; if not, write to the Free 18: Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19: 02111-1307 USA. */ 20: 21: #include "localeinfo.h" 22: #include <ctype.h> 23: #include <endian.h> 24: #include <stdint.h> 25: 26: _NL_CURRENT_DEFINE (LC_CTYPE); 27: 28: /* We are called after loading LC_CTYPE data to load it into 29: the variables used by the ctype.h macros. */ 30: 31: 32: 33: void 34: _nl_postload_ctype (void) 35: { 36: #define current(type,x,offset) \ 37: ((const type *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_##x) + offset) 38: 39: const union locale_data_value *const ctypes 40: = _nl_global_locale.__locales[LC_CTYPE]->values; 41: 42: /* These thread-local variables are defined in ctype-info.c. 43: The declarations here must match those in localeinfo.h. 44: 45: These point into arrays of 384, so they can be indexed by any `unsigned 46: char' value [0,255]; by EOF (-1); or by any `signed char' value 47: [-128,-1). ISO C requires that the ctype functions work for `unsigned 48: char' values and for EOF; we also support negative `signed char' values 49: for broken old programs. The case conversion arrays are of `int's 50: rather than `unsigned char's because tolower (EOF) must be EOF, which 51: doesn't fit into an `unsigned char'. But today more important is that 52: the arrays are also used for multi-byte character sets. 53: 54: First we update the special members of _nl_global_locale as newlocale 55: would. This is necessary for uselocale (LC_GLOBAL_LOCALE) to find these 56: values properly. */ 57: 58: _nl_global_locale.__ctype_b = (const unsigned short int *) 59: ctypes[_NL_ITEM_INDEX (_NL_CTYPE_CLASS)].string + 128; 60: _nl_global_locale.__ctype_tolower = (const int *) 61: ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOLOWER)].string + 128; 62: _nl_global_locale.__ctype_toupper = (const int *) 63: ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOUPPER)].string + 128; 64: 65: /* Next we must set the thread-local caches if and only if this thread is 66: in fact using the global locale. */ 67: if (_NL_CURRENT_LOCALE == &_nl_global_locale) 68: { 69: __libc_tsd_set (CTYPE_B, (void *) _nl_global_locale.__ctype_b); 70: __libc_tsd_set (CTYPE_TOUPPER, 71: (void *) _nl_global_locale.__ctype_toupper); 72: __libc_tsd_set (CTYPE_TOLOWER, 73: (void *) _nl_global_locale.__ctype_tolower); 74: } 75: 76: #include <shlib-compat.h> 77: #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3) 78: /* We must use the exported names to access these so we are sure to 79: be accessing the main executable's copy if it has COPY relocs. */ 80: 81: extern __const unsigned short int *__ctype_b; /* Characteristics. */ 82: extern __const __int32_t *__ctype_tolower; /* Case conversions. */ 83: extern __const __int32_t *__ctype_toupper; /* Case conversions. */ 84: 85: extern const uint32_t *__ctype32_b; 86: extern const uint32_t *__ctype32_toupper; 87: extern const uint32_t *__ctype32_tolower; 88: 89: /* We need the .symver declarations these macros generate so that 90: our references are explicitly bound to the versioned symbol names 91: rather than the unadorned names that are not exported. When the 92: linker sees these bound to local symbols (as the unexported names are) 93: then it doesn't generate a proper relocation to the global symbols. 94: We need those relocations so that a versioned definition with a COPY 95: reloc in an executable will override the libc.so definition. */ 96: 97: compat_symbol (libc, __ctype_b, __ctype_b, GLIBC_2_0); 98: compat_symbol (libc, __ctype_tolower, __ctype_tolower, GLIBC_2_0); 99: compat_symbol (libc, __ctype_toupper, __ctype_toupper, GLIBC_2_0); 100: compat_symbol (libc, __ctype32_b, __ctype32_b, GLIBC_2_0); 101: compat_symbol (libc, __ctype32_tolower, __ctype32_tolower, GLIBC_2_2); 102: compat_symbol (libc, __ctype32_toupper, __ctype32_toupper, GLIBC_2_2); 103: 104: __ctype_b = current (uint16_t, CLASS, 128); 105: __ctype_toupper = current (int32_t, TOUPPER, 128); 106: __ctype_tolower = current (int32_t, TOLOWER, 128); 107: __ctype32_b = current (uint32_t, CLASS32, 0); 108: __ctype32_toupper = current (uint32_t, TOUPPER32, 0); 109: __ctype32_tolower = current (uint32_t, TOLOWER32, 0); 110: #endif 111: }