Print this page
2964 need POSIX 2008 locale object support
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libc/port/locale/setrunelocale.c
+++ new/usr/src/lib/libc/port/locale/setrunelocale.c
1 1 /*
2 2 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
3 3 * Copyright (c) 1993
4 4 * The Regents of the University of California. All rights reserved.
5 5 *
6 6 * This code is derived from software contributed to Berkeley by
7 7 * Paul Borman at Krystal Technologies.
8 8 *
9 + * Copyright (c) 2011 The FreeBSD Foundation
10 + * All rights reserved.
11 + * Portions of this software were developed by David Chisnall
12 + * under sponsorship from the FreeBSD Foundation.
13 + *
9 14 * Redistribution and use in source and binary forms, with or without
10 15 * modification, are permitted provided that the following conditions
11 16 * are met:
12 17 * 1. Redistributions of source code must retain the above copyright
13 18 * notice, this list of conditions and the following disclaimer.
14 19 * 2. Redistributions in binary form must reproduce the above copyright
15 20 * notice, this list of conditions and the following disclaimer in the
16 21 * documentation and/or other materials provided with the distribution.
17 22 * 4. Neither the name of the University nor the names of its contributors
18 23 * may be used to endorse or promote products derived from this software
19 24 * without specific prior written permission.
20 25 *
21 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 36 * SUCH DAMAGE.
32 37 */
33 38
34 39 #include "lint.h"
35 40 #include "file64.h"
36 41 #include <errno.h>
37 42 #include <limits.h>
38 43 #include <string.h>
39 44 #include <stdio.h>
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
40 45 #include <stdlib.h>
41 46 #include <unistd.h>
42 47 #include <wchar.h>
43 48 #include "runetype.h"
44 49 #include "ldpart.h"
45 50 #include "mblocal.h"
46 51 #include "setlocale.h"
47 52 #include "_ctype.h"
48 53 #include "../i18n/_locale.h"
49 54
55 +/*
56 + * A cached version of the runes for this thread. Used by ctype.h
57 + */
58 +__thread const _RuneLocale *_ThreadRuneLocale;
59 +
50 60 extern _RuneLocale *_Read_RuneMagi(FILE *);
51 61 extern unsigned char __ctype_C[];
52 62
53 63 static int __setrunelocale(const char *);
54 64
55 65 static int
56 66 __setrunelocale(const char *encoding)
57 67 {
58 68 FILE *fp;
59 69 char name[PATH_MAX];
60 70 _RuneLocale *rl;
61 71 int saverr, ret;
62 72 size_t (*old__mbrtowc)(wchar_t *_RESTRICT_KYWD,
63 73 const char *_RESTRICT_KYWD, size_t, mbstate_t *_RESTRICT_KYWD);
64 74 size_t (*old__wcrtomb)(char *_RESTRICT_KYWD, wchar_t,
65 75 mbstate_t *_RESTRICT_KYWD);
66 76 int (*old__mbsinit)(const mbstate_t *);
67 77 size_t (*old__mbsnrtowcs)(wchar_t *_RESTRICT_KYWD,
68 78 const char **_RESTRICT_KYWD, size_t, size_t,
69 79 mbstate_t *_RESTRICT_KYWD);
70 80 size_t (*old__wcsnrtombs)(char *_RESTRICT_KYWD,
71 81 const wchar_t **_RESTRICT_KYWD, size_t, size_t,
72 82 mbstate_t *_RESTRICT_KYWD);
73 83 static char ctype_encoding[ENCODING_LEN + 1];
74 84 static _RuneLocale *CachedRuneLocale;
75 85 static size_t (*Cached__mbrtowc)(wchar_t *_RESTRICT_KYWD,
76 86 const char *_RESTRICT_KYWD, size_t, mbstate_t *_RESTRICT_KYWD);
77 87 static size_t (*Cached__wcrtomb)(char *_RESTRICT_KYWD, wchar_t,
78 88 mbstate_t *_RESTRICT_KYWD);
79 89 static int (*Cached__mbsinit)(const mbstate_t *);
80 90 static size_t (*Cached__mbsnrtowcs)(wchar_t *_RESTRICT_KYWD,
81 91 const char **_RESTRICT_KYWD, size_t, size_t,
82 92 mbstate_t *_RESTRICT_KYWD);
83 93 static size_t (*Cached__wcsnrtombs)(char *_RESTRICT_KYWD,
84 94 const wchar_t **_RESTRICT_KYWD, size_t, size_t,
85 95 mbstate_t *_RESTRICT_KYWD);
86 96
87 97 /*
88 98 * The "C" and "POSIX" locale are always here.
89 99 */
90 100 if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) {
91 101 int i;
92 102
93 103 (void) memcpy(__ctype, __ctype_C, SZ_TOTAL);
94 104
95 105 for (i = 0; i < _CACHED_RUNES; i++) {
96 106 __ctype_mask[i] = _DefaultRuneLocale.__runetype[i];
97 107 __trans_upper[i] = _DefaultRuneLocale.__mapupper[i];
98 108 __trans_lower[i] = _DefaultRuneLocale.__maplower[i];
99 109 }
100 110
101 111 (void) _none_init(&_DefaultRuneLocale);
102 112 return (0);
103 113 }
104 114
105 115 /*
106 116 * If the locale name is the same as our cache, use the cache.
107 117 */
108 118 if (CachedRuneLocale != NULL &&
109 119 strcmp(encoding, ctype_encoding) == 0) {
110 120 _CurrentRuneLocale = CachedRuneLocale;
111 121 __mbrtowc = Cached__mbrtowc;
112 122 __mbsinit = Cached__mbsinit;
113 123 __mbsnrtowcs = Cached__mbsnrtowcs;
114 124 __wcrtomb = Cached__wcrtomb;
115 125 __wcsnrtombs = Cached__wcsnrtombs;
116 126 return (0);
117 127 }
118 128
119 129 /*
120 130 * Slurp the locale file into the cache.
121 131 */
122 132
123 133 (void) snprintf(name, sizeof (name), "%s/%s/LC_CTYPE/LCL_DATA",
124 134 _PathLocale, encoding);
125 135
126 136 if ((fp = fopen(name, "r")) == NULL)
127 137 return (errno == 0 ? ENOENT : errno);
128 138
129 139 if ((rl = _Read_RuneMagi(fp)) == NULL) {
130 140 saverr = (errno == 0 ? EINVAL : errno);
131 141 (void) fclose(fp);
132 142 return (saverr);
133 143 }
134 144 (void) fclose(fp);
135 145
136 146 old__mbrtowc = __mbrtowc;
137 147 old__mbsinit = __mbsinit;
138 148 old__mbsnrtowcs = __mbsnrtowcs;
139 149 old__wcrtomb = __wcrtomb;
140 150 old__wcsnrtombs = __wcsnrtombs;
141 151
142 152 __mbrtowc = NULL;
143 153 __mbsinit = NULL;
144 154 __mbsnrtowcs = __mbsnrtowcs_std;
145 155 __wcrtomb = NULL;
146 156 __wcsnrtombs = __wcsnrtombs_std;
147 157
148 158 if (strcmp(rl->__encoding, "NONE") == 0)
149 159 ret = _none_init(rl);
150 160 else if (strcmp(rl->__encoding, "UTF-8") == 0)
151 161 ret = _UTF8_init(rl);
152 162 else if (strcmp(rl->__encoding, "EUC-CN") == 0)
153 163 ret = _EUC_CN_init(rl);
154 164 else if (strcmp(rl->__encoding, "EUC-JP") == 0)
155 165 ret = _EUC_JP_init(rl);
156 166 else if (strcmp(rl->__encoding, "EUC-KR") == 0)
157 167 ret = _EUC_KR_init(rl);
158 168 else if (strcmp(rl->__encoding, "EUC-TW") == 0)
159 169 ret = _EUC_TW_init(rl);
160 170 else if (strcmp(rl->__encoding, "GB18030") == 0)
161 171 ret = _GB18030_init(rl);
162 172 else if (strcmp(rl->__encoding, "GB2312") == 0)
163 173 ret = _GB2312_init(rl);
164 174 else if (strcmp(rl->__encoding, "GBK") == 0)
165 175 ret = _GBK_init(rl);
166 176 else if (strcmp(rl->__encoding, "BIG5") == 0)
167 177 ret = _BIG5_init(rl);
168 178 else if (strcmp(rl->__encoding, "MSKanji") == 0)
169 179 ret = _MSKanji_init(rl);
170 180 else
171 181 ret = EINVAL;
172 182
173 183 if (ret == 0) {
174 184 if (CachedRuneLocale != NULL) {
175 185 free(CachedRuneLocale);
176 186 }
177 187 CachedRuneLocale = _CurrentRuneLocale;
178 188 Cached__mbrtowc = __mbrtowc;
179 189 Cached__mbsinit = __mbsinit;
180 190 Cached__mbsnrtowcs = __mbsnrtowcs;
181 191 Cached__wcrtomb = __wcrtomb;
182 192 Cached__wcsnrtombs = __wcsnrtombs;
183 193 (void) strcpy(ctype_encoding, encoding);
184 194
185 195 /*
186 196 * We need to overwrite the _ctype array. This requires
187 197 * some finagling. This is because references to it may
188 198 * have been baked into applications.
189 199 *
190 200 * Note that it is interesting that toupper/tolower only
191 201 * produce defined results when the input is representable
192 202 * as a byte.
193 203 */
194 204
195 205 /*
196 206 * The top half is the type mask array. Because we
197 207 * want to support both legacy Solaris code (which have
198 208 * mask valeus baked in to them), and we want to be able
199 209 * to import locale files from other sources (FreeBSD)
200 210 * which probably uses different masks, we have to perform
201 211 * a conversion here. Ugh. Note that the _CTYPE definitions
202 212 * we use from FreeBSD are richer than the Solaris legacy.
203 213 *
204 214 * We have to cope with these limitations though, because the
205 215 * inadequate Solaris definitions were baked into binaries.
206 216 */
207 217 for (int i = 0; i < _CACHED_RUNES; i++) {
208 218 /* ctype can only encode the lower 8 bits. */
209 219 __ctype[i+1] = rl->__runetype[i] & 0xff;
210 220 __ctype_mask[i] = rl->__runetype[i];
211 221 }
212 222
213 223 /* The bottom half is the toupper/lower array */
214 224 for (int i = 0; i < _CACHED_RUNES; i++) {
215 225 __ctype[258 + i] = i;
216 226 if (rl->__mapupper[i] && rl->__mapupper[i] != i)
217 227 __ctype[258+i] = rl->__mapupper[i];
218 228 if (rl->__maplower[i] && rl->__maplower[i] != i)
219 229 __ctype[258+i] = rl->__maplower[i];
220 230
221 231 /* Don't forget these annoyances either! */
222 232 __trans_upper[i] = rl->__mapupper[i];
223 233 __trans_lower[i] = rl->__maplower[i];
224 234 }
225 235
226 236 /*
227 237 * Note that we expect the init code will have populated
228 238 * the CSWIDTH array (__ctype[514-520]) properly.
229 239 */
230 240 } else {
231 241 __mbrtowc = old__mbrtowc;
232 242 __mbsinit = old__mbsinit;
233 243 __mbsnrtowcs = old__mbsnrtowcs;
234 244 __wcrtomb = old__wcrtomb;
235 245 __wcsnrtombs = old__wcsnrtombs;
236 246 free(rl);
237 247 }
238 248
239 249 return (ret);
240 250 }
241 251
242 252 int
↓ open down ↓ |
183 lines elided |
↑ open up ↑ |
243 253 __wrap_setrunelocale(const char *locale)
244 254 {
245 255 int ret = __setrunelocale(locale);
246 256
247 257 if (ret != 0) {
248 258 errno = ret;
249 259 return (_LDP_ERROR);
250 260 }
251 261 return (_LDP_LOADED);
252 262 }
263 +
264 +void
265 +__set_thread_rune_locale(locale_t loc)
266 +{
267 +
268 + if (loc == NULL) {
269 + _ThreadRuneLocale = &_DefaultRuneLocale;
270 + } else {
271 + _ThreadRuneLocale = XLOCALE_CTYPE(loc)->runes;
272 + }
273 +}
274 +
275 +void *
276 +__ctype_load(const char *locale, locale_t unused)
277 +{
278 + struct xlocale_ctype *l;
279 +
280 + l = calloc(sizeof(struct xlocale_ctype), 1);
281 + /* XXX */
282 +
283 + return (l);
284 +}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX