xlocale.c revision ea2741973acd73619da693548388a05527b92d57
1ea2741973acd73619da693548388a05527b92d57David Chisnall 2ea2741973acd73619da693548388a05527b92d57David Chisnall#ifdef __sun__ 3ea2741973acd73619da693548388a05527b92d57David Chisnall 4ea2741973acd73619da693548388a05527b92d57David Chisnall#include <stdio.h> 5ea2741973acd73619da693548388a05527b92d57David Chisnall#include <stdlib.h> 6ea2741973acd73619da693548388a05527b92d57David Chisnall#include <string.h> 7ea2741973acd73619da693548388a05527b92d57David Chisnall#include <dlfcn.h> 8ea2741973acd73619da693548388a05527b92d57David Chisnall#include <locale.h> 9ea2741973acd73619da693548388a05527b92d57David Chisnall#include <limits.h> 10ea2741973acd73619da693548388a05527b92d57David Chisnall#include <assert.h> 11ea2741973acd73619da693548388a05527b92d57David Chisnall#include <sys/localedef.h> 12ea2741973acd73619da693548388a05527b92d57David Chisnall#include "xlocale.h" 13ea2741973acd73619da693548388a05527b92d57David Chisnall 14ea2741973acd73619da693548388a05527b92d57David Chisnallstatic _LC_locale_t *__C_locale; 15ea2741973acd73619da693548388a05527b92d57David Chisnall 16ea2741973acd73619da693548388a05527b92d57David Chisnall#define FIX_LOCALE(l) l = (l == 0) ? __C_locale : l 17ea2741973acd73619da693548388a05527b92d57David Chisnall 18ea2741973acd73619da693548388a05527b92d57David Chisnall#include "mbsnrtowcs.inc" 19ea2741973acd73619da693548388a05527b92d57David Chisnall#include "wcsnrtombs.inc" 20ea2741973acd73619da693548388a05527b92d57David Chisnall 21ea2741973acd73619da693548388a05527b92d57David Chisnallsize_t __mb_cur_max(locale_t __l) { 22ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 23ea2741973acd73619da693548388a05527b92d57David Chisnall return (__l->lc_ctype->cmapp->cm_mb_cur_max); 24ea2741973acd73619da693548388a05527b92d57David Chisnall} 25ea2741973acd73619da693548388a05527b92d57David Chisnall 26ea2741973acd73619da693548388a05527b92d57David Chisnallwint_t btowc_l(int __c, locale_t __l) { 27ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 28ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->cmapp->core.user_api->btowc(__l->lc_ctype->cmapp, __c); 29ea2741973acd73619da693548388a05527b92d57David Chisnall} 30ea2741973acd73619da693548388a05527b92d57David Chisnall 31ea2741973acd73619da693548388a05527b92d57David Chisnallint wctob_l(wint_t __c, locale_t __l) { 32ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 33ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->cmapp->core.user_api->wctob(__l->lc_ctype->cmapp, __c); 34ea2741973acd73619da693548388a05527b92d57David Chisnall} 35ea2741973acd73619da693548388a05527b92d57David Chisnall 36ea2741973acd73619da693548388a05527b92d57David Chisnallsize_t wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) { 37ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 38ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->cmapp->core.user_api->wcrtomb(__l->lc_ctype->cmapp, 39ea2741973acd73619da693548388a05527b92d57David Chisnall __s, __wc, __ps); 40ea2741973acd73619da693548388a05527b92d57David Chisnall} 41ea2741973acd73619da693548388a05527b92d57David Chisnall 42ea2741973acd73619da693548388a05527b92d57David Chisnallsize_t mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, 43ea2741973acd73619da693548388a05527b92d57David Chisnall mbstate_t *__ps, locale_t __l) { 44ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 45ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->cmapp->core.user_api->mbrtowc(__l->lc_ctype->cmapp, 46ea2741973acd73619da693548388a05527b92d57David Chisnall __pwc, __s, __n, __ps); 47ea2741973acd73619da693548388a05527b92d57David Chisnall} 48ea2741973acd73619da693548388a05527b92d57David Chisnall 49ea2741973acd73619da693548388a05527b92d57David Chisnallint mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) { 50ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 51ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->cmapp->core.user_api->mbtowc(__l->lc_ctype->cmapp, 52ea2741973acd73619da693548388a05527b92d57David Chisnall __pwc, __pmb, __max); 53ea2741973acd73619da693548388a05527b92d57David Chisnall} 54ea2741973acd73619da693548388a05527b92d57David Chisnall 55ea2741973acd73619da693548388a05527b92d57David Chisnallsize_t mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) { 56ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 57ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->cmapp->core.user_api->mbrlen(__l->lc_ctype->cmapp, __s, 58ea2741973acd73619da693548388a05527b92d57David Chisnall __n, __ps); 59ea2741973acd73619da693548388a05527b92d57David Chisnall} 60ea2741973acd73619da693548388a05527b92d57David Chisnall 61ea2741973acd73619da693548388a05527b92d57David Chisnallstruct lconv *localeconv_l(locale_t __l) { 62ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 63ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->core.user_api->localeconv(__l); 64ea2741973acd73619da693548388a05527b92d57David Chisnall} 65ea2741973acd73619da693548388a05527b92d57David Chisnall 66ea2741973acd73619da693548388a05527b92d57David Chisnallsize_t mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, 67ea2741973acd73619da693548388a05527b92d57David Chisnall mbstate_t *__ps, locale_t __l) { 68ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 69ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->cmapp->core.user_api->mbsrtowcs(__l->lc_ctype->cmapp, 70ea2741973acd73619da693548388a05527b92d57David Chisnall __dest, __src, __len, __ps); 71ea2741973acd73619da693548388a05527b92d57David Chisnall} 72ea2741973acd73619da693548388a05527b92d57David Chisnall 73ea2741973acd73619da693548388a05527b92d57David Chisnallint wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t __l) { 74ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 75ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_collate->core.user_api->wcscoll(__l->lc_collate, 76ea2741973acd73619da693548388a05527b92d57David Chisnall __s1, __s2); 77ea2741973acd73619da693548388a05527b92d57David Chisnall} 78ea2741973acd73619da693548388a05527b92d57David Chisnall 79ea2741973acd73619da693548388a05527b92d57David Chisnallint strcoll_l(const char *__s1, const char *__s2, locale_t __l) { 80ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 81ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_collate->core.user_api->strcoll(__l->lc_collate, 82ea2741973acd73619da693548388a05527b92d57David Chisnall __s1, __s2); 83ea2741973acd73619da693548388a05527b92d57David Chisnall} 84ea2741973acd73619da693548388a05527b92d57David Chisnall 85ea2741973acd73619da693548388a05527b92d57David Chisnallsize_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t __l) { 86ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 87ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_collate->core.user_api->strxfrm(__l->lc_collate, 88ea2741973acd73619da693548388a05527b92d57David Chisnall __s1, __s2, __n); 89ea2741973acd73619da693548388a05527b92d57David Chisnall} 90ea2741973acd73619da693548388a05527b92d57David Chisnallsize_t strftime_l(char *__s, size_t __size, const char *__fmt, const struct tm 91ea2741973acd73619da693548388a05527b92d57David Chisnall *__tm, locale_t __l) { 92ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 93ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_time->core.user_api->strftime(__l->lc_time, 94ea2741973acd73619da693548388a05527b92d57David Chisnall __s, __size, __fmt, __tm); 95ea2741973acd73619da693548388a05527b92d57David Chisnall} 96ea2741973acd73619da693548388a05527b92d57David Chisnall 97ea2741973acd73619da693548388a05527b92d57David Chisnallsize_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n, 98ea2741973acd73619da693548388a05527b92d57David Chisnall locale_t __l) { 99ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 100ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_collate->core.user_api->wcsxfrm(__l->lc_collate, 101ea2741973acd73619da693548388a05527b92d57David Chisnall __ws1, __ws2, __n); 102ea2741973acd73619da693548388a05527b92d57David Chisnall} 103ea2741973acd73619da693548388a05527b92d57David Chisnall 104ea2741973acd73619da693548388a05527b92d57David Chisnall#define LOCALE_ISCTYPE(ctype, m) \ 105ea2741973acd73619da693548388a05527b92d57David Chisnall int is##ctype##_l(int __c, locale_t __l) { \ 106ea2741973acd73619da693548388a05527b92d57David Chisnall if ((__c < 0) || (__c > 255)) return 0;\ 107ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l);\ 108ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->mask[__c] & m;\ 109ea2741973acd73619da693548388a05527b92d57David Chisnall }\ 110ea2741973acd73619da693548388a05527b92d57David Chisnall int isw##ctype##_l(wchar_t __c, locale_t __l) { \ 111ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l);\ 112ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->core.user_api->iswctype(__l->lc_ctype, __c, m);\ 113ea2741973acd73619da693548388a05527b92d57David Chisnall } 114ea2741973acd73619da693548388a05527b92d57David Chisnall 115ea2741973acd73619da693548388a05527b92d57David ChisnallLOCALE_ISCTYPE(alnum, _ISALNUM) 116ea2741973acd73619da693548388a05527b92d57David ChisnallLOCALE_ISCTYPE(alpha, _ISALPHA) 117ea2741973acd73619da693548388a05527b92d57David ChisnallLOCALE_ISCTYPE(blank, _ISALPHA) 118ea2741973acd73619da693548388a05527b92d57David ChisnallLOCALE_ISCTYPE(cntrl, _ISCNTRL) 119ea2741973acd73619da693548388a05527b92d57David ChisnallLOCALE_ISCTYPE(digit, _ISDIGIT) 120ea2741973acd73619da693548388a05527b92d57David ChisnallLOCALE_ISCTYPE(graph, _ISGRAPH) 121ea2741973acd73619da693548388a05527b92d57David ChisnallLOCALE_ISCTYPE(lower, _ISLOWER) 122ea2741973acd73619da693548388a05527b92d57David ChisnallLOCALE_ISCTYPE(print, _ISPRINT) 123ea2741973acd73619da693548388a05527b92d57David ChisnallLOCALE_ISCTYPE(punct, _ISPUNCT) 124ea2741973acd73619da693548388a05527b92d57David ChisnallLOCALE_ISCTYPE(space, _ISSPACE) 125ea2741973acd73619da693548388a05527b92d57David ChisnallLOCALE_ISCTYPE(upper, _ISUPPER) 126ea2741973acd73619da693548388a05527b92d57David ChisnallLOCALE_ISCTYPE(xdigit, _ISXDIGIT) 127ea2741973acd73619da693548388a05527b92d57David Chisnall 128ea2741973acd73619da693548388a05527b92d57David Chisnallint iswctype_l(wint_t __c, wctype_t __m, locale_t __l) { 129ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l);\ 130ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->core.user_api->iswctype(__l->lc_ctype, __c, __m);\ 131ea2741973acd73619da693548388a05527b92d57David Chisnall} 132ea2741973acd73619da693548388a05527b92d57David Chisnall 133ea2741973acd73619da693548388a05527b92d57David Chisnallint toupper_l(int __c, locale_t __l) { 134ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 135ea2741973acd73619da693548388a05527b92d57David Chisnall if ((__c < 0) || (__c > __l->lc_ctype->max_upper)) return __c; 136ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->upper[__c]; 137ea2741973acd73619da693548388a05527b92d57David Chisnall} 138ea2741973acd73619da693548388a05527b92d57David Chisnallint tolower_l(int __c, locale_t __l) { 139ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 140ea2741973acd73619da693548388a05527b92d57David Chisnall if ((__c < 0) || (__c > __l->lc_ctype->max_lower)) return __c; 141ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->lower[__c]; 142ea2741973acd73619da693548388a05527b92d57David Chisnall} 143ea2741973acd73619da693548388a05527b92d57David Chisnallwint_t towupper_l(wint_t __c, locale_t __l) { 144ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 145ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->core.user_api->towupper(__l->lc_ctype, __c); 146ea2741973acd73619da693548388a05527b92d57David Chisnall} 147ea2741973acd73619da693548388a05527b92d57David Chisnallwint_t towlower_l(wint_t __c, locale_t __l) { 148ea2741973acd73619da693548388a05527b92d57David Chisnall FIX_LOCALE(__l); 149ea2741973acd73619da693548388a05527b92d57David Chisnall return __l->lc_ctype->core.user_api->towlower(__l->lc_ctype, __c); 150ea2741973acd73619da693548388a05527b92d57David Chisnall} 151ea2741973acd73619da693548388a05527b92d57David Chisnall 152ea2741973acd73619da693548388a05527b92d57David Chisnall// FIXME: This disregards the locale, which is Very Wrong 153ea2741973acd73619da693548388a05527b92d57David Chisnall#define vsnprintf_l(__s, __n, __l, __format, __va) \ 154ea2741973acd73619da693548388a05527b92d57David Chisnall vsnprintf(__s, __n, __format, __va) 155ea2741973acd73619da693548388a05527b92d57David Chisnall 156ea2741973acd73619da693548388a05527b92d57David Chisnallint sprintf_l(char *__s, locale_t __l, const char *__format, ...) { 157ea2741973acd73619da693548388a05527b92d57David Chisnall va_list __va; 158ea2741973acd73619da693548388a05527b92d57David Chisnall va_start(__va, __format); 159ea2741973acd73619da693548388a05527b92d57David Chisnall int __res = vsnprintf_l(__s, SIZE_MAX, __l, __format, __va); 160ea2741973acd73619da693548388a05527b92d57David Chisnall va_end(__va); 161ea2741973acd73619da693548388a05527b92d57David Chisnall return __res; 162ea2741973acd73619da693548388a05527b92d57David Chisnall} 163ea2741973acd73619da693548388a05527b92d57David Chisnall 164ea2741973acd73619da693548388a05527b92d57David Chisnallint snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) 165ea2741973acd73619da693548388a05527b92d57David Chisnall{ 166ea2741973acd73619da693548388a05527b92d57David Chisnall va_list __va; 167ea2741973acd73619da693548388a05527b92d57David Chisnall va_start(__va, __format); 168ea2741973acd73619da693548388a05527b92d57David Chisnall int __res = vsnprintf_l(__s, __n , __l, __format, __va); 169ea2741973acd73619da693548388a05527b92d57David Chisnall va_end(__va); 170ea2741973acd73619da693548388a05527b92d57David Chisnall return __res; 171ea2741973acd73619da693548388a05527b92d57David Chisnall} 172ea2741973acd73619da693548388a05527b92d57David Chisnall 173ea2741973acd73619da693548388a05527b92d57David Chisnallint asprintf_l(char **__s, locale_t __l, const char *__format, ...) { 174ea2741973acd73619da693548388a05527b92d57David Chisnall va_list __va; 175ea2741973acd73619da693548388a05527b92d57David Chisnall va_start(__va, __format); 176ea2741973acd73619da693548388a05527b92d57David Chisnall // FIXME: 177ea2741973acd73619da693548388a05527b92d57David Chisnall int __res = vasprintf(__s, __format, __va); 178ea2741973acd73619da693548388a05527b92d57David Chisnall va_end(__va); 179ea2741973acd73619da693548388a05527b92d57David Chisnall return __res; 180ea2741973acd73619da693548388a05527b92d57David Chisnall} 181ea2741973acd73619da693548388a05527b92d57David Chisnall 182ea2741973acd73619da693548388a05527b92d57David Chisnallint sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { 183ea2741973acd73619da693548388a05527b92d57David Chisnall va_list __va; 184ea2741973acd73619da693548388a05527b92d57David Chisnall va_start(__va, __format); 185ea2741973acd73619da693548388a05527b92d57David Chisnall // FIXME: 186ea2741973acd73619da693548388a05527b92d57David Chisnall int __res = vsscanf(__s, __format, __va); 187ea2741973acd73619da693548388a05527b92d57David Chisnall va_end(__va); 188ea2741973acd73619da693548388a05527b92d57David Chisnall return __res; 189ea2741973acd73619da693548388a05527b92d57David Chisnall} 190ea2741973acd73619da693548388a05527b92d57David Chisnall 191ea2741973acd73619da693548388a05527b92d57David Chisnalllocale_t newlocale(int mask, const char *locale, locale_t base) { 192ea2741973acd73619da693548388a05527b92d57David Chisnall 193ea2741973acd73619da693548388a05527b92d57David Chisnall if ((locale == NULL) || (locale[0] == '\0') || 194ea2741973acd73619da693548388a05527b92d57David Chisnall ((locale[0] == 'C') && (locale[1] == '\0'))) 195ea2741973acd73619da693548388a05527b92d57David Chisnall { 196ea2741973acd73619da693548388a05527b92d57David Chisnall return __C_locale; 197ea2741973acd73619da693548388a05527b92d57David Chisnall } 198ea2741973acd73619da693548388a05527b92d57David Chisnall 199ea2741973acd73619da693548388a05527b92d57David Chisnall // Solaris locales are shared libraries that contain 200ea2741973acd73619da693548388a05527b92d57David Chisnall char *path; 201ea2741973acd73619da693548388a05527b92d57David Chisnall#ifdef __LP64 202ea2741973acd73619da693548388a05527b92d57David Chisnall asprintf(&path, "/usr/lib/locale/%1$s/amd64/%1$s.so.3", locale); 203ea2741973acd73619da693548388a05527b92d57David Chisnall#else 204ea2741973acd73619da693548388a05527b92d57David Chisnall asprintf(&path, "/usr/lib/locale/%1$s/%1$s.so.3", locale); 205ea2741973acd73619da693548388a05527b92d57David Chisnall#endif 206ea2741973acd73619da693548388a05527b92d57David Chisnall void *handle = dlopen(path, RTLD_LOCAL | RTLD_NOW); 207ea2741973acd73619da693548388a05527b92d57David Chisnall free(path); 208ea2741973acd73619da693548388a05527b92d57David Chisnall if (!handle) 209ea2741973acd73619da693548388a05527b92d57David Chisnall return 0; 210ea2741973acd73619da693548388a05527b92d57David Chisnall _LC_locale_t *(*init)() = dlsym(handle, "instantiate"); 211ea2741973acd73619da693548388a05527b92d57David Chisnall if (!init) 212ea2741973acd73619da693548388a05527b92d57David Chisnall return 0; 213ea2741973acd73619da693548388a05527b92d57David Chisnall _LC_locale_t *p = init(); 214ea2741973acd73619da693548388a05527b92d57David Chisnall if (!p) 215ea2741973acd73619da693548388a05527b92d57David Chisnall return 0; 216ea2741973acd73619da693548388a05527b92d57David Chisnall 217ea2741973acd73619da693548388a05527b92d57David Chisnall if (!base) 218ea2741973acd73619da693548388a05527b92d57David Chisnall base = __C_locale; 219ea2741973acd73619da693548388a05527b92d57David Chisnall 220ea2741973acd73619da693548388a05527b92d57David Chisnall locale_t ret = calloc(1, sizeof(struct _LC_locale_t)); 221ea2741973acd73619da693548388a05527b92d57David Chisnall memcpy(ret, p, sizeof (_LC_locale_t)); 222ea2741973acd73619da693548388a05527b92d57David Chisnall ret->lc_collate = (mask & LC_COLLATE_MASK) ? p->lc_collate : base->lc_collate; 223ea2741973acd73619da693548388a05527b92d57David Chisnall ret->lc_ctype = (mask & LC_CTYPE_MASK) ? p->lc_ctype : base->lc_ctype; 224ea2741973acd73619da693548388a05527b92d57David Chisnall ret->lc_messages = (mask & LC_MESSAGES_MASK) ? p->lc_messages : base->lc_messages; 225ea2741973acd73619da693548388a05527b92d57David Chisnall ret->lc_monetary = (mask & LC_MONETARY_MASK) ? p->lc_monetary : base->lc_monetary; 226ea2741973acd73619da693548388a05527b92d57David Chisnall ret->lc_time = (mask & LC_TIME_MASK) ? p->lc_time : base->lc_time; 227ea2741973acd73619da693548388a05527b92d57David Chisnall return ret; 228ea2741973acd73619da693548388a05527b92d57David Chisnall} 229ea2741973acd73619da693548388a05527b92d57David Chisnall 230ea2741973acd73619da693548388a05527b92d57David Chisnallvoid freelocale(locale_t loc) 231ea2741973acd73619da693548388a05527b92d57David Chisnall{ 232ea2741973acd73619da693548388a05527b92d57David Chisnall if (loc != __C_locale) 233ea2741973acd73619da693548388a05527b92d57David Chisnall free(loc); 234ea2741973acd73619da693548388a05527b92d57David Chisnall} 235ea2741973acd73619da693548388a05527b92d57David Chisnall 236ea2741973acd73619da693548388a05527b92d57David Chisnall__attribute__((constructor)) 237ea2741973acd73619da693548388a05527b92d57David Chisnallstatic void setupCLocale(void) { 238ea2741973acd73619da693548388a05527b92d57David Chisnall // The default initial locale is the C locale. This is a statically 239ea2741973acd73619da693548388a05527b92d57David Chisnall // allocated locale inside libc. At program start, __lc_locale will point to 240ea2741973acd73619da693548388a05527b92d57David Chisnall // this. We need to grab a copy because it's not a public symbol. If we had 241ea2741973acd73619da693548388a05527b92d57David Chisnall // access to the source code for libc, then we'd just use it directly... 242ea2741973acd73619da693548388a05527b92d57David Chisnall assert('C' == setlocale(LC_ALL, 0)[0]); 243ea2741973acd73619da693548388a05527b92d57David Chisnall __C_locale = __lc_locale; 244ea2741973acd73619da693548388a05527b92d57David Chisnall} 245ea2741973acd73619da693548388a05527b92d57David Chisnall#endif 246