From 758539c8a3ddd75b6dff2a42752100ec75c833fd Mon Sep 17 00:00:00 2001
From: Mikolaj Zalewski <mikolajz@google.com>
Date: Thu, 23 Aug 2007 18:11:43 -0700
Subject: [PATCH] msvcrt: Implement and test _mbsbtype.

---
 dlls/msvcrt/mbcs.c         | 32 ++++++++++++++++++++++++++++++++
 dlls/msvcrt/msvcrt.spec    |  2 +-
 dlls/msvcrt/tests/string.c | 18 ++++++++++++++++++
 3 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c
index 91efadd73dd..258751ef719 100644
--- a/dlls/msvcrt/mbcs.c
+++ b/dlls/msvcrt/mbcs.c
@@ -1088,6 +1088,38 @@ int CDECL _ismbstrail(const unsigned char* start, const unsigned char* str)
     return 0;
 }
 
+/*********************************************************************
+ *		_mbsbtype (MSVCRT.@)
+ */
+int CDECL _mbsbtype(const unsigned char *str, MSVCRT_size_t count)
+{
+  int lead = 0;
+  const unsigned char *end = str + count;
+  int mbcp = g_mbcp_is_multibyte;
+
+  /* Lead bytes can also be trail bytes so we need to analyse the string.
+   * Also we must return _MBC_ILLEGAL for chars past the end of the string
+   */
+  while (str < end) /* Note: we skip the last byte - will check after the loop */
+  {
+    if (!*str)
+      return _MBC_ILLEGAL;
+    lead = mbcp && !lead && _ismbblead(*str);
+    str++;
+  }
+
+  if (lead)
+    if (_ismbbtrail(*str))
+      return _MBC_TRAIL;
+    else
+      return _MBC_ILLEGAL;
+  else
+    if (_ismbblead(*str))
+      return _MBC_LEAD;
+    else
+      return _MBC_SINGLE;
+}
+
 /*********************************************************************
  *		_mbsset(MSVCRT.@)
  */
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index fc818986e87..1a516f0456f 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -355,7 +355,7 @@
 @ stub _mbctombb #(long)
 @ cdecl _mbctoupper(long)
 @ extern _mbctype MSVCRT_mbctype
-@ stub _mbsbtype #(str long)
+@ cdecl _mbsbtype(str long)
 @ cdecl _mbscat(str str)
 @ cdecl _mbschr(str long)
 @ cdecl _mbscmp(str str)
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c
index 919964132d7..6dabc615392 100644
--- a/dlls/msvcrt/tests/string.c
+++ b/dlls/msvcrt/tests/string.c
@@ -239,6 +239,24 @@ static void test_mbcp(void)
     expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[4]), FALSE, int, "%d");
     expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[5]), FALSE, int, "%d");
 
+    /* _mbsbtype */
+    expect_eq(_mbsbtype(mbstring, 0), _MBC_LEAD, int, "%d");
+    expect_eq(_mbsbtype(mbstring, 1), _MBC_TRAIL, int, "%d");
+    expect_eq(_mbsbtype(mbstring, 2), _MBC_LEAD, int, "%d");
+    expect_eq(_mbsbtype(mbstring, 3), _MBC_ILLEGAL, int, "%d");
+    expect_eq(_mbsbtype(mbstring, 4), _MBC_LEAD, int, "%d");
+    expect_eq(_mbsbtype(mbstring, 5), _MBC_TRAIL, int, "%d");
+    expect_eq(_mbsbtype(mbstring, 6), _MBC_SINGLE, int, "%d");
+    expect_eq(_mbsbtype(mbstring, 7), _MBC_LEAD, int, "%d");
+    expect_eq(_mbsbtype(mbstring, 8), _MBC_ILLEGAL, int, "%d");
+
+    expect_eq(_mbsbtype(mbsonlylead, 0), _MBC_LEAD, int, "%d");
+    expect_eq(_mbsbtype(mbsonlylead, 1), _MBC_ILLEGAL, int, "%d");
+    expect_eq(_mbsbtype(mbsonlylead, 2), _MBC_ILLEGAL, int, "%d");
+    expect_eq(_mbsbtype(mbsonlylead, 3), _MBC_ILLEGAL, int, "%d");
+    expect_eq(_mbsbtype(mbsonlylead, 4), _MBC_ILLEGAL, int, "%d");
+    expect_eq(_mbsbtype(mbsonlylead, 5), _MBC_ILLEGAL, int, "%d");
+
     /* _mbsnextc */
     expect_eq(_mbsnextc(mbstring), 0xb0b1, int, "%x");
     expect_eq(_mbsnextc(&mbstring[2]), 0xb220, int, "%x");  /* lead + invalid tail */
-- 
GitLab