forked from Mirrors/wine-wine
msvcr120: Add ___lc_locale_name_func implementation.
parent
7a89251c2f
commit
f55192aabc
|
@ -893,7 +893,7 @@
|
||||||
@ stub __TypeMatch
|
@ stub __TypeMatch
|
||||||
@ cdecl ___lc_codepage_func()
|
@ cdecl ___lc_codepage_func()
|
||||||
@ cdecl ___lc_collate_cp_func()
|
@ cdecl ___lc_collate_cp_func()
|
||||||
@ stub ___lc_locale_name_func
|
@ cdecl ___lc_locale_name_func()
|
||||||
@ cdecl ___mb_cur_max_func() MSVCRT____mb_cur_max_func
|
@ cdecl ___mb_cur_max_func() MSVCRT____mb_cur_max_func
|
||||||
@ cdecl ___mb_cur_max_l_func(ptr)
|
@ cdecl ___mb_cur_max_l_func(ptr)
|
||||||
@ cdecl ___setlc_active_func() MSVCRT____setlc_active_func
|
@ cdecl ___setlc_active_func() MSVCRT____setlc_active_func
|
||||||
|
|
|
@ -876,7 +876,7 @@
|
||||||
@ stub __TypeMatch
|
@ stub __TypeMatch
|
||||||
@ cdecl ___lc_codepage_func()
|
@ cdecl ___lc_codepage_func()
|
||||||
@ cdecl ___lc_collate_cp_func()
|
@ cdecl ___lc_collate_cp_func()
|
||||||
@ stub ___lc_locale_name_func
|
@ cdecl ___lc_locale_name_func()
|
||||||
@ cdecl ___mb_cur_max_func() MSVCRT____mb_cur_max_func
|
@ cdecl ___mb_cur_max_func() MSVCRT____mb_cur_max_func
|
||||||
@ cdecl ___mb_cur_max_l_func(ptr)
|
@ cdecl ___mb_cur_max_l_func(ptr)
|
||||||
@ cdecl ___setlc_active_func() MSVCRT____setlc_active_func
|
@ cdecl ___setlc_active_func() MSVCRT____setlc_active_func
|
||||||
|
|
|
@ -63,6 +63,7 @@ static struct MSVCRT_lconv* (CDECL *p_localeconv)(void);
|
||||||
static size_t (CDECL *p_wcstombs_s)(size_t *ret, char* dest, size_t sz, const wchar_t* src, size_t max);
|
static size_t (CDECL *p_wcstombs_s)(size_t *ret, char* dest, size_t sz, const wchar_t* src, size_t max);
|
||||||
static int (CDECL *p__dsign)(double);
|
static int (CDECL *p__dsign)(double);
|
||||||
static int (CDECL *p__fdsign)(float);
|
static int (CDECL *p__fdsign)(float);
|
||||||
|
static wchar_t** (CDECL *p____lc_locale_name_func)(void);
|
||||||
|
|
||||||
static BOOL init(void)
|
static BOOL init(void)
|
||||||
{
|
{
|
||||||
|
@ -80,6 +81,7 @@ static BOOL init(void)
|
||||||
p_wcstombs_s = (void*)GetProcAddress(module, "wcstombs_s");
|
p_wcstombs_s = (void*)GetProcAddress(module, "wcstombs_s");
|
||||||
p__dsign = (void*)GetProcAddress(module, "_dsign");
|
p__dsign = (void*)GetProcAddress(module, "_dsign");
|
||||||
p__fdsign = (void*)GetProcAddress(module, "_fdsign");
|
p__fdsign = (void*)GetProcAddress(module, "_fdsign");
|
||||||
|
p____lc_locale_name_func = (void*)GetProcAddress(module, "___lc_locale_name_func");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,9 +173,58 @@ static void test__dsign(void)
|
||||||
ok(ret == 0x8000, "p_fdsign(-1) = %x\n", ret);
|
ok(ret == 0x8000, "p_fdsign(-1) = %x\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test____lc_locale_name_func(void)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
const char *locale;
|
||||||
|
const WCHAR name[10];
|
||||||
|
const WCHAR broken_name[10];
|
||||||
|
BOOL todo;
|
||||||
|
} tests[] = {
|
||||||
|
{ "American", {'e','n',0}, {'e','n','-','U','S',0} },
|
||||||
|
{ "Belgian", {'n','l','-','B','E',0} },
|
||||||
|
{ "Chinese", {'z','h',0}, {'z','h','-','C','N',0}, TRUE },
|
||||||
|
{ "Dutch", {'n','l',0}, {'n','l','-','N','L',0} },
|
||||||
|
{ "English", {'e','n',0}, {'e','n','-','U','S',0} },
|
||||||
|
{ "French", {'f','r',0}, {'f','r','-','F','R',0} },
|
||||||
|
{ "German", {'d','e',0}, {'d','e','-','D','E',0} },
|
||||||
|
{ "Hungarian", {'h','u',0}, {'h','u','-','H','U',0} },
|
||||||
|
{ "Icelandic", {'i','s',0}, {'i','s','-','I','S',0} },
|
||||||
|
{ "Japanese", {'j','a',0}, {'j','a','-','J','P',0} },
|
||||||
|
{ "Korean", {'k','o',0}, {'k','o','-','K','R',0} }
|
||||||
|
};
|
||||||
|
int i, j;
|
||||||
|
wchar_t **lc_names;
|
||||||
|
|
||||||
|
for(i=0; i<sizeof(tests)/sizeof(*tests); i++) {
|
||||||
|
if(!p_setlocale(LC_ALL, tests[i].locale))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
lc_names = p____lc_locale_name_func();
|
||||||
|
ok(lc_names[0] == NULL, "%d - lc_names[0] = %s\n", i, wine_dbgstr_w(lc_names[0]));
|
||||||
|
if(tests[i].todo) {
|
||||||
|
todo_wine ok(!lstrcmpW(lc_names[1], tests[i].name) || broken(!lstrcmpW(lc_names[1], tests[i].broken_name)),
|
||||||
|
"%d - lc_names[1] = %s\n", i, wine_dbgstr_w(lc_names[1]));
|
||||||
|
} else {
|
||||||
|
ok(!lstrcmpW(lc_names[1], tests[i].name) || broken(!lstrcmpW(lc_names[1], tests[i].broken_name)),
|
||||||
|
"%d - lc_names[1] = %s\n", i, wine_dbgstr_w(lc_names[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(j=LC_MIN+2; j<=LC_MAX; j++) {
|
||||||
|
ok(!lstrcmpW(lc_names[1], lc_names[j]), "%d - lc_names[%d] = %s, expected %s\n",
|
||||||
|
i, j, wine_dbgstr_w(lc_names[j]), wine_dbgstr_w(lc_names[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p_setlocale(LC_ALL, "C");
|
||||||
|
lc_names = p____lc_locale_name_func();
|
||||||
|
ok(!lc_names[1], "___lc_locale_name_func()[1] = %s\n", wine_dbgstr_w(lc_names[1]));
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(msvcr120)
|
START_TEST(msvcr120)
|
||||||
{
|
{
|
||||||
if (!init()) return;
|
if (!init()) return;
|
||||||
test_lconv();
|
test_lconv();
|
||||||
test__dsign();
|
test__dsign();
|
||||||
|
test____lc_locale_name_func();
|
||||||
}
|
}
|
||||||
|
|
|
@ -872,7 +872,7 @@
|
||||||
@ stub __TypeMatch
|
@ stub __TypeMatch
|
||||||
@ cdecl ___lc_codepage_func() msvcr120.___lc_codepage_func
|
@ cdecl ___lc_codepage_func() msvcr120.___lc_codepage_func
|
||||||
@ cdecl ___lc_collate_cp_func() msvcr120.___lc_collate_cp_func
|
@ cdecl ___lc_collate_cp_func() msvcr120.___lc_collate_cp_func
|
||||||
@ stub ___lc_locale_name_func
|
@ cdecl ___lc_locale_name_func() msvcr120.___lc_locale_name_func
|
||||||
@ cdecl ___mb_cur_max_func() msvcr120.___mb_cur_max_func
|
@ cdecl ___mb_cur_max_func() msvcr120.___mb_cur_max_func
|
||||||
@ cdecl ___mb_cur_max_l_func(ptr) msvcr120.___mb_cur_max_l_func
|
@ cdecl ___mb_cur_max_l_func(ptr) msvcr120.___mb_cur_max_l_func
|
||||||
@ cdecl ___setlc_active_func() msvcr120.___setlc_active_func
|
@ cdecl ___setlc_active_func() msvcr120.___setlc_active_func
|
||||||
|
|
|
@ -683,6 +683,16 @@ LCID* CDECL ___lc_handle_func(void)
|
||||||
return get_locinfo()->lc_handle;
|
return get_locinfo()->lc_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* ___lc_locale_name_func (MSVCR110.@)
|
||||||
|
*/
|
||||||
|
#if _MSVCR_VER >= 110
|
||||||
|
MSVCRT_wchar_t** CDECL ___lc_locale_name_func(void)
|
||||||
|
{
|
||||||
|
return get_locinfo()->lc_name;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* ___lc_codepage_func (MSVCRT.@)
|
* ___lc_codepage_func (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
@ -713,6 +723,9 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo)
|
||||||
for(i=MSVCRT_LC_MIN+1; i<=MSVCRT_LC_MAX; i++) {
|
for(i=MSVCRT_LC_MIN+1; i<=MSVCRT_LC_MAX; i++) {
|
||||||
MSVCRT_free(locinfo->lc_category[i].locale);
|
MSVCRT_free(locinfo->lc_category[i].locale);
|
||||||
MSVCRT_free(locinfo->lc_category[i].refcount);
|
MSVCRT_free(locinfo->lc_category[i].refcount);
|
||||||
|
#if _MSVCR_VER >= 110
|
||||||
|
MSVCRT_free(locinfo->lc_name[i]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if(locinfo->lconv) {
|
if(locinfo->lconv) {
|
||||||
|
@ -794,6 +807,33 @@ void CDECL MSVCRT__free_locale(MSVCRT__locale_t locale)
|
||||||
MSVCRT_free(locale);
|
MSVCRT_free(locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if _MSVCR_VER >= 110
|
||||||
|
static inline BOOL set_lc_locale_name(MSVCRT__locale_t loc, int cat)
|
||||||
|
{
|
||||||
|
LCID lcid = loc->locinfo->lc_handle[cat];
|
||||||
|
WCHAR buf[100];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = GetLocaleInfoW(lcid, LOCALE_SISO639LANGNAME
|
||||||
|
|LOCALE_NOUSEROVERRIDE, buf, 100);
|
||||||
|
if(!len) return FALSE;
|
||||||
|
|
||||||
|
if(LocaleNameToLCID(buf, 0) != lcid)
|
||||||
|
len = LCIDToLocaleName(lcid, buf, 100, 0);
|
||||||
|
|
||||||
|
if(!len || !(loc->locinfo->lc_name[cat] = MSVCRT_malloc(len*sizeof(MSVCRT_wchar_t))))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
memcpy(loc->locinfo->lc_name[cat], buf, len*sizeof(MSVCRT_wchar_t));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline BOOL set_lc_locale_name(MSVCRT__locale_t loc, int cat)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _create_locale (MSVCRT.@)
|
* _create_locale (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
@ -950,6 +990,11 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
||||||
}
|
}
|
||||||
|
|
||||||
loc->locinfo->lc_collate_cp = loc->locinfo->lc_id[MSVCRT_LC_COLLATE].wCodePage;
|
loc->locinfo->lc_collate_cp = loc->locinfo->lc_id[MSVCRT_LC_COLLATE].wCodePage;
|
||||||
|
|
||||||
|
if(!set_lc_locale_name(loc, MSVCRT_LC_COLLATE)) {
|
||||||
|
MSVCRT__free_locale(loc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
loc->locinfo->lc_category[MSVCRT_LC_COLLATE].locale = MSVCRT__strdup("C");
|
loc->locinfo->lc_category[MSVCRT_LC_COLLATE].locale = MSVCRT__strdup("C");
|
||||||
|
|
||||||
|
@ -995,6 +1040,11 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
||||||
for(i=0; cp_info.LeadByte[i+1]!=0; i+=2)
|
for(i=0; cp_info.LeadByte[i+1]!=0; i+=2)
|
||||||
for(j=cp_info.LeadByte[i]; j<=cp_info.LeadByte[i+1]; j++)
|
for(j=cp_info.LeadByte[i]; j<=cp_info.LeadByte[i+1]; j++)
|
||||||
loc->locinfo->ctype1[j+1] |= MSVCRT__LEADBYTE;
|
loc->locinfo->ctype1[j+1] |= MSVCRT__LEADBYTE;
|
||||||
|
|
||||||
|
if(!set_lc_locale_name(loc, MSVCRT_LC_CTYPE)) {
|
||||||
|
MSVCRT__free_locale(loc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
loc->locinfo->lc_clike = 1;
|
loc->locinfo->lc_clike = 1;
|
||||||
loc->locinfo->mb_cur_max = 1;
|
loc->locinfo->mb_cur_max = 1;
|
||||||
|
@ -1229,6 +1279,10 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if(!set_lc_locale_name(loc, MSVCRT_LC_MONETARY)) {
|
||||||
|
MSVCRT__free_locale(loc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
loc->locinfo->lconv->int_curr_symbol = MSVCRT_malloc(sizeof(char));
|
loc->locinfo->lconv->int_curr_symbol = MSVCRT_malloc(sizeof(char));
|
||||||
loc->locinfo->lconv->currency_symbol = MSVCRT_malloc(sizeof(char));
|
loc->locinfo->lconv->currency_symbol = MSVCRT_malloc(sizeof(char));
|
||||||
|
@ -1358,6 +1412,10 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if(!set_lc_locale_name(loc, MSVCRT_LC_NUMERIC)) {
|
||||||
|
MSVCRT__free_locale(loc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
loc->locinfo->lconv->decimal_point = MSVCRT_malloc(sizeof(char[2]));
|
loc->locinfo->lconv->decimal_point = MSVCRT_malloc(sizeof(char[2]));
|
||||||
loc->locinfo->lconv->thousands_sep = MSVCRT_malloc(sizeof(char));
|
loc->locinfo->lconv->thousands_sep = MSVCRT_malloc(sizeof(char));
|
||||||
|
@ -1395,6 +1453,11 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
||||||
MSVCRT__free_locale(loc);
|
MSVCRT__free_locale(loc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!set_lc_locale_name(loc, MSVCRT_LC_TIME)) {
|
||||||
|
MSVCRT__free_locale(loc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
loc->locinfo->lc_category[MSVCRT_LC_TIME].locale = MSVCRT__strdup("C");
|
loc->locinfo->lc_category[MSVCRT_LC_TIME].locale = MSVCRT__strdup("C");
|
||||||
|
|
||||||
|
@ -1505,6 +1568,11 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale)
|
||||||
swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_COLLATE].refcount,
|
swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_COLLATE].refcount,
|
||||||
(void**)&loc->locinfo->lc_category[MSVCRT_LC_COLLATE].refcount);
|
(void**)&loc->locinfo->lc_category[MSVCRT_LC_COLLATE].refcount);
|
||||||
|
|
||||||
|
#if _MSVCR_VER >= 110
|
||||||
|
swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_COLLATE],
|
||||||
|
(void**)&loc->locinfo->lc_name[MSVCRT_LC_COLLATE]);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(category != MSVCRT_LC_ALL)
|
if(category != MSVCRT_LC_ALL)
|
||||||
break;
|
break;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
@ -1527,6 +1595,11 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale)
|
||||||
swap_pointers((void**)&locinfo->pclmap, (void**)&loc->locinfo->pclmap);
|
swap_pointers((void**)&locinfo->pclmap, (void**)&loc->locinfo->pclmap);
|
||||||
swap_pointers((void**)&locinfo->pcumap, (void**)&loc->locinfo->pcumap);
|
swap_pointers((void**)&locinfo->pcumap, (void**)&loc->locinfo->pcumap);
|
||||||
|
|
||||||
|
#if _MSVCR_VER >= 110
|
||||||
|
swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_CTYPE],
|
||||||
|
(void**)&loc->locinfo->lc_name[MSVCRT_LC_CTYPE]);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(category != MSVCRT_LC_ALL)
|
if(category != MSVCRT_LC_ALL)
|
||||||
break;
|
break;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
@ -1577,6 +1650,11 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale)
|
||||||
locinfo->lconv->p_sign_posn = loc->locinfo->lconv->p_sign_posn;
|
locinfo->lconv->p_sign_posn = loc->locinfo->lconv->p_sign_posn;
|
||||||
locinfo->lconv->n_sign_posn = loc->locinfo->lconv->n_sign_posn;
|
locinfo->lconv->n_sign_posn = loc->locinfo->lconv->n_sign_posn;
|
||||||
|
|
||||||
|
#if _MSVCR_VER >= 110
|
||||||
|
swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_MONETARY],
|
||||||
|
(void**)&loc->locinfo->lc_name[MSVCRT_LC_MONETARY]);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(category != MSVCRT_LC_ALL)
|
if(category != MSVCRT_LC_ALL)
|
||||||
break;
|
break;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
@ -1602,6 +1680,11 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale)
|
||||||
(void**)&loc->locinfo->lconv->_W_thousands_sep);
|
(void**)&loc->locinfo->lconv->_W_thousands_sep);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if _MSVCR_VER >= 110
|
||||||
|
swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_NUMERIC],
|
||||||
|
(void**)&loc->locinfo->lc_name[MSVCRT_LC_NUMERIC]);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(category != MSVCRT_LC_ALL)
|
if(category != MSVCRT_LC_ALL)
|
||||||
break;
|
break;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
@ -1615,6 +1698,11 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale)
|
||||||
swap_pointers((void**)&locinfo->lc_time_curr,
|
swap_pointers((void**)&locinfo->lc_time_curr,
|
||||||
(void**)&loc->locinfo->lc_time_curr);
|
(void**)&loc->locinfo->lc_time_curr);
|
||||||
|
|
||||||
|
#if _MSVCR_VER >= 110
|
||||||
|
swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_TIME],
|
||||||
|
(void**)&loc->locinfo->lc_name[MSVCRT_LC_TIME]);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(category != MSVCRT_LC_ALL)
|
if(category != MSVCRT_LC_ALL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ typedef struct MSVCRT_threadlocaleinfostruct {
|
||||||
MSVCRT_LC_ID lc_id[6];
|
MSVCRT_LC_ID lc_id[6];
|
||||||
struct {
|
struct {
|
||||||
char *locale;
|
char *locale;
|
||||||
wchar_t *wlocale;
|
MSVCRT_wchar_t *wlocale;
|
||||||
int *refcount;
|
int *refcount;
|
||||||
int *wrefcount;
|
int *wrefcount;
|
||||||
} lc_category[6];
|
} lc_category[6];
|
||||||
|
@ -175,6 +175,9 @@ typedef struct MSVCRT_threadlocaleinfostruct {
|
||||||
unsigned char *pclmap;
|
unsigned char *pclmap;
|
||||||
unsigned char *pcumap;
|
unsigned char *pcumap;
|
||||||
MSVCRT___lc_time_data *lc_time_curr;
|
MSVCRT___lc_time_data *lc_time_curr;
|
||||||
|
#if _MSVCR_VER >= 110
|
||||||
|
MSVCRT_wchar_t *lc_name[6];
|
||||||
|
#endif
|
||||||
} MSVCRT_threadlocinfo;
|
} MSVCRT_threadlocinfo;
|
||||||
|
|
||||||
typedef struct MSVCRT_threadmbcinfostruct {
|
typedef struct MSVCRT_threadmbcinfostruct {
|
||||||
|
|
Loading…
Reference in New Issue