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