1/* 2 * Copyright (c) 2005, 2008 Apple Inc. All rights reserved. 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> 28#define __DARWIN_XLOCALE_PRIVATE 29#include <xlocale.h> 30#undef __DARWIN_XLOCALE_PRIVATE 31#include <stdlib.h> 32#include <locale.h> 33#include <libkern/OSAtomic.h> 34#include <pthread.h> 35#include <pthread_spinlock.h> 36#include <limits.h> 37#include "setlocale.h" 38#include "collate.h" 39#include "runetype.h" 40#include "lmessages.h" 41#include "lmonetary.h" 42#include "lnumeric.h" 43#include "timelocal.h" 44#include <TargetConditionals.h> 45 46#undef MB_CUR_MAX 47#define MB_CUR_MAX (__current_locale()->__lc_ctype->__mb_cur_max) 48#undef MB_CUR_MAX_L 49#define MB_CUR_MAX_L(x) ((x)->__lc_ctype->__mb_cur_max) 50 51typedef void (*__free_extra_t)(void *); 52 53#define XPERMANENT ((__free_extra_t)-1) 54#define XMAGIC 0x786c6f63616c6530LL /* 'xlocale0' */ 55 56#define __STRUCT_COMMON \ 57 int32_t __refcount; \ 58 __free_extra_t __free_extra; 59 60struct __xlocale_st_collate { 61 __STRUCT_COMMON 62 char __encoding[ENCODING_LEN + 1]; 63 struct __collate_st_info __info; 64 struct __collate_st_subst *__substitute_table[COLL_WEIGHTS_MAX]; 65 struct __collate_st_chain_pri *__chain_pri_table; 66 struct __collate_st_large_char_pri *__large_char_pri_table; 67 struct __collate_st_char_pri __char_pri_table[UCHAR_MAX + 1]; 68}; 69struct __xlocale_st_runelocale { 70 __STRUCT_COMMON 71 char __ctype_encoding[ENCODING_LEN + 1]; 72 int __mb_cur_max; 73 int __mb_sb_limit; 74 size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, 75 size_t, __darwin_mbstate_t * __restrict, struct _xlocale *); 76 int (*__mbsinit)(const __darwin_mbstate_t *, struct _xlocale *); 77 size_t (*__mbsnrtowcs)(wchar_t * __restrict, const char ** __restrict, 78 size_t, size_t, __darwin_mbstate_t * __restrict, struct _xlocale *); 79 size_t (*__wcrtomb)(char * __restrict, wchar_t, 80 __darwin_mbstate_t * __restrict, struct _xlocale *); 81 size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, 82 size_t, size_t, __darwin_mbstate_t * __restrict, struct _xlocale *); 83 int __datasize; 84 _RuneLocale _CurrentRuneLocale; 85}; 86struct __xlocale_st_ldpart { 87 __STRUCT_COMMON 88 char *_locale_buf; 89}; 90/* 91 * the next four structures must have the first three fields of the same 92 * as the _xlocale_st_ldpart structure above. 93 */ 94struct __xlocale_st_messages { 95 __STRUCT_COMMON 96 char *_messages_locale_buf; 97 struct lc_messages_T _messages_locale; 98}; 99struct __xlocale_st_monetary { 100 __STRUCT_COMMON 101 char *_monetary_locale_buf; 102 struct lc_monetary_T _monetary_locale; 103}; 104struct __xlocale_st_numeric { 105 __STRUCT_COMMON 106 char *_numeric_locale_buf; 107 struct lc_numeric_T _numeric_locale; 108}; 109struct __xlocale_st_time { 110 __STRUCT_COMMON 111 char *_time_locale_buf; 112 struct lc_time_T _time_locale; 113}; 114 115/* the extended locale structure */ 116 /* values for __numeric_fp_cvt */ 117#define LC_NUMERIC_FP_UNINITIALIZED 0 118#define LC_NUMERIC_FP_SAME_LOCALE 1 119#define LC_NUMERIC_FP_USE_LOCALE 2 120 121struct _xlocale { 122/* The item(s) before __magic are not copied when duplicating locale_t's */ 123 __STRUCT_COMMON /* only used for locale_t's in __lc_numeric_loc */ 124 /* 10 independent mbstate_t buffers! */ 125 __darwin_mbstate_t __mbs_mblen; 126 __darwin_mbstate_t __mbs_mbrlen; 127 __darwin_mbstate_t __mbs_mbrtowc; 128 __darwin_mbstate_t __mbs_mbsnrtowcs; 129 __darwin_mbstate_t __mbs_mbsrtowcs; 130 __darwin_mbstate_t __mbs_mbtowc; 131 __darwin_mbstate_t __mbs_wcrtomb; 132 __darwin_mbstate_t __mbs_wcsnrtombs; 133 __darwin_mbstate_t __mbs_wcsrtombs; 134 __darwin_mbstate_t __mbs_wctomb; 135 pthread_lock_t __lock; 136/* magic (Here up to the end is copied when duplicating locale_t's) */ 137 int64_t __magic; 138/* flags */ 139 unsigned char __collate_load_error; 140 unsigned char __collate_substitute_nontrivial; 141 unsigned char _messages_using_locale; 142 unsigned char _monetary_using_locale; 143 unsigned char _numeric_using_locale; 144 unsigned char _time_using_locale; 145 unsigned char __mlocale_changed; 146 unsigned char __nlocale_changed; 147 unsigned char __numeric_fp_cvt; 148/* collate */ 149 struct __xlocale_st_collate *__lc_collate; 150/* ctype */ 151 struct __xlocale_st_runelocale *__lc_ctype; 152/* messages */ 153 struct __xlocale_st_messages *__lc_messages; 154/* monetary */ 155 struct __xlocale_st_monetary *__lc_monetary; 156/* numeric */ 157 struct __xlocale_st_numeric *__lc_numeric; 158 struct _xlocale *__lc_numeric_loc; 159/* time */ 160 struct __xlocale_st_time *__lc_time; 161/* localeconv */ 162 struct lconv __lc_localeconv; 163}; 164 165#define DEFAULT_CURRENT_LOCALE(x) \ 166 if ((x) == NULL) { \ 167 (x) = __current_locale(); \ 168 } else if ((x) == LC_GLOBAL_LOCALE) { \ 169 (x) = &__global_locale; \ 170 } 171 172#define NORMALIZE_LOCALE(x) if ((x) == NULL) { \ 173 (x) = _c_locale; \ 174 } else if ((x) == LC_GLOBAL_LOCALE) { \ 175 (x) = &__global_locale; \ 176 } 177 178#define XL_LOCK(x) LOCK((x)->__lock); 179#define XL_RELEASE(x) if ((x) && (x)->__free_extra != XPERMANENT && OSAtomicDecrement32Barrier(&(x)->__refcount) == 0) { \ 180 if ((x)->__free_extra) \ 181 (*(x)->__free_extra)((x)); \ 182 free((x)); \ 183 } 184#define XL_RETAIN(x) if ((x) && (x)->__free_extra != XPERMANENT) { OSAtomicIncrement32Barrier(&(x)->__refcount); } 185#define XL_UNLOCK(x) UNLOCK((x)->__lock); 186 187__attribute__((visibility("hidden"))) 188extern struct __xlocale_st_runelocale _DefaultRuneXLocale; 189 190__attribute__((visibility("hidden"))) 191extern struct _xlocale __global_locale; 192 193__attribute__((visibility("hidden"))) 194extern pthread_key_t __locale_key; 195 196__BEGIN_DECLS 197 198void __ldpart_free_extra(struct __xlocale_st_ldpart *); 199locale_t __numeric_ctype(locale_t); 200void __xlocale_init(void); 201 202static inline __attribute__((always_inline)) locale_t 203__current_locale(void) 204{ 205#if TARGET_IPHONE_SIMULATOR 206 /* <rdar://problem/14136256> Crash in _objc_inform for duplicate class name during simulator launch 207 * TODO: Remove after the simulator's libSystem is initialized properly. 208 */ 209 if (__locale_key == (pthread_key_t)-1) { 210 return &__global_locale; 211 } 212#endif 213 214 locale_t __locale = (locale_t)pthread_getspecific(__locale_key); 215 return (__locale ? __locale : &__global_locale); 216} 217 218static inline __attribute__((always_inline)) locale_t 219__locale_ptr(locale_t __loc) 220{ 221 NORMALIZE_LOCALE(__loc); 222 return __loc; 223} 224 225__END_DECLS 226 227#endif /* _XLOCALE_PRIVATE_H_ */ 228