msvcrt[2/2]: implement _mbsbtype
Mikolaj Zalewski
mikolajz at google.com
Thu Aug 16 15:45:03 CDT 2007
Skipped content of type multipart/alternative-------------- next part --------------
From 0596765b14e604221f5cd4efa6ebb68b694a59e1 Mon Sep 17 00:00:00 2001
From: Mikolaj Zalewski <mikolaj at zalewski.pl>
Date: Thu, 16 Aug 2007 12:11:39 -0700
Subject: [PATCH] msvcrt: implement _mbsbtype
---
dlls/msvcrt/mbcs.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
dlls/msvcrt/msvcrt.spec | 2 +-
dlls/msvcrt/tests/string.c | 11 ++++++++++-
3 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c
index 0dc0120..f5cd1e0 100644
--- a/dlls/msvcrt/mbcs.c
+++ b/dlls/msvcrt/mbcs.c
@@ -921,6 +921,7 @@ int CDECL _ismbblead(unsigned int c)
int CDECL _ismbbtrail(unsigned int c)
{
/* FIXME: should reference MSVCRT_mbctype */
+ /* FIXME: the same code can be a lead byte and a trail byte */
return !_ismbblead(c);
}
@@ -952,6 +953,50 @@ int CDECL _ismbstrail(const unsigned cha
return !_ismbslead(start, str) && MSVCRT_isleadbyte(str[-1]);
}
+static int count_leads(const unsigned char *start, const unsigned char *end)
+{
+ int count = 0;
+ while (start <= end)
+ {
+ if (!_ismbblead(*end))
+ return count;
+ count++;
+ }
+ return count;
+}
+
+/*********************************************************************
+ * _mbsbtype(MSVCRT.@)
+ */
+int CDECL _mbsbtype(const unsigned char *start, size_t pos)
+{
+ if (start == NULL || start[pos] == 0)
+ return _MBC_ILLEGAL;
+
+ /* Note: the same byte can be a lead and a trail so we must go backward
+ * to check something is really a lead/trail
+ */
+ /* TODO: call _ismbtrail before returning _MBC_TRAIL to check it is correct */
+ if (_ismbblead(start[pos]))
+ {
+ if (count_leads(start, start + pos) % 2)
+ return _MBC_LEAD;
+ else
+ return _MBC_TRAIL;
+ }
+ else
+ {
+ int count = count_leads(start, start + pos - 1);
+ if (count == 0)
+ return _MBC_SINGLE;
+
+ if (count % 2)
+ return _MBC_TRAIL;
+ else
+ return _MBC_LEAD;
+ }
+}
+
/*********************************************************************
* _mbsset(MSVCRT.@)
*/
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index fc81898..1a516f0 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -355,7 +355,7 @@ # extern _mbcasemap
@ 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 d7148da..ff6266c 100644
--- a/dlls/msvcrt/tests/string.c
+++ b/dlls/msvcrt/tests/string.c
@@ -77,12 +77,21 @@ static void test_swab( void ) {
static void test_ismbblead(void)
{
+ const unsigned char *str = (const unsigned char *)"\xB0\xB0\xB0\x30\xB0\xB0\x30";
unsigned int s = '\354';
int mb_orig_max = __mb_cur_max;
- _setmbcp(936);
+ _setmbcp(936); /* Codepage 936 - lead bytes 0x81-0xfe, trail bytes: 0x40-0xfe */
ok(__mb_cur_max == mb_orig_max, "__mb_cur_max shouldn't be updated (is %d != %d)\n", __mb_cur_max, mb_orig_max);
todo_wine ok(_ismbblead(s), "got result %d\n", _ismbblead(s));
+ todo_wine ok(_mbsbtype(str, 0) == _MBC_LEAD, "char 0 should be LEAD\n");
+ todo_wine ok(_mbsbtype(str, 1) == _MBC_TRAIL, "char 1 should be TRAIL\n");
+ todo_wine ok(_mbsbtype(str, 2) == _MBC_LEAD, "char 2 should be LEAD\n");
+ todo_wine ok(_mbsbtype(str, 3) == _MBC_ILLEGAL, "char 3 should be ILLEGAL\n");
+ todo_wine ok(_mbsbtype(str, 4) == _MBC_LEAD, "char 4 should be LEAD\n");
+ todo_wine ok(_mbsbtype(str, 5) == _MBC_TRAIL, "char 5 should be TRAIL\n");
+ ok(_mbsbtype(str, 6) == _MBC_SINGLE, "char 6 should be SINGLE\n");
+ ok(_mbsbtype(str, 7) == _MBC_ILLEGAL, "char 7 should be ILLEGAL\n");
_setmbcp(1252);
}
--
1.4.1
More information about the wine-patches
mailing list