2 * Some stuff takem from wine msvcrt\locale.c
4 * Copyright 2000 Jon Griffiths
13 #define _SETLOCALE_LOCK 19
16 #define MSVCRT_LC_ALL 0
17 #define MSVCRT_LC_COLLATE 1
18 #define MSVCRT_LC_CTYPE 2
19 #define MSVCRT_LC_MONETARY 3
20 #define MSVCRT_LC_NUMERIC 4
21 #define MSVCRT_LC_TIME 5
22 #define MSVCRT_LC_MIN MSVCRT_LC_ALL
23 #define MSVCRT_LC_MAX MSVCRT_LC_TIME
25 /* FIXME: Need to hold locale for each LC_* type and aggregate
26 * string to produce lc_all.
28 #define MAX_ELEM_LEN 64 /* Max length of country/language/CP string */
30 unsigned char _mbctype
[257] = { 0 };
31 int g_mbcp_is_multibyte
= 0;
33 /* It seems that the data about valid trail bytes is not available from kernel32
34 * so we have to store is here. The format is the same as for lead bytes in CPINFO */
35 struct cp_extra_info_t
38 BYTE TrailBytes
[MAX_LEADBYTES
];
41 static struct cp_extra_info_t g_cpextrainfo
[] =
43 {932, {0x40, 0x7e, 0x80, 0xfc, 0, 0}},
44 {936, {0x40, 0xfe, 0, 0}},
45 {949, {0x41, 0xfe, 0, 0}},
46 {950, {0x40, 0x7e, 0xa1, 0xfe, 0, 0}},
47 {20932, {1, 255, 0, 0}}, /* seems to give different results on different systems */
48 {0, {1, 255, 0, 0}} /* match all with FIXME */
52 char MSVCRT_current_lc_all
[MAX_LOCALE_LENGTH
] = { 0 };
53 LCID MSVCRT_current_lc_all_lcid
= 0;
54 int MSVCRT___lc_codepage
= 0;
55 int MSVCRT___lc_collate_cp
= 0;
56 HANDLE MSVCRT___lc_handle
[MSVCRT_LC_MAX
- MSVCRT_LC_MIN
+ 1] = { 0 };
59 #define LOCK_LOCALE _mlock(_SETLOCALE_LOCK);
60 #define UNLOCK_LOCALE _munlock(_SETLOCALE_LOCK);
62 #define MSVCRT_LEADBYTE 0x8000
65 char search_language
[MAX_ELEM_LEN
];
66 char search_country
[MAX_ELEM_LEN
];
67 char search_codepage
[MAX_ELEM_LEN
];
68 char found_language
[MAX_ELEM_LEN
];
69 char found_country
[MAX_ELEM_LEN
];
70 char found_codepage
[MAX_ELEM_LEN
];
71 unsigned int match_flags
;
75 unsigned int __setlc_active
;
76 unsigned int __unguarded_readlc_active
;
77 int _current_category
; /* used by setlocale */
78 const char *_current_locale
;
81 int parse_locale(const char *locale
, char *lang
, char *country
, char *code_page
);
91 WORD MSVCRT__ctype
[257] = {
92 0, _C_
, _C_
, _C_
, _C_
, _C_
, _C_
, _C_
, _C_
, _C_
, _S_
|_C_
, _S_
|_C_
,
93 _S_
|_C_
, _S_
|_C_
, _S_
|_C_
, _C_
, _C_
, _C_
, _C_
, _C_
, _C_
, _C_
, _C_
,
94 _C_
, _C_
, _C_
, _C_
, _C_
, _C_
, _C_
, _C_
, _C_
, _C_
, _S_
|_BLANK
,
95 _P_
, _P_
, _P_
, _P_
, _P_
, _P_
, _P_
, _P_
, _P_
, _P_
, _P_
, _P_
, _P_
, _P_
,
96 _P_
, _D_
|_H_
, _D_
|_H_
, _D_
|_H_
, _D_
|_H_
, _D_
|_H_
, _D_
|_H_
, _D_
|_H_
,
97 _D_
|_H_
, _D_
|_H_
, _D_
|_H_
, _P_
, _P_
, _P_
, _P_
, _P_
, _P_
, _P_
, _U_
|_H_
,
98 _U_
|_H_
, _U_
|_H_
, _U_
|_H_
, _U_
|_H_
, _U_
|_H_
, _U_
, _U_
, _U_
, _U_
, _U_
,
99 _U_
, _U_
, _U_
, _U_
, _U_
, _U_
, _U_
, _U_
, _U_
, _U_
, _U_
, _U_
, _U_
, _U_
,
100 _U_
, _P_
, _P_
, _P_
, _P_
, _P_
, _P_
, _L_
|_H_
, _L_
|_H_
, _L_
|_H_
, _L_
|_H_
,
101 _L_
|_H_
, _L_
|_H_
, _L_
, _L_
, _L_
, _L_
, _L_
, _L_
, _L_
, _L_
, _L_
, _L_
,
102 _L_
, _L_
, _L_
, _L_
, _L_
, _L_
, _L_
, _L_
, _L_
, _L_
, _P_
, _P_
, _P_
, _P_
,
103 _C_
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
111 /* Internal: Current ctype table for locale */
112 WORD MSVCRT_current_ctype
[257];
114 /* pctype is used by macros in the Win32 headers. It must point
115 * To a table of flags exactly like ctype. To allow locale
116 * changes to affect ctypes (i.e. isleadbyte), we use a second table
117 * and update its flags whenever the current locale changes.
119 WORD
* MSVCRT__pctype
= MSVCRT_current_ctype
+ 1;
121 /* Friendly country strings & iso codes for synonym support.
122 * Based on MS documentation for setlocale().
124 static const char * const _country_synonyms
[] =
132 "United Kingdom","GB",
133 "United-Kingdom","GB",
136 "Great Britain","GB",
137 "United States","US",
138 "United-States","US",
142 /* Note: Flags are weighted in order of matching importance */
143 #define FOUND_LANGUAGE 0x4
144 #define FOUND_COUNTRY 0x2
145 #define FOUND_CODEPAGE 0x1
147 /* INTERNAL: Map a synonym to an ISO code */
148 static void remap_synonym(char *name
)
151 for (i
= 0; i
< sizeof(_country_synonyms
)/sizeof(char*); i
+= 2 )
153 if (!_stricmp(_country_synonyms
[i
],name
))
155 TRACE(":Mapping synonym %s to %s\n",name
,_country_synonyms
[i
+1]);
156 name
[0] = _country_synonyms
[i
+1][0];
157 name
[1] = _country_synonyms
[i
+1][1];
164 #define CONTINUE_LOOKING TRUE
165 #define STOP_LOOKING FALSE
167 /* INTERNAL: Get and compare locale info with a given string */
168 static int compare_info(LCID lcid
, DWORD flags
, char* buff
, const char* cmp
)
171 GetLocaleInfoA(lcid
, flags
|LOCALE_NOUSEROVERRIDE
,buff
, MAX_ELEM_LEN
);
172 if (!buff
[0] || !cmp
[0])
174 /* Partial matches are allowed, e.g. "Germ" matches "Germany" */
175 return !_strnicmp(cmp
, buff
, strlen(cmp
));
180 find_best_locale_proc(HMODULE hModule
, LPCSTR type
, LPCSTR name
, WORD LangID
, LONG_PTR lParam
)
182 locale_search_t
*res
= (locale_search_t
*)lParam
;
183 const LCID lcid
= MAKELCID(LangID
, SORT_DEFAULT
);
184 char buff
[MAX_ELEM_LEN
];
185 unsigned int flags
= 0;
187 if(PRIMARYLANGID(LangID
) == LANG_NEUTRAL
)
188 return CONTINUE_LOOKING
;
191 if (compare_info(lcid
,LOCALE_SISO639LANGNAME
,buff
,res
->search_language
) ||
192 compare_info(lcid
,LOCALE_SABBREVLANGNAME
,buff
,res
->search_language
) ||
193 compare_info(lcid
,LOCALE_SENGLANGUAGE
,buff
,res
->search_language
))
195 TRACE(":Found language: %s->%s\n", res
->search_language
, buff
);
196 flags
|= FOUND_LANGUAGE
;
197 memcpy(res
->found_language
,res
->search_language
,MAX_ELEM_LEN
);
199 else if (res
->match_flags
& FOUND_LANGUAGE
)
201 return CONTINUE_LOOKING
;
205 if (compare_info(lcid
,LOCALE_SISO3166CTRYNAME
,buff
,res
->search_country
) ||
206 compare_info(lcid
,LOCALE_SABBREVCTRYNAME
,buff
,res
->search_country
) ||
207 compare_info(lcid
,LOCALE_SENGCOUNTRY
,buff
,res
->search_country
))
209 TRACE("Found country:%s->%s\n", res
->search_country
, buff
);
210 flags
|= FOUND_COUNTRY
;
211 memcpy(res
->found_country
,res
->search_country
,MAX_ELEM_LEN
);
213 else if (res
->match_flags
& FOUND_COUNTRY
)
215 return CONTINUE_LOOKING
;
219 if (compare_info(lcid
,LOCALE_IDEFAULTCODEPAGE
,buff
,res
->search_codepage
) ||
220 (compare_info(lcid
,LOCALE_IDEFAULTANSICODEPAGE
,buff
,res
->search_codepage
)))
222 TRACE("Found codepage:%s->%s\n", res
->search_codepage
, buff
);
223 flags
|= FOUND_CODEPAGE
;
224 memcpy(res
->found_codepage
,res
->search_codepage
,MAX_ELEM_LEN
);
226 else if (res
->match_flags
& FOUND_CODEPAGE
)
228 return CONTINUE_LOOKING
;
231 if (flags
> res
->match_flags
)
233 /* Found a better match than previously */
234 res
->match_flags
= flags
;
235 res
->found_lang_id
= LangID
;
237 if ((flags
& (FOUND_LANGUAGE
| FOUND_COUNTRY
| FOUND_CODEPAGE
)) ==
238 (FOUND_LANGUAGE
| FOUND_COUNTRY
| FOUND_CODEPAGE
))
240 TRACE(":found exact locale match\n");
243 return CONTINUE_LOOKING
;
246 /* Internal: Find the LCID for a locale specification */
247 static LCID
MSVCRT_locale_to_LCID(locale_search_t
* locale
)
250 EnumResourceLanguagesA(GetModuleHandleA("KERNEL32"), (LPSTR
)RT_STRING
,
251 (LPCSTR
)LOCALE_ILANGUAGE
,find_best_locale_proc
,
254 if (!locale
->match_flags
)
257 /* If we were given something that didn't match, fail */
258 if (locale
->search_country
[0] && !(locale
->match_flags
& FOUND_COUNTRY
))
261 lcid
= MAKELCID(locale
->found_lang_id
, SORT_DEFAULT
);
263 /* Populate partial locale, translating LCID to locale string elements */
264 if (!locale
->found_codepage
[0])
266 /* Even if a codepage is not enumerated for a locale
267 * it can be set if valid */
268 if (locale
->search_codepage
[0])
270 if (IsValidCodePage(atoi(locale
->search_codepage
)))
271 memcpy(locale
->found_codepage
,locale
->search_codepage
,MAX_ELEM_LEN
);
274 /* Special codepage values: OEM & ANSI */
275 if (_stricmp(locale
->search_codepage
,"OCP"))
277 GetLocaleInfoA(lcid
, LOCALE_IDEFAULTCODEPAGE
,
278 locale
->found_codepage
, MAX_ELEM_LEN
);
280 if (_stricmp(locale
->search_codepage
,"ACP"))
282 GetLocaleInfoA(lcid
, LOCALE_IDEFAULTANSICODEPAGE
,
283 locale
->found_codepage
, MAX_ELEM_LEN
);
288 if (!atoi(locale
->found_codepage
))
294 /* Prefer ANSI codepages if present */
295 GetLocaleInfoA(lcid
, LOCALE_IDEFAULTANSICODEPAGE
,
296 locale
->found_codepage
, MAX_ELEM_LEN
);
297 if (!locale
->found_codepage
[0] || !atoi(locale
->found_codepage
))
298 GetLocaleInfoA(lcid
, LOCALE_IDEFAULTCODEPAGE
,
299 locale
->found_codepage
, MAX_ELEM_LEN
);
302 GetLocaleInfoA(lcid
, LOCALE_SENGLANGUAGE
|LOCALE_NOUSEROVERRIDE
,
303 locale
->found_language
, MAX_ELEM_LEN
);
304 GetLocaleInfoA(lcid
, LOCALE_SENGCOUNTRY
|LOCALE_NOUSEROVERRIDE
,
305 locale
->found_country
, MAX_ELEM_LEN
);
309 /* INTERNAL: Set ctype behaviour for a codepage */
310 static void msvcrt_set_ctype(unsigned int codepage
, LCID lcid
)
314 memset(&cp
, 0, sizeof(CPINFO
));
316 if (GetCPInfo(codepage
, &cp
))
320 unsigned char *traverse
= cp
.LeadByte
;
322 memset(MSVCRT_current_ctype
, 0, sizeof(MSVCRT__ctype
));
323 MSVCRT___lc_codepage
= codepage
;
324 MSVCRT___lc_collate_cp
= codepage
;
326 /* Switch ctype macros to MBCS if needed */
327 __mb_cur_max
= cp
.MaxCharSize
;
329 /* Set remaining ctype flags: FIXME: faster way to do this? */
331 for (i
= 0; i
< 256; i
++)
333 if (!(MSVCRT__pctype
[i
] & MSVCRT_LEADBYTE
))
336 GetStringTypeA(lcid
, CT_CTYPE1
, str
, 1, MSVCRT__pctype
+ i
);
340 /* Set leadbyte flags */
341 while (traverse
[0] || traverse
[1])
343 for( i
= traverse
[0]; i
<= traverse
[1]; i
++ )
344 MSVCRT_current_ctype
[i
+1] |= MSVCRT_LEADBYTE
;
354 char *setlocale(int category
, const char *locale
)
358 int haveLang
, haveCountry
, haveCP
;
362 TRACE("(%d %s)\n",category
,locale
);
364 if (category
< MSVCRT_LC_MIN
|| category
> MSVCRT_LC_MAX
)
369 /* Report the current Locale */
370 return MSVCRT_current_lc_all
;
375 if (locale
[0] == 'L' && locale
[1] == 'C' && locale
[2] == '_')
377 WARN(":restore previous locale not implemented!\n");
378 /* FIXME: Easiest way to do this is parse the string and
379 * call this function recursively with its elements,
380 * Where they differ for each lc_ type.
383 return MSVCRT_current_lc_all
;
386 /* Default Locale: Special case handling */
387 if (!strlen(locale
) || ((toupper(locale
[0]) == 'C') && !locale
[1]))
389 MSVCRT_current_lc_all
[0] = 'C';
390 MSVCRT_current_lc_all
[1] = '\0';
391 MSVCRT___lc_codepage
= GetACP();
392 MSVCRT___lc_collate_cp
= GetACP();
396 lc_all
= 1; /* Fall through all cases ... */
397 case MSVCRT_LC_COLLATE
:
399 case MSVCRT_LC_CTYPE
:
400 /* Restore C locale ctype info */
402 memcpy(MSVCRT_current_ctype
, MSVCRT__ctype
, sizeof(MSVCRT__ctype
));
404 case MSVCRT_LC_MONETARY
:
406 case MSVCRT_LC_NUMERIC
:
412 return MSVCRT_current_lc_all
;
415 /* Get locale elements */
416 haveLang
= haveCountry
= haveCP
= 0;
417 memset(&lc
,0,sizeof(lc
));
419 next
= strchr(locale
,'_');
420 if (next
&& next
!= locale
)
423 memcpy(lc
.search_language
,locale
,next
-locale
);
424 locale
+= next
-locale
+1;
427 next
= strchr(locale
,'.');
434 lstrcpynA(lc
.search_codepage
, locale
, MAX_ELEM_LEN
);
441 memcpy(lc
.search_country
,locale
,next
-locale
);
442 locale
+= next
-locale
+1;
447 memcpy(lc
.search_language
,locale
,next
-locale
);
448 locale
+= next
-locale
+1;
450 lstrcpynA(lc
.search_codepage
, locale
, MAX_ELEM_LEN
);
458 lstrcpynA(lc
.search_country
, locale
, MAX_ELEM_LEN
);
463 lstrcpynA(lc
.search_language
, locale
, MAX_ELEM_LEN
);
468 remap_synonym(lc
.search_country
);
470 if (haveCP
&& !haveCountry
&& !haveLang
)
472 ERR(":Codepage only locale not implemented\n");
473 /* FIXME: Use default lang/country and skip locale_to_LCID()
480 lcid
= MSVCRT_locale_to_LCID(&lc
);
482 TRACE(":found LCID %d\n",lcid
);
490 MSVCRT_current_lc_all_lcid
= lcid
;
492 _snprintf(MSVCRT_current_lc_all
,MAX_LOCALE_LENGTH
,"%s_%s.%s",
493 lc
.found_language
,lc
.found_country
,lc
.found_codepage
);
497 lc_all
= 1; /* Fall through all cases ... */
498 case MSVCRT_LC_COLLATE
:
500 case MSVCRT_LC_CTYPE
:
501 msvcrt_set_ctype(atoi(lc
.found_codepage
),lcid
);
503 case MSVCRT_LC_MONETARY
:
505 case MSVCRT_LC_NUMERIC
:
511 return MSVCRT_current_lc_all
;
517 wchar_t* _wsetlocale(int category
, const wchar_t* locale
)
519 static wchar_t fake
[] = {
520 'E','n','g','l','i','s','h','_','U','n','i','t','e','d',' ',
521 'S','t','a','t','e','s','.','1','2','5','2',0 };
523 TRACE("%d %S\n", category
, locale
);
530 locale "lang[_country[.code_page]]"
536 int parse_locale(const char *locale
, char *lang
, char *country
, char *code_page
)
538 while ( *locale
!= 0 && *locale
!= '.' && *locale
!= '_' )
545 if ( *locale
== '_' ) {
547 while ( *locale
!= 0 && *locale
!= '.' )
557 if ( *locale
== '.' ) {
559 while ( *locale
!= 0 && *locale
!= '.' )
561 *code_page
= *locale
;
571 const struct map_lcid2str
{
573 const char *langname
;
576 {0x0409,"English", "United States"},
577 {0x0809,"English", "United Kingdom"},
578 {0x0000,"Unknown", "Unknown"}
582 const struct map_cntr
{
586 {"britain", "united kingdom"},
587 {"england", "united kingdom"},
588 {"gbr", "united kingdom"},
589 {"great britain", "united kingdom"},
590 {"uk", "united kingdom"},
591 {"united kingdom", "united kingdom"},
592 {"united-kingdom", "united kingdom"},
593 {"america", "united states" },
594 {"united states", "united states"},
595 {"united-states", "united states"},
596 {"us", "united states"},
597 {"usa", "united states"}
601 struct lconv _lconv
= {
602 ".", // decimal_point
603 ",", // thousands_sep
605 "DOL", // int_curr_symbol
606 "$", // currency_symbol
607 ".", // mon_decimal_point
608 ",", // mon_thousands_sep
610 "+", // positive_sign
611 "-", // negative_sign
612 127, // int_frac_digits
614 127, // p_cs_precedes
615 127, // p_sep_by_space
616 127, // n_cs_precedes
617 127, // n_sep_by_space
625 struct lconv
*localeconv(void)
627 return (struct lconv
*) &_lconv
;
630 /*********************************************************************
631 * _setmbcp (MSVCRT.@)
634 int CDECL
_setmbcp(int cp
)
647 TRACE("_setmbcp %d\n",cp
);
657 newcp
= MSVCRT___lc_codepage
;
660 newcp
= 20127; /* ASCII */
667 if (!GetCPInfo(newcp
, &cpi
))
669 ERR("Codepage %d not found\n", newcp
);
674 /* setup the _mbctype */
675 memset(_mbctype
, 0, sizeof(_mbctype
));
677 bytes
= cpi
.LeadByte
;
678 while (bytes
[0] || bytes
[1])
680 for (i
= bytes
[0]; i
<= bytes
[1]; i
++)
681 _mbctype
[i
+ 1] |= _M1
;
685 if (cpi
.MaxCharSize
> 1)
687 /* trail bytes not available through kernel32 but stored in a structure in msvcrt */
688 struct cp_extra_info_t
*cpextra
= g_cpextrainfo
;
690 g_mbcp_is_multibyte
= 1;
693 if (cpextra
->cp
== 0 || cpextra
->cp
== newcp
)
695 if (cpextra
->cp
== 0)
696 ERR("trail bytes data not available for DBCS codepage %d - assuming all bytes\n", newcp
);
698 bytes
= cpextra
->TrailBytes
;
699 while (bytes
[0] || bytes
[1])
701 for (i
= bytes
[0]; i
<= bytes
[1]; i
++)
702 _mbctype
[i
+ 1] |= _M2
;
711 g_mbcp_is_multibyte
= 0;
713 /* we can't use GetStringTypeA directly because we don't have a locale - only a code page
716 for (i
= 0; i
< 256; i
++)
717 if (!(_mbctype
[i
+ 1] & _M1
))
718 bufA
[charcount
++] = i
;
720 ret
= MultiByteToWideChar(newcp
, 0, bufA
, charcount
, bufW
, charcount
);
721 if (ret
!= charcount
)
722 ERR("MultiByteToWideChar of chars failed for cp %d, ret=%d (exp %d), error=%d\n", newcp
, ret
, charcount
, GetLastError());
724 GetStringTypeW(CT_CTYPE1
, bufW
, charcount
, chartypes
);
726 curr_type
= chartypes
;
727 for (i
= 0; i
< 256; i
++)
728 if (!(_mbctype
[i
+ 1] & _M1
))
730 if ((*curr_type
) & C1_UPPER
)
731 _mbctype
[i
+ 1] |= _SBUP
;
732 if ((*curr_type
) & C1_LOWER
)
733 _mbctype
[i
+ 1] |= _SBLOW
;
737 if (newcp
== 932) /* CP932 only - set _MP and _MS */
739 /* On Windows it's possible to calculate the _MP and _MS from CT_CTYPE1
740 * and CT_CTYPE3. But as of Wine 0.9.43 we return wrong values what makes
741 * it hard. As this is set only for codepage 932 we hardcode it what gives
742 * also faster execution.
744 for (i
= 161; i
<= 165; i
++)
745 _mbctype
[i
+ 1] |= _MP
;
746 for (i
= 166; i
<= 223; i
++)
747 _mbctype
[i
+ 1] |= _MS
;
750 MSVCRT___lc_collate_cp
= MSVCRT___lc_codepage
= newcp
;
751 TRACE("(%d) -> %d\n", cp
, MSVCRT___lc_codepage
);
756 /*********************************************************************
757 * __lc_collate_cp (MSVCRT.@)
761 void __lc_collate_cp(int cp
)
763 FIXME("__lc_collate_cp - stub\n");
768 /*********************************************************************
769 * __lc_handle (MSVCRT.@)
773 void __lc_handle(void)
775 FIXME("__lc_handle - stub\n");
780 /*********************************************************************
781 * __lc_codepage (MSVCRT.@)
785 void __lc_codepage(void)
787 FIXME("__lc_codepage - stub\n");
792 /*********************************************************************
793 * _Gettnames (MSVCRT.@)
795 void *_Gettnames(void)
797 FIXME("(void), stub!\n");
801 /*********************************************************************
802 * __lconv_init (MSVCRT.@)
804 void __lconv_init(void)
806 char Char
= (char) UCHAR_MAX
;
808 TRACE("__lconv_init()\n");
810 _lconv
.int_frac_digits
= Char
;
811 _lconv
.frac_digits
= Char
;
812 _lconv
.p_sep_by_space
= _lconv
.n_sep_by_space
= Char
;
813 _lconv
.p_cs_precedes
= _lconv
.n_cs_precedes
= Char
;
814 _lconv
.p_sign_posn
= _lconv
.n_sign_posn
= Char
;
818 /*********************************************************************
819 * _Strftime (MSVCRT.@)
821 const char* _Strftime(char *out
, unsigned int len
, const char *fmt
,
822 const void *tm
, void *foo
)
825 FIXME("(%p %d %s %p %p) stub\n", out
, len
, fmt
, tm
, foo
);
830 /*********************************************************************
831 * _Getdays (MSVCRT.@)
833 const char* _Getdays(void)
835 static const char *MSVCRT_days
= ":Sun:Sunday:Mon:Monday:Tue:Tuesday:Wed:"
836 "Wednesday:Thu:Thursday:Fri:Friday:Sat:Saturday";
837 /* FIXME: Use locale */
838 FIXME("(void) semi-stub\n");
842 /*********************************************************************
843 * _Getmonths (MSVCRT.@)
845 const char* _Getmonths(void)
847 static const char *MSVCRT_months
= ":Jan:January:Feb:February:Mar:March:Apr:"
848 "April:May:May:Jun:June:Jul:July:Aug:August:Sep:September:Oct:"
849 "October:Nov:November:Dec:December";
850 /* FIXME: Use locale */
851 FIXME("(void) semi-stub\n");
852 return MSVCRT_months
;
855 /*********************************************************************
856 * __crtLCMapStringA (MSVCRT.@)
858 int __crtLCMapStringA(
859 LCID lcid
, DWORD mapflags
, const char* src
, int srclen
, char* dst
,
860 int dstlen
, unsigned int codepage
, int xflag
862 TRACE("(lcid %lx, flags %lx, %s(%d), %p(%d), %x, %d), partial stub!\n",
863 lcid
,mapflags
,src
,srclen
,dst
,dstlen
,codepage
,xflag
);
864 /* FIXME: A bit incorrect. But msvcrt itself just converts its
865 * arguments to wide strings and then calls LCMapStringW
867 return LCMapStringA(lcid
,mapflags
,src
,srclen
,dst
,dstlen
);
870 /*********************************************************************
871 * __crtLCMapStringW (MSVCRT.@)
873 int __crtLCMapStringW(
874 LCID lcid
, DWORD mapflags
, LPCWSTR src
, int srclen
, LPWSTR dst
,
875 int dstlen
, unsigned int codepage
, int xflag
877 TRACE("(lcid %lx, flags %lx, %s(%d), %p(%d), %x, %d), partial stub!\n",
878 lcid
,mapflags
,src
,srclen
,dst
,dstlen
,codepage
,xflag
);
880 return LCMapStringW(lcid
,mapflags
,src
,srclen
,dst
,dstlen
);
883 int CDECL
_getmbcp(void)
885 return MSVCRT___lc_codepage
;
888 /*********************************************************************
889 * ___unguarded_readlc_active_add_func (MSVCRT.@)
891 unsigned int * CDECL
___unguarded_readlc_active_add_func(void)
893 return &__unguarded_readlc_active
;
896 /*********************************************************************
897 * ___setlc_active_func (MSVCRT.@)
899 unsigned int CDECL
___setlc_active_func(void)
901 return __setlc_active
;