From dcecdf6a4684aed56b037abf470e120a4b3c7e0b Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Wed, 3 Feb 2021 11:57:06 +0100 Subject: [PATCH] msvcp90: Add _Wcsxfrm implementation. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50401 Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard (cherry picked from commit 3657c8b8293a1a026c81aa9cf4c04b1884c133cd) Signed-off-by: Michael Stefaniuc --- dlls/msvcp100/msvcp100.spec | 2 +- dlls/msvcp110/msvcp110.spec | 2 +- dlls/msvcp120/msvcp120.spec | 2 +- dlls/msvcp120_app/msvcp120_app.spec | 2 +- dlls/msvcp140/msvcp140.spec | 2 +- dlls/msvcp71/msvcp71.spec | 2 +- dlls/msvcp80/msvcp80.spec | 2 +- dlls/msvcp90/locale.c | 37 +++++++++++++++++++++++++++++ dlls/msvcp90/msvcp90.spec | 2 +- dlls/msvcp90/tests/misc.c | 24 +++++++++++++++++++ 10 files changed, 69 insertions(+), 8 deletions(-) diff --git a/dlls/msvcp100/msvcp100.spec b/dlls/msvcp100/msvcp100.spec index dd5ccfaf7e0..a05d20dea4e 100644 --- a/dlls/msvcp100/msvcp100.spec +++ b/dlls/msvcp100/msvcp100.spec @@ -2969,7 +2969,7 @@ @ cdecl _Towupper(long ptr) @ cdecl _Wcrtomb(ptr long ptr ptr) @ cdecl _Wcscoll(ptr ptr ptr ptr ptr) -@ stub _Wcsxfrm +@ cdecl _Wcsxfrm(ptr ptr ptr ptr ptr) # extern _Xbig @ stub __Wcrtomb_lk @ cdecl towctrans(long long) diff --git a/dlls/msvcp110/msvcp110.spec b/dlls/msvcp110/msvcp110.spec index 6a386237ed7..10c2216aebb 100644 --- a/dlls/msvcp110/msvcp110.spec +++ b/dlls/msvcp110/msvcp110.spec @@ -3877,7 +3877,7 @@ @ cdecl _Unlock_shared_ptr_spin_lock() @ cdecl _Wcrtomb(ptr long ptr ptr) @ cdecl _Wcscoll(ptr ptr ptr ptr ptr) -@ stub _Wcsxfrm +@ cdecl _Wcsxfrm(ptr ptr ptr ptr ptr) # extern _Xbig @ stub _Xp_addh @ stub _Xp_addx diff --git a/dlls/msvcp120/msvcp120.spec b/dlls/msvcp120/msvcp120.spec index fd42183beae..6f3e7b65f92 100644 --- a/dlls/msvcp120/msvcp120.spec +++ b/dlls/msvcp120/msvcp120.spec @@ -3824,7 +3824,7 @@ @ cdecl _Unlock_shared_ptr_spin_lock() @ cdecl _Wcrtomb(ptr long ptr ptr) @ cdecl _Wcscoll(ptr ptr ptr ptr ptr) -@ stub _Wcsxfrm +@ cdecl _Wcsxfrm(ptr ptr ptr ptr ptr) # extern _Xbig @ stub _Xp_addh @ stub _Xp_addx diff --git a/dlls/msvcp120_app/msvcp120_app.spec b/dlls/msvcp120_app/msvcp120_app.spec index b7662613b94..c35dcb2d427 100644 --- a/dlls/msvcp120_app/msvcp120_app.spec +++ b/dlls/msvcp120_app/msvcp120_app.spec @@ -3824,7 +3824,7 @@ @ cdecl _Unlock_shared_ptr_spin_lock() msvcp120._Unlock_shared_ptr_spin_lock @ cdecl _Wcrtomb(ptr long ptr ptr) msvcp120._Wcrtomb @ cdecl _Wcscoll(ptr ptr ptr ptr ptr) msvcp120._Wcscoll -@ stub _Wcsxfrm +@ cdecl _Wcsxfrm(ptr ptr ptr ptr ptr) msvcp120._Wcsxfrm # extern _Xbig @ stub _Xp_addh @ stub _Xp_addx diff --git a/dlls/msvcp140/msvcp140.spec b/dlls/msvcp140/msvcp140.spec index 94dd37ad4b3..dcd062aa4fc 100644 --- a/dlls/msvcp140/msvcp140.spec +++ b/dlls/msvcp140/msvcp140.spec @@ -3747,7 +3747,7 @@ @ stub _WStoldx @ cdecl _Wcrtomb(ptr long ptr ptr) @ cdecl _Wcscoll(ptr ptr ptr ptr ptr) -@ stub _Wcsxfrm +@ cdecl _Wcsxfrm(ptr ptr ptr ptr ptr) @ cdecl _Xtime_diff_to_millis(ptr) _Xtime_diff_to_millis @ cdecl _Xtime_diff_to_millis2(ptr ptr) _Xtime_diff_to_millis2 @ cdecl -ret64 _Xtime_get_ticks() _Xtime_get_ticks diff --git a/dlls/msvcp71/msvcp71.spec b/dlls/msvcp71/msvcp71.spec index 422902375cd..0b371131613 100644 --- a/dlls/msvcp71/msvcp71.spec +++ b/dlls/msvcp71/msvcp71.spec @@ -5153,7 +5153,7 @@ @ cdecl _Towupper(long ptr) @ cdecl _Wcrtomb(ptr long ptr ptr) @ cdecl _Wcscoll(ptr ptr ptr ptr ptr) -@ stub _Wcsxfrm +@ cdecl _Wcsxfrm(ptr ptr ptr ptr ptr) # extern _Xbig # extern _Zero @ stub __Wcrtomb_lk diff --git a/dlls/msvcp80/msvcp80.spec b/dlls/msvcp80/msvcp80.spec index fa4d6eaf405..6505f893b50 100644 --- a/dlls/msvcp80/msvcp80.spec +++ b/dlls/msvcp80/msvcp80.spec @@ -5779,7 +5779,7 @@ @ cdecl _Towupper(long ptr) @ cdecl _Wcrtomb(ptr long ptr ptr) @ cdecl _Wcscoll(ptr ptr ptr ptr ptr) -@ stub _Wcsxfrm +@ cdecl _Wcsxfrm(ptr ptr ptr ptr ptr) # extern _Xbig @ stub __Stodx @ stub __Stofx diff --git a/dlls/msvcp90/locale.c b/dlls/msvcp90/locale.c index 6b547c384a4..b4ed8d5e75d 100644 --- a/dlls/msvcp90/locale.c +++ b/dlls/msvcp90/locale.c @@ -12701,6 +12701,43 @@ size_t __cdecl _Strxfrm(char *dest, char *dest_end, const char *src, const char return len; } +size_t __cdecl _Wcsxfrm(wchar_t *dest, wchar_t *dest_end, + const wchar_t *src, const wchar_t *src_end, _Collvec *coll) +{ + size_t dest_len = dest_end - dest; + size_t src_len = src_end - src; + _Collvec cv; + LCID lcid; + int i, len; + + TRACE("(%p %p %p %p %p)\n", dest, dest_end, src, src_end, coll); + + if (coll) cv = *coll; + else getcoll(&cv); + +#if _MSVCP_VER < 110 + lcid = cv.handle; +#else + lcid = LocaleNameToLCID(cv.lc_name, 0); +#endif + + if (!lcid) + { + if (src_len > dest_len) return src_len; + memcpy(dest, src, src_len * sizeof(wchar_t)); + return src_len; + } + + len = LCMapStringW(lcid, LCMAP_SORTKEY, src, src_len, NULL, 0); + if (!len) return INT_MAX; + if (len > dest_len) return len; + + LCMapStringW(lcid, LCMAP_SORTKEY, src, src_len, dest, dest_len); + for (i = len - 1; i >= 0; i--) + dest[i] = ((BYTE*)dest)[i]; + return len; +} + DEFINE_RTTI_DATA0(_Facet_base, 0, ".?AV_Facet_base@std@@") DEFINE_RTTI_DATA0(locale_facet, 0, ".?AVfacet@locale@std@@") DEFINE_RTTI_DATA1(locale__Locimp, 0, &locale_facet_rtti_base_descriptor, ".?AV_Locimp@locale@std@@") diff --git a/dlls/msvcp90/msvcp90.spec b/dlls/msvcp90/msvcp90.spec index c38dd041af2..1fbabe3114c 100644 --- a/dlls/msvcp90/msvcp90.spec +++ b/dlls/msvcp90/msvcp90.spec @@ -6554,7 +6554,7 @@ @ cdecl _Towupper(long ptr) @ cdecl _Wcrtomb(ptr long ptr ptr) @ cdecl _Wcscoll(ptr ptr ptr ptr ptr) -@ stub _Wcsxfrm +@ cdecl _Wcsxfrm(ptr ptr ptr ptr ptr) # extern _Xbig @ stub __Wcrtomb_lk @ cdecl towctrans(long long) diff --git a/dlls/msvcp90/tests/misc.c b/dlls/msvcp90/tests/misc.c index d700b6d933c..9d6fe2b9bcc 100644 --- a/dlls/msvcp90/tests/misc.c +++ b/dlls/msvcp90/tests/misc.c @@ -106,6 +106,8 @@ static wctrans_t (__cdecl *p_wctrans)(const char*); static wint_t (__cdecl *p_towctrans)(wint_t, wctrans_t); static void (__cdecl *p_locale__Locimp__Locimp_Addfac)(locale__Locimp*,locale_facet*,size_t); static size_t (__cdecl *p__Strxfrm)(char*, char*, const char*, const char*, const MSVCP__Collvec*); +static size_t (__cdecl *p__Wcsxfrm)(wchar_t*, wchar_t*, const wchar_t*, + const wchar_t*, const MSVCP__Collvec*); #undef __thiscall #ifdef __i386__ @@ -250,6 +252,7 @@ static BOOL init(void) SET(p_wctrans, "wctrans"); SET(p_towctrans, "towctrans"); SET(p__Strxfrm, "_Strxfrm"); + SET(p__Wcsxfrm, "_Wcsxfrm"); SET(basic_ostringstream_char_vbtable, "??_8?$basic_ostringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@7B@"); SET(p_std_Ctraits_float__Isnan, "?_Isnan@?$_Ctraits@M@std@@SA_NM@Z"); @@ -1110,6 +1113,26 @@ static void test__Strxfrm(void) ok(!strcmp(in, out), "out = %s\n", out); } +static void test__Wcsxfrm(void) +{ + const wchar_t in[] = L"abc"; + + MSVCP__Collvec coll; + wchar_t out[64]; + size_t ret; + + memset(&coll, 0, sizeof(coll)); + + out[0] = 'z'; + ret = p__Wcsxfrm(out, out + 1, in, in + 2, &coll); + ok(ret == 2, "ret = %d\n", (int)ret); + ok(out[0] == 'z', "out[0] = %x\n", out[0]); + + ret = p__Wcsxfrm(out, out + ARRAY_SIZE(out), in, in + 4, &coll); + ok(ret == 4, "ret = %d\n", (int)ret); + ok(!wcscmp(in, out), "out = %s\n", wine_dbgstr_w(out)); +} + START_TEST(misc) { if(!init()) @@ -1131,6 +1154,7 @@ START_TEST(misc) test_locale__Locimp__Locimp_Addfac(); test_raise_handler(); test__Strxfrm(); + test__Wcsxfrm(); ok(!invalid_parameter, "invalid_parameter_handler was invoked too many times\n");