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 */