1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/stlport/src/c_locale_win32/c_locale_win32.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1786 @@ 1.4 +/* 1.5 + * Copyright (c) 1999 1.6 + * Silicon Graphics Computer Systems, Inc. 1.7 + * 1.8 + * Copyright (c) 1999 1.9 + * Boris Fomitchev 1.10 + * 1.11 + * Written 2000 1.12 + * Anton Lapach 1.13 + * 1.14 + * This material is provided "as is", with absolutely no warranty expressed 1.15 + * or implied. Any use is at your own risk. 1.16 + * 1.17 + * Permission to use or copy this software for any purpose is hereby granted 1.18 + * without fee, provided the above notices are retained on all copies. 1.19 + * Permission to modify the code and to distribute modified code is granted, 1.20 + * provided the above notices are retained, and a notice that the code was 1.21 + * modified is included with the above copyright notice. 1.22 + * 1.23 + */ 1.24 + 1.25 +#include <limits.h> 1.26 +#if defined (_STLP_MSVC) || defined (__ICL) 1.27 +# include <memory.h> 1.28 +#endif 1.29 +#include <string.h> 1.30 +#include <locale.h> 1.31 +#include <stdlib.h> 1.32 +#include <stdio.h> 1.33 + 1.34 +#if defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 1.35 +# define _STLP_STRCPY(D, DS, S) strcpy_s(D, DS, S) 1.36 +# define _STLP_STRNCPY(D, DS, S, C) strncpy_s(D, DS, S, C) 1.37 +# define _STLP_STRCAT(D, DS, S) strcat_s(D, DS, S) 1.38 +#else 1.39 +# define _STLP_STRCPY(D, DS, S) strcpy(D, S) 1.40 +# define _STLP_STRNCPY(D, DS, S, C) strncpy(D, S, C) 1.41 +# define _STLP_STRCAT(D, DS, S) strcat(D, S) 1.42 +#endif 1.43 + 1.44 +#if defined (__cplusplus) 1.45 +extern "C" { 1.46 +#endif 1.47 + 1.48 +/* Framework functions */ 1.49 +/* 1.50 + locale :: "lang[_country[.code_page]]" 1.51 + | ".code_page" 1.52 + | "" 1.53 + | NULL 1.54 + 1.55 +*/ 1.56 + 1.57 +typedef struct _LOCALECONV { 1.58 + const char* name; 1.59 + const char* abbrev; 1.60 +} LOCALECONV; 1.61 + 1.62 +#define MAX_LANG_LEN 64 /* max language name length */ 1.63 +#define MAX_CTRY_LEN 64 /* max country name length */ 1.64 +#define MAX_MODIFIER_LEN 0 /* max modifier name length - n/a */ 1.65 +#define MAX_LC_LEN (MAX_LANG_LEN+MAX_CTRY_LEN+MAX_MODIFIER_LEN+3) 1.66 + /* max entire locale string length */ 1.67 +#define MAX_CP_LEN 5 /* max code page name length */ 1.68 + 1.69 +#if !defined (LANG_INVARIANT) 1.70 +# define LANG_INVARIANT 0x7f 1.71 +# define _STLP_LANG_INVARIANT_DEFINED 1.72 +#endif 1.73 + 1.74 +#ifndef CP_UTF7 1.75 +# define CP_UTF7 65000 1.76 +#endif 1.77 + 1.78 +#ifndef CP_UTF8 1.79 +# define CP_UTF8 65001 1.80 +#endif 1.81 + 1.82 +#define INVARIANT_LCID MAKELCID(MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), SORT_DEFAULT) 1.83 + 1.84 +static const char *_C_name = "C"; 1.85 + 1.86 +/* non-NLS language string table */ 1.87 +static LOCALECONV __rg_language[] = { 1.88 + {"american", "ENU"}, 1.89 + {"american english", "ENU"}, 1.90 + {"american-english", "ENU"}, 1.91 + {"australian", "ENA"}, 1.92 + {"belgian", "NLB"}, 1.93 + {"canadian", "ENC"}, 1.94 + {"chh", "ZHH"}, 1.95 + {"chi", "ZHI"}, 1.96 + {"chinese", "CHS"}, 1.97 + {"chinese-hongkong", "ZHH"}, 1.98 + {"chinese-simplified", "CHS"}, 1.99 + {"chinese-singapore", "ZHI"}, 1.100 + {"chinese-traditional", "CHT"}, 1.101 + {"dutch-belgian", "NLB"}, 1.102 + {"english-american", "ENU"}, 1.103 + {"english-aus", "ENA"}, 1.104 + {"english-belize", "ENL"}, 1.105 + {"english-can", "ENC"}, 1.106 + {"english-caribbean", "ENB"}, 1.107 + {"english-ire", "ENI"}, 1.108 + {"english-jamaica", "ENJ"}, 1.109 + {"english-nz", "ENZ"}, 1.110 + {"english-south africa", "ENS"}, 1.111 + {"english-trinidad y tobago", "ENT"}, 1.112 + {"english-uk", "ENG"}, 1.113 + {"english-us", "ENU"}, 1.114 + {"english-usa", "ENU"}, 1.115 + {"french-belgian", "FRB"}, 1.116 + {"french-canadian", "FRC"}, 1.117 + {"french-luxembourg", "FRL"}, 1.118 + {"french-swiss", "FRS"}, 1.119 + {"german-austrian", "DEA"}, 1.120 + {"german-lichtenstein", "DEC"}, 1.121 + {"german-luxembourg", "DEL"}, 1.122 + {"german-swiss", "DES"}, 1.123 + {"irish-english", "ENI"}, 1.124 + {"italian-swiss", "ITS"}, 1.125 + {"norwegian", "NOR"}, 1.126 + {"norwegian-bokmal", "NOR"}, 1.127 + {"norwegian-nynorsk", "NON"}, 1.128 + {"portuguese-brazilian", "PTB"}, 1.129 + {"spanish-argentina", "ESS"}, 1.130 + {"spanish-bolivia", "ESB"}, 1.131 + {"spanish-chile", "ESL"}, 1.132 + {"spanish-colombia", "ESO"}, 1.133 + {"spanish-costa rica", "ESC"}, 1.134 + {"spanish-dominican republic", "ESD"}, 1.135 + {"spanish-ecuador", "ESF"}, 1.136 + {"spanish-el salvador", "ESE"}, 1.137 + {"spanish-guatemala", "ESG"}, 1.138 + {"spanish-honduras", "ESH"}, 1.139 + {"spanish-mexican", "ESM"}, 1.140 + {"spanish-modern", "ESN"}, 1.141 + {"spanish-nicaragua", "ESI"}, 1.142 + {"spanish-panama", "ESA"}, 1.143 + {"spanish-paraguay", "ESZ"}, 1.144 + {"spanish-peru", "ESR"}, 1.145 + {"spanish-puerto rico", "ESU"}, 1.146 + {"spanish-uruguay", "ESY"}, 1.147 + {"spanish-venezuela", "ESV"}, 1.148 + {"swedish-finland", "SVF"}, 1.149 + {"swiss", "DES"}, 1.150 + {"uk", "ENG"}, 1.151 + {"us", "ENU"}, 1.152 + {"usa", "ENU"} 1.153 +}; 1.154 + 1.155 +/* non-NLS country string table */ 1.156 +static LOCALECONV __rg_country[] = { 1.157 + {"america", "USA"}, 1.158 + {"britain", "GBR"}, 1.159 + {"china", "CHN"}, 1.160 + {"czech", "CZE"}, 1.161 + {"england", "GBR"}, 1.162 + {"great britain", "GBR"}, 1.163 + {"holland", "NLD"}, 1.164 + {"hong-kong", "HKG"}, 1.165 + {"new-zealand", "NZL"}, 1.166 + {"nz", "NZL"}, 1.167 + {"pr china", "CHN"}, 1.168 + {"pr-china", "CHN"}, 1.169 + {"puerto-rico", "PRI"}, 1.170 + {"slovak", "SVK"}, 1.171 + {"south africa", "ZAF"}, 1.172 + {"south korea", "KOR"}, 1.173 + {"south-africa", "ZAF"}, 1.174 + {"south-korea", "KOR"}, 1.175 + {"trinidad & tobago", "TTO"}, 1.176 + {"uk", "GBR"}, 1.177 + {"united-kingdom", "GBR"}, 1.178 + {"united-states", "USA"}, 1.179 + {"us", "USA"}, 1.180 +}; 1.181 + 1.182 +typedef struct _Locale_name_hint { 1.183 + LCID id; 1.184 +} _Locale_lcid_t; 1.185 + 1.186 +typedef struct _Locale_ctype { 1.187 + _Locale_lcid_t lc; 1.188 + UINT cp; 1.189 + unsigned short ctable[256]; 1.190 +} _Locale_ctype_t; 1.191 + 1.192 +typedef struct _Locale_numeric { 1.193 + _Locale_lcid_t lc; 1.194 + char cp[MAX_CP_LEN + 1]; 1.195 + char decimal_point[4]; 1.196 + char thousands_sep[4]; 1.197 + char *grouping; 1.198 +} _Locale_numeric_t; 1.199 + 1.200 +typedef struct _Locale_time { 1.201 + _Locale_lcid_t lc; 1.202 + char cp[MAX_CP_LEN + 1]; 1.203 + char *month[12]; 1.204 + char *abbrev_month[12]; 1.205 + char *dayofweek[7]; 1.206 + char *abbrev_dayofweek[7]; 1.207 + char *date_time_format; 1.208 + char *long_date_time_format; 1.209 + char *date_format; 1.210 + char *long_date_format; 1.211 + char *time_format; 1.212 + char am[9]; 1.213 + char pm[9]; 1.214 +} _Locale_time_t; 1.215 + 1.216 +typedef struct _Locale_collate { 1.217 + _Locale_lcid_t lc; 1.218 + char cp[MAX_CP_LEN + 1]; 1.219 +} _Locale_collate_t; 1.220 + 1.221 +typedef struct _Locale_monetary { 1.222 + _Locale_lcid_t lc; 1.223 + char cp[MAX_CP_LEN + 1]; 1.224 + char decimal_point[4]; 1.225 + char thousands_sep[4]; 1.226 + char *grouping; 1.227 + char int_curr_symbol[5]; /* 3 + 1 + 1 */ 1.228 + char curr_symbol[6]; 1.229 + char negative_sign[5]; 1.230 + char positive_sign[5]; 1.231 + int frac_digits; 1.232 + int int_frac_digits; 1.233 +} _Locale_monetary_t; 1.234 + 1.235 +/* Internal function */ 1.236 +static void __FixGrouping(char *grouping); 1.237 +static const char* __ConvertName(const char* lname, LOCALECONV* ConvTable, int TableSize); 1.238 +static int __ParseLocaleString(const char* lname, char* lang, char* ctry, char* page); 1.239 +static int __GetLCID(const char* lang, const char* ctry, LCID* lcid); 1.240 +static int __GetLCIDFromName(const char* lname, LCID* lcid, char *cp, _Locale_lcid_t *hint); 1.241 +static char const* __GetLocaleName(LCID lcid, const char* cp, char* buf); 1.242 +static char const* __Extract_locale_name(const char* loc, const char* category, char* buf); 1.243 +static char const* __TranslateToSystem(const char* lname, char* buf, _Locale_lcid_t* hint, int *__err_code); 1.244 +static void __GetLocaleInfoUsingACP(LCID lcid, const char* cp, LCTYPE lctype, char* buf, int buf_size, wchar_t* wbuf, int wbuf_size); 1.245 +static int __intGetACP(LCID lcid); 1.246 +static int __intGetOCP(LCID lcid); 1.247 +static int __GetDefaultCP(LCID lcid); 1.248 +static char* __ConvertToCP(int from_cp, int to_cp, const char *from, size_t size, size_t *ret_buf_size); 1.249 +static void my_ltoa(long __x, char* buf); 1.250 + 1.251 +void my_ltoa(long __x, char* buf) { 1.252 + char rbuf[64]; 1.253 + char* ptr = rbuf; 1.254 + 1.255 + if (__x == 0) 1.256 + *ptr++ = '0'; 1.257 + else { 1.258 + for (; __x != 0; __x /= 10) 1.259 + *ptr++ = (char)(__x % 10) + '0'; 1.260 + } 1.261 + while(ptr > rbuf) *buf++ = *--ptr; 1.262 + /* psw */ 1.263 + *buf = '\0'; 1.264 +} 1.265 + 1.266 +#if defined (__cplusplus) 1.267 +_STLP_BEGIN_NAMESPACE 1.268 +extern "C" { 1.269 +#endif 1.270 + 1.271 +_Locale_lcid_t* _Locale_get_ctype_hint(_Locale_ctype_t* ltype) 1.272 +{ return (ltype != 0) ? <ype->lc : 0; } 1.273 +_Locale_lcid_t* _Locale_get_numeric_hint(_Locale_numeric_t* lnumeric) 1.274 +{ return (lnumeric != 0) ? &lnumeric->lc : 0; } 1.275 +_Locale_lcid_t* _Locale_get_time_hint(_Locale_time_t* ltime) 1.276 +{ return (ltime != 0) ? <ime->lc : 0; } 1.277 +_Locale_lcid_t* _Locale_get_collate_hint(_Locale_collate_t* lcollate) 1.278 +{ return (lcollate != 0) ? &lcollate->lc : 0; } 1.279 +_Locale_lcid_t* _Locale_get_monetary_hint(_Locale_monetary_t* lmonetary) 1.280 +{ return (lmonetary != 0) ? &lmonetary->lc : 0; } 1.281 +_Locale_lcid_t* _Locale_get_messages_hint(struct _Locale_messages* lmessages) { 1.282 + _STLP_MARK_PARAMETER_AS_UNUSED(lmessages) 1.283 + return 0; 1.284 +} 1.285 + 1.286 +#define MAP(x, y) if ((mask & x) != 0) ret |= (y) 1.287 +unsigned short MapCtypeMask(unsigned short mask) { 1.288 + unsigned short ret = 0; 1.289 + MAP(C1_UPPER, _Locale_UPPER | _Locale_PRINT); 1.290 + MAP(C1_LOWER, _Locale_LOWER | _Locale_PRINT); 1.291 + MAP(C1_DIGIT, _Locale_DIGIT | _Locale_PRINT); 1.292 + MAP(C1_SPACE, _Locale_SPACE | _Locale_PRINT); 1.293 + MAP(C1_PUNCT, _Locale_PUNCT | _Locale_PRINT); 1.294 + /* MAP(C1_BLANK, ?); */ 1.295 + MAP(C1_XDIGIT, _Locale_XDIGIT | _Locale_PRINT); 1.296 + MAP(C1_ALPHA, _Locale_ALPHA | _Locale_PRINT); 1.297 + if ((mask & C1_CNTRL) != 0) { ret |= _Locale_CNTRL; ret &= ~_Locale_PRINT; } 1.298 + return ret; 1.299 +} 1.300 + 1.301 +static void MapCtypeMasks(unsigned short *cur, unsigned short *end) { 1.302 + for (; cur != end; ++cur) { 1.303 + *cur = MapCtypeMask(*cur); 1.304 + } 1.305 +} 1.306 + 1.307 +_Locale_ctype_t* _Locale_ctype_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) { 1.308 + char cp_name[MAX_CP_LEN + 1]; 1.309 + int NativeCP; 1.310 + unsigned char Buffer[256]; 1.311 + unsigned char *ptr; 1.312 + CPINFO CPInfo; 1.313 + int i; 1.314 + wchar_t *wbuffer; 1.315 + int BufferSize; 1.316 + 1.317 + _Locale_ctype_t *ltype = (_Locale_ctype_t*)malloc(sizeof(_Locale_ctype_t)); 1.318 + 1.319 + if (!ltype) { *__err_code = _STLP_LOC_NO_MEMORY; return ltype; } 1.320 + memset(ltype, 0, sizeof(_Locale_ctype_t)); 1.321 + 1.322 + if (__GetLCIDFromName(name, <ype->lc.id, cp_name, lc_hint) == -1) 1.323 + { free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } 1.324 + 1.325 +#if defined (__BORLANDC__) 1.326 + if ( ltype->lc.id == INVARIANT_LCID && name[0] == 'C' && name[1] == 0 ) 1.327 + { ltype->lc.id = 0x409; } 1.328 +#endif 1.329 + 1.330 + ltype->cp = atoi(cp_name); 1.331 + 1.332 + NativeCP = __GetDefaultCP(ltype->lc.id); 1.333 + 1.334 + /* Make table with all characters. */ 1.335 + for (i = 0; i < 256; ++i) Buffer[i] = (unsigned char)i; 1.336 + 1.337 + if (!GetCPInfo(NativeCP, &CPInfo)) { free(ltype); return NULL; } 1.338 + 1.339 + if (CPInfo.MaxCharSize > 1) { 1.340 + for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr+=2) 1.341 + for (i = *ptr; i <= *(ptr + 1); ++i) Buffer[i] = 0; 1.342 + } 1.343 + 1.344 + if ((UINT)NativeCP != ltype->cp) { 1.345 + OSVERSIONINFO ver_info; 1.346 + ver_info.dwOSVersionInfoSize = sizeof(ver_info); 1.347 + GetVersionEx(&ver_info); 1.348 + if (ver_info.dwPlatformId == VER_PLATFORM_WIN32_NT) { 1.349 + /* Convert character sequence to Unicode. */ 1.350 + BufferSize = MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, NULL, 0); 1.351 + if (!BufferSize) { free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } 1.352 + wbuffer = (wchar_t*)malloc(BufferSize * sizeof(wchar_t)); 1.353 + if (!wbuffer) { free(ltype); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.354 + MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize); 1.355 + 1.356 + GetStringTypeW(CT_CTYPE1, wbuffer, 256, ltype->ctable); 1.357 + MapCtypeMasks(ltype->ctable, ltype->ctable + 256); 1.358 + free(wbuffer); 1.359 + } 1.360 + else { 1.361 + unsigned short ctable[256]; 1.362 + unsigned char TargetBuffer[256]; 1.363 + GetStringTypeA(ltype->lc.id, CT_CTYPE1, (const char*)Buffer, 256, ctable); 1.364 + 1.365 + /* Convert character sequence to target code page. */ 1.366 + BufferSize = MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, NULL, 0); 1.367 + if (!BufferSize) { free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } 1.368 + wbuffer = (wchar_t*)malloc(BufferSize * sizeof(wchar_t)); 1.369 + if (!wbuffer) { free(ltype); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.370 + MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize); 1.371 + if (!WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuffer, BufferSize, (char*)TargetBuffer, 256, NULL, FALSE)) 1.372 + { free(wbuffer); free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } 1.373 + 1.374 + free(wbuffer); 1.375 + 1.376 + /* Translate ctype table. */ 1.377 + for (i = 0; i < 256; ++i) { 1.378 + if (!TargetBuffer[i]) continue; 1.379 + ltype->ctable[TargetBuffer[i]] = MapCtypeMask(ctable[i]); 1.380 + } 1.381 + } 1.382 + } 1.383 + else { 1.384 + GetStringTypeA(ltype->lc.id, CT_CTYPE1, (const char*)Buffer, 256, ltype->ctable); 1.385 + MapCtypeMasks(ltype->ctable, ltype->ctable + 256); 1.386 + } 1.387 + return ltype; 1.388 +} 1.389 + 1.390 +_Locale_numeric_t* _Locale_numeric_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) { 1.391 + wchar_t wbuf[4]; 1.392 + char *GroupingBuffer; 1.393 + int BufferSize; 1.394 + 1.395 + _Locale_numeric_t *lnum = (_Locale_numeric_t*)malloc(sizeof(_Locale_numeric_t)); 1.396 + if (!lnum) { *__err_code = _STLP_LOC_NO_MEMORY; return lnum; } 1.397 + memset(lnum, 0, sizeof(_Locale_numeric_t)); 1.398 + 1.399 + if (__GetLCIDFromName(name, &lnum->lc.id, lnum->cp, lc_hint) == -1) 1.400 + { free(lnum); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } 1.401 + 1.402 +#if defined (__BORLANDC__) 1.403 + if (lnum->lc.id != INVARIANT_LCID) { 1.404 +#endif 1.405 + __GetLocaleInfoUsingACP(lnum->lc.id, lnum->cp, LOCALE_SDECIMAL, lnum->decimal_point, 4, wbuf, 4); 1.406 + __GetLocaleInfoUsingACP(lnum->lc.id, lnum->cp, LOCALE_STHOUSAND, lnum->thousands_sep, 4, wbuf, 4); 1.407 +#if defined (__BORLANDC__) 1.408 + } 1.409 + else 1.410 + lnum->decimal_point[0] = '.'; 1.411 +#endif 1.412 + 1.413 + if (lnum->lc.id != INVARIANT_LCID) { 1.414 + BufferSize = GetLocaleInfoA(lnum->lc.id, LOCALE_SGROUPING, NULL, 0); 1.415 + GroupingBuffer = (char*)malloc(BufferSize); 1.416 + if (!GroupingBuffer) { free(lnum); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.417 + GetLocaleInfoA(lnum->lc.id, LOCALE_SGROUPING, GroupingBuffer, BufferSize); 1.418 + __FixGrouping(GroupingBuffer); 1.419 + lnum->grouping = GroupingBuffer; 1.420 + } 1.421 + else { 1.422 + lnum->grouping = (char*)malloc(1); 1.423 + if (!lnum->grouping) { free(lnum); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.424 + lnum->grouping[0] = 0; 1.425 + } 1.426 + 1.427 + return lnum; 1.428 +} 1.429 + 1.430 +static int __ConvertDate(const char *NTDate, char *buffer, int buf_size) { 1.431 + /* This function will return an incomplete buffer if buffer is not long enough */ 1.432 + const char *cur_char; 1.433 + char *cur_output, *end_output; 1.434 + 1.435 + /* Correct time format. */ 1.436 + cur_char = NTDate; 1.437 + cur_output = buffer; 1.438 + end_output = cur_output + buf_size; 1.439 + buf_size = 0; 1.440 + while (*cur_char) { 1.441 + if (cur_output && (cur_output == end_output)) break; 1.442 + switch (*cur_char) { 1.443 + case 'd': 1.444 + { 1.445 + if (*(cur_char + 1) == 'd') { 1.446 + if (cur_output && (cur_output + 2 > end_output)) { 1.447 + *cur_output = 0; 1.448 + return ++buf_size; 1.449 + } 1.450 + if (*(cur_char + 2) == 'd') { 1.451 + if (*(cur_char + 3) == 'd') { 1.452 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'A'; } 1.453 + buf_size += 2; 1.454 + cur_char += 3; 1.455 + } 1.456 + else { 1.457 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'a'; } 1.458 + buf_size += 2; 1.459 + cur_char += 2; 1.460 + } 1.461 + } 1.462 + else { 1.463 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'd'; } 1.464 + buf_size += 2; 1.465 + cur_char++; 1.466 + } 1.467 + } 1.468 + else { 1.469 + if (cur_output && (cur_output + 3 > end_output)) { 1.470 + *cur_output = 0; 1.471 + return ++buf_size; 1.472 + } 1.473 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'd'; } 1.474 + buf_size += 3; 1.475 + } 1.476 + } 1.477 + break; 1.478 + case 'M': 1.479 + { 1.480 + if (*(cur_char + 1) == 'M') { 1.481 + if (cur_output && (cur_output + 2 > end_output)) { 1.482 + *cur_output = 0; 1.483 + return ++buf_size; 1.484 + } 1.485 + if (*(cur_char + 2) == 'M') { 1.486 + if (*(cur_char + 3) == 'M') { 1.487 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'B'; } 1.488 + buf_size += 2; 1.489 + cur_char += 3; 1.490 + } 1.491 + else { 1.492 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'b'; } 1.493 + buf_size += 2; 1.494 + cur_char += 2; 1.495 + } 1.496 + } 1.497 + else { 1.498 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'm'; } 1.499 + buf_size += 2; 1.500 + cur_char++; 1.501 + } 1.502 + } 1.503 + else { 1.504 + if (cur_output && (cur_output + 3 > end_output)) { 1.505 + *cur_output = 0; 1.506 + return ++buf_size; 1.507 + } 1.508 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'm'; } 1.509 + buf_size += 3; 1.510 + } 1.511 + } 1.512 + break; 1.513 + case 'y': 1.514 + { 1.515 + if (*(cur_char + 1) == 'y') { 1.516 + if (cur_output && (cur_output + 2 > end_output)) { 1.517 + *cur_output = 0; 1.518 + return ++buf_size; 1.519 + } 1.520 + if (*(cur_char + 2) == 'y' && *(cur_char + 3) == 'y') { 1.521 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'Y'; } 1.522 + buf_size += 2; 1.523 + cur_char += 3; 1.524 + } 1.525 + else { 1.526 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'y'; } 1.527 + buf_size += 2; 1.528 + cur_char++; 1.529 + } 1.530 + } 1.531 + else { 1.532 + if (cur_output && (cur_output + 3 > end_output)) { 1.533 + *cur_output = 0; 1.534 + return ++buf_size; 1.535 + } 1.536 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'y'; } 1.537 + buf_size += 3; 1.538 + } 1.539 + } 1.540 + break; 1.541 + case '%': 1.542 + { 1.543 + if (cur_output && (cur_output + 2 > end_output)) { 1.544 + *cur_output = 0; 1.545 + return ++buf_size; 1.546 + } 1.547 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '%'; } 1.548 + buf_size += 2; 1.549 + } 1.550 + break; 1.551 + case '\'': 1.552 + { 1.553 + ++cur_char; 1.554 + while (*cur_char != '\'' && *cur_char != 0 && (cur_output == NULL || cur_output != end_output)) { 1.555 + if (cur_output) { *cur_output++ = *cur_char; } 1.556 + ++cur_char; 1.557 + buf_size += 1; 1.558 + } 1.559 + } 1.560 + break; 1.561 + default: 1.562 + { 1.563 + if (cur_output) { *(cur_output++) = *cur_char; } 1.564 + buf_size += 1; 1.565 + } 1.566 + break; 1.567 + } 1.568 + if (*cur_char == 0) break; 1.569 + ++cur_char; 1.570 + } 1.571 + 1.572 + if (!cur_output || cur_output != end_output) { 1.573 + if (cur_output) *cur_output = 0; 1.574 + buf_size += 1; 1.575 + } 1.576 + else { 1.577 + /* We trunc result */ 1.578 + *(--cur_output) = 0; 1.579 + } 1.580 + 1.581 + return buf_size; 1.582 +} 1.583 + 1.584 +static int __ConvertTime(const char *NTTime, char *buffer, int buf_size) { 1.585 + const char *cur_char; 1.586 + char *cur_output, *end_output; 1.587 + cur_char = NTTime; 1.588 + cur_output = buffer; 1.589 + end_output = cur_output + buf_size; 1.590 + buf_size = 0; 1.591 + while (*cur_char) { 1.592 + switch(*cur_char) { 1.593 + case 'h': 1.594 + if (*(cur_char + 1) == 'h') { 1.595 + if (cur_output && (cur_output + 2 > end_output)) { 1.596 + *cur_output = 0; 1.597 + return ++buf_size; 1.598 + } 1.599 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'I'; } 1.600 + buf_size += 2; 1.601 + ++cur_char; 1.602 + } 1.603 + else { 1.604 + if (cur_output && (cur_output + 3 > end_output)) { 1.605 + *cur_output = 0; 1.606 + return ++buf_size; 1.607 + } 1.608 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'I'; } 1.609 + buf_size += 3; 1.610 + } 1.611 + break; 1.612 + case 'H': 1.613 + if (*(cur_char + 1) == 'H') { 1.614 + if (cur_output && (cur_output + 2 > end_output)) { 1.615 + *cur_output = 0; 1.616 + return ++buf_size; 1.617 + } 1.618 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'H'; } 1.619 + buf_size += 2; 1.620 + ++cur_char; 1.621 + } 1.622 + else { 1.623 + if (cur_output && (cur_output + 3 > end_output)) { 1.624 + *cur_output = 0; 1.625 + return ++buf_size; 1.626 + } 1.627 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'H'; } 1.628 + buf_size += 3; 1.629 + } 1.630 + break; 1.631 + case 'm': 1.632 + if (*(cur_char + 1) == 'm') { 1.633 + if (cur_output && (cur_output + 2 > end_output)) { 1.634 + *cur_output = 0; 1.635 + return ++buf_size; 1.636 + } 1.637 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'M'; } 1.638 + buf_size += 2; 1.639 + cur_char++; 1.640 + } 1.641 + else { 1.642 + if (cur_output && (cur_output + 3 > end_output)) { 1.643 + *cur_output = 0; 1.644 + return ++buf_size; 1.645 + } 1.646 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'M'; } 1.647 + buf_size += 3; 1.648 + } 1.649 + break; 1.650 + case 's': 1.651 + if (*(cur_char + 1) == 's') { 1.652 + if (cur_output && (cur_output + 2 > end_output)) { 1.653 + *cur_output = 0; 1.654 + return ++buf_size; 1.655 + } 1.656 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'S'; } 1.657 + buf_size += 2; 1.658 + ++cur_char; 1.659 + } 1.660 + else { 1.661 + if (cur_output && (cur_output + 3 > end_output)) { 1.662 + *cur_output = 0; 1.663 + return ++buf_size; 1.664 + } 1.665 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = '#'; *(cur_output++) = 'S'; } 1.666 + buf_size += 3; 1.667 + } 1.668 + break; 1.669 + case 't': 1.670 + if (*(cur_char + 1) == 't') 1.671 + ++cur_char; 1.672 + if (cur_output && (cur_output + 2 > end_output)) { 1.673 + *cur_output = 0; 1.674 + return ++buf_size; 1.675 + } 1.676 + if (cur_output) { *(cur_output++) = '%'; *(cur_output++) = 'p'; } 1.677 + buf_size += 2; 1.678 + break; 1.679 + case '%': 1.680 + if (cur_output && (cur_output + 2 > end_output)) { 1.681 + *cur_output = 0; 1.682 + return ++buf_size; 1.683 + } 1.684 + if (cur_output) { *(cur_output++)='%'; *(cur_output++)='%'; } 1.685 + buf_size += 2; 1.686 + break; 1.687 + case '\'': 1.688 + ++cur_char; 1.689 + while (*cur_char != '\'' && *cur_char != 0 && (!cur_output || (cur_output != end_output))) { 1.690 + if (cur_output) *cur_output++ = *cur_char; 1.691 + ++cur_char; 1.692 + buf_size += 1; 1.693 + } 1.694 + break; 1.695 + default: 1.696 + if (cur_output) { *(cur_output++) = *cur_char; } 1.697 + buf_size += 1; 1.698 + break; 1.699 + } 1.700 + if (*cur_char == 0) break; 1.701 + ++cur_char; 1.702 + } 1.703 + 1.704 + if (!cur_output || cur_output != end_output) { 1.705 + if (cur_output) *cur_output = 0; 1.706 + buf_size += 1; 1.707 + } 1.708 + else { 1.709 + /* We trunc result */ 1.710 + *(--cur_output) = 0; 1.711 + } 1.712 + 1.713 + return buf_size; 1.714 +} 1.715 + 1.716 +_Locale_time_t* _Locale_time_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) { 1.717 + int size, month, dayofweek; 1.718 + size_t length; 1.719 + char fmt80[80]; 1.720 + wchar_t wbuf80[80]; 1.721 + 1.722 + _Locale_time_t *ltime = (_Locale_time_t*)malloc(sizeof(_Locale_time_t)); 1.723 + 1.724 + if (!ltime) { *__err_code = _STLP_LOC_NO_MEMORY; return ltime; } 1.725 + memset(ltime, 0, sizeof(_Locale_time_t)); 1.726 + 1.727 + if (__GetLCIDFromName(name, <ime->lc.id, ltime->cp, lc_hint) == -1) 1.728 + { free(ltime); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } 1.729 + 1.730 +#if defined (__BORLANDC__) 1.731 + if ( ltime->lc.id == INVARIANT_LCID && name[0] == 'C' && name[1] == 0 ) 1.732 + { ltime->lc.id = 0x409; } 1.733 +#endif 1.734 + 1.735 + for (month = LOCALE_SMONTHNAME1; month <= LOCALE_SMONTHNAME12; ++month) { /* Small hack :-) */ 1.736 + size = GetLocaleInfoA(ltime->lc.id, month, NULL, 0); 1.737 + ltime->month[month - LOCALE_SMONTHNAME1] = (char*)malloc(size); 1.738 + if (!ltime->month[month - LOCALE_SMONTHNAME1]) 1.739 + { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.740 + __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, month, ltime->month[month - LOCALE_SMONTHNAME1], size, wbuf80, 80); 1.741 + } 1.742 + 1.743 + for (month = LOCALE_SABBREVMONTHNAME1; month <= LOCALE_SABBREVMONTHNAME12; ++month) { 1.744 + size = GetLocaleInfoA(ltime->lc.id, month, NULL, 0); 1.745 + ltime->abbrev_month[month - LOCALE_SABBREVMONTHNAME1] = (char*)malloc(size); 1.746 + if (!ltime->abbrev_month[month - LOCALE_SABBREVMONTHNAME1]) 1.747 + { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.748 + __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, month, ltime->abbrev_month[month - LOCALE_SABBREVMONTHNAME1], size, wbuf80, 80); 1.749 + } 1.750 + 1.751 + for (dayofweek = LOCALE_SDAYNAME1; dayofweek <= LOCALE_SDAYNAME7; ++dayofweek) { 1.752 + int dayindex = ( dayofweek != LOCALE_SDAYNAME7 ) ? dayofweek - LOCALE_SDAYNAME1 + 1 : 0; 1.753 + size = GetLocaleInfoA(ltime->lc.id, dayofweek, NULL, 0); 1.754 + ltime->dayofweek[dayindex] = (char*)malloc(size); 1.755 + if (!ltime->dayofweek[dayindex]) 1.756 + { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.757 + __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, dayofweek, ltime->dayofweek[dayindex], size, wbuf80, 80); 1.758 + } 1.759 + 1.760 + for (dayofweek = LOCALE_SABBREVDAYNAME1; dayofweek <= LOCALE_SABBREVDAYNAME7; ++dayofweek) { 1.761 + int dayindex = ( dayofweek != LOCALE_SABBREVDAYNAME7 ) ? dayofweek - LOCALE_SABBREVDAYNAME1 + 1 : 0; 1.762 + size = GetLocaleInfoA(ltime->lc.id, dayofweek, NULL, 0); 1.763 + ltime->abbrev_dayofweek[dayindex] = (char*)malloc(size); 1.764 + if (!ltime->abbrev_dayofweek[dayindex]) 1.765 + { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.766 + __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, dayofweek, ltime->abbrev_dayofweek[dayindex], size, wbuf80, 80); 1.767 + } 1.768 + 1.769 + __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, LOCALE_SSHORTDATE, fmt80, 80, wbuf80, 80); 1.770 + size = __ConvertDate(fmt80, NULL, 0); 1.771 + ltime->date_format = (char*)malloc(size); 1.772 + if (!ltime->date_format) 1.773 + { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.774 + __ConvertDate(fmt80, ltime->date_format, size); 1.775 + 1.776 + __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, LOCALE_SLONGDATE, fmt80, 80, wbuf80, 80); 1.777 + size = __ConvertDate(fmt80, NULL, 0); 1.778 + ltime->long_date_format = (char*)malloc(size); 1.779 + if (!ltime->long_date_format) 1.780 + { _Locale_time_destroy(ltime);*__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.781 + __ConvertDate(fmt80, ltime->long_date_format, size); 1.782 + 1.783 + __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, LOCALE_STIMEFORMAT, fmt80, 80, wbuf80, 80); 1.784 + size = __ConvertTime(fmt80, NULL, 0); 1.785 + ltime->time_format = (char*)malloc(size); 1.786 + if (!ltime->time_format) 1.787 + { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.788 + __ConvertTime(fmt80, ltime->time_format, size); 1.789 + 1.790 + /* NT doesn't provide this information, we must simulate. */ 1.791 + length = strlen(ltime->date_format) + strlen(ltime->time_format) + 1 /* space */ + 1 /* trailing 0 */; 1.792 + ltime->date_time_format = (char*)malloc(length); 1.793 + if (!ltime->date_time_format) 1.794 + { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.795 + _STLP_STRCPY(ltime->date_time_format, length, ltime->date_format); 1.796 + _STLP_STRCAT(ltime->date_time_format, length, " "); 1.797 + _STLP_STRCAT(ltime->date_time_format, length, ltime->time_format); 1.798 + 1.799 + /* NT doesn't provide this information, we must simulate. */ 1.800 + length = strlen(ltime->long_date_format) + strlen(ltime->time_format) + 1 /* space */ + 1 /* trailing 0 */; 1.801 + ltime->long_date_time_format = (char*)malloc(length); 1.802 + if (!ltime->long_date_time_format) 1.803 + { _Locale_time_destroy(ltime); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } 1.804 + _STLP_STRCPY(ltime->long_date_time_format, length, ltime->long_date_format); 1.805 + _STLP_STRCAT(ltime->long_date_time_format, length, " "); 1.806 + _STLP_STRCAT(ltime->long_date_time_format, length, ltime->time_format); 1.807 + 1.808 + __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, LOCALE_S1159, ltime->am, 9, wbuf80, 80); 1.809 + __GetLocaleInfoUsingACP(ltime->lc.id, ltime->cp, LOCALE_S2359, ltime->pm, 9, wbuf80, 80); 1.810 + 1.811 + return ltime; 1.812 +} 1.813 + 1.814 +_Locale_collate_t* _Locale_collate_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) { 1.815 + _Locale_collate_t *lcol = (_Locale_collate_t*)malloc(sizeof(_Locale_collate_t)); 1.816 + if (!lcol) { *__err_code = _STLP_LOC_NO_MEMORY; return lcol; } 1.817 + memset(lcol, 0, sizeof(_Locale_collate_t)); 1.818 + 1.819 + if (__GetLCIDFromName(name, &lcol->lc.id, lcol->cp, lc_hint) == -1) 1.820 + { free(lcol); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } 1.821 + 1.822 +#if defined (__BORLANDC__) 1.823 + if ( lcol->lc.id == INVARIANT_LCID && name[0] == 'C' && name[1] == 0 ) 1.824 + { lcol->lc.id = 0x409; } 1.825 +#endif 1.826 + 1.827 + return lcol; 1.828 +} 1.829 + 1.830 +_Locale_monetary_t* _Locale_monetary_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) { 1.831 + char *GroupingBuffer; 1.832 + int BufferSize; 1.833 + char FracDigits[3]; 1.834 + wchar_t wbuf[6]; 1.835 + 1.836 + _Locale_monetary_t *lmon = (_Locale_monetary_t*)malloc(sizeof(_Locale_monetary_t)); 1.837 + if (!lmon) { *__err_code = _STLP_LOC_NO_MEMORY; return lmon; } 1.838 + memset(lmon, 0, sizeof(_Locale_monetary_t)); 1.839 + 1.840 + if (__GetLCIDFromName(name, &lmon->lc.id, lmon->cp, lc_hint) == -1) 1.841 + { free(lmon); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } 1.842 + 1.843 + if (lmon->lc.id != INVARIANT_LCID) { 1.844 + /* Extract information about monetary system */ 1.845 + __GetLocaleInfoUsingACP(lmon->lc.id, lmon->cp, LOCALE_SDECIMAL, lmon->decimal_point, 4, wbuf, 6); 1.846 + __GetLocaleInfoUsingACP(lmon->lc.id, lmon->cp, LOCALE_STHOUSAND, lmon->thousands_sep, 4, wbuf, 6); 1.847 + 1.848 + BufferSize = GetLocaleInfoA(lmon->lc.id, LOCALE_SGROUPING, NULL, 0); 1.849 + GroupingBuffer = (char*)malloc(BufferSize); 1.850 + if (!GroupingBuffer) 1.851 + { lmon->grouping = NULL; *__err_code = _STLP_LOC_NO_MEMORY; return lmon; } 1.852 + GetLocaleInfoA(lmon->lc.id, LOCALE_SGROUPING, GroupingBuffer, BufferSize); 1.853 + __FixGrouping(GroupingBuffer); 1.854 + lmon->grouping = GroupingBuffer; 1.855 + 1.856 + __GetLocaleInfoUsingACP(lmon->lc.id, lmon->cp, LOCALE_SCURRENCY, lmon->curr_symbol, 6, wbuf, 6); 1.857 + __GetLocaleInfoUsingACP(lmon->lc.id, lmon->cp, LOCALE_SNEGATIVESIGN, lmon->negative_sign, 5, wbuf, 6); 1.858 + __GetLocaleInfoUsingACP(lmon->lc.id, lmon->cp, LOCALE_SPOSITIVESIGN, lmon->positive_sign, 5, wbuf, 6); 1.859 + 1.860 + GetLocaleInfoA(lmon->lc.id, LOCALE_ICURRDIGITS, FracDigits, 3); 1.861 + lmon->frac_digits = atoi(FracDigits); 1.862 + 1.863 + GetLocaleInfoA(lmon->lc.id, LOCALE_IINTLCURRDIGITS, FracDigits, 3); 1.864 + lmon->int_frac_digits = atoi(FracDigits); 1.865 + 1.866 + __GetLocaleInfoUsingACP(lmon->lc.id, lmon->cp, LOCALE_SINTLSYMBOL, lmon->int_curr_symbol, 5, wbuf, 6); 1.867 + /* Even if Platform SDK documentation says that the returned symbol should 1.868 + * be a 3 letters symbol followed by a seperation character, experimentation 1.869 + * has shown that no seperation character is ever appended. We are adding it 1.870 + * ourself to conform to the POSIX specification. 1.871 + */ 1.872 + if (lmon->int_curr_symbol[3] == 0) { 1.873 + lmon->int_curr_symbol[3] = ' '; 1.874 + lmon->int_curr_symbol[4] = 0; 1.875 + } 1.876 + } 1.877 + /* else it is already ok */ 1.878 + 1.879 + return lmon; 1.880 +} 1.881 + 1.882 +struct _Locale_messages* _Locale_messages_create(const char *name, _Locale_lcid_t* lc_hint, int *__err_code) { 1.883 + /* The Win32 API has no support for messages facet */ 1.884 + _STLP_MARK_PARAMETER_AS_UNUSED(name) 1.885 + _STLP_MARK_PARAMETER_AS_UNUSED(lc_hint) 1.886 + *__err_code = _STLP_LOC_UNSUPPORTED_FACET_CATEGORY; 1.887 + return NULL; 1.888 +} 1.889 + 1.890 +static const char* _Locale_common_default(char* buf) { 1.891 + char cp[MAX_CP_LEN + 1]; 1.892 + int CodePage = __GetDefaultCP(LOCALE_USER_DEFAULT); 1.893 + my_ltoa(CodePage, cp); 1.894 + return __GetLocaleName(LOCALE_USER_DEFAULT, cp, buf); 1.895 +} 1.896 + 1.897 +const char* _Locale_ctype_default(char* buf) 1.898 +{ return _Locale_common_default(buf); } 1.899 + 1.900 +const char* _Locale_numeric_default(char * buf) 1.901 +{ return _Locale_common_default(buf); } 1.902 + 1.903 +const char* _Locale_time_default(char* buf) 1.904 +{ return _Locale_common_default(buf); } 1.905 + 1.906 +const char* _Locale_collate_default(char* buf) 1.907 +{ return _Locale_common_default(buf); } 1.908 + 1.909 +const char* _Locale_monetary_default(char* buf) 1.910 +{ return _Locale_common_default(buf); } 1.911 + 1.912 +const char* _Locale_messages_default(char* buf) 1.913 +{ return _Locale_common_default(buf); } 1.914 + 1.915 +char const* _Locale_ctype_name(const _Locale_ctype_t* ltype, char* buf) { 1.916 + char cp_buf[MAX_CP_LEN + 1]; 1.917 + my_ltoa(ltype->cp, cp_buf); 1.918 + return __GetLocaleName(ltype->lc.id, cp_buf, buf); 1.919 +} 1.920 + 1.921 +char const* _Locale_numeric_name(const _Locale_numeric_t* lnum, char* buf) 1.922 +{ return __GetLocaleName(lnum->lc.id, lnum->cp, buf); } 1.923 + 1.924 +char const* _Locale_time_name(const _Locale_time_t* ltime, char* buf) 1.925 +{ return __GetLocaleName(ltime->lc.id, ltime->cp, buf); } 1.926 + 1.927 +char const* _Locale_collate_name(const _Locale_collate_t* lcol, char* buf) 1.928 +{ return __GetLocaleName(lcol->lc.id, lcol->cp, buf); } 1.929 + 1.930 +char const* _Locale_monetary_name(const _Locale_monetary_t* lmon, char* buf) 1.931 +{ return __GetLocaleName(lmon->lc.id, lmon->cp, buf); } 1.932 + 1.933 +char const* _Locale_messages_name(const struct _Locale_messages* lmes, char* buf) { 1.934 + _STLP_MARK_PARAMETER_AS_UNUSED(lmes) 1.935 + _STLP_MARK_PARAMETER_AS_UNUSED(buf) 1.936 + return NULL; 1.937 +} 1.938 + 1.939 +void _Locale_ctype_destroy(_Locale_ctype_t* ltype) { 1.940 + if (!ltype) return; 1.941 + 1.942 + free(ltype); 1.943 +} 1.944 + 1.945 +void _Locale_numeric_destroy(_Locale_numeric_t* lnum) { 1.946 + if (!lnum) return; 1.947 + 1.948 + if (lnum->grouping) free(lnum->grouping); 1.949 + free(lnum); 1.950 +} 1.951 + 1.952 +void _Locale_time_destroy(_Locale_time_t* ltime) { 1.953 + int i; 1.954 + if (!ltime) return; 1.955 + 1.956 + for (i = 0; i < 12; ++i) { 1.957 + if (ltime->month[i]) free(ltime->month[i]); 1.958 + if (ltime->abbrev_month[i]) free(ltime->abbrev_month[i]); 1.959 + } 1.960 + 1.961 + for (i = 0; i < 7; ++i) { 1.962 + if (ltime->dayofweek[i]) free(ltime->dayofweek[i]); 1.963 + if (ltime->abbrev_dayofweek[i]) free(ltime->abbrev_dayofweek[i]); 1.964 + } 1.965 + 1.966 + if (ltime->date_format) free(ltime->date_format); 1.967 + if (ltime->long_date_format) free(ltime->long_date_format); 1.968 + if (ltime->time_format) free(ltime->time_format); 1.969 + if (ltime->date_time_format) free(ltime->date_time_format); 1.970 + if (ltime->long_date_time_format) free(ltime->long_date_time_format); 1.971 + 1.972 + free(ltime); 1.973 +} 1.974 + 1.975 +void _Locale_collate_destroy(_Locale_collate_t* lcol) { 1.976 + if (!lcol) return; 1.977 + 1.978 + free(lcol); 1.979 +} 1.980 + 1.981 +void _Locale_monetary_destroy(_Locale_monetary_t* lmon) { 1.982 + if (!lmon) return; 1.983 + 1.984 + if (lmon->grouping) free(lmon->grouping); 1.985 + free(lmon); 1.986 +} 1.987 + 1.988 +void _Locale_messages_destroy(struct _Locale_messages* lmes) 1.989 +{ _STLP_MARK_PARAMETER_AS_UNUSED(lmes) } 1.990 + 1.991 +static char const* _Locale_extract_category_name(const char* name, const char* category, char* buf, 1.992 + _Locale_lcid_t* hint, int *__err_code) { 1.993 + const char* cname = __Extract_locale_name(name, category, buf); 1.994 + if (cname == 0 || (cname[0] == 'C' && cname[1] == 0)) { 1.995 + return cname; 1.996 + } 1.997 + return __TranslateToSystem(cname, buf, hint, __err_code); 1.998 +} 1.999 + 1.1000 +char const* _Locale_extract_ctype_name(const char* cname, char* buf, 1.1001 + _Locale_lcid_t* hint, int *__err_code) 1.1002 +{ return _Locale_extract_category_name(cname, "LC_CTYPE", buf, hint, __err_code); } 1.1003 + 1.1004 +char const* _Locale_extract_numeric_name(const char* cname, char* buf, 1.1005 + _Locale_lcid_t* hint, int *__err_code) 1.1006 +{ return _Locale_extract_category_name(cname, "LC_NUMERIC", buf, hint, __err_code); } 1.1007 + 1.1008 +char const* _Locale_extract_time_name(const char* cname, char* buf, 1.1009 + _Locale_lcid_t* hint, int *__err_code) 1.1010 +{ return _Locale_extract_category_name(cname, "LC_TIME", buf, hint, __err_code); } 1.1011 + 1.1012 +char const* _Locale_extract_collate_name(const char* cname, char* buf, 1.1013 + _Locale_lcid_t* hint, int *__err_code) 1.1014 +{ return _Locale_extract_category_name(cname, "LC_COLLATE", buf, hint, __err_code); } 1.1015 + 1.1016 +char const* _Locale_extract_monetary_name(const char* cname, char* buf, 1.1017 + _Locale_lcid_t* hint, int *__err_code) 1.1018 +{ return _Locale_extract_category_name(cname, "LC_MONETARY", buf, hint, __err_code); } 1.1019 + 1.1020 +char const* _Locale_extract_messages_name(const char* cname, char* buf, 1.1021 + _Locale_lcid_t* hint, int *__err_code) { 1.1022 + if (cname[0] == 'L' && cname[1] == 'C' && cname[2] == '_') { 1.1023 + return _C_name; 1.1024 + } 1.1025 + if (cname[0] == 'C' && cname[1] == 0) { 1.1026 + return _C_name; 1.1027 + } 1.1028 + return __TranslateToSystem(cname, buf, hint, __err_code); 1.1029 +} 1.1030 + 1.1031 +/* ctype */ 1.1032 + 1.1033 +const _Locale_mask_t* _Locale_ctype_table(_Locale_ctype_t* ltype) { 1.1034 + _STLP_STATIC_ASSERT(sizeof(_Locale_mask_t) == sizeof(ltype->ctable[0])) 1.1035 + return (const _Locale_mask_t*)ltype->ctable; 1.1036 +} 1.1037 + 1.1038 +int _Locale_toupper(_Locale_ctype_t* ltype, int c) { 1.1039 + char buf[2], out_buf[2]; 1.1040 + buf[0] = (char)c; buf[1] = 0; 1.1041 + if ((UINT)__GetDefaultCP(ltype->lc.id) == ltype->cp) { 1.1042 + LCMapStringA(ltype->lc.id, LCMAP_LINGUISTIC_CASING | LCMAP_UPPERCASE, buf, 2, out_buf, 2); 1.1043 + return out_buf[0]; 1.1044 + } 1.1045 + else { 1.1046 + wchar_t wbuf[2]; 1.1047 + MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, buf, 2, wbuf, 2); 1.1048 + WideCharToMultiByte(__GetDefaultCP(ltype->lc.id), WC_COMPOSITECHECK | WC_SEPCHARS, wbuf, 2, buf, 2, NULL, FALSE); 1.1049 + 1.1050 + LCMapStringA(ltype->lc.id, LCMAP_LINGUISTIC_CASING | LCMAP_UPPERCASE, buf, 2, out_buf, 2); 1.1051 + 1.1052 + MultiByteToWideChar(__GetDefaultCP(ltype->lc.id), MB_PRECOMPOSED, out_buf, 2, wbuf, 2); 1.1053 + WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuf, 2, out_buf, 2, NULL, FALSE); 1.1054 + return out_buf[0]; 1.1055 + } 1.1056 +} 1.1057 + 1.1058 +int _Locale_tolower(_Locale_ctype_t* ltype, int c) { 1.1059 + char buf[2], out_buf[2]; 1.1060 + buf[0] = (char)c; buf[1] = 0; 1.1061 + if ((UINT)__GetDefaultCP(ltype->lc.id) == ltype->cp) { 1.1062 + LCMapStringA(ltype->lc.id, LCMAP_LINGUISTIC_CASING | LCMAP_LOWERCASE, buf, 2, out_buf, 2); 1.1063 + return out_buf[0]; 1.1064 + } 1.1065 + else { 1.1066 + wchar_t wbuf[2]; 1.1067 + MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, buf, 2, wbuf, 2); 1.1068 + WideCharToMultiByte(__GetDefaultCP(ltype->lc.id), WC_COMPOSITECHECK | WC_SEPCHARS, wbuf, 2, buf, 2, NULL, FALSE); 1.1069 + 1.1070 + LCMapStringA(ltype->lc.id, LCMAP_LINGUISTIC_CASING | LCMAP_LOWERCASE, buf, 2, out_buf, 2); 1.1071 + 1.1072 + MultiByteToWideChar(__GetDefaultCP(ltype->lc.id), MB_PRECOMPOSED, out_buf, 2, wbuf, 2); 1.1073 + WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuf, 2, out_buf, 2, NULL, FALSE); 1.1074 + return out_buf[0]; 1.1075 + } 1.1076 +} 1.1077 + 1.1078 +#ifndef CSTR_EQUAL /* VC5SP3*/ 1.1079 +# define CSTR_EQUAL 2 1.1080 +#endif 1.1081 +#ifndef CSTR_LESS_THAN /* VC5SP3 */ 1.1082 +# define CSTR_LESS_THAN 1 1.1083 +#endif 1.1084 + 1.1085 +static DWORD max_DWORD = 0xffffffff; 1.1086 +static DWORD trim_size_t_to_DWORD(size_t n) { return n < (size_t)max_DWORD ? (DWORD)n : max_DWORD; } 1.1087 + 1.1088 +/* Collate */ 1.1089 +/* This function takes care of the potential size_t DWORD different size. */ 1.1090 +static int _Locale_strcmp_auxA(_Locale_collate_t* lcol, 1.1091 + const char* s1, size_t n1, 1.1092 + const char* s2, size_t n2) { 1.1093 + int result = CSTR_EQUAL; 1.1094 + while (n1 > 0 || n2 > 0) { 1.1095 + DWORD size1 = trim_size_t_to_DWORD(n1); 1.1096 + DWORD size2 = trim_size_t_to_DWORD(n2); 1.1097 + result = CompareStringA(lcol->lc.id, 0, s1, size1, s2, size2); 1.1098 + if (result != CSTR_EQUAL) 1.1099 + break; 1.1100 + n1 -= size1; 1.1101 + n2 -= size2; 1.1102 + } 1.1103 + return result; 1.1104 +} 1.1105 + 1.1106 +int _Locale_strcmp(_Locale_collate_t* lcol, 1.1107 + const char* s1, size_t n1, 1.1108 + const char* s2, size_t n2) { 1.1109 + int result; 1.1110 + if (__GetDefaultCP(lcol->lc.id) == atoi(lcol->cp)) { 1.1111 + result = _Locale_strcmp_auxA(lcol, s1, n1, s2, n2); 1.1112 + } 1.1113 + else { 1.1114 + char *buf1, *buf2; 1.1115 + size_t size1, size2; 1.1116 + buf1 = __ConvertToCP(atoi(lcol->cp), __GetDefaultCP(lcol->lc.id), s1, n1, &size1); 1.1117 + buf2 = __ConvertToCP(atoi(lcol->cp), __GetDefaultCP(lcol->lc.id), s2, n2, &size2); 1.1118 + 1.1119 + result = _Locale_strcmp_auxA(lcol, buf1, size1, buf2, size2); 1.1120 + free(buf1); free(buf2); 1.1121 + } 1.1122 + return (result == CSTR_EQUAL) ? 0 : (result == CSTR_LESS_THAN) ? -1 : 1; 1.1123 +} 1.1124 + 1.1125 +size_t _Locale_strxfrm(_Locale_collate_t* lcol, 1.1126 + char* dst, size_t dst_size, 1.1127 + const char* src, size_t src_size) { 1.1128 + int result; 1.1129 + 1.1130 + /* The Windows API do not support transformation of very long strings (src_size > INT_MAX) 1.1131 + * In this case the result will just be the input string: 1.1132 + */ 1.1133 + if (src_size > INT_MAX) { 1.1134 + if (dst != 0) { 1.1135 + _STLP_STRNCPY(dst, dst_size, src, src_size); 1.1136 + } 1.1137 + return src_size; 1.1138 + } 1.1139 + if (dst_size > INT_MAX) { 1.1140 + /* now that we know that src_size <= INT_MAX we can safely decrease dst_size to INT_MAX. */ 1.1141 + dst_size = INT_MAX; 1.1142 + } 1.1143 + 1.1144 + if (__GetDefaultCP(lcol->lc.id) == atoi(lcol->cp)) 1.1145 + result = LCMapStringA(lcol->lc.id, LCMAP_SORTKEY, src, (int)src_size, dst, (int)dst_size); 1.1146 + else { 1.1147 + char *buf; 1.1148 + size_t size; 1.1149 + buf = __ConvertToCP(atoi(lcol->cp), __GetDefaultCP(lcol->lc.id), src, src_size, &size); 1.1150 + 1.1151 + result = LCMapStringA(lcol->lc.id, LCMAP_SORTKEY, buf, (int)size, dst, (int)dst_size); 1.1152 + free(buf); 1.1153 + } 1.1154 + return result != 0 ? result - 1 : 0; 1.1155 +} 1.1156 + 1.1157 +/* Numeric */ 1.1158 +static const char* __true_name = "true"; 1.1159 +static const char* __false_name = "false"; 1.1160 + 1.1161 +char _Locale_decimal_point(_Locale_numeric_t* lnum) 1.1162 +{ return lnum->decimal_point[0]; } 1.1163 + 1.1164 +char _Locale_thousands_sep(_Locale_numeric_t* lnum) 1.1165 +{ return lnum->thousands_sep[0]; } 1.1166 + 1.1167 +const char* _Locale_grouping(_Locale_numeric_t * lnum) { 1.1168 + if (!lnum->grouping) return ""; 1.1169 + else return lnum->grouping; 1.1170 +} 1.1171 + 1.1172 +const char * _Locale_true(_Locale_numeric_t * lnum) { 1.1173 + _STLP_MARK_PARAMETER_AS_UNUSED(lnum) 1.1174 + return __true_name; /* NT does't provide information about this */ 1.1175 +} 1.1176 + 1.1177 +const char * _Locale_false(_Locale_numeric_t * lnum) { 1.1178 + _STLP_MARK_PARAMETER_AS_UNUSED(lnum) 1.1179 + return __false_name; /* NT does't provide information about this */ 1.1180 +} 1.1181 + 1.1182 +/* Monetary */ 1.1183 +const char* _Locale_int_curr_symbol(_Locale_monetary_t * lmon) 1.1184 +{ return lmon->int_curr_symbol; } 1.1185 + 1.1186 +const char* _Locale_currency_symbol(_Locale_monetary_t * lmon) 1.1187 +{ return lmon->curr_symbol; } 1.1188 + 1.1189 +char _Locale_mon_decimal_point(_Locale_monetary_t * lmon) 1.1190 +{ return lmon->decimal_point[0]; } 1.1191 + 1.1192 +char _Locale_mon_thousands_sep(_Locale_monetary_t * lmon) 1.1193 +{ return lmon->thousands_sep[0]; } 1.1194 + 1.1195 +const char* _Locale_mon_grouping(_Locale_monetary_t * lmon) { 1.1196 + if (!lmon->grouping) return ""; 1.1197 + else return lmon->grouping; 1.1198 +} 1.1199 + 1.1200 +const char* _Locale_positive_sign(_Locale_monetary_t * lmon) 1.1201 +{ return lmon->positive_sign; } 1.1202 + 1.1203 +const char* _Locale_negative_sign(_Locale_monetary_t * lmon) 1.1204 +{ return lmon->negative_sign; } 1.1205 + 1.1206 +char _Locale_int_frac_digits(_Locale_monetary_t * lmon) 1.1207 +{ return (char)lmon->int_frac_digits; } 1.1208 + 1.1209 +char _Locale_frac_digits(_Locale_monetary_t * lmon) 1.1210 +{ return (char)lmon->frac_digits; } 1.1211 + 1.1212 +int _Locale_p_cs_precedes(_Locale_monetary_t * lmon) { 1.1213 + char loc_data[2]; 1.1214 + GetLocaleInfoA(lmon->lc.id, LOCALE_IPOSSYMPRECEDES, loc_data, 2); 1.1215 + if (loc_data[0] == '0') return 0; 1.1216 + else if (loc_data[0] == '1') return 1; 1.1217 + else return -1; 1.1218 +} 1.1219 + 1.1220 +int _Locale_p_sep_by_space(_Locale_monetary_t * lmon) { 1.1221 + char loc_data[2]; 1.1222 + GetLocaleInfoA(lmon->lc.id, LOCALE_IPOSSEPBYSPACE, loc_data, 2); 1.1223 + if (loc_data[0] == '0') return 0; 1.1224 + else if (loc_data[0] == '1') return 1; 1.1225 + else return -1; 1.1226 +} 1.1227 + 1.1228 +int _Locale_p_sign_posn(_Locale_monetary_t * lmon) { 1.1229 + char loc_data[2]; 1.1230 + if (lmon->lc.id != INVARIANT_LCID) { 1.1231 + GetLocaleInfoA(lmon->lc.id, LOCALE_IPOSSIGNPOSN, loc_data, 2); 1.1232 + return atoi(loc_data); 1.1233 + } 1.1234 + else { 1.1235 + return CHAR_MAX; 1.1236 + } 1.1237 +} 1.1238 + 1.1239 +int _Locale_n_cs_precedes(_Locale_monetary_t * lmon) { 1.1240 + char loc_data[2]; 1.1241 + GetLocaleInfoA(lmon->lc.id, LOCALE_INEGSYMPRECEDES, loc_data, 2); 1.1242 + if (loc_data[0] == '0') return 0; 1.1243 + else if (loc_data[0] == '1') return 1; 1.1244 + else return -1; 1.1245 +} 1.1246 + 1.1247 +int _Locale_n_sep_by_space(_Locale_monetary_t * lmon) { 1.1248 + char loc_data[2]; 1.1249 + GetLocaleInfoA(lmon->lc.id, LOCALE_INEGSEPBYSPACE, loc_data, 2); 1.1250 + if (loc_data[0] == '0') return 0; 1.1251 + else if (loc_data[0] == '1') return 1; 1.1252 + else return -1; 1.1253 +} 1.1254 + 1.1255 +int _Locale_n_sign_posn(_Locale_monetary_t * lmon) { 1.1256 + char loc_data[2]; 1.1257 + if (lmon->lc.id != INVARIANT_LCID) { 1.1258 + GetLocaleInfoA(lmon->lc.id, LOCALE_INEGSIGNPOSN, loc_data, 2); 1.1259 + return atoi(loc_data); 1.1260 + } 1.1261 + else { 1.1262 + return CHAR_MAX; 1.1263 + } 1.1264 +} 1.1265 + 1.1266 +/* Time */ 1.1267 +const char * _Locale_full_monthname(_Locale_time_t * ltime, int month) { 1.1268 + const char **names = (const char**)ltime->month; 1.1269 + return names[month]; 1.1270 +} 1.1271 + 1.1272 +const char * _Locale_abbrev_monthname(_Locale_time_t * ltime, int month) { 1.1273 + const char **names = (const char**)ltime->abbrev_month; 1.1274 + return names[month]; 1.1275 +} 1.1276 + 1.1277 +const char * _Locale_full_dayofweek(_Locale_time_t * ltime, int day) { 1.1278 + const char **names = (const char**)ltime->dayofweek; 1.1279 + return names[day]; 1.1280 +} 1.1281 + 1.1282 +const char * _Locale_abbrev_dayofweek(_Locale_time_t * ltime, int day) { 1.1283 + const char **names = (const char**)ltime->abbrev_dayofweek; 1.1284 + return names[day]; 1.1285 +} 1.1286 + 1.1287 +const char* _Locale_d_t_fmt(_Locale_time_t* ltime) 1.1288 +{ return ltime->date_time_format; } 1.1289 + 1.1290 +const char* _Locale_long_d_t_fmt(_Locale_time_t* ltime) 1.1291 +{ return ltime->long_date_time_format; } 1.1292 + 1.1293 +const char* _Locale_d_fmt(_Locale_time_t* ltime) 1.1294 +{ return ltime->date_format; } 1.1295 + 1.1296 +const char* _Locale_long_d_fmt(_Locale_time_t* ltime) 1.1297 +{ return ltime->long_date_format; } 1.1298 + 1.1299 +const char* _Locale_t_fmt(_Locale_time_t* ltime) 1.1300 +{ return ltime->time_format; } 1.1301 + 1.1302 +const char* _Locale_am_str(_Locale_time_t* ltime) 1.1303 +{ return ltime->am; } 1.1304 + 1.1305 +const char* _Locale_pm_str(_Locale_time_t* ltime) 1.1306 +{ return ltime->pm; } 1.1307 + 1.1308 +/* Messages */ 1.1309 +nl_catd_type _Locale_catopen(struct _Locale_messages* lmes, const char* cat_name) { 1.1310 + _STLP_MARK_PARAMETER_AS_UNUSED(lmes) 1.1311 + _STLP_MARK_PARAMETER_AS_UNUSED(cat_name) 1.1312 + return -1; 1.1313 +} 1.1314 +void _Locale_catclose(struct _Locale_messages* lmes, nl_catd_type cat) { 1.1315 + _STLP_MARK_PARAMETER_AS_UNUSED(lmes) 1.1316 + _STLP_MARK_PARAMETER_AS_UNUSED(&cat) 1.1317 +} 1.1318 +const char* _Locale_catgets(struct _Locale_messages* lmes, nl_catd_type cat, 1.1319 + int setid, int msgid, const char *dfault) { 1.1320 + _STLP_MARK_PARAMETER_AS_UNUSED(lmes) 1.1321 + _STLP_MARK_PARAMETER_AS_UNUSED(&cat) 1.1322 + _STLP_MARK_PARAMETER_AS_UNUSED(&setid) 1.1323 + _STLP_MARK_PARAMETER_AS_UNUSED(&msgid) 1.1324 + return dfault; 1.1325 +} 1.1326 + 1.1327 +#ifdef __cplusplus 1.1328 +} /* extern C */ 1.1329 +_STLP_END_NAMESPACE 1.1330 +#endif 1.1331 + 1.1332 +void __FixGrouping(char *grouping) { 1.1333 + /* This converts NT version which uses '0' instead of 0, etc ; to ANSI */ 1.1334 + char *g = grouping; 1.1335 + char building_group = 0; 1.1336 + char repeat_last = 0; 1.1337 + /* Check there is a grouping info otherwise we would add a useless CHAR_MAX */ 1.1338 + if (*g) { 1.1339 + for (; *g; ++g) { 1.1340 + if (*g > '0' && *g <= '9') { 1.1341 + if (!building_group) { 1.1342 + *grouping = *g - '0'; 1.1343 + building_group = 1; 1.1344 + } 1.1345 + else { 1.1346 + /* Known issue: grouping might roll. */ 1.1347 + *grouping = *grouping * 10 + *g - '0'; 1.1348 + } 1.1349 + } 1.1350 + else if (*g == '0') { 1.1351 + if (!building_group) { 1.1352 + repeat_last = 1; 1.1353 + } 1.1354 + else 1.1355 + /* Known issue: grouping might roll. */ 1.1356 + *grouping *= 10; 1.1357 + } 1.1358 + else if (*g == ';') { 1.1359 + /* Stop adding to the current group */ 1.1360 + building_group = 0; 1.1361 + ++grouping; 1.1362 + } 1.1363 + /* else we ignore the character */ 1.1364 + } 1.1365 + 1.1366 + if (!repeat_last) 1.1367 + *grouping++ = CHAR_MAX; 1.1368 + *grouping = 0; 1.1369 + } 1.1370 +} 1.1371 + 1.1372 +const char* __ConvertName(const char* lname, LOCALECONV* ConvTable, int TableSize) { 1.1373 + int i; 1.1374 + int cmp; 1.1375 + int low = 0; 1.1376 + int high = TableSize - 1; 1.1377 + 1.1378 + /* typical binary search - do until no more to search or match */ 1.1379 + while (low <= high) { 1.1380 + i = (low + high) / 2; 1.1381 + 1.1382 + if ((cmp = lstrcmpiA(lname, (*(ConvTable + i)).name)) == 0) 1.1383 + return (*(ConvTable + i)).abbrev; 1.1384 + else if (cmp < 0) 1.1385 + high = i - 1; 1.1386 + else 1.1387 + low = i + 1; 1.1388 + } 1.1389 + return lname; 1.1390 +} 1.1391 + 1.1392 +int __ParseLocaleString(const char* lname, 1.1393 + char* lang, char* ctry, char* page) { 1.1394 + int param = 0; 1.1395 + size_t len; 1.1396 + size_t tmpLen; 1.1397 + 1.1398 + if (lname[0] == 0) 1.1399 + return 0; 1.1400 + 1.1401 + /* We look for the first country separator '_' */ 1.1402 + len = strcspn(lname, "_"); 1.1403 + if (lname[len] == '_') { 1.1404 + if (len == 0 || len > MAX_LANG_LEN) return -1; /* empty lang is invalid*/ 1.1405 + _STLP_STRNCPY(lang, MAX_LANG_LEN + 1, lname, len); 1.1406 + lname += len + 1; 1.1407 + ++param; 1.1408 + } 1.1409 + 1.1410 + /* We look for the last code page separator '.' */ 1.1411 + len = -1; 1.1412 + tmpLen = strcspn(lname, "."); 1.1413 + while (lname[tmpLen] == '.') { 1.1414 + len = tmpLen; ++tmpLen; 1.1415 + tmpLen += strcspn(lname + tmpLen, "."); 1.1416 + } 1.1417 + if (len != -1) { /* Means that we found a '.' */ 1.1418 + if (param == 0) { 1.1419 + /* We have no lang yet so we have to fill it first, no country */ 1.1420 + if (len > MAX_LANG_LEN) return -1; 1.1421 + if (len == 0) { 1.1422 + /* No language nor country, only code page */ 1.1423 + ++param; 1.1424 + } 1.1425 + else 1.1426 + { _STLP_STRNCPY(lang, MAX_LANG_LEN + 1, lname, len); } 1.1427 + ++param; 1.1428 + } 1.1429 + else { 1.1430 + /* We already have a lang so we are now looking for the country: */ 1.1431 + if (len == 0) return -1; /* We forbid locale name with the "_." motif in it */ 1.1432 + if (len > MAX_CTRY_LEN) return -1; 1.1433 + _STLP_STRNCPY(ctry, MAX_CTRY_LEN + 1, lname, len); 1.1434 + } 1.1435 + ++param; 1.1436 + lname += len + 1; 1.1437 + } 1.1438 + 1.1439 + /* We look for ',' for compatibility with POSIX */ 1.1440 + len = strcspn(lname, ","); 1.1441 + switch (param) { 1.1442 + case 0: 1.1443 + if (len > MAX_LANG_LEN) return -1; 1.1444 + _STLP_STRNCPY(lang, MAX_LANG_LEN + 1, lname, len); 1.1445 + break; 1.1446 + case 1: 1.1447 + if (len > MAX_CTRY_LEN) return -1; 1.1448 + _STLP_STRNCPY(ctry, MAX_CTRY_LEN + 1, lname, len); 1.1449 + break; 1.1450 + default: 1.1451 + if (len > MAX_CP_LEN) return -1; 1.1452 + _STLP_STRNCPY(page, MAX_CP_LEN + 1, lname, len); 1.1453 + break; 1.1454 + } 1.1455 + 1.1456 + /* ',' POSIX modifier is not used in NT */ 1.1457 + return 0; 1.1458 +} 1.1459 + 1.1460 +/* Data necessary for find LCID*/ 1.1461 +static CRITICAL_SECTION __criticalSection; 1.1462 +static int __FindFlag; 1.1463 +static LCID __FndLCID; 1.1464 +static const char* __FndLang; 1.1465 +static const char* __FndCtry; 1.1466 + 1.1467 +void _Locale_init() 1.1468 +{ InitializeCriticalSection(&__criticalSection); } 1.1469 + 1.1470 +void _Locale_final() 1.1471 +{ DeleteCriticalSection(&__criticalSection); } 1.1472 + 1.1473 +static LCID LocaleFromHex(const char* locale) { 1.1474 + unsigned long result = 0; 1.1475 + int digit; 1.1476 + while (*locale) { 1.1477 + result <<= 4; 1.1478 + digit = (*locale >= '0' && *locale <= '9') ? *locale - '0': 1.1479 + (*locale >= 'A' && *locale <= 'F') ? (*locale - 'A') + 10 1.1480 + : (*locale - 'a') + 10; 1.1481 + result += digit; 1.1482 + ++locale; 1.1483 + } 1.1484 + return (LCID)result; 1.1485 +} 1.1486 + 1.1487 +static BOOL CALLBACK EnumLocalesProcA(LPSTR locale) { 1.1488 + LCID lcid = LocaleFromHex(locale); 1.1489 + int LangFlag = 0, CtryFlag = !__FndCtry; 1.1490 + static char Lang[MAX_LANG_LEN], Ctry[MAX_CTRY_LEN]; 1.1491 + 1.1492 + GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE, Lang, MAX_LANG_LEN); 1.1493 + if (lstrcmpiA(Lang, __FndLang) != 0) { 1.1494 + GetLocaleInfoA(lcid, LOCALE_SABBREVLANGNAME, Lang, MAX_LANG_LEN); 1.1495 + if (lstrcmpiA(Lang, __FndLang) != 0) { 1.1496 + GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, Lang, MAX_LANG_LEN); 1.1497 + if (lstrcmpiA(Lang, __FndLang) == 0) LangFlag = 1; 1.1498 + } 1.1499 + else LangFlag = 1; 1.1500 + } 1.1501 + else LangFlag = 1; 1.1502 + 1.1503 + if (__FndCtry) { 1.1504 + GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY, Ctry, MAX_CTRY_LEN); 1.1505 + if (lstrcmpiA(Ctry, __FndCtry) != 0) { 1.1506 + GetLocaleInfoA(lcid, LOCALE_SABBREVCTRYNAME, Ctry, MAX_CTRY_LEN); 1.1507 + if (lstrcmpiA(Ctry, __FndCtry) != 0) { 1.1508 + GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, Ctry, MAX_CTRY_LEN); 1.1509 + if (lstrcmpiA(Ctry, __FndCtry) == 0) CtryFlag = 1; 1.1510 + } 1.1511 + else CtryFlag = 1; 1.1512 + } 1.1513 + else 1.1514 + CtryFlag = 1; 1.1515 + } 1.1516 + 1.1517 + if (LangFlag && CtryFlag) { 1.1518 + __FindFlag = 1; 1.1519 + __FndLCID = lcid; 1.1520 + return FALSE; 1.1521 + } 1.1522 + 1.1523 + return TRUE; 1.1524 +} 1.1525 + 1.1526 +int __GetLCID(const char* lang, const char* ctry, LCID* lcid) { 1.1527 + int ret; 1.1528 + EnterCriticalSection(&__criticalSection); 1.1529 + 1.1530 + __FindFlag = 0; 1.1531 + __FndLang = lang; 1.1532 + __FndCtry = ctry; 1.1533 + EnumSystemLocalesA(EnumLocalesProcA, LCID_INSTALLED); 1.1534 + 1.1535 + if (__FindFlag != 0) *lcid = __FndLCID; 1.1536 + ret = __FindFlag != 0 ? 0 : -1; 1.1537 + 1.1538 + LeaveCriticalSection(&__criticalSection); 1.1539 + return ret; 1.1540 +} 1.1541 + 1.1542 +int __GetLCIDFromName(const char* lname, LCID* lcid, char* cp, _Locale_lcid_t *hint) { 1.1543 + char lang[MAX_LANG_LEN + 1], ctry[MAX_CTRY_LEN + 1], page[MAX_CP_LEN + 1]; 1.1544 + int result = 0; 1.1545 + if (lname == NULL || lname[0] == 0) { 1.1546 + *lcid = LOCALE_USER_DEFAULT; 1.1547 + return 0; 1.1548 + } 1.1549 + 1.1550 + memset(lang, 0, MAX_LANG_LEN + 1); 1.1551 + memset(ctry, 0, MAX_CTRY_LEN + 1); 1.1552 + memset(page, 0, MAX_CP_LEN + 1); 1.1553 + if (__ParseLocaleString(lname, lang, ctry, page) == -1) return -1; 1.1554 + 1.1555 + if (hint != 0) { 1.1556 + *lcid = hint->id; 1.1557 + } 1.1558 + else { 1.1559 + if (lang[0] == 0 && ctry[0] == 0) 1.1560 + *lcid = LOCALE_USER_DEFAULT; /* Only code page given. */ 1.1561 + else { 1.1562 + if (ctry[0] == 0) { 1.1563 + result = __GetLCID(__ConvertName(lang, __rg_language, sizeof(__rg_language) / sizeof(LOCALECONV)), NULL, lcid); 1.1564 + if (result != 0) { 1.1565 + /* Check 'C' special case. Check is done after call to __GetLCID because normal programs do not 1.1566 + * generate facet from 'C' name, they use the locale::classic() facets. */ 1.1567 + if (lang[0] == 'C' && lang[1] == 0) { 1.1568 + *lcid = INVARIANT_LCID; 1.1569 + result = 0; 1.1570 + } 1.1571 + } 1.1572 + } 1.1573 + else { 1.1574 + result = __GetLCID(__ConvertName(lang, __rg_language, sizeof(__rg_language) / sizeof(LOCALECONV)), 1.1575 + __ConvertName(ctry, __rg_country, sizeof(__rg_country) / sizeof(LOCALECONV)), 1.1576 + lcid); 1.1577 + if (result != 0) { 1.1578 + /* Non NLS mapping might introduce problem with some locales when only one entry is mapped, 1.1579 + * the lang or the country (example: chinese locales like 'chinese_taiwan' gives 'CHS_taiwan' 1.1580 + * that do not exists in system). This is why we are giving this locale an other chance by 1.1581 + * calling __GetLCID without the mapping. */ 1.1582 + result = __GetLCID(lang, ctry, lcid); 1.1583 + } 1.1584 + } 1.1585 + } 1.1586 + } 1.1587 + 1.1588 + if (result == 0) { 1.1589 + /* Handling code page */ 1.1590 + if (lstrcmpiA(page, "ACP") == 0 || page[0] == 0) 1.1591 + my_ltoa(__intGetACP(*lcid), cp); 1.1592 + else if (lstrcmpiA(page, "OCP") == 0) 1.1593 + my_ltoa(__intGetOCP(*lcid), cp); 1.1594 + else if (lstrcmpiA(page, "UTF7") == 0) 1.1595 + my_ltoa(CP_UTF7, cp); 1.1596 + else if (lstrcmpiA(page, "UTF8") == 0) 1.1597 + my_ltoa(CP_UTF8, cp); 1.1598 + else 1.1599 + _STLP_STRNCPY(cp, MAX_CP_LEN + 1, page, 5); 1.1600 + 1.1601 + /* Code page must be an integer value, 1.1602 + * 0 returned by __intGetACP and 1 returned by __intGetOCP are invalid 1.1603 + * values. 1.1604 + */ 1.1605 + if (cp[1] == 0 && (cp[0] == '0' || cp[1] == '1')) 1.1606 + return -1; 1.1607 + else if (atoi(cp) == 0) 1.1608 + return -1; 1.1609 + } 1.1610 + 1.1611 + return result; 1.1612 +} 1.1613 + 1.1614 +char const* __GetLocaleName(LCID lcid, const char* cp, char* buf) { 1.1615 + if (lcid == INVARIANT_LCID) { 1.1616 + return _C_name; 1.1617 + } 1.1618 + else { 1.1619 + char lang[MAX_LANG_LEN + 1], ctry[MAX_CTRY_LEN + 1]; 1.1620 + GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE, lang, MAX_LANG_LEN); 1.1621 + GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY, ctry, MAX_CTRY_LEN); 1.1622 + _STLP_STRCPY(buf, _Locale_MAX_SIMPLE_NAME, lang); 1.1623 + _STLP_STRCAT(buf, _Locale_MAX_SIMPLE_NAME, "_"); 1.1624 + _STLP_STRCAT(buf, _Locale_MAX_SIMPLE_NAME, ctry); 1.1625 + _STLP_STRCAT(buf, _Locale_MAX_SIMPLE_NAME, "."); 1.1626 + _STLP_STRCAT(buf, _Locale_MAX_SIMPLE_NAME, cp); 1.1627 + return buf; 1.1628 + } 1.1629 +} 1.1630 + 1.1631 +char const* __Extract_locale_name(const char* loc, const char* category, char* buf) { 1.1632 + char *expr; 1.1633 + size_t len_name; 1.1634 + 1.1635 + if (loc[0] == 'L' && loc[1] == 'C' && loc[2] == '_') { 1.1636 + expr = strstr((char*)loc, category); 1.1637 + if (expr == NULL) return NULL; /* Category not found. */ 1.1638 + expr = strchr(expr, '='); 1.1639 + if (expr == NULL) return NULL; 1.1640 + ++expr; 1.1641 + len_name = strcspn(expr, ";"); 1.1642 + len_name = len_name >= _Locale_MAX_SIMPLE_NAME ? _Locale_MAX_SIMPLE_NAME - 1 1.1643 + : len_name; 1.1644 + _STLP_STRNCPY(buf, _Locale_MAX_SIMPLE_NAME, expr, len_name); buf[len_name] = 0; 1.1645 + return buf; 1.1646 + } 1.1647 + else { 1.1648 + return loc; 1.1649 + } 1.1650 +} 1.1651 + 1.1652 +char const* __TranslateToSystem(const char* lname, char* buf, _Locale_lcid_t* hint, 1.1653 + int *__err_code) { 1.1654 + LCID lcid; 1.1655 + char cp[MAX_CP_LEN + 1]; 1.1656 + if (__GetLCIDFromName(lname, &lcid, cp, hint) != 0) 1.1657 + { *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } 1.1658 + 1.1659 + return __GetLocaleName(lcid, cp, buf); 1.1660 +} 1.1661 + 1.1662 +void __GetLocaleInfoUsingACP(LCID lcid, const char* cp, LCTYPE lctype, char* buf, int buf_size, wchar_t* wbuf, int wbuf_size) { 1.1663 + wchar_t *Buffer; 1.1664 + int BufferSize; 1.1665 + int icp; 1.1666 + 1.1667 + GetLocaleInfoA(lcid, lctype, buf, buf_size); 1.1668 + 1.1669 + icp = atoi(cp); 1.1670 + if (icp != CP_ACP && buf[0] != 0) { 1.1671 + BufferSize = MultiByteToWideChar(CP_ACP, 0, buf, -1, NULL, 0); 1.1672 + if (BufferSize > wbuf_size) 1.1673 + { 1.1674 + Buffer = (wchar_t*)malloc(sizeof(wchar_t) * BufferSize); 1.1675 + } 1.1676 + else 1.1677 + { 1.1678 + Buffer = wbuf; 1.1679 + } 1.1680 + MultiByteToWideChar(CP_ACP, 0, buf, -1, Buffer, BufferSize); 1.1681 + WideCharToMultiByte(icp, 0, Buffer, -1, buf, buf_size, NULL, NULL); 1.1682 + if (Buffer != wbuf) 1.1683 + { 1.1684 + free(Buffer); 1.1685 + } 1.1686 + } 1.1687 +} 1.1688 + 1.1689 +/* Return 0 if ANSI code page not used */ 1.1690 +int __intGetACP(LCID lcid) { 1.1691 + char cp[6]; 1.1692 + if (!GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, cp, 6)) { 1.1693 +#if defined (_STLP_LANG_INVARIANT_DEFINED) 1.1694 + if (lcid == INVARIANT_LCID) { 1.1695 + /* We are using a limited PSDK, we rely on the most common code page */ 1.1696 + return 1252; 1.1697 + } 1.1698 +#endif 1.1699 + return 0; 1.1700 + } 1.1701 + return atoi(cp); 1.1702 +} 1.1703 + 1.1704 +/* Return 1 if OEM code page not used */ 1.1705 +int __intGetOCP(LCID lcid) { 1.1706 + char cp[6]; 1.1707 + if (!GetLocaleInfoA(lcid, LOCALE_IDEFAULTCODEPAGE, cp, 6)) 1.1708 + return 0; 1.1709 + return atoi(cp); 1.1710 +} 1.1711 + 1.1712 +int __GetDefaultCP(LCID lcid) { 1.1713 + int cp = __intGetACP(lcid); 1.1714 + if (cp == 0) return __intGetOCP(lcid); 1.1715 + else return cp; 1.1716 +} 1.1717 + 1.1718 +static int trim_size_t_to_int(size_t n) { return n < (size_t)INT_MAX ? (int)n : INT_MAX; } 1.1719 + 1.1720 +char* __ConvertToCP(int from_cp, int to_cp, const char *from, size_t size, size_t *ret_buf_size) { 1.1721 + size_t wbuffer_size, buffer_size, from_offset, wbuf_offset; 1.1722 + int from_size, to_size, wbuf_size; 1.1723 + wchar_t *wbuffer; 1.1724 + char* buffer; 1.1725 + 1.1726 + size_t orig_size = size; 1.1727 + 1.1728 + wbuffer_size = 0; 1.1729 + from_offset = 0; 1.1730 + while (size > 0) { 1.1731 + from_size = trim_size_t_to_int(size); 1.1732 + wbuffer_size += MultiByteToWideChar(from_cp, MB_PRECOMPOSED, 1.1733 + from + from_offset, from_size, NULL, 0); 1.1734 + from_offset += from_size; 1.1735 + size -= from_size; 1.1736 + } 1.1737 + 1.1738 + wbuffer = (wchar_t*)malloc(sizeof(wchar_t)*wbuffer_size); 1.1739 + 1.1740 + size = orig_size; 1.1741 + wbuf_offset = 0; 1.1742 + from_offset = 0; 1.1743 + while (size > 0) { 1.1744 + from_size = trim_size_t_to_int(size); 1.1745 + wbuf_size = trim_size_t_to_int(wbuffer_size - wbuf_offset); 1.1746 + wbuf_offset += MultiByteToWideChar(from_cp, MB_PRECOMPOSED, 1.1747 + from + from_offset, from_size, wbuffer + wbuf_offset, wbuf_size); 1.1748 + from_offset += from_size; 1.1749 + size -= from_size; 1.1750 + } 1.1751 + 1.1752 + buffer_size = 0; 1.1753 + wbuf_offset = 0; 1.1754 + size = wbuffer_size; 1.1755 + while (size > 0) { 1.1756 + wbuf_size = trim_size_t_to_int(size); 1.1757 + buffer_size += WideCharToMultiByte(to_cp, WC_COMPOSITECHECK | WC_SEPCHARS, 1.1758 + wbuffer + wbuf_offset, wbuf_size, 1.1759 + NULL, 0, NULL, FALSE); 1.1760 + wbuf_offset += wbuf_size; 1.1761 + size -= wbuf_size; 1.1762 + } 1.1763 + 1.1764 + buffer = (char*)malloc(buffer_size); 1.1765 + *ret_buf_size = buffer_size; 1.1766 + 1.1767 + size = wbuffer_size; 1.1768 + wbuf_offset = 0; 1.1769 + while (size > 0) { 1.1770 + wbuf_size = trim_size_t_to_int(size); 1.1771 + to_size = trim_size_t_to_int(buffer_size); 1.1772 + buffer_size -= WideCharToMultiByte(to_cp, WC_COMPOSITECHECK | WC_SEPCHARS, 1.1773 + wbuffer + wbuf_offset, wbuf_size, 1.1774 + buffer, to_size, NULL, FALSE); 1.1775 + wbuf_offset += wbuf_size; 1.1776 + size -= wbuf_size; 1.1777 + } 1.1778 + 1.1779 + free(wbuffer); 1.1780 + return buffer; 1.1781 +} 1.1782 + 1.1783 +#ifdef __cplusplus 1.1784 +} 1.1785 +#endif 1.1786 + 1.1787 +#ifndef _STLP_NO_WCHAR_T 1.1788 +# include "c_wlocale_win32.c" 1.1789 +#endif