build/stlport/src/c_locale_win32/c_locale_win32.c

changeset 0
6474c204b198
     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) ? &ltype->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) ? &ltime->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, &ltype->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, &ltime->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

mercurial