]>
Commit | Line | Data |
---|---|---|
3d9156a7 | 1 | /* |
34e8f829 | 2 | * Copyright (c) 2005, 2008 Apple Inc. All rights reserved. |
3d9156a7 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | #ifndef _XLOCALE_PRIVATE_H_ | |
25 | #define _XLOCALE_PRIVATE_H_ | |
26 | ||
27 | #include <sys/cdefs.h> | |
224c7076 | 28 | #define __DARWIN_XLOCALE_PRIVATE |
3d9156a7 | 29 | #include <xlocale.h> |
224c7076 | 30 | #undef __DARWIN_XLOCALE_PRIVATE |
3d9156a7 A |
31 | #include <stdlib.h> |
32 | #include <locale.h> | |
33 | #include <libkern/OSAtomic.h> | |
34 | #include <pthread.h> | |
70ad1dc8 | 35 | #include <pthread/tsd_private.h> |
224c7076 | 36 | #include <limits.h> |
b061a43b | 37 | #include <os/lock.h> |
3d9156a7 A |
38 | #include "setlocale.h" |
39 | #include "collate.h" | |
40 | #include "runetype.h" | |
41 | #include "lmessages.h" | |
42 | #include "lmonetary.h" | |
43 | #include "lnumeric.h" | |
44 | #include "timelocal.h" | |
23e20b00 | 45 | #include <TargetConditionals.h> |
3d9156a7 A |
46 | |
47 | #undef MB_CUR_MAX | |
48 | #define MB_CUR_MAX (__current_locale()->__lc_ctype->__mb_cur_max) | |
49 | #undef MB_CUR_MAX_L | |
50 | #define MB_CUR_MAX_L(x) ((x)->__lc_ctype->__mb_cur_max) | |
51 | ||
3d9156a7 A |
52 | typedef void (*__free_extra_t)(void *); |
53 | ||
54 | #define XPERMANENT ((__free_extra_t)-1) | |
55 | #define XMAGIC 0x786c6f63616c6530LL /* 'xlocale0' */ | |
56 | ||
57 | #define __STRUCT_COMMON \ | |
58 | int32_t __refcount; \ | |
59 | __free_extra_t __free_extra; | |
60 | ||
61 | struct __xlocale_st_collate { | |
62 | __STRUCT_COMMON | |
63 | char __encoding[ENCODING_LEN + 1]; | |
224c7076 A |
64 | struct __collate_st_info __info; |
65 | struct __collate_st_subst *__substitute_table[COLL_WEIGHTS_MAX]; | |
3d9156a7 | 66 | struct __collate_st_chain_pri *__chain_pri_table; |
224c7076 A |
67 | struct __collate_st_large_char_pri *__large_char_pri_table; |
68 | struct __collate_st_char_pri __char_pri_table[UCHAR_MAX + 1]; | |
3d9156a7 A |
69 | }; |
70 | struct __xlocale_st_runelocale { | |
71 | __STRUCT_COMMON | |
72 | char __ctype_encoding[ENCODING_LEN + 1]; | |
73 | int __mb_cur_max; | |
1f2f436a | 74 | int __mb_sb_limit; |
3d9156a7 A |
75 | size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, |
76 | size_t, __darwin_mbstate_t * __restrict, struct _xlocale *); | |
77 | int (*__mbsinit)(const __darwin_mbstate_t *, struct _xlocale *); | |
78 | size_t (*__mbsnrtowcs)(wchar_t * __restrict, const char ** __restrict, | |
79 | size_t, size_t, __darwin_mbstate_t * __restrict, struct _xlocale *); | |
80 | size_t (*__wcrtomb)(char * __restrict, wchar_t, | |
81 | __darwin_mbstate_t * __restrict, struct _xlocale *); | |
82 | size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, | |
83 | size_t, size_t, __darwin_mbstate_t * __restrict, struct _xlocale *); | |
84 | int __datasize; | |
85 | _RuneLocale _CurrentRuneLocale; | |
86 | }; | |
87 | struct __xlocale_st_ldpart { | |
88 | __STRUCT_COMMON | |
89 | char *_locale_buf; | |
90 | }; | |
91 | /* | |
92 | * the next four structures must have the first three fields of the same | |
93 | * as the _xlocale_st_ldpart structure above. | |
94 | */ | |
95 | struct __xlocale_st_messages { | |
96 | __STRUCT_COMMON | |
97 | char *_messages_locale_buf; | |
98 | struct lc_messages_T _messages_locale; | |
99 | }; | |
100 | struct __xlocale_st_monetary { | |
101 | __STRUCT_COMMON | |
102 | char *_monetary_locale_buf; | |
103 | struct lc_monetary_T _monetary_locale; | |
104 | }; | |
105 | struct __xlocale_st_numeric { | |
106 | __STRUCT_COMMON | |
107 | char *_numeric_locale_buf; | |
108 | struct lc_numeric_T _numeric_locale; | |
109 | }; | |
110 | struct __xlocale_st_time { | |
111 | __STRUCT_COMMON | |
112 | char *_time_locale_buf; | |
113 | struct lc_time_T _time_locale; | |
114 | }; | |
115 | ||
3d9156a7 | 116 | /* the extended locale structure */ |
224c7076 A |
117 | /* values for __numeric_fp_cvt */ |
118 | #define LC_NUMERIC_FP_UNINITIALIZED 0 | |
119 | #define LC_NUMERIC_FP_SAME_LOCALE 1 | |
120 | #define LC_NUMERIC_FP_USE_LOCALE 2 | |
121 | ||
3d9156a7 A |
122 | struct _xlocale { |
123 | /* The item(s) before __magic are not copied when duplicating locale_t's */ | |
224c7076 | 124 | __STRUCT_COMMON /* only used for locale_t's in __lc_numeric_loc */ |
3d9156a7 A |
125 | /* 10 independent mbstate_t buffers! */ |
126 | __darwin_mbstate_t __mbs_mblen; | |
127 | __darwin_mbstate_t __mbs_mbrlen; | |
128 | __darwin_mbstate_t __mbs_mbrtowc; | |
129 | __darwin_mbstate_t __mbs_mbsnrtowcs; | |
130 | __darwin_mbstate_t __mbs_mbsrtowcs; | |
131 | __darwin_mbstate_t __mbs_mbtowc; | |
132 | __darwin_mbstate_t __mbs_wcrtomb; | |
133 | __darwin_mbstate_t __mbs_wcsnrtombs; | |
134 | __darwin_mbstate_t __mbs_wcsrtombs; | |
135 | __darwin_mbstate_t __mbs_wctomb; | |
b061a43b | 136 | os_unfair_lock __lock; |
3d9156a7 A |
137 | /* magic (Here up to the end is copied when duplicating locale_t's) */ |
138 | int64_t __magic; | |
139 | /* flags */ | |
140 | unsigned char __collate_load_error; | |
141 | unsigned char __collate_substitute_nontrivial; | |
142 | unsigned char _messages_using_locale; | |
143 | unsigned char _monetary_using_locale; | |
144 | unsigned char _numeric_using_locale; | |
145 | unsigned char _time_using_locale; | |
146 | unsigned char __mlocale_changed; | |
147 | unsigned char __nlocale_changed; | |
224c7076 | 148 | unsigned char __numeric_fp_cvt; |
3d9156a7 A |
149 | /* collate */ |
150 | struct __xlocale_st_collate *__lc_collate; | |
151 | /* ctype */ | |
152 | struct __xlocale_st_runelocale *__lc_ctype; | |
153 | /* messages */ | |
154 | struct __xlocale_st_messages *__lc_messages; | |
155 | /* monetary */ | |
156 | struct __xlocale_st_monetary *__lc_monetary; | |
157 | /* numeric */ | |
158 | struct __xlocale_st_numeric *__lc_numeric; | |
224c7076 | 159 | struct _xlocale *__lc_numeric_loc; |
3d9156a7 A |
160 | /* time */ |
161 | struct __xlocale_st_time *__lc_time; | |
162 | /* localeconv */ | |
34e8f829 | 163 | struct lconv __lc_localeconv; |
3d9156a7 A |
164 | }; |
165 | ||
6465356a A |
166 | #define DEFAULT_CURRENT_LOCALE(x) \ |
167 | if ((x) == NULL) { \ | |
168 | (x) = __current_locale(); \ | |
169 | } else if ((x) == LC_GLOBAL_LOCALE) { \ | |
170 | (x) = &__global_locale; \ | |
171 | } | |
172 | ||
507116e3 | 173 | #define NORMALIZE_LOCALE(x) if ((x) == LC_C_LOCALE) { \ |
3d9156a7 A |
174 | (x) = _c_locale; \ |
175 | } else if ((x) == LC_GLOBAL_LOCALE) { \ | |
176 | (x) = &__global_locale; \ | |
177 | } | |
178 | ||
b061a43b | 179 | #define XL_LOCK(x) os_unfair_lock_lock(&(x)->__lock); |
34e8f829 | 180 | #define XL_RELEASE(x) if ((x) && (x)->__free_extra != XPERMANENT && OSAtomicDecrement32Barrier(&(x)->__refcount) == 0) { \ |
3d9156a7 A |
181 | if ((x)->__free_extra) \ |
182 | (*(x)->__free_extra)((x)); \ | |
183 | free((x)); \ | |
974e3884 | 184 | (x) = NULL; \ |
3d9156a7 A |
185 | } |
186 | #define XL_RETAIN(x) if ((x) && (x)->__free_extra != XPERMANENT) { OSAtomicIncrement32Barrier(&(x)->__refcount); } | |
b061a43b | 187 | #define XL_UNLOCK(x) os_unfair_lock_unlock(&(x)->__lock); |
3d9156a7 | 188 | |
23e20b00 A |
189 | __attribute__((visibility("hidden"))) |
190 | extern struct __xlocale_st_runelocale _DefaultRuneXLocale; | |
191 | ||
192 | __attribute__((visibility("hidden"))) | |
193 | extern struct _xlocale __global_locale; | |
194 | ||
195 | __attribute__((visibility("hidden"))) | |
196 | extern pthread_key_t __locale_key; | |
3d9156a7 A |
197 | |
198 | __BEGIN_DECLS | |
199 | ||
200 | void __ldpart_free_extra(struct __xlocale_st_ldpart *); | |
224c7076 | 201 | locale_t __numeric_ctype(locale_t); |
3d9156a7 A |
202 | void __xlocale_init(void); |
203 | ||
204 | static inline __attribute__((always_inline)) locale_t | |
205 | __current_locale(void) | |
206 | { | |
23e20b00 A |
207 | #if TARGET_IPHONE_SIMULATOR |
208 | /* <rdar://problem/14136256> Crash in _objc_inform for duplicate class name during simulator launch | |
209 | * TODO: Remove after the simulator's libSystem is initialized properly. | |
210 | */ | |
211 | if (__locale_key == (pthread_key_t)-1) { | |
212 | return &__global_locale; | |
213 | } | |
214 | #endif | |
70ad1dc8 A |
215 | void *__thread_locale; |
216 | if (_pthread_has_direct_tsd()) { | |
217 | __thread_locale = _pthread_getspecific_direct(__locale_key); | |
218 | } else { | |
219 | __thread_locale = pthread_getspecific(__locale_key); | |
220 | } | |
221 | return (__thread_locale ? (locale_t)__thread_locale : &__global_locale); | |
3d9156a7 A |
222 | } |
223 | ||
224 | static inline __attribute__((always_inline)) locale_t | |
225 | __locale_ptr(locale_t __loc) | |
226 | { | |
34e8f829 A |
227 | NORMALIZE_LOCALE(__loc); |
228 | return __loc; | |
3d9156a7 A |
229 | } |
230 | ||
231 | __END_DECLS | |
232 | ||
233 | #endif /* _XLOCALE_PRIVATE_H_ */ |