[PATCH 3/3] msvcrt: Implement _mbbtype_l().

Paul Gofman pgofman at codeweavers.com
Wed Sep 23 14:56:25 CDT 2020


Fixes Midnight Castle Succubus.

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
 .../api-ms-win-crt-multibyte-l1-1-0.spec      |  2 +-
 .../api-ms-win-crt-private-l1-1-0.spec        |  2 +-
 dlls/msvcr100/msvcr100.spec                   |  2 +-
 dlls/msvcr110/msvcr110.spec                   |  2 +-
 dlls/msvcr120/msvcr120.spec                   |  2 +-
 dlls/msvcr80/msvcr80.spec                     |  2 +-
 dlls/msvcr90/msvcr90.spec                     |  2 +-
 dlls/msvcrt/mbcs.c                            | 45 +++++++--------
 dlls/msvcrt/msvcrt.h                          |  1 +
 dlls/msvcrt/tests/string.c                    | 55 +++++++++++++++++++
 dlls/ucrtbase/tests/string.c                  | 19 +++++++
 dlls/ucrtbase/ucrtbase.spec                   |  4 +-
 include/msvcrt/mbstring.h                     |  1 +
 13 files changed, 105 insertions(+), 34 deletions(-)

diff --git a/dlls/api-ms-win-crt-multibyte-l1-1-0/api-ms-win-crt-multibyte-l1-1-0.spec b/dlls/api-ms-win-crt-multibyte-l1-1-0/api-ms-win-crt-multibyte-l1-1-0.spec
index 287c3c105b2..e5550a24853 100644
--- a/dlls/api-ms-win-crt-multibyte-l1-1-0/api-ms-win-crt-multibyte-l1-1-0.spec
+++ b/dlls/api-ms-win-crt-multibyte-l1-1-0/api-ms-win-crt-multibyte-l1-1-0.spec
@@ -65,7 +65,7 @@
 @ cdecl _mbbtombc(long) ucrtbase._mbbtombc
 @ stub _mbbtombc_l
 @ cdecl _mbbtype(long long) ucrtbase._mbbtype
-@ stub _mbbtype_l
+@ cdecl _mbbtype_l(long long ptr) ucrtbase._mbbtype_l
 @ stub _mbcasemap
 @ cdecl _mbccpy(ptr ptr) ucrtbase._mbccpy
 @ cdecl _mbccpy_l(ptr ptr ptr) ucrtbase._mbccpy_l
diff --git a/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec b/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec
index 3bbe14613da..87dc6585f3c 100644
--- a/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec
+++ b/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec
@@ -491,7 +491,7 @@
 @ cdecl _o__mbbtombc(long) ucrtbase._o__mbbtombc
 @ stub _o__mbbtombc_l
 @ cdecl _o__mbbtype(long long) ucrtbase._o__mbbtype
-@ stub _o__mbbtype_l
+@ cdecl _o__mbbtype_l(long long ptr) ucrtbase._o__mbbtype_l
 @ cdecl _o__mbccpy(ptr ptr) ucrtbase._o__mbccpy
 @ cdecl _o__mbccpy_l(ptr ptr ptr) ucrtbase._o__mbccpy_l
 @ cdecl _o__mbccpy_s(ptr long ptr ptr) ucrtbase._o__mbccpy_s
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index ec1eb0a7714..9f8755c6e85 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -1071,7 +1071,7 @@
 @ cdecl _mbbtombc(long)
 @ stub _mbbtombc_l
 @ cdecl _mbbtype(long long)
-@ stub _mbbtype_l
+@ cdecl _mbbtype_l(long long ptr)
 # extern _mbcasemap
 @ cdecl _mbccpy(ptr ptr)
 @ cdecl _mbccpy_l(ptr ptr ptr)
diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec
index f32f8faba98..64205b704ce 100644
--- a/dlls/msvcr110/msvcr110.spec
+++ b/dlls/msvcr110/msvcr110.spec
@@ -1428,7 +1428,7 @@
 @ cdecl _mbbtombc(long)
 @ stub _mbbtombc_l
 @ cdecl _mbbtype(long long)
-@ stub _mbbtype_l
+@ cdecl _mbbtype_l(long long ptr)
 # extern _mbcasemap
 @ cdecl _mbccpy(ptr ptr)
 @ cdecl _mbccpy_l(ptr ptr ptr)
diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec
index 82598b74edd..0d38f97fffe 100644
--- a/dlls/msvcr120/msvcr120.spec
+++ b/dlls/msvcr120/msvcr120.spec
@@ -1438,7 +1438,7 @@
 @ cdecl _mbbtombc(long)
 @ stub _mbbtombc_l
 @ cdecl _mbbtype(long long)
-@ stub _mbbtype_l
+@ cdecl _mbbtype_l(long long ptr)
 # extern _mbcasemap
 @ cdecl _mbccpy(ptr ptr)
 @ cdecl _mbccpy_l(ptr ptr ptr)
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index 95ffa62ab51..f83637038b7 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -743,7 +743,7 @@
 @ cdecl _mbbtombc(long)
 @ stub _mbbtombc_l
 @ cdecl _mbbtype(long long)
-@ stub _mbbtype_l
+@ cdecl _mbbtype_l(long long ptr)
 # extern _mbcasemap
 @ cdecl _mbccpy(ptr ptr)
 @ cdecl _mbccpy_l(ptr ptr ptr)
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index f2d56166099..ba75c3452e8 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -721,7 +721,7 @@
 @ cdecl _mbbtombc(long)
 @ stub _mbbtombc_l
 @ cdecl _mbbtype(long long)
-@ stub _mbbtype_l
+@ cdecl _mbbtype_l(long long ptr)
 # extern _mbcasemap
 @ cdecl _mbccpy(ptr ptr)
 @ cdecl _mbccpy_l(ptr ptr ptr)
diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c
index abd1f1df053..13fffc5734a 100644
--- a/dlls/msvcrt/mbcs.c
+++ b/dlls/msvcrt/mbcs.c
@@ -1394,31 +1394,6 @@ unsigned int CDECL _mbbtombc(unsigned int c)
   return c;  /* not Japanese or no MB char */
 }
 
-/*********************************************************************
- *		_mbbtype(MSVCRT.@)
- */
-int CDECL _mbbtype(unsigned char c, int type)
-{
-    if (type == 1)
-    {
-        if ((c >= 0x20 && c <= 0x7e) || (c >= 0xa1 && c <= 0xdf))
-            return _MBC_SINGLE;
-        else if ((c >= 0x40 && c <= 0x7e) || (c >= 0x80 && c <= 0xfc))
-            return _MBC_TRAIL;
-        else
-            return _MBC_ILLEGAL;
-    }
-    else
-    {
-        if ((c >= 0x20 && c <= 0x7e) || (c >= 0xa1 && c <= 0xdf))
-            return _MBC_SINGLE;
-        else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc))
-            return _MBC_LEAD;
-        else
-            return _MBC_ILLEGAL;
-    }
-}
-
 /*********************************************************************
  *		_ismbbkana_l(MSVCRT.@)
  */
@@ -1730,6 +1705,26 @@ int CDECL _ismbstrail(const unsigned char* start, const unsigned char* str)
     return 0;
 }
 
+/*********************************************************************
+ *		_mbbtype_l(MSVCRT.@)
+ */
+int CDECL _mbbtype_l(unsigned char c, int type, MSVCRT__locale_t locale)
+{
+    if (type == 1)
+        return _ismbbtrail_l(c, locale) ? _MBC_TRAIL : _MBC_ILLEGAL;
+    else
+        return _ismbblead_l(c, locale) ? _MBC_LEAD
+                : MSVCRT__isprint_l(c, locale) ? _MBC_SINGLE : _MBC_ILLEGAL;
+}
+
+/*********************************************************************
+ *		_mbbtype(MSVCRT.@)
+ */
+int CDECL _mbbtype(unsigned char c, int type)
+{
+    return _mbbtype_l(c, type, NULL);
+}
+
 /*********************************************************************
  *		_mbsbtype (MSVCRT.@)
  */
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index 86938c8cc0e..4f79778f7cc 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -1204,6 +1204,7 @@ int __cdecl MSVCRT_wcsncmp(const MSVCRT_wchar_t*, const MSVCRT_wchar_t*, MSVCRT_
 int __cdecl MSVCRT__wcsnicmp(const MSVCRT_wchar_t*, const MSVCRT_wchar_t*, MSVCRT_size_t);
 int __cdecl MSVCRT_towlower(MSVCRT_wint_t);
 int __cdecl MSVCRT_towupper(MSVCRT_wint_t);
+int __cdecl MSVCRT__isprint_l(int c, MSVCRT__locale_t locale);
 int __cdecl MSVCRT__iswalnum_l(MSVCRT_wchar_t, MSVCRT__locale_t);
 int __cdecl MSVCRT__iswdigit_l(MSVCRT_wchar_t, MSVCRT__locale_t);
 int __cdecl MSVCRT__iswgraph_l(MSVCRT_wchar_t, MSVCRT__locale_t);
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c
index 6517995edde..451bc3014d4 100644
--- a/dlls/msvcrt/tests/string.c
+++ b/dlls/msvcrt/tests/string.c
@@ -35,6 +35,7 @@
 #undef strncpy
 #include "winbase.h"
 #include "winnls.h"
+#include "winuser.h"
 
 static char *buf_to_string(const unsigned char *bin, int len, int nr)
 {
@@ -4396,6 +4397,59 @@ static void test_SpecialCasing(void)
     }
 }
 
+
+static void test__mbbtype(void)
+{
+    static const char *test_locales[] =
+    {
+        "Arabic_Algeria",
+        "Chinese_China",
+        "English_Australia",
+        "French_Belgium",
+        "German_Austria",
+        "Greek",
+        "Hindi",
+        "Japanese",
+        "Korean",
+        "Polish",
+        "Portuguese_Brazil",
+        "Russian",
+        "Spanish_Argentina",
+        "Swedish_Finland",
+        "Ukrainian",
+        "Vietnamese",
+    };
+
+    int expected, ret;
+    unsigned int c, i;
+
+    for (i = 0; i < ARRAY_SIZE(test_locales); ++i)
+    {
+        setlocale(LC_ALL, test_locales[i]);
+        _setmbcp(_MB_CP_LOCALE);
+        for (c = 0; c < 256; ++c)
+        {
+            if (_ismbblead(c))
+                expected = _MBC_LEAD;
+            else if (isprint(c))
+                expected = _MBC_SINGLE;
+            else
+                expected = _MBC_ILLEGAL;
+
+            ret = _mbbtype(c, 0);
+            ok(ret == expected, "test %u, c %#x, got ret %#x, expected %#x.\n", i, c, ret, expected);
+
+            if (_ismbbtrail(c))
+                expected = _MBC_TRAIL;
+            else
+                expected = _MBC_ILLEGAL;
+
+            ret = _mbbtype(c, 1);
+            ok(ret == expected, "test %u, c %#x, got ret %#x, expected %#x.\n", i, c, ret, expected);
+        }
+    }
+}
+
 START_TEST(string)
 {
     char mem[100];
@@ -4550,4 +4604,5 @@ START_TEST(string)
     test_wcscmp();
     test___STRINGTOLD();
     test_SpecialCasing();
+    test__mbbtype();
 }
diff --git a/dlls/ucrtbase/tests/string.c b/dlls/ucrtbase/tests/string.c
index beeebc5c3ca..1a4fbbd76f0 100644
--- a/dlls/ucrtbase/tests/string.c
+++ b/dlls/ucrtbase/tests/string.c
@@ -516,6 +516,24 @@ static void test_SpecialCasing(void)
     }
 }
 
+static void test__mbbtype_l(void)
+{
+    int expected, ret;
+    unsigned int c;
+
+    _setmbcp(_MB_CP_LOCALE);
+    for (c = 0; c < 256; ++c)
+    {
+        expected = _mbbtype(c, 0);
+        ret = _mbbtype_l(c, 0, NULL);
+        ok(ret == expected, "c %#x, got ret %#x, expected %#x.\n", c, ret, expected);
+
+        expected = _mbbtype(c, 1);
+        ret = _mbbtype_l(c, 1, NULL);
+        ok(ret == expected, "c %#x, got ret %#x, expected %#x.\n", c, ret, expected);
+    }
+}
+
 START_TEST(string)
 {
     ok(_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
@@ -530,4 +548,5 @@ START_TEST(string)
     test_wcstok();
     test__strnicmp();
     test_SpecialCasing();
+    test__mbbtype_l();
 }
diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec
index a6c30f9a15b..f556b9e1c3d 100644
--- a/dlls/ucrtbase/ucrtbase.spec
+++ b/dlls/ucrtbase/ucrtbase.spec
@@ -584,7 +584,7 @@
 @ cdecl _mbbtombc(long)
 @ stub _mbbtombc_l
 @ cdecl _mbbtype(long long)
-@ stub _mbbtype_l
+@ cdecl _mbbtype_l(long long ptr)
 @ stub _mbcasemap
 @ cdecl _mbccpy(ptr ptr)
 @ cdecl _mbccpy_l(ptr ptr ptr)
@@ -1155,7 +1155,7 @@
 @ cdecl _o__mbbtombc(long) _mbbtombc
 @ stub _o__mbbtombc_l
 @ cdecl _o__mbbtype(long long) _mbbtype
-@ stub _o__mbbtype_l
+@ cdecl _o__mbbtype_l(long long ptr) _mbbtype_l
 @ cdecl _o__mbccpy(ptr ptr) _mbccpy
 @ cdecl _o__mbccpy_l(ptr ptr ptr) _mbccpy_l
 @ cdecl _o__mbccpy_s(ptr long ptr ptr) _mbccpy_s
diff --git a/include/msvcrt/mbstring.h b/include/msvcrt/mbstring.h
index b3336a2fbae..15eea68215b 100644
--- a/include/msvcrt/mbstring.h
+++ b/include/msvcrt/mbstring.h
@@ -51,6 +51,7 @@ int            __cdecl _ismbcsymbol(unsigned int);
 int            __cdecl _ismbcupper(unsigned int);
 unsigned int   __cdecl _mbbtombc(unsigned int);
 int            __cdecl _mbbtype(unsigned char,int);
+int            __cdecl _mbbtype_l(unsigned char,int,_locale_t);
 #define                _mbccmp(_cpc1,_cpc2) _mbsncmp((_cpc1),(_cpc2),1)
 void           __cdecl _mbccpy(unsigned char*,const unsigned char*);
 unsigned int   __cdecl _mbcjistojms(unsigned int);
-- 
2.26.2




More information about the wine-devel mailing list