ReactOS  r76032
locale.c
Go to the documentation of this file.
1 /*
2  * msvcrt.dll locale functions
3  *
4  * Copyright 2000 Jon Griffiths
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <precomp.h>
22 #include <locale.h>
23 
24 #include "mbctype.h"
25 #include <internal/wine/msvcrt.h>
26 
27 #define MAX_ELEM_LEN 64 /* Max length of country/language/CP string */
28 #define MAX_LOCALE_LENGTH 256
29 
30 #ifdef _pctype
31 #error _pctype should not be defined
32 #endif
33 
34 unsigned int __lc_codepage = 0;
37 int __mb_cur_max = 1;
38 static unsigned char charmax = CHAR_MAX;
39 
40 unsigned char _mbctype[257] = { 0 };
41 
42 /* MT */
43 #define LOCK_LOCALE _mlock(_SETLOCALE_LOCK);
44 #define UNLOCK_LOCALE _munlock(_SETLOCALE_LOCK);
45 
46 #define MSVCRT_LEADBYTE 0x8000
47 #define MSVCRT_C1_DEFINED 0x200
48 
49 /* Friendly country strings & language names abbreviations. */
50 static const char * const _country_synonyms[] =
51 {
52  "american", "enu",
53  "american english", "enu",
54  "american-english", "enu",
55  "english-american", "enu",
56  "english-us", "enu",
57  "english-usa", "enu",
58  "us", "enu",
59  "usa", "enu",
60  "australian", "ena",
61  "english-aus", "ena",
62  "belgian", "nlb",
63  "french-belgian", "frb",
64  "canadian", "enc",
65  "english-can", "enc",
66  "french-canadian", "frc",
67  "chinese", "chs",
68  "chinese-simplified", "chs",
69  "chinese-traditional", "cht",
70  "dutch-belgian", "nlb",
71  "english-nz", "enz",
72  "uk", "eng",
73  "english-uk", "eng",
74  "french-swiss", "frs",
75  "swiss", "des",
76  "german-swiss", "des",
77  "italian-swiss", "its",
78  "german-austrian", "dea",
79  "portuguese", "ptb",
80  "portuguese-brazil", "ptb",
81  "spanish-mexican", "esm",
82  "norwegian-bokmal", "nor",
83  "norwegian-nynorsk", "non",
84  "spanish-modern", "esn"
85 };
86 
87 /* INTERNAL: Map a synonym to an ISO code */
88 static void remap_synonym(char *name)
89 {
90  unsigned int i;
91  for (i = 0; i < sizeof(_country_synonyms)/sizeof(char*); i += 2 )
92  {
93  if (!strcasecmp(_country_synonyms[i],name))
94  {
95  TRACE(":Mapping synonym %s to %s\n",name,_country_synonyms[i+1]);
96  strcpy(name, _country_synonyms[i+1]);
97  return;
98  }
99  }
100 }
101 
102 /* Note: Flags are weighted in order of matching importance */
103 #define FOUND_LANGUAGE 0x4
104 #define FOUND_COUNTRY 0x2
105 #define FOUND_CODEPAGE 0x1
106 
107 typedef struct {
108  char search_language[MAX_ELEM_LEN];
109  char search_country[MAX_ELEM_LEN];
110  char search_codepage[MAX_ELEM_LEN];
111  char found_codepage[MAX_ELEM_LEN];
112  unsigned int match_flags;
115 
116 #define CONTINUE_LOOKING TRUE
117 #define STOP_LOOKING FALSE
118 
119 /* INTERNAL: Get and compare locale info with a given string */
120 static int compare_info(LCID lcid, DWORD flags, char* buff, const char* cmp, BOOL exact)
121 {
122  int len;
123 
124  if(!cmp[0])
125  return 0;
126 
127  buff[0] = 0;
129  if (!buff[0])
130  return 0;
131 
132  /* Partial matches are only allowed on language/country names */
133  len = strlen(cmp);
134  if(exact || len<=3)
135  return !strcasecmp(cmp, buff);
136  else
137  return !strncasecmp(cmp, buff, len);
138 }
139 
140 static BOOL CALLBACK
142 {
143  locale_search_t *res = (locale_search_t *)lParam;
144  const LCID lcid = MAKELCID(LangID, SORT_DEFAULT);
145  char buff[MAX_ELEM_LEN];
146  unsigned int flags = 0;
147 
148  if(PRIMARYLANGID(LangID) == LANG_NEUTRAL)
149  return CONTINUE_LOOKING;
150 
151  /* Check Language */
155  {
156  TRACE(":Found language: %s->%s\n", res->search_language, buff);
157  flags |= FOUND_LANGUAGE;
158  }
159  else if (res->match_flags & FOUND_LANGUAGE)
160  {
161  return CONTINUE_LOOKING;
162  }
163 
164  /* Check Country */
168  {
169  TRACE("Found country:%s->%s\n", res->search_country, buff);
170  flags |= FOUND_COUNTRY;
171  }
172  else if (!flags && (res->match_flags & FOUND_COUNTRY))
173  {
174  return CONTINUE_LOOKING;
175  }
176 
177  /* Check codepage */
180  {
181  TRACE("Found codepage:%s->%s\n", res->search_codepage, buff);
182  flags |= FOUND_CODEPAGE;
184  }
185  else if (!flags && (res->match_flags & FOUND_CODEPAGE))
186  {
187  return CONTINUE_LOOKING;
188  }
189 
190  if (flags > res->match_flags)
191  {
192  /* Found a better match than previously */
193  res->match_flags = flags;
194  res->found_lang_id = LangID;
195  }
196  if ((flags & (FOUND_LANGUAGE | FOUND_COUNTRY | FOUND_CODEPAGE)) ==
198  {
199  TRACE(":found exact locale match\n");
200  return STOP_LOOKING;
201  }
202  return CONTINUE_LOOKING;
203 }
204 
205 extern int atoi(const char *);
206 
207 /* Internal: Find the LCID for a locale specification */
208 LCID MSVCRT_locale_to_LCID(const char *locale, unsigned short *codepage)
209 {
210  LCID lcid;
212  const char *cp, *region;
213 
214  memset(&search, 0, sizeof(locale_search_t));
215 
216  cp = strchr(locale, '.');
217  region = strchr(locale, '_');
218 
219  lstrcpynA(search.search_language, locale, MAX_ELEM_LEN);
220  if(region) {
221  lstrcpynA(search.search_country, region+1, MAX_ELEM_LEN);
222  if(region-locale < MAX_ELEM_LEN)
223  search.search_language[region-locale] = '\0';
224  } else
225  search.search_country[0] = '\0';
226 
227  if(cp) {
228  lstrcpynA(search.search_codepage, cp+1, MAX_ELEM_LEN);
229  if(region && cp-region-1<MAX_ELEM_LEN)
230  search.search_country[cp-region-1] = '\0';
231  if(cp-locale < MAX_ELEM_LEN)
232  search.search_language[cp-locale] = '\0';
233  } else
234  search.search_codepage[0] = '\0';
235 
236  if(!search.search_country[0] && !search.search_codepage[0])
238 
241  (LONG_PTR)&search);
242 
243  if (!search.match_flags)
244  return -1;
245 
246  /* If we were given something that didn't match, fail */
247  if (search.search_country[0] && !(search.match_flags & FOUND_COUNTRY))
248  return -1;
249 
250  lcid = MAKELCID(search.found_lang_id, SORT_DEFAULT);
251 
252  /* Populate partial locale, translating LCID to locale string elements */
253  if (!(search.match_flags & FOUND_CODEPAGE)) {
254  /* Even if a codepage is not enumerated for a locale
255  * it can be set if valid */
256  if (search.search_codepage[0]) {
257  if (IsValidCodePage(atoi(search.search_codepage)))
258  memcpy(search.found_codepage,search.search_codepage,MAX_ELEM_LEN);
259  else {
260  /* Special codepage values: OEM & ANSI */
261  if (!strcasecmp(search.search_codepage,"OCP")) {
263  search.found_codepage, MAX_ELEM_LEN);
264  } else if (!strcasecmp(search.search_codepage,"ACP")) {
266  search.found_codepage, MAX_ELEM_LEN);
267  } else
268  return -1;
269 
270  if (!atoi(search.found_codepage))
271  return -1;
272  }
273  } else {
274  /* Prefer ANSI codepages if present */
276  search.found_codepage, MAX_ELEM_LEN);
277  if (!search.found_codepage[0] || !atoi(search.found_codepage))
279  search.found_codepage, MAX_ELEM_LEN);
280  }
281  }
282  if (codepage)
283  *codepage = atoi(search.found_codepage);
284 
285  return lcid;
286 }
287 
288 /* INTERNAL: Set lc_handle, lc_id and lc_category in threadlocinfo struct */
289 static BOOL update_threadlocinfo_category(LCID lcid, unsigned short cp,
290  MSVCRT__locale_t loc, int category)
291 {
292  char buf[256], *p;
293  int len;
294 
296  p = buf;
297 
298  loc->locinfo->lc_id[category].wLanguage = 0;
299  while(*p) {
300  loc->locinfo->lc_id[category].wLanguage *= 16;
301 
302  if(*p <= '9')
303  loc->locinfo->lc_id[category].wLanguage += *p-'0';
304  else
305  loc->locinfo->lc_id[category].wLanguage += *p-'a'+10;
306 
307  p++;
308  }
309 
310  loc->locinfo->lc_id[category].wCountry =
311  loc->locinfo->lc_id[category].wLanguage;
312  }
313 
314  loc->locinfo->lc_id[category].wCodePage = cp;
315 
316  loc->locinfo->lc_handle[category] = lcid;
317 
318  len = 0;
320  |LOCALE_NOUSEROVERRIDE, buf, 256);
321  buf[len-1] = '_';
323  |LOCALE_NOUSEROVERRIDE, &buf[len], 256-len);
324  buf[len-1] = '.';
325  sprintf(buf+len, "%u", cp);
326  len += strlen(buf+len)+1;
327 
328  loc->locinfo->lc_category[category].locale = MSVCRT_malloc(len);
329  loc->locinfo->lc_category[category].refcount = MSVCRT_malloc(sizeof(int));
330  if(!loc->locinfo->lc_category[category].locale
331  || !loc->locinfo->lc_category[category].refcount) {
332  MSVCRT_free(loc->locinfo->lc_category[category].locale);
333  MSVCRT_free(loc->locinfo->lc_category[category].refcount);
334  loc->locinfo->lc_category[category].locale = NULL;
335  loc->locinfo->lc_category[category].refcount = NULL;
336  return TRUE;
337  }
338  memcpy(loc->locinfo->lc_category[category].locale, buf, len);
339  *loc->locinfo->lc_category[category].refcount = 1;
340 
341  return FALSE;
342 }
343 
344 /* INTERNAL: swap pointers values */
345 static inline void swap_pointers(void **p1, void **p2) {
346  void *hlp;
347 
348  hlp = *p1;
349  *p1 = *p2;
350  *p2 = hlp;
351 }
352 
353 /* INTERNAL: returns pthreadlocinfo struct */
356 
357  if(!data || !data->have_locale)
358  return MSVCRT_locale->locinfo;
359 
360  return data->locinfo;
361 }
362 
363 /* INTERNAL: returns pthreadlocinfo struct */
366 
367  if(!data || !data->have_locale)
368  return MSVCRT_locale->mbcinfo;
369 
370  return data->mbcinfo;
371 }
372 
373 /* INTERNAL: constructs string returned by setlocale */
375  static char current_lc_all[MAX_LOCALE_LENGTH];
376 
377  int i;
378 
379  for(i=MSVCRT_LC_MIN+1; i<MSVCRT_LC_MAX; i++) {
380  if(strcmp(locinfo->lc_category[i].locale,
381  locinfo->lc_category[i+1].locale))
382  break;
383  }
384 
385  if(i==MSVCRT_LC_MAX)
386  return locinfo->lc_category[MSVCRT_LC_COLLATE].locale;
387 
388  sprintf(current_lc_all,
389  "LC_COLLATE=%s;LC_CTYPE=%s;LC_MONETARY=%s;LC_NUMERIC=%s;LC_TIME=%s",
390  locinfo->lc_category[MSVCRT_LC_COLLATE].locale,
391  locinfo->lc_category[MSVCRT_LC_CTYPE].locale,
392  locinfo->lc_category[MSVCRT_LC_MONETARY].locale,
393  locinfo->lc_category[MSVCRT_LC_NUMERIC].locale,
394  locinfo->lc_category[MSVCRT_LC_TIME].locale);
395 
396  return current_lc_all;
397 }
398 
399 
400 /*********************************************************************
401  * wsetlocale (MSVCRT.@)
402  */
403 wchar_t* CDECL _wsetlocale(int category, const wchar_t* locale)
404 {
405  static wchar_t fake[] = {
406  'E','n','g','l','i','s','h','_','U','n','i','t','e','d',' ',
407  'S','t','a','t','e','s','.','1','2','5','2',0 };
408 
409  FIXME("%d %s\n", category, debugstr_w(locale));
410 
411  return fake;
412 }
413 
414 /*********************************************************************
415  * _Getdays (MSVCRT.@)
416  */
417 char* CDECL _Getdays(void)
418 {
420  int i, len, size;
421  char *out;
422 
423  TRACE("\n");
424 
425  size = cur->str.names.short_mon[0]-cur->str.names.short_wday[0];
426  out = MSVCRT_malloc(size+1);
427  if(!out)
428  return NULL;
429 
430  size = 0;
431  for(i=0; i<7; i++) {
432  out[size++] = ':';
433  len = strlen(cur->str.names.short_wday[i]);
434  memcpy(&out[size], cur->str.names.short_wday[i], len);
435  size += len;
436 
437  out[size++] = ':';
438  len = strlen(cur->str.names.wday[i]);
439  memcpy(&out[size], cur->str.names.wday[i], len);
440  size += len;
441  }
442  out[size] = '\0';
443 
444  return out;
445 }
446 
447 /*********************************************************************
448  * _Getmonths (MSVCRT.@)
449  */
450 char* CDECL _Getmonths(void)
451 {
453  int i, len, size;
454  char *out;
455 
456  TRACE("\n");
457 
458  size = cur->str.names.am-cur->str.names.short_mon[0];
459  out = MSVCRT_malloc(size+1);
460  if(!out)
461  return NULL;
462 
463  size = 0;
464  for(i=0; i<12; i++) {
465  out[size++] = ':';
466  len = strlen(cur->str.names.short_mon[i]);
467  memcpy(&out[size], cur->str.names.short_mon[i], len);
468  size += len;
469 
470  out[size++] = ':';
471  len = strlen(cur->str.names.mon[i]);
472  memcpy(&out[size], cur->str.names.mon[i], len);
473  size += len;
474  }
475  out[size] = '\0';
476 
477  return out;
478 }
479 
480 /*********************************************************************
481  * _Gettnames (MSVCRT.@)
482  */
483 void* CDECL _Gettnames(void)
484 {
486  unsigned int i, size = sizeof(MSVCRT___lc_time_data);
487 
488  TRACE("\n");
489 
490  for(i=0; i<sizeof(cur->str.str)/sizeof(cur->str.str[0]); i++)
491  size += strlen(cur->str.str[i])+1;
492 
493  ret = MSVCRT_malloc(size);
494  if(!ret)
495  return NULL;
496  memcpy(ret, cur, size);
497 
498  size = 0;
499  for(i=0; i<sizeof(cur->str.str)/sizeof(cur->str.str[0]); i++) {
500  ret->str.str[i] = &ret->data[size];
501  size += strlen(&ret->data[size])+1;
502  }
503 
504  return ret;
505 }
506 
507 /*********************************************************************
508  * __crtLCMapStringA (MSVCRT.@)
509  */
511  LCID lcid, DWORD mapflags, const char* src, int srclen, char* dst,
512  int dstlen, unsigned int codepage, int xflag
513 ) {
514  FIXME("(lcid %x, flags %x, %s(%d), %p(%d), %x, %d), partial stub!\n",
515  lcid,mapflags,src,srclen,dst,dstlen,codepage,xflag);
516  /* FIXME: A bit incorrect. But msvcrt itself just converts its
517  * arguments to wide strings and then calls LCMapStringW
518  */
519  return LCMapStringA(lcid,mapflags,src,srclen,dst,dstlen);
520 }
521 
522 /*********************************************************************
523  * __crtLCMapStringW (MSVCRT.@)
524  */
525 int CDECL __crtLCMapStringW(LCID lcid, DWORD mapflags, const wchar_t *src,
526  int srclen, wchar_t *dst, int dstlen, unsigned int codepage, int xflag)
527 {
528  FIXME("(lcid %x, flags %x, %s(%d), %p(%d), %x, %d), partial stub!\n",
529  lcid, mapflags, debugstr_w(src), srclen, dst, dstlen, codepage, xflag);
530 
531  return LCMapStringW(lcid, mapflags, src, srclen, dst, dstlen);
532 }
533 
534 /*********************************************************************
535  * __crtCompareStringA (MSVCRT.@)
536  */
537 int CDECL __crtCompareStringA( LCID lcid, DWORD flags, const char *src1, int len1,
538  const char *src2, int len2 )
539 {
540  FIXME("(lcid %x, flags %x, %s(%d), %s(%d), partial stub\n",
541  lcid, flags, debugstr_a(src1), len1, debugstr_a(src2), len2 );
542  /* FIXME: probably not entirely right */
543  return CompareStringA( lcid, flags, src1, len1, src2, len2 );
544 }
545 
546 /*********************************************************************
547  * __crtCompareStringW (MSVCRT.@)
548  */
549 int CDECL __crtCompareStringW( LCID lcid, DWORD flags, const wchar_t *src1, int len1,
550  const wchar_t *src2, int len2 )
551 {
552  FIXME("(lcid %x, flags %x, %s(%d), %s(%d), partial stub\n",
553  lcid, flags, debugstr_w(src1), len1, debugstr_w(src2), len2 );
554  /* FIXME: probably not entirely right */
555  return CompareStringW( lcid, flags, src1, len1, src2, len2 );
556 }
557 
558 /*********************************************************************
559  * __crtGetLocaleInfoW (MSVCRT.@)
560  */
561 int CDECL __crtGetLocaleInfoW( LCID lcid, LCTYPE type, wchar_t *buffer, int len )
562 {
563  FIXME("(lcid %x, type %x, %p(%d), partial stub\n", lcid, type, buffer, len );
564  /* FIXME: probably not entirely right */
565  return GetLocaleInfoW( lcid, type, buffer, len );
566 }
567 
568 /*********************************************************************
569  * btowc(MSVCRT.@)
570  */
572 {
573  unsigned char letter = c;
574  wchar_t ret;
575 
576  if(!MultiByteToWideChar(get_locinfo()->lc_handle[LC_CTYPE],
577  0, (LPCSTR)&letter, 1, &ret, 1))
578  return 0;
579 
580  return ret;
581 }
582 
583 /*********************************************************************
584  * __crtGetStringTypeW(MSVCRT.@)
585  *
586  * This function was accepting different number of arguments in older
587  * versions of msvcrt.
588  */
590  wchar_t *buffer, int len, WORD *out)
591 {
592  FIXME("(unk %x, type %x, wstr %p(%d), %p) partial stub\n",
593  unk, type, buffer, len, out);
594 
595  return GetStringTypeW(type, buffer, len, out);
596 }
597 
598 /*********************************************************************
599  * localeconv (MSVCRT.@)
600  */
601 struct lconv * CDECL localeconv(void)
602 {
603  return (struct lconv*)get_locinfo()->lconv;
604 }
605 
606 /*********************************************************************
607  * __lconv_init (MSVCRT.@)
608  */
610 {
611  /* this is used to make chars unsigned */
612  charmax = 255;
613  return 0;
614 }
615 
616 /*********************************************************************
617  * ___lc_handle_func (MSVCRT.@)
618  */
620 {
621  return MSVCRT___lc_handle;
622 }
623 
624 /*********************************************************************
625  * ___lc_codepage_func (MSVCRT.@)
626  */
627 unsigned int CDECL ___lc_codepage_func(void)
628 {
629  return __lc_codepage;
630 }
631 
632 /*********************************************************************
633  * ___lc_collate_cp_func (MSVCRT.@)
634  */
636 {
637  return get_locinfo()->lc_collate_cp;
638 }
639 
640 /* INTERNAL: frees MSVCRT_pthreadlocinfo struct */
642 {
643  int i;
644 
645  if(!locinfo)
646  return;
647 
648  if(InterlockedDecrement(&locinfo->refcount))
649  return;
650 
651  for(i=MSVCRT_LC_MIN+1; i<=MSVCRT_LC_MAX; i++) {
652  MSVCRT_free(locinfo->lc_category[i].locale);
653  MSVCRT_free(locinfo->lc_category[i].refcount);
654  }
655 
656  if(locinfo->lconv) {
657  MSVCRT_free(locinfo->lconv->decimal_point);
658  MSVCRT_free(locinfo->lconv->thousands_sep);
659  MSVCRT_free(locinfo->lconv->grouping);
660  MSVCRT_free(locinfo->lconv->int_curr_symbol);
661  MSVCRT_free(locinfo->lconv->currency_symbol);
662  MSVCRT_free(locinfo->lconv->mon_decimal_point);
663  MSVCRT_free(locinfo->lconv->mon_thousands_sep);
664  MSVCRT_free(locinfo->lconv->mon_grouping);
665  MSVCRT_free(locinfo->lconv->positive_sign);
666  MSVCRT_free(locinfo->lconv->negative_sign);
667  }
671  MSVCRT_free(locinfo->lconv);
672 
673  MSVCRT_free(locinfo->ctype1_refcount);
674  MSVCRT_free(locinfo->ctype1);
675 
676  MSVCRT_free(locinfo->pclmap);
677  MSVCRT_free(locinfo->pcumap);
678 
679  MSVCRT_free(locinfo->lc_time_curr);
680 
681  MSVCRT_free(locinfo);
682 }
683 
684 /* INTERNAL: frees MSVCRT_pthreadmbcinfo struct */
686 {
687  if(!mbcinfo)
688  return;
689 
690  if(InterlockedDecrement(&mbcinfo->refcount))
691  return;
692 
693  MSVCRT_free(mbcinfo);
694 }
695 
696 /* _get_current_locale - not exported in native msvcrt */
698 {
700  if(!loc)
701  return NULL;
702 
703  loc->locinfo = get_locinfo();
704  loc->mbcinfo = get_mbcinfo();
707  return loc;
708 }
709 
710 /* _free_locale - not exported in native msvcrt */
712 {
713  if (!locale)
714  return;
715 
716  free_locinfo(locale->locinfo);
717  free_mbcinfo(locale->mbcinfo);
718  MSVCRT_free(locale);
719 }
720 
721 /* _create_locale - not exported in native msvcrt */
723 {
724  static const DWORD time_data[] = {
740  };
741  static const char collate[] = "COLLATE=";
742  static const char ctype[] = "CTYPE=";
743  static const char monetary[] = "MONETARY=";
744  static const char numeric[] = "NUMERIC=";
745  static const char time[] = "TIME=";
746  static const char cloc_short_date[] = "MM/dd/yy";
747  static const wchar_t cloc_short_dateW[] = {'M','M','/','d','d','/','y','y',0};
748  static const char cloc_long_date[] = "dddd, MMMM dd, yyyy";
749  static const wchar_t cloc_long_dateW[] = {'d','d','d','d',',',' ','M','M','M','M',' ','d','d',',',' ','y','y','y','y',0};
750  static const char cloc_time[] = "HH:mm:ss";
751  static const wchar_t cloc_timeW[] = {'H','H',':','m','m',':','s','s',0};
752 
753  MSVCRT__locale_t loc;
754  LCID lcid[6] = { 0 }, lcid_tmp;
755  unsigned short cp[6] = { 0 };
756  char buf[256];
757  int i, ret, size;
758 
759  TRACE("(%d %s)\n", category, locale);
760 
762  return NULL;
763 
764  if(locale[0]=='C' && !locale[1]) {
765  lcid[0] = 0;
766  cp[0] = CP_ACP;
767  } else if(!locale[0]) {
768  lcid[0] = GetSystemDefaultLCID();
770  |LOCALE_NOUSEROVERRIDE, buf, sizeof(buf));
771  cp[0] = atoi(buf);
772 
773  for(i=1; i<6; i++) {
774  lcid[i] = lcid[0];
775  cp[i] = cp[0];
776  }
777  } else if (locale[0] == 'L' && locale[1] == 'C' && locale[2] == '_') {
778  const char *p;
779 
780  while(1) {
781  locale += 3; /* LC_ */
782  if(!memcmp(locale, collate, sizeof(collate)-1)) {
783  i = MSVCRT_LC_COLLATE;
784  locale += sizeof(collate)-1;
785  } else if(!memcmp(locale, ctype, sizeof(ctype)-1)) {
786  i = MSVCRT_LC_CTYPE;
787  locale += sizeof(ctype)-1;
788  } else if(!memcmp(locale, monetary, sizeof(monetary)-1)) {
789  i = MSVCRT_LC_MONETARY;
790  locale += sizeof(monetary)-1;
791  } else if(!memcmp(locale, numeric, sizeof(numeric)-1)) {
792  i = MSVCRT_LC_NUMERIC;
793  locale += sizeof(numeric)-1;
794  } else if(!memcmp(locale, time, sizeof(time)-1)) {
795  i = MSVCRT_LC_TIME;
796  locale += sizeof(time)-1;
797  } else
798  return NULL;
799 
800  p = strchr(locale, ';');
801  if(locale[0]=='C' && (locale[1]==';' || locale[1]=='\0')) {
802  lcid[i] = 0;
803  cp[i] = CP_ACP;
804  } else if(p) {
805  memcpy(buf, locale, p-locale);
806  buf[p-locale] = '\0';
807  lcid[i] = MSVCRT_locale_to_LCID(buf, &cp[i]);
808  } else
809  lcid[i] = MSVCRT_locale_to_LCID(locale, &cp[i]);
810 
811  if(lcid[i] == -1)
812  return NULL;
813 
814  if(!p || *(p+1)!='L' || *(p+2)!='C' || *(p+3)!='_')
815  break;
816 
817  locale = p+1;
818  }
819  } else {
820  lcid[0] = MSVCRT_locale_to_LCID(locale, &cp[0]);
821  if(lcid[0] == -1)
822  return NULL;
823 
824  for(i=1; i<6; i++) {
825  lcid[i] = lcid[0];
826  cp[i] = cp[0];
827  }
828  }
829 
830  loc = MSVCRT_malloc(sizeof(MSVCRT__locale_tstruct));
831  if(!loc)
832  return NULL;
833 
835  if(!loc->locinfo) {
836  MSVCRT_free(loc);
837  return NULL;
838  }
839 
841  if(!loc->mbcinfo) {
842  MSVCRT_free(loc->locinfo);
843  MSVCRT_free(loc);
844  return NULL;
845  }
846 
847  memset(loc->locinfo, 0, sizeof(MSVCRT_threadlocinfo));
848  loc->locinfo->refcount = 1;
849  loc->mbcinfo->refcount = 1;
850 
851  loc->locinfo->lconv = MSVCRT_malloc(sizeof(struct MSVCRT_lconv));
852  if(!loc->locinfo->lconv) {
853  MSVCRT__free_locale(loc);
854  return NULL;
855  }
856  memset(loc->locinfo->lconv, 0, sizeof(struct MSVCRT_lconv));
857 
858  loc->locinfo->pclmap = MSVCRT_malloc(sizeof(char[256]));
859  loc->locinfo->pcumap = MSVCRT_malloc(sizeof(char[256]));
860  if(!loc->locinfo->pclmap || !loc->locinfo->pcumap) {
861  MSVCRT__free_locale(loc);
862  return NULL;
863  }
864 
865  if(lcid[MSVCRT_LC_COLLATE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_COLLATE)) {
866  if(update_threadlocinfo_category(lcid[MSVCRT_LC_COLLATE], cp[MSVCRT_LC_COLLATE], loc, MSVCRT_LC_COLLATE)) {
867  MSVCRT__free_locale(loc);
868  return NULL;
869  }
870 
872  } else
873  loc->locinfo->lc_category[LC_COLLATE].locale = _strdup("C");
874 
875  if(lcid[MSVCRT_LC_CTYPE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_CTYPE)) {
876  CPINFO cp_info;
877  int j;
878 
879  if(update_threadlocinfo_category(lcid[MSVCRT_LC_CTYPE], cp[MSVCRT_LC_CTYPE], loc, MSVCRT_LC_CTYPE)) {
880  MSVCRT__free_locale(loc);
881  return NULL;
882  }
883 
885  loc->locinfo->lc_clike = 1;
886  if(!GetCPInfo(loc->locinfo->lc_codepage, &cp_info)) {
887  MSVCRT__free_locale(loc);
888  return NULL;
889  }
890  loc->locinfo->mb_cur_max = cp_info.MaxCharSize;
891 
892  loc->locinfo->ctype1_refcount = MSVCRT_malloc(sizeof(int));
893  loc->locinfo->ctype1 = MSVCRT_malloc(sizeof(short[257]));
894  if(!loc->locinfo->ctype1_refcount || !loc->locinfo->ctype1) {
895  MSVCRT__free_locale(loc);
896  return NULL;
897  }
898 
899  *loc->locinfo->ctype1_refcount = 1;
900  loc->locinfo->ctype1[0] = 0;
901  loc->locinfo->pctype = loc->locinfo->ctype1+1;
902 
903  buf[1] = buf[2] = '\0';
904  for(i=1; i<257; i++) {
905  buf[0] = i-1;
906 
907  /* builtin GetStringTypeA doesn't set output to 0 on invalid input */
908  loc->locinfo->ctype1[i] = 0;
909 
910  GetStringTypeA(lcid[MSVCRT_LC_CTYPE], CT_CTYPE1, buf,
911  1, loc->locinfo->ctype1+i);
912  }
913 
914  for(i=0; cp_info.LeadByte[i+1]!=0; i+=2)
915  for(j=cp_info.LeadByte[i]; j<=cp_info.LeadByte[i+1]; j++)
916  loc->locinfo->ctype1[j+1] |= _LEADBYTE;
917  } else {
918  loc->locinfo->lc_clike = 1;
919  loc->locinfo->mb_cur_max = 1;
920  loc->locinfo->pctype = _ctype+1;
921  loc->locinfo->lc_category[LC_CTYPE].locale = _strdup("C");
922  }
923 
924  for(i=0; i<256; i++) {
925  if(loc->locinfo->pctype[i] & _LEADBYTE)
926  buf[i] = ' ';
927  else
928  buf[i] = i;
929 
930  }
931 
932  if(lcid[MSVCRT_LC_CTYPE]) {
933  LCMapStringA(lcid[MSVCRT_LC_CTYPE], LCMAP_LOWERCASE, buf, 256,
934  (char*)loc->locinfo->pclmap, 256);
935  LCMapStringA(lcid[MSVCRT_LC_CTYPE], LCMAP_UPPERCASE, buf, 256,
936  (char*)loc->locinfo->pcumap, 256);
937  } else {
938  for(i=0; i<256; i++) {
939  loc->locinfo->pclmap[i] = (i>='A' && i<='Z' ? i-'A'+'a' : i);
940  loc->locinfo->pcumap[i] = (i>='a' && i<='z' ? i-'a'+'A' : i);
941  }
942  }
943 
944  _setmbcp_l(loc->locinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage, lcid[MSVCRT_LC_CTYPE], loc->mbcinfo);
945 
946  if(lcid[MSVCRT_LC_MONETARY] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_MONETARY)) {
947  if(update_threadlocinfo_category(lcid[MSVCRT_LC_MONETARY], cp[MSVCRT_LC_MONETARY], loc, MSVCRT_LC_MONETARY)) {
948  MSVCRT__free_locale(loc);
949  return NULL;
950  }
951 
952  loc->locinfo->lconv_intl_refcount = MSVCRT_malloc(sizeof(int));
953  loc->locinfo->lconv_mon_refcount = MSVCRT_malloc(sizeof(int));
955  MSVCRT__free_locale(loc);
956  return NULL;
957  }
958 
959  *loc->locinfo->lconv_intl_refcount = 1;
960  *loc->locinfo->lconv_mon_refcount = 1;
961 
962  i = GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_SINTLSYMBOL
963  |LOCALE_NOUSEROVERRIDE, buf, 256);
964  if(i && (loc->locinfo->lconv->int_curr_symbol = MSVCRT_malloc(i)))
965  memcpy(loc->locinfo->lconv->int_curr_symbol, buf, i);
966  else {
967  MSVCRT__free_locale(loc);
968  return NULL;
969  }
970 
971  i = GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_SCURRENCY
972  |LOCALE_NOUSEROVERRIDE, buf, 256);
973  if(i && (loc->locinfo->lconv->currency_symbol = MSVCRT_malloc(i)))
974  memcpy(loc->locinfo->lconv->currency_symbol, buf, i);
975  else {
976  MSVCRT__free_locale(loc);
977  return NULL;
978  }
979 
980  i = GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_SMONDECIMALSEP
981  |LOCALE_NOUSEROVERRIDE, buf, 256);
982  if(i && (loc->locinfo->lconv->mon_decimal_point = MSVCRT_malloc(i)))
983  memcpy(loc->locinfo->lconv->mon_decimal_point, buf, i);
984  else {
985  MSVCRT__free_locale(loc);
986  return NULL;
987  }
988 
989  i = GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_SMONTHOUSANDSEP
990  |LOCALE_NOUSEROVERRIDE, buf, 256);
991  if(i && (loc->locinfo->lconv->mon_thousands_sep = MSVCRT_malloc(i)))
992  memcpy(loc->locinfo->lconv->mon_thousands_sep, buf, i);
993  else {
994  MSVCRT__free_locale(loc);
995  return NULL;
996  }
997 
998  i = GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_SMONGROUPING
999  |LOCALE_NOUSEROVERRIDE, buf, 256);
1000  if(i>1)
1001  i = i/2 + (buf[i-2]=='0'?0:1);
1002  if(i && (loc->locinfo->lconv->mon_grouping = MSVCRT_malloc(i))) {
1003  for(i=0; buf[i+1]==';'; i+=2)
1004  loc->locinfo->lconv->mon_grouping[i/2] = buf[i]-'0';
1005  loc->locinfo->lconv->mon_grouping[i/2] = buf[i]-'0';
1006  if(buf[i] != '0')
1007  loc->locinfo->lconv->mon_grouping[i/2+1] = 127;
1008  } else {
1009  MSVCRT__free_locale(loc);
1010  return NULL;
1011  }
1012 
1013  i = GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_SPOSITIVESIGN
1014  |LOCALE_NOUSEROVERRIDE, buf, 256);
1015  if(i && (loc->locinfo->lconv->positive_sign = MSVCRT_malloc(i)))
1016  memcpy(loc->locinfo->lconv->positive_sign, buf, i);
1017  else {
1018  MSVCRT__free_locale(loc);
1019  return NULL;
1020  }
1021 
1022  i = GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_SNEGATIVESIGN
1023  |LOCALE_NOUSEROVERRIDE, buf, 256);
1024  if(i && (loc->locinfo->lconv->negative_sign = MSVCRT_malloc(i)))
1025  memcpy(loc->locinfo->lconv->negative_sign, buf, i);
1026  else {
1027  MSVCRT__free_locale(loc);
1028  return NULL;
1029  }
1030 
1031  if(GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_IINTLCURRDIGITS
1032  |LOCALE_NOUSEROVERRIDE, buf, 256))
1033  loc->locinfo->lconv->int_frac_digits = atoi(buf);
1034  else {
1035  MSVCRT__free_locale(loc);
1036  return NULL;
1037  }
1038 
1039  if(GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_ICURRDIGITS
1040  |LOCALE_NOUSEROVERRIDE, buf, 256))
1041  loc->locinfo->lconv->frac_digits = atoi(buf);
1042  else {
1043  MSVCRT__free_locale(loc);
1044  return NULL;
1045  }
1046 
1047  if(GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_IPOSSYMPRECEDES
1048  |LOCALE_NOUSEROVERRIDE, buf, 256))
1049  loc->locinfo->lconv->p_cs_precedes = atoi(buf);
1050  else {
1051  MSVCRT__free_locale(loc);
1052  return NULL;
1053  }
1054 
1055  if(GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_IPOSSEPBYSPACE
1056  |LOCALE_NOUSEROVERRIDE, buf, 256))
1057  loc->locinfo->lconv->p_sep_by_space = atoi(buf);
1058  else {
1059  MSVCRT__free_locale(loc);
1060  return NULL;
1061  }
1062 
1063  if(GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_INEGSYMPRECEDES
1064  |LOCALE_NOUSEROVERRIDE, buf, 256))
1065  loc->locinfo->lconv->n_cs_precedes = atoi(buf);
1066  else {
1067  MSVCRT__free_locale(loc);
1068  return NULL;
1069  }
1070 
1071  if(GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_INEGSEPBYSPACE
1072  |LOCALE_NOUSEROVERRIDE, buf, 256))
1073  loc->locinfo->lconv->n_sep_by_space = atoi(buf);
1074  else {
1075  MSVCRT__free_locale(loc);
1076  return NULL;
1077  }
1078 
1079  if(GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_IPOSSIGNPOSN
1080  |LOCALE_NOUSEROVERRIDE, buf, 256))
1081  loc->locinfo->lconv->p_sign_posn = atoi(buf);
1082  else {
1083  MSVCRT__free_locale(loc);
1084  return NULL;
1085  }
1086 
1087  if(GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_INEGSIGNPOSN
1088  |LOCALE_NOUSEROVERRIDE, buf, 256))
1089  loc->locinfo->lconv->n_sign_posn = atoi(buf);
1090  else {
1091  MSVCRT__free_locale(loc);
1092  return NULL;
1093  }
1094  } else {
1095  loc->locinfo->lconv->int_curr_symbol = MSVCRT_malloc(sizeof(char));
1096  loc->locinfo->lconv->currency_symbol = MSVCRT_malloc(sizeof(char));
1097  loc->locinfo->lconv->mon_decimal_point = MSVCRT_malloc(sizeof(char));
1098  loc->locinfo->lconv->mon_thousands_sep = MSVCRT_malloc(sizeof(char));
1099  loc->locinfo->lconv->mon_grouping = MSVCRT_malloc(sizeof(char));
1100  loc->locinfo->lconv->positive_sign = MSVCRT_malloc(sizeof(char));
1101  loc->locinfo->lconv->negative_sign = MSVCRT_malloc(sizeof(char));
1102 
1103  if(!loc->locinfo->lconv->int_curr_symbol || !loc->locinfo->lconv->currency_symbol
1104  || !loc->locinfo->lconv->mon_decimal_point || !loc->locinfo->lconv->mon_thousands_sep
1105  || !loc->locinfo->lconv->mon_grouping || !loc->locinfo->lconv->positive_sign
1106  || !loc->locinfo->lconv->negative_sign) {
1107  MSVCRT__free_locale(loc);
1108  return NULL;
1109  }
1110 
1111  loc->locinfo->lconv->int_curr_symbol[0] = '\0';
1112  loc->locinfo->lconv->currency_symbol[0] = '\0';
1113  loc->locinfo->lconv->mon_decimal_point[0] = '\0';
1114  loc->locinfo->lconv->mon_thousands_sep[0] = '\0';
1115  loc->locinfo->lconv->mon_grouping[0] = '\0';
1116  loc->locinfo->lconv->positive_sign[0] = '\0';
1117  loc->locinfo->lconv->negative_sign[0] = '\0';
1118  loc->locinfo->lconv->int_frac_digits = 127;
1119  loc->locinfo->lconv->frac_digits = 127;
1120  loc->locinfo->lconv->p_cs_precedes = 127;
1121  loc->locinfo->lconv->p_sep_by_space = 127;
1122  loc->locinfo->lconv->n_cs_precedes = 127;
1123  loc->locinfo->lconv->n_sep_by_space = 127;
1124  loc->locinfo->lconv->p_sign_posn = 127;
1125  loc->locinfo->lconv->n_sign_posn = 127;
1126 
1127  loc->locinfo->lc_category[LC_MONETARY].locale = _strdup("C");
1128  }
1129 
1130  if(lcid[MSVCRT_LC_NUMERIC] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_NUMERIC)) {
1131  if(update_threadlocinfo_category(lcid[MSVCRT_LC_NUMERIC], cp[MSVCRT_LC_NUMERIC], loc, MSVCRT_LC_NUMERIC)) {
1132  MSVCRT__free_locale(loc);
1133  return NULL;
1134  }
1135 
1136  if(!loc->locinfo->lconv_intl_refcount)
1137  loc->locinfo->lconv_intl_refcount = MSVCRT_malloc(sizeof(int));
1138  loc->locinfo->lconv_num_refcount = MSVCRT_malloc(sizeof(int));
1139  if(!loc->locinfo->lconv_intl_refcount || !loc->locinfo->lconv_num_refcount) {
1140  MSVCRT__free_locale(loc);
1141  return NULL;
1142  }
1143 
1144  *loc->locinfo->lconv_intl_refcount = 1;
1145  *loc->locinfo->lconv_num_refcount = 1;
1146 
1147  i = GetLocaleInfoA(lcid[MSVCRT_LC_NUMERIC], LOCALE_SDECIMAL
1148  |LOCALE_NOUSEROVERRIDE, buf, 256);
1149  if(i && (loc->locinfo->lconv->decimal_point = MSVCRT_malloc(i)))
1150  memcpy(loc->locinfo->lconv->decimal_point, buf, i);
1151  else {
1152  MSVCRT__free_locale(loc);
1153  return NULL;
1154  }
1155 
1156  i = GetLocaleInfoA(lcid[MSVCRT_LC_NUMERIC], LOCALE_STHOUSAND
1157  |LOCALE_NOUSEROVERRIDE, buf, 256);
1158  if(i && (loc->locinfo->lconv->thousands_sep = MSVCRT_malloc(i)))
1159  memcpy(loc->locinfo->lconv->thousands_sep, buf, i);
1160  else {
1161  MSVCRT__free_locale(loc);
1162  return NULL;
1163  }
1164 
1165  i = GetLocaleInfoA(lcid[MSVCRT_LC_NUMERIC], LOCALE_SGROUPING
1166  |LOCALE_NOUSEROVERRIDE, buf, 256);
1167  if(i>1)
1168  i = i/2 + (buf[i-2]=='0'?0:1);
1169  if(i && (loc->locinfo->lconv->grouping = MSVCRT_malloc(i))) {
1170  for(i=0; buf[i+1]==';'; i+=2)
1171  loc->locinfo->lconv->grouping[i/2] = buf[i]-'0';
1172  loc->locinfo->lconv->grouping[i/2] = buf[i]-'0';
1173  if(buf[i] != '0')
1174  loc->locinfo->lconv->grouping[i/2+1] = 127;
1175  } else {
1176  MSVCRT__free_locale(loc);
1177  return NULL;
1178  }
1179  } else {
1180  loc->locinfo->lconv->decimal_point = MSVCRT_malloc(sizeof(char[2]));
1181  loc->locinfo->lconv->thousands_sep = MSVCRT_malloc(sizeof(char));
1182  loc->locinfo->lconv->grouping = MSVCRT_malloc(sizeof(char));
1183  if(!loc->locinfo->lconv->decimal_point || !loc->locinfo->lconv->thousands_sep
1184  || !loc->locinfo->lconv->grouping) {
1185  MSVCRT__free_locale(loc);
1186  return NULL;
1187  }
1188 
1189  loc->locinfo->lconv->decimal_point[0] = '.';
1190  loc->locinfo->lconv->decimal_point[1] = '\0';
1191  loc->locinfo->lconv->thousands_sep[0] = '\0';
1192  loc->locinfo->lconv->grouping[0] = '\0';
1193 
1194  loc->locinfo->lc_category[LC_NUMERIC].locale = _strdup("C");
1195  }
1196 
1197  if(lcid[MSVCRT_LC_TIME] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_TIME)) {
1198  if(update_threadlocinfo_category(lcid[MSVCRT_LC_TIME], cp[MSVCRT_LC_TIME], loc, MSVCRT_LC_TIME)) {
1199  MSVCRT__free_locale(loc);
1200  return NULL;
1201  }
1202  } else
1203  loc->locinfo->lc_category[LC_TIME].locale = _strdup("C");
1204 
1205  size = sizeof(MSVCRT___lc_time_data);
1206  lcid_tmp = lcid[MSVCRT_LC_TIME] ? lcid[MSVCRT_LC_TIME] : MAKELCID(LANG_ENGLISH, SORT_DEFAULT);
1207  for(i=0; i<sizeof(time_data)/sizeof(time_data[0]); i++) {
1208  if(time_data[i]==LOCALE_SSHORTDATE && !lcid[MSVCRT_LC_TIME]) {
1209  size += sizeof(cloc_short_date) + sizeof(cloc_short_dateW);
1210  }else if(time_data[i]==LOCALE_SLONGDATE && !lcid[MSVCRT_LC_TIME]) {
1211  size += sizeof(cloc_long_date) + sizeof(cloc_long_dateW);
1212  }else {
1213  ret = GetLocaleInfoA(lcid_tmp, time_data[i]
1215  if(!ret) {
1216  MSVCRT__free_locale(loc);
1217  return NULL;
1218  }
1219  size += ret;
1220 
1221  ret = GetLocaleInfoW(lcid_tmp, time_data[i]
1223  if(!ret) {
1224  MSVCRT__free_locale(loc);
1225  return NULL;
1226  }
1227  size += ret*sizeof(wchar_t);
1228  }
1229  }
1230 
1231  loc->locinfo->lc_time_curr = MSVCRT_malloc(size);
1232  if(!loc->locinfo->lc_time_curr) {
1233  MSVCRT__free_locale(loc);
1234  return NULL;
1235  }
1236 
1237  ret = 0;
1238  for(i=0; i<sizeof(time_data)/sizeof(time_data[0]); i++) {
1239  loc->locinfo->lc_time_curr->str.str[i] = &loc->locinfo->lc_time_curr->data[ret];
1240  if(time_data[i]==LOCALE_SSHORTDATE && !lcid[MSVCRT_LC_TIME]) {
1241  memcpy(&loc->locinfo->lc_time_curr->data[ret], cloc_short_date, sizeof(cloc_short_date));
1242  ret += sizeof(cloc_short_date);
1243  }else if(time_data[i]==LOCALE_SLONGDATE && !lcid[MSVCRT_LC_TIME]) {
1244  memcpy(&loc->locinfo->lc_time_curr->data[ret], cloc_long_date, sizeof(cloc_long_date));
1245  ret += sizeof(cloc_long_date);
1246  }else if(time_data[i]==LOCALE_STIMEFORMAT && !lcid[MSVCRT_LC_TIME]) {
1247  memcpy(&loc->locinfo->lc_time_curr->data[ret], cloc_time, sizeof(cloc_time));
1248  ret += sizeof(cloc_time);
1249  }else {
1250  ret += GetLocaleInfoA(lcid_tmp, time_data[i]|LOCALE_NOUSEROVERRIDE,
1251  &loc->locinfo->lc_time_curr->data[ret], size-ret);
1252  }
1253  }
1254  for(i=0; i<sizeof(time_data)/sizeof(time_data[0]); i++) {
1255  loc->locinfo->lc_time_curr->wstr[i] = (wchar_t*)&loc->locinfo->lc_time_curr->data[ret];
1256  if(time_data[i]==LOCALE_SSHORTDATE && !lcid[MSVCRT_LC_TIME]) {
1257  memcpy(&loc->locinfo->lc_time_curr->data[ret], cloc_short_dateW, sizeof(cloc_short_dateW));
1258  ret += sizeof(cloc_short_dateW);
1259  }else if(time_data[i]==LOCALE_SLONGDATE && !lcid[MSVCRT_LC_TIME]) {
1260  memcpy(&loc->locinfo->lc_time_curr->data[ret], cloc_long_dateW, sizeof(cloc_long_dateW));
1261  ret += sizeof(cloc_long_dateW);
1262  }else if(time_data[i]==LOCALE_STIMEFORMAT && !lcid[MSVCRT_LC_TIME]) { memcpy(&loc->locinfo->lc_time_curr->data[ret], cloc_timeW, sizeof(cloc_timeW));
1263  ret += sizeof(cloc_timeW);
1264  }else {
1265  ret += GetLocaleInfoW(lcid_tmp, time_data[i]|LOCALE_NOUSEROVERRIDE,
1266  (wchar_t*)&loc->locinfo->lc_time_curr->data[ret], size-ret)*sizeof(wchar_t);
1267  }
1268  }
1269  loc->locinfo->lc_time_curr->lcid = lcid[MSVCRT_LC_TIME];
1270 
1271  return loc;
1272 }
1273 
1274 /*********************************************************************
1275  * setlocale (MSVCRT.@)
1276  */
1277 char* CDECL setlocale(int category, const char* locale)
1278 {
1279  MSVCRT__locale_t loc;
1281 
1283  return NULL;
1284 
1285  if(!locale) {
1286  if(category == MSVCRT_LC_ALL)
1287  return construct_lc_all(locinfo);
1288 
1289  return locinfo->lc_category[category].locale;
1290  }
1291 
1292  loc = MSVCRT__create_locale(category, locale);
1293  if(!loc) {
1294  WARN("%d %s failed\n", category, locale);
1295  return NULL;
1296  }
1297 
1298  LOCK_LOCALE;
1299 
1300  switch(category) {
1301  case MSVCRT_LC_ALL:
1302  case MSVCRT_LC_COLLATE:
1303  locinfo->lc_collate_cp = loc->locinfo->lc_collate_cp;
1304  locinfo->lc_handle[MSVCRT_LC_COLLATE] =
1306  swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_COLLATE].locale,
1307  (void**)&loc->locinfo->lc_category[MSVCRT_LC_COLLATE].locale);
1308  swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_COLLATE].refcount,
1309  (void**)&loc->locinfo->lc_category[MSVCRT_LC_COLLATE].refcount);
1310 
1311  if(category != MSVCRT_LC_ALL)
1312  break;
1313  /* fall through */
1314  case MSVCRT_LC_CTYPE:
1315  locinfo->lc_handle[MSVCRT_LC_CTYPE] =
1317  swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_CTYPE].locale,
1318  (void**)&loc->locinfo->lc_category[MSVCRT_LC_CTYPE].locale);
1319  swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_CTYPE].refcount,
1320  (void**)&loc->locinfo->lc_category[MSVCRT_LC_CTYPE].refcount);
1321 
1322  locinfo->lc_codepage = loc->locinfo->lc_codepage;
1323  locinfo->lc_clike = loc->locinfo->lc_clike;
1324  locinfo->mb_cur_max = loc->locinfo->mb_cur_max;
1325 
1326  swap_pointers((void**)&locinfo->ctype1_refcount,
1327  (void**)&loc->locinfo->ctype1_refcount);
1328  swap_pointers((void**)&locinfo->ctype1, (void**)&loc->locinfo->ctype1);
1329  swap_pointers((void**)&locinfo->pctype, (void**)&loc->locinfo->pctype);
1330  swap_pointers((void**)&locinfo->pclmap, (void**)&loc->locinfo->pclmap);
1331  swap_pointers((void**)&locinfo->pcumap, (void**)&loc->locinfo->pcumap);
1332 
1333  if(category != MSVCRT_LC_ALL)
1334  break;
1335  /* fall through */
1336  case MSVCRT_LC_MONETARY:
1337  locinfo->lc_handle[MSVCRT_LC_MONETARY] =
1339  swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_MONETARY].locale,
1340  (void**)&loc->locinfo->lc_category[MSVCRT_LC_MONETARY].locale);
1341  swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_MONETARY].refcount,
1342  (void**)&loc->locinfo->lc_category[MSVCRT_LC_MONETARY].refcount);
1343 
1344  swap_pointers((void**)&locinfo->lconv->int_curr_symbol,
1345  (void**)&loc->locinfo->lconv->int_curr_symbol);
1346  swap_pointers((void**)&locinfo->lconv->currency_symbol,
1347  (void**)&loc->locinfo->lconv->currency_symbol);
1348  swap_pointers((void**)&locinfo->lconv->mon_decimal_point,
1349  (void**)&loc->locinfo->lconv->mon_decimal_point);
1350  swap_pointers((void**)&locinfo->lconv->mon_thousands_sep,
1351  (void**)&loc->locinfo->lconv->mon_thousands_sep);
1352  swap_pointers((void**)&locinfo->lconv->mon_grouping,
1353  (void**)&loc->locinfo->lconv->mon_grouping);
1354  swap_pointers((void**)&locinfo->lconv->positive_sign,
1355  (void**)&loc->locinfo->lconv->positive_sign);
1356  swap_pointers((void**)&locinfo->lconv->negative_sign,
1357  (void**)&loc->locinfo->lconv->negative_sign);
1358  locinfo->lconv->int_frac_digits = loc->locinfo->lconv->int_frac_digits;
1359  locinfo->lconv->frac_digits = loc->locinfo->lconv->frac_digits;
1360  locinfo->lconv->p_cs_precedes = loc->locinfo->lconv->p_cs_precedes;
1361  locinfo->lconv->p_sep_by_space = loc->locinfo->lconv->p_sep_by_space;
1362  locinfo->lconv->n_cs_precedes = loc->locinfo->lconv->n_cs_precedes;
1363  locinfo->lconv->n_sep_by_space = loc->locinfo->lconv->n_sep_by_space;
1364  locinfo->lconv->p_sign_posn = loc->locinfo->lconv->p_sign_posn;
1365  locinfo->lconv->n_sign_posn = loc->locinfo->lconv->n_sign_posn;
1366 
1367  if(category != MSVCRT_LC_ALL)
1368  break;
1369  /* fall through */
1370  case MSVCRT_LC_NUMERIC:
1371  locinfo->lc_handle[MSVCRT_LC_NUMERIC] =
1373  swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_NUMERIC].locale,
1374  (void**)&loc->locinfo->lc_category[MSVCRT_LC_NUMERIC].locale);
1375  swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_NUMERIC].refcount,
1376  (void**)&loc->locinfo->lc_category[MSVCRT_LC_NUMERIC].refcount);
1377 
1378  swap_pointers((void**)&locinfo->lconv->decimal_point,
1379  (void**)&loc->locinfo->lconv->decimal_point);
1380  swap_pointers((void**)&locinfo->lconv->thousands_sep,
1381  (void**)&loc->locinfo->lconv->thousands_sep);
1382  swap_pointers((void**)&locinfo->lconv->grouping,
1383  (void**)&loc->locinfo->lconv->grouping);
1384 
1385  if(category != MSVCRT_LC_ALL)
1386  break;
1387  /* fall through */
1388  case MSVCRT_LC_TIME:
1389  locinfo->lc_handle[MSVCRT_LC_TIME] =
1391  swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_TIME].locale,
1392  (void**)&loc->locinfo->lc_category[MSVCRT_LC_TIME].locale);
1393  swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_TIME].refcount,
1394  (void**)&loc->locinfo->lc_category[MSVCRT_LC_TIME].refcount);
1395  swap_pointers((void**)&locinfo->lc_time_curr,
1396  (void**)&loc->locinfo->lc_time_curr);
1397 
1398  if(category != MSVCRT_LC_ALL)
1399  break;
1400  }
1401 
1402  MSVCRT__free_locale(loc);
1403  UNLOCK_LOCALE;
1404 
1405  if(locinfo == MSVCRT_locale->locinfo) {
1406  int i;
1407 
1408  __lc_codepage = locinfo->lc_codepage;
1410  __mb_cur_max = locinfo->mb_cur_max;
1411  _pctype = locinfo->pctype;
1412  for(i=LC_MIN; i<=LC_MAX; i++)
1414  }
1415 
1416  if(category == MSVCRT_LC_ALL)
1417  return construct_lc_all(locinfo);
1418 
1419  _Analysis_assume_(category <= 5);
1420  return locinfo->lc_category[category].locale;
1421 }
1422 
1423 /* _configthreadlocale - not exported in native msvcrt */
1425 {
1428  int ret;
1429 
1430  if(!data)
1431  return -1;
1432 
1433  ret = (data->have_locale ? _ENABLE_PER_THREAD_LOCALE : _DISABLE_PER_THREAD_LOCALE);
1434 
1435  if(type == _ENABLE_PER_THREAD_LOCALE) {
1436  if(!data->have_locale) {
1437  /* Copy current global locale */
1439  if(!locale)
1440  return -1;
1441 
1442  data->locinfo = locale->locinfo;
1443  data->mbcinfo = locale->mbcinfo;
1444  data->have_locale = TRUE;
1445  MSVCRT_free(locale);
1446  }
1447 
1448  return ret;
1449  }
1450 
1451  if(type == _DISABLE_PER_THREAD_LOCALE) {
1452  if(data->have_locale) {
1453  free_locinfo(data->locinfo);
1454  free_mbcinfo(data->mbcinfo);
1455  data->locinfo = MSVCRT_locale->locinfo;
1456  data->mbcinfo = MSVCRT_locale->mbcinfo;
1457  data->have_locale = FALSE;
1458  }
1459 
1460  return ret;
1461  }
1462 
1463  if(!type)
1464  return ret;
1465 
1466  return -1;
1467 }
1468 
1469 /*********************************************************************
1470  * _getmbcp (MSVCRT.@)
1471  */
1472 int CDECL _getmbcp(void)
1473 {
1474  return get_mbcinfo()->mbcodepage;
1475 }
1476 
1477 extern unsigned int __setlc_active;
1478 /*********************************************************************
1479  * ___setlc_active_func (MSVCRT.@)
1480  */
1481 unsigned int CDECL ___setlc_active_func(void)
1482 {
1483  return __setlc_active;
1484 }
1485 
1486 extern unsigned int __unguarded_readlc_active;
1487 /*********************************************************************
1488  * ___unguarded_readlc_active_add_func (MSVCRT.@)
1489  */
1491 {
1492  return &__unguarded_readlc_active;
1493 }
1494 
1497 {
1498  unsigned i;
1499 
1500  LOCK_LOCALE;
1501  /* Someone created it before us */
1502  if(global_locale)
1503  return;
1504  global_locale = MSVCRT__create_locale(0, "C");
1505 
1509  for(i=LC_MIN; i<=LC_MAX; i++)
1512  UNLOCK_LOCALE;
1513 }
1514 
1515 /*
1516  * @implemented
1517  */
1518 const unsigned short **__p__pctype(void)
1519 {
1520  return &get_locinfo()->pctype;
1521 }
1522 
1523 const unsigned short* __cdecl __pctype_func(void)
1524 {
1525  return get_locinfo()->pctype;
1526 }
1527 
unsigned int *CDECL ___unguarded_readlc_active_add_func(void)
Definition: locale.c:1490
#define LOCALE_SGROUPING
Definition: winnls.h:44
#define FOUND_COUNTRY
Definition: locale.c:104
#define LOCK_LOCALE
Definition: locale.c:43
int CDECL _getmbcp(void)
Definition: locale.c:1472
#define LC_CTYPE
Definition: locale.h:27
BOOL WINAPI GetCPInfo(UINT CodePage, LPCPINFO CodePageInfo)
Definition: nls.c:1813
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:38
#define MAKELCID(lgid, srtid)
#define LOCALE_SABBREVMONTHNAME12
Definition: winnls.h:115
struct lconv *CDECL localeconv(void)
Definition: locale.c:601
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
unsigned short WORD
Definition: ntddk_ex.h:93
#define TRUE
Definition: types.h:120
#define LOCALE_SMONGROUPING
Definition: winnls.h:53
#define LC_MIN
Definition: locale.h:32
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define LOCALE_SABBREVDAYNAME2
Definition: winnls.h:85
#define LOCALE_SABBREVMONTHNAME1
Definition: winnls.h:104
#define LOCALE_SISO639LANGNAME
Definition: winnls.h:127
#define LOCALE_SMONTHNAME5
Definition: winnls.h:95
MSVCRT_LC_ID lc_id[6]
Definition: msvcrt.h:116
#define __cdecl
Definition: accygwin.h:79
#define strcasecmp
Definition: fake.h:9
#define LOCALE_SENGLANGUAGE
Definition: winnls.h:27
#define LOCALE_IPOSSYMPRECEDES
Definition: winnls.h:122
#define LOCALE_SABBREVMONTHNAME6
Definition: winnls.h:109
#define LOCALE_SENGCOUNTRY
Definition: winnls.h:32
void *__cdecl _Gettnames(void)
Definition: locale.c:483
#define CONTINUE_LOOKING
Definition: locale.c:116
#define LOCALE_SMONTHNAME2
Definition: winnls.h:92
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define MSVCRT_LC_MIN
Definition: msvcrt.h:656
#define LOCALE_SABBREVDAYNAME4
Definition: winnls.h:87
char *CDECL _Getdays(void)
Definition: locale.c:417
#define LANG_NEUTRAL
Definition: nls.h:22
#define LOCALE_SABBREVCTRYNAME
Definition: winnls.h:33
#define CP_ACP
Definition: compat.h:99
INT WINAPI GetLocaleInfoA(LCID lcid, LCTYPE lctype, LPSTR buffer, INT len)
Definition: lang.c:727
#define LOCALE_SABBREVDAYNAME7
Definition: winnls.h:90
#define LOCALE_SABBREVDAYNAME1
Definition: winnls.h:84
unsigned short wCountry
Definition: msvcrt.h:107
#define LOCALE_INEGSYMPRECEDES
Definition: winnls.h:124
#define WARN(fmt,...)
Definition: debug.h:111
static char * construct_lc_all(MSVCRT_pthreadlocinfo locinfo)
Definition: locale.c:374
#define LOCALE_SDAYNAME2
Definition: winnls.h:78
MSVCRT_pthreadlocinfo get_locinfo(void)
Definition: locale.c:354
#define STOP_LOOKING
Definition: locale.c:117
#define LC_NUMERIC
Definition: locale.h:29
#define CALLBACK
Definition: compat.h:27
char * str[43]
Definition: locale.h:53
#define LOCALE_SMONTHNAME6
Definition: winnls.h:96
#define MAX_ELEM_LEN
Definition: locale.c:27
int CDECL ___lc_collate_cp_func(void)
Definition: locale.c:635
BOOL CDECL __crtGetStringTypeW(DWORD unk, DWORD type, wchar_t *buffer, int len, WORD *out)
Definition: locale.c:589
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define LOCALE_SABBREVMONTHNAME7
Definition: winnls.h:110
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
UINT MaxCharSize
Definition: winnls.h:569
DWORD LCID
Definition: nls.h:13
WORD LANGID
Definition: typedefs.h:79
char *CDECL setlocale(int category, const char *locale)
Definition: locale.c:1277
void __cdecl MSVCRT_free(void *)
#define LOCALE_ILANGUAGE
Definition: winnls.h:25
__u16 time
Definition: mkdosfs.c:366
char search_country[MAX_ELEM_LEN]
Definition: locale.c:109
#define cmp(status, error)
Definition: error.c:114
char * LPSTR
Definition: xmlstorage.h:182
#define _strdup
Definition: debug_ros.c:7
#define LOCALE_SABBREVMONTHNAME3
Definition: winnls.h:106
int CDECL _configthreadlocale(int type)
Definition: locale.c:1424
static BOOL update_threadlocinfo_category(LCID lcid, unsigned short cp, MSVCRT__locale_t loc, int category)
Definition: locale.c:289
#define LOCALE_SMONTHNAME8
Definition: winnls.h:98
MSVCRT__locale_t CDECL MSVCRT__get_current_locale(void)
Definition: locale.c:697
#define LOCALE_IPOSSEPBYSPACE
Definition: winnls.h:123
DWORD DWORD
Definition: winlogon.h:75
int CDECL __crtLCMapStringA(LCID lcid, DWORD mapflags, const char *src, int srclen, char *dst, int dstlen, unsigned int codepage, int xflag)
Definition: locale.c:510
#define LOCALE_SABBREVMONTHNAME8
Definition: winnls.h:111
#define LOCALE_SCURRENCY
Definition: winnls.h:49
int CDECL __crtCompareStringW(LCID lcid, DWORD flags, const wchar_t *src1, int len1, const wchar_t *src2, int len2)
Definition: locale.c:549
static const char *const _country_synonyms[]
Definition: locale.c:50
#define LOCALE_SDAYNAME5
Definition: winnls.h:81
void free_locinfo(MSVCRT_pthreadlocinfo locinfo)
Definition: locale.c:641
const GLfloat * p2
Definition: s_aatritemp.h:44
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:807
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define LOCALE_SDAYNAME1
Definition: winnls.h:77
GLuint const GLubyte GLvoid * src
Definition: s_context.h:57
#define LOCALE_SABBREVDAYNAME3
Definition: winnls.h:86
wchar_t *CDECL _wsetlocale(int category, const wchar_t *locale)
Definition: locale.c:403
#define MSVCRT_LC_MAX
Definition: msvcrt.h:657
#define LOCALE_SABBREVMONTHNAME5
Definition: winnls.h:108
DWORD LCTYPE
Definition: winnls.h:505
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define UNLOCK_LOCALE
Definition: locale.c:44
#define LOCALE_SMONTHNAME1
Definition: winnls.h:91
#define LOCALE_STHOUSAND
Definition: winnls.h:43
#define FOUND_LANGUAGE
Definition: locale.c:103
int CDECL __crtGetLocaleInfoW(LCID lcid, LCTYPE type, wchar_t *buffer, int len)
Definition: locale.c:561
#define LOCALE_NOUSEROVERRIDE
Definition: winnls.h:19
#define FALSE
Definition: types.h:117
Definition: _locale.h:75
BOOL WINAPI GetStringTypeA(LCID locale, DWORD type, LPCSTR src, INT count, LPWORD chartype)
Definition: lang.c:1420
#define LOCALE_SABBREVMONTHNAME10
Definition: winnls.h:113
unsigned int CDECL ___lc_codepage_func(void)
Definition: locale.c:627
#define LOCALE_SINTLSYMBOL
Definition: winnls.h:50
#define LOCALE_SABBREVDAYNAME6
Definition: winnls.h:89
#define debugstr_w
Definition: kernel32.h:32
INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen)
Definition: lang.c:1628
#define LOCALE_SLONGDATE
Definition: winnls.h:61
#define FIXME(fmt,...)
Definition: debug.h:110
MSVCRT_pthreadmbcinfo mbcinfo
Definition: msvcrt.h:153
const unsigned short * _pctype
Definition: ctype.c:556
int codepage
Definition: win_iconv.c:156
#define LCMAP_LOWERCASE
Definition: winnls.h:181
int wint_t
Definition: _apple.h:38
LCID MSVCRT___lc_handle[LC_MAX-LC_MIN+1]
Definition: locale.c:36
#define _ENABLE_PER_THREAD_LOCALE
Definition: locale.h:62
#define strncasecmp
Definition: fake.h:10
#define LOCALE_SABBREVMONTHNAME4
Definition: winnls.h:107
smooth NULL
Definition: ftsmooth.c:557
wint_t CDECL MSVCRT_btowc(int c)
Definition: locale.c:571
unsigned char * pcumap
Definition: msvcrt.h:133
struct MSVCRT_threadlocaleinfostruct::@1454 lc_category[6]
static BOOL CALLBACK find_best_locale_proc(HMODULE hModule, LPCSTR type, LPCSTR name, WORD LangID, LONG_PTR lParam)
Definition: locale.c:141
unsigned short * ctype1
Definition: msvcrt.h:130
#define LOCALE_SMONTHNAME4
Definition: winnls.h:94
Definition: locale.h:37
LCID WINAPI GetSystemDefaultLCID(void)
Definition: lang.c:542
#define LOCALE_SDECIMAL
Definition: winnls.h:42
static int compare_info(LCID lcid, DWORD flags, char *buff, const char *cmp, BOOL exact)
Definition: locale.c:120
const char * LPCSTR
Definition: xmlstorage.h:183
unsigned int __lc_codepage
Definition: locale.c:34
int CDECL __lconv_init(void)
Definition: locale.c:609
#define LOCALE_SDAYNAME4
Definition: winnls.h:80
INT WINAPI CompareStringA(LCID lcid, DWORD flags, LPCSTR str1, INT len1, LPCSTR str2, INT len2)
Definition: lang.c:1906
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: lang.c:1882
struct MSVCRT___lc_time_data * lc_time_curr
Definition: msvcrt.h:134
#define FOUND_CODEPAGE
Definition: locale.c:105
#define LOCALE_SMONDECIMALSEP
Definition: winnls.h:51
#define LOCALE_SMONTHNAME11
Definition: winnls.h:101
#define LC_ALL
Definition: locale.h:25
#define TRACE(s)
Definition: solgame.cpp:4
Definition: _ctype.h:58
unsigned int BOOL
Definition: ntddk_ex.h:94
#define LOCALE_SDAYNAME3
Definition: winnls.h:79
static void swap_pointers(void **p1, void **p2)
Definition: locale.c:345
MSVCRT_pthreadmbcinfo get_mbcinfo(void)
Definition: locale.c:364
#define _LEADBYTE
Definition: ctype.h:75
#define LOCALE_SMONTHOUSANDSEP
Definition: winnls.h:52
#define LOCALE_SMONTHNAME10
Definition: winnls.h:100
#define debugstr_a
Definition: kernel32.h:31
void CDECL MSVCRT__free_locale(MSVCRT__locale_t locale)
Definition: locale.c:711
#define SORT_DEFAULT
BYTE LeadByte[MAX_LEADBYTES]
Definition: winnls.h:571
#define MSVCRT_LC_CTYPE
Definition: msvcrt.h:652
void __init_global_locale()
Definition: locale.c:1496
#define LOCALE_SABBREVLANGNAME
Definition: winnls.h:28
BOOL WINAPI GetStringTypeW(DWORD type, LPCWSTR src, INT count, LPWORD chartype)
Definition: lang.c:1306
int __cdecl _setmbcp(int)
Definition: _setmbcp.c:218
char *CDECL _Getmonths(void)
Definition: locale.c:450
static DWORD LPDWORD LPCSTR DWORD srclen
Definition: directory.c:47
#define LOCALE_SPOSITIVESIGN
Definition: winnls.h:117
#define LOCALE_SABBREVMONTHNAME2
Definition: winnls.h:105
const GLubyte * c
Definition: glext.h:8905
static FILE * out
Definition: regtests2xml.c:44
MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
Definition: locale.c:722
unsigned int CDECL ___setlc_active_func(void)
Definition: locale.c:1481
unsigned char _mbctype[257]
Definition: locale.c:40
unsigned char * pclmap
Definition: msvcrt.h:132
#define MSVCRT_LC_NUMERIC
Definition: msvcrt.h:654
unsigned int lc_collate_cp
Definition: msvcrt.h:114
LCID *CDECL ___lc_handle_func(void)
Definition: locale.c:619
BOOL WINAPI EnumResourceLanguagesA(HMODULE hmod, LPCSTR type, LPCSTR name, ENUMRESLANGPROCA lpfun, LONG_PTR lparam)
Definition: res.c:428
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define LOCALE_SDAYNAME7
Definition: winnls.h:83
unsigned int match_flags
Definition: locale.c:112
GLbitfield flags
Definition: glext.h:7161
#define CT_CTYPE1
Definition: winnls.h:225
#define LANG_ENGLISH
Definition: nls.h:52
#define LOCALE_S1159
Definition: winnls.h:71
#define LOCALE_INEGSIGNPOSN
Definition: winnls.h:121
#define LOCALE_IINTLCURRDIGITS
Definition: winnls.h:55
int ret
int MSVCRT___lc_collate_cp
Definition: locale.c:35
void free_mbcinfo(MSVCRT_pthreadmbcinfo mbcinfo)
Definition: locale.c:685
else locinfo
Definition: scanf.h:159
#define LOCALE_SMONTHNAME3
Definition: winnls.h:93
#define LOCALE_SDAYNAME6
Definition: winnls.h:82
#define InterlockedDecrement
Definition: armddk.h:52
#define LOCALE_SNEGATIVESIGN
Definition: winnls.h:118
unsigned short wCodePage
Definition: msvcrt.h:108
#define LOCALE_SSHORTDATE
Definition: winnls.h:60
int CDECL __crtLCMapStringW(LCID lcid, DWORD mapflags, const wchar_t *src, int srclen, wchar_t *dst, int dstlen, unsigned int codepage, int xflag)
Definition: locale.c:525
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:818
#define RT_STRING
Definition: pedump.c:368
GLenum GLsizei len
Definition: glext.h:6722
const unsigned short _ctype[257]
Definition: ctype.c:36
thread_data_t * msvcrt_get_thread_data(void)
Definition: tls.c:31
#define LOCALE_IDEFAULTCODEPAGE
Definition: winnls.h:37
static unsigned char charmax
Definition: locale.c:38
unsigned int lc_codepage
Definition: msvcrt.h:113
#define MAX_LOCALE_LENGTH
Definition: locale.c:28
char found_codepage[MAX_ELEM_LEN]
Definition: locale.c:111
MSVCRT__locale_t MSVCRT_locale
Definition: msvcrt.h:885
static const wchar_t void * locale
Definition: printf.c:73
MSVCRT_pthreadlocinfo locinfo
Definition: msvcrt.h:152
#define LOCALE_SABBREVMONTHNAME9
Definition: winnls.h:112
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1377
static DWORD dstlen
Definition: directory.c:47
#define LOCALE_SABBREVMONTHNAME11
Definition: winnls.h:114
#define LOCALE_ICURRDIGITS
Definition: winnls.h:54
#define InterlockedIncrement
Definition: armddk.h:53
int _setmbcp_l(int, LCID, MSVCRT_pthreadmbcinfo)
Definition: _setmbcp.c:52
#define LOCALE_SISO3166CTRYNAME
Definition: winnls.h:128
#define CDECL
Definition: compat.h:21
#define LOCALE_SABBREVDAYNAME5
Definition: winnls.h:88
unsigned short wLanguage
Definition: msvcrt.h:106
GLsizeiptr size
Definition: glext.h:5919
unsigned int __setlc_active
Definition: environ.c:16
struct __lc_time_data MSVCRT___lc_time_data
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
int atoi(const char *)
UINT WPARAM LPARAM lParam
Definition: precomp.h:53
#define LOCALE_SMONTHNAME9
Definition: winnls.h:99
#define _MB_CP_ANSI
Definition: msvcrt.h:830
unsigned short * pctype
Definition: msvcrt.h:131
GLuint const GLubyte GLvoid const GLvoid * dst
Definition: s_context.h:57
#define LC_COLLATE
Definition: locale.h:26
#define LOCALE_SMONTHNAME12
Definition: winnls.h:102
#define lstrcpynA
Definition: compat.h:408
const unsigned short ** __p__pctype(void)
Definition: locale.c:1518
#define MultiByteToWideChar
Definition: compat.h:100
#define LOCALE_IPOSSIGNPOSN
Definition: winnls.h:120
#define _DISABLE_PER_THREAD_LOCALE
Definition: locale.h:63
char * strchr(const char *String, int ch)
Definition: utclib.c:501
static void remap_synonym(char *name)
Definition: locale.c:88
HANDLE HMODULE
Definition: typedefs.h:75
#define LCMAP_UPPERCASE
Definition: winnls.h:182
#define LC_TIME
Definition: locale.h:30
int CDECL __crtCompareStringA(LCID lcid, DWORD flags, const char *src1, int len1, const char *src2, int len2)
Definition: locale.c:537
struct MSVCRT_lconv * lconv
Definition: msvcrt.h:128
char search_codepage[MAX_ELEM_LEN]
Definition: locale.c:110
char data[1]
Definition: locale.h:69
POINT cp
Definition: magnifier.c:58
Definition: name.c:23
GLuint res
Definition: glext.h:9613
#define LOCALE_INEGSEPBYSPACE
Definition: winnls.h:125
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define LOCALE_SMONTHNAME7
Definition: winnls.h:97
#define c
Definition: ke_i.h:80
#define wchar_t
Definition: wchar.h:102
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
const unsigned short *__cdecl __pctype_func(void)
Definition: locale.c:1523
LANGID found_lang_id
Definition: locale.c:113
LCID MSVCRT_locale_to_LCID(const char *locale, unsigned short *codepage)
Definition: locale.c:208
unsigned int __unguarded_readlc_active
Definition: environ.c:17
#define LC_MAX
Definition: locale.h:33
MSVCRT__locale_t global_locale
Definition: locale.c:1495
GLfloat GLfloat p
Definition: glext.h:8902
#define LC_MONETARY
Definition: locale.h:28
const GLfloat * p1
Definition: s_aatritemp.h:43
int __mb_cur_max
Definition: locale.c:37
BSTR search
#define memset(x, y, z)
Definition: compat.h:39
void *__cdecl MSVCRT_malloc(MSVCRT_size_t)
#define MSVCRT_LC_ALL
Definition: msvcrt.h:650
#define LOCALE_S2359
Definition: winnls.h:72
#define LOCALE_STIMEFORMAT
Definition: winnls.h:62
#define MSVCRT_LC_COLLATE
Definition: msvcrt.h:651
static unsigned char buff[32768]
Definition: fatten.c:17
#define MSVCRT_LC_MONETARY
Definition: msvcrt.h:653
#define MSVCRT_LC_TIME
Definition: msvcrt.h:655
char search_language[MAX_ELEM_LEN]
Definition: locale.c:108
MSVCRT_ulong lc_handle[6]
Definition: msvcrt.h:115
INT WINAPI LCMapStringA(LCID lcid, DWORD flags, LPCSTR src, INT srclen, LPSTR dst, INT dstlen)
Definition: lang.c:1654
#define _Analysis_assume_(expr)
Definition: no_sal2.h:10
HMODULE hModule
Definition: animate.c:43
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define CHAR_MAX
Definition: limits.h:32