Module: wine Branch: master Commit: 71144728cfebd8a5b2f355fefa1a7fe6be8d9174 URL: https://gitlab.winehq.org/wine/wine/-/commit/71144728cfebd8a5b2f355fefa1a7fe...
Author: Piotr Caban piotr@codeweavers.com Date: Wed Oct 19 13:16:17 2022 +0200
msvcrt: Add support for multi-byte characters in _mbctoupper_l.
---
dlls/msvcrt/mbcs.c | 30 ++++++++++++++++++++++++++---- dlls/msvcrt/tests/string.c | 8 ++++++++ 2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index 1c747ac1573..d098f5b23f4 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -494,12 +494,34 @@ unsigned int CDECL _mbctolower(unsigned int c) */ unsigned int CDECL _mbctoupper_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_UPPERCASE, + (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 _toupper_l(c, locale); /* ASCII CP or SB char */ + + return mbcinfo->mbctype[c + 1] & _SBLOW ? mbcinfo->mbcasemap[c] : c; }
/********************************************************************* diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 14c0adf0efc..905607e416d 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -2839,6 +2839,7 @@ static void test__mbsupr_s(void) { errno_t ret; unsigned char buffer[20]; + int cp = _getmbcp();
if (!p_mbsupr_s) { @@ -2890,6 +2891,13 @@ static void test__mbsupr_s(void) "Expected the output buffer to be "ABCDEFGH\0ijklmnop", got "%s"\n", buffer);
+ _setmbcp(936); + memcpy(buffer, "\xa2\xa1\xa2\xa2q", sizeof("\xa2\xa1\xa2\xa2q")); + ret = p_mbsupr_s(buffer, sizeof(buffer)); + ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret); + ok(!memcmp(buffer, "\xa2\xf1\xa2\xf2Q", sizeof("\xa2\xf1\xa2\xf2Q")), + "got %s\n", debugstr_a((char*)buffer)); + _setmbcp(cp); }
static void test__mbslwr_s(void)