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