Piotr Caban : msvcp90: Add _Wcsxfrm implementation.

Alexandre Julliard julliard at winehq.org
Mon Jun 7 15:02:05 CDT 2021


Module: wine
Branch: stable
Commit: dcecdf6a4684aed56b037abf470e120a4b3c7e0b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=dcecdf6a4684aed56b037abf470e120a4b3c7e0b

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Feb  3 11:57:06 2021 +0100

msvcp90: Add _Wcsxfrm implementation.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50401
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit 3657c8b8293a1a026c81aa9cf4c04b1884c133cd)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 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 at std@@")
 DEFINE_RTTI_DATA0(locale_facet, 0, ".?AVfacet at locale@std@@")
 DEFINE_RTTI_DATA1(locale__Locimp, 0, &locale_facet_rtti_base_descriptor, ".?AV_Locimp at 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 at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@7B@");
 
     SET(p_std_Ctraits_float__Isnan, "?_Isnan@?$_Ctraits at M@std@@SA_NM at 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");
 




More information about the wine-cvs mailing list