Module: wine Branch: master Commit: 3861c1e36ac835eb3584fe71b8294816e1ed7a85 URL: https://gitlab.winehq.org/wine/wine/-/commit/3861c1e36ac835eb3584fe71b829481...
Author: Piotr Caban piotr@codeweavers.com Date: Wed Oct 19 13:14:44 2022 +0200
msvcrt: Add support for multi-byte characters in _mbctolower_l.
---
dlls/msvcrt/mbcs.c | 30 ++++++++++++++++++++++++++---- dlls/msvcrt/tests/string.c | 9 +++++++++ 2 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index f1d82b5e268..1c747ac1573 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -451,12 +451,34 @@ unsigned int CDECL _mbsnextc(const unsigned char* str) */ unsigned int CDECL _mbctolower_l(unsigned int c, _locale_t locale) { - if (_ismbblead_l(c, locale)) + unsigned char str[2], ret[2]; + pthreadmbcinfo mbcinfo; + + if(!locale) + mbcinfo = get_mbcinfo(); + else + mbcinfo = locale->mbcinfo; + + if (c > 0xff) { - FIXME("Handle MBC chars\n"); - return c; + if (!_ismbblead_l((c >> 8) & 0xff, locale)) + return c; + + str[0] = c >> 8; + str[1] = c; + switch(__crtLCMapStringA(mbcinfo->mblcid, LCMAP_LOWERCASE, + (char*)str, 2, (char*)ret, 2, mbcinfo->mbcodepage, 0)) + { + case 0: + return c; + case 1: + return ret[0]; + default: + return ret[1] + (ret[0] << 8); + } } - return _tolower_l(c, locale); /* ASCII CP or SB char */ + + return mbcinfo->mbctype[c + 1] & _SBUP ? mbcinfo->mbcasemap[c] : c; }
/********************************************************************* diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 4e525193ced..14c0adf0efc 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -2896,6 +2896,7 @@ static void test__mbslwr_s(void) { errno_t ret; unsigned char buffer[20]; + int cp = _getmbcp();
if (!p_mbslwr_s) { @@ -2946,6 +2947,14 @@ static void test__mbslwr_s(void) ok(!memcmp(buffer, "abcdefgh\0IJKLMNOP", sizeof("abcdefgh\0IJKLMNOP")), "Expected the output buffer to be "abcdefgh\0IJKLMNOP", got "%s"\n", buffer); + + _setmbcp(936); + memcpy(buffer, "\xa2\xf1\xa2\xf2Q", sizeof("\xa2\xf1\xa2\xf2Q")); + ret = p_mbslwr_s(buffer, sizeof(buffer)); + ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret); + ok(!memcmp(buffer, "\xa2\xa1\xa2\xa2q", sizeof("\xa2\xa1\xa2\xa2q")), + "got %s\n", debugstr_a((char*)buffer)); + _setmbcp(cp); }
static void test__mbstok(void)