From 0b3175cb24a6ae9c3a1f6c97c9cc24dea5b8a1c3 Mon Sep 17 00:00:00 2001 From: Konrad Rzepecki Date: Sun, 20 Mar 2011 02:17:12 +0100 Subject: [PATCH] msvcrt: Implement _mbsupr_s. --- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/mbcs.c | 40 +++++++++++++++++++++++++ dlls/msvcrt/msvcrt.spec | 2 +- dlls/msvcrt/tests/string.c | 60 +++++++++++++++++++++++++++++++++++++ 6 files changed, 104 insertions(+), 4 deletions(-) diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 473f6638def..a4589e1a1f3 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1001,7 +1001,7 @@ @ stub _mbstrnlen_l @ cdecl _mbsupr(str) msvcrt._mbsupr @ stub _mbsupr_l -@ stub _mbsupr_s +@ cdecl _mbsupr_s(str long) msvcrt._mbsupr_s @ stub _mbsupr_s_l @ stub _mbtowc_l @ cdecl _memccpy(ptr ptr long long) msvcrt._memccpy diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 9da91db6894..b491d872a09 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -847,7 +847,7 @@ @ stub _mbstrnlen_l @ cdecl _mbsupr(str) msvcrt._mbsupr @ stub _mbsupr_l -@ stub _mbsupr_s +@ cdecl _mbsupr_s(str long) msvcrt._mbsupr_s @ stub _mbsupr_s_l @ stub _mbtowc_l @ cdecl _memccpy(ptr ptr long long) msvcrt._memccpy diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 96d4589c268..d1cae36ab9c 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -835,7 +835,7 @@ @ stub _mbstrnlen_l @ cdecl _mbsupr(str) msvcrt._mbsupr @ stub _mbsupr_l -@ stub _mbsupr_s +@ cdecl _mbsupr_s(str long) msvcrt._mbsupr_s @ stub _mbsupr_s_l @ stub _mbtowc_l @ cdecl _memccpy(ptr ptr long long) msvcrt._memccpy diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index 576724287a8..081aa889627 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -1571,6 +1571,46 @@ unsigned char* CDECL _mbsupr(unsigned char* s) } +/********************************************************************* + * _mbsupr_s(MSVCRT.@) + */ +int CDECL _mbsupr_s(unsigned char* s, MSVCRT_size_t len) +{ + if (!s && !len) + { + return 0; + } + else if (!s || !len) + { + *MSVCRT__errno() = MSVCRT_EINVAL; + return MSVCRT_EINVAL; + } + if (get_locale()->locinfo->mb_cur_max > 1) + { + unsigned int c; + for ( ; *s && len > 0; len--) + { + c = _mbctoupper(_mbsnextc(s)); + /* Note that I assume that the size of the character is unchanged */ + if (c > 255) + { + *s++=(c>>8); + c=c & 0xff; + } + *s++=c; + } + } + else for ( ; *s && len > 0; s++, len--) *s = toupper(*s); + if (*s) + { + *s = '\0'; + *MSVCRT__errno() = MSVCRT_EINVAL; + return MSVCRT_EINVAL; + } + return 0; +} + + /********************************************************************* * _mbsspn (MSVCRT.@) */ diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index c324dea37a9..e43c3f5338b 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -783,7 +783,7 @@ # stub _mbstrnlen_l @ cdecl _mbsupr(str) # stub _mbsupr_l -# stub _mbsupr_s +@ cdecl _mbsupr_s(str long) # stub _mbsupr_s_l # stub _mbtowc_l @ cdecl _memccpy(ptr ptr long long) ntdll._memccpy diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index dfa38e62e24..e23107793c9 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -76,6 +76,7 @@ static int *p__mb_cur_max; static unsigned char *p_mbctype; static _invalid_parameter_handler (__cdecl *p_set_invalid_parameter_handler)(_invalid_parameter_handler); static int (__cdecl *p_wcslwr_s)(wchar_t*,size_t); +static errno_t (__cdecl *p_mbsupr_s)(unsigned char *str, size_t numberOfElements); #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y) #define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y) @@ -1711,6 +1712,63 @@ static void test__mbsnbcat_s(void) "Expected the output buffer string to be \"\\0inosaurdu\" without ending null terminator\n"); } +static void test__mbsupr_s(void) +{ + errno_t ret; + unsigned char buffer[20]; + + if (!p_mbsupr_s) + { + win_skip("Skipping _mbsupr_s tests\n"); + return; + } + + errno = EBADF; + ret = p_mbsupr_s(NULL, 0); + ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret); + + errno = EBADF; + ret = p_mbsupr_s(NULL, sizeof(buffer)); + ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + + errno = EBADF; + ret = p_mbsupr_s(buffer, 0); + ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + + memcpy(buffer, "abcdefgh", sizeof("abcdefgh")); + errno = EBADF; + ret = p_mbsupr_s(buffer, sizeof("abcdefgh")); + ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret); + ok(!memcmp(buffer, "ABCDEFGH", sizeof("ABCDEFGH")), + "Expected the output buffer to be \"ABCDEFGH\", got \"%s\"\n", + buffer); + + memcpy(buffer, "abcdefgh", sizeof("abcdefgh")); + errno = EBADF; + ret = p_mbsupr_s(buffer, sizeof(buffer)); + ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret); + ok(!memcmp(buffer, "ABCDEFGH", sizeof("ABCDEFGH")), + "Expected the output buffer to be \"ABCDEFGH\", got \"%s\"\n", + buffer); + + memcpy(buffer, "abcdefgh", sizeof("abcdefgh")); + errno = EBADF; + ret = p_mbsupr_s(buffer, 4); + ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + + memcpy(buffer, "abcdefgh\0ijklmnop", sizeof("abcdefgh\0ijklmnop")); + errno = EBADF; + ret = p_mbsupr_s(buffer, sizeof(buffer)); + ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret); + ok(!memcmp(buffer, "ABCDEFGH\0ijklmnop", sizeof("ABCDEFGH\0ijklmnop")), + "Expected the output buffer to be \"ABCDEFGH\\0ijklmnop\", got \"%s\"\n", + buffer); + +} + static void test__ultoa_s(void) { errno_t ret; @@ -1821,6 +1879,7 @@ START_TEST(string) p_ultoa_s = (void *)GetProcAddress(hMsvcrt, "_ultoa_s"); p_set_invalid_parameter_handler = (void *) GetProcAddress(hMsvcrt, "_set_invalid_parameter_handler"); p_wcslwr_s = (void*)GetProcAddress(hMsvcrt, "_wcslwr_s"); + p_mbsupr_s = (void*)GetProcAddress(hMsvcrt, "_mbsupr_s"); /* MSVCRT memcpy behaves like memmove for overlapping moves, MFC42 CString::Insert seems to rely on that behaviour */ @@ -1861,4 +1920,5 @@ START_TEST(string) test__mbsnbcat_s(); test__ultoa_s(); test__wcslwr_s(); + test__mbsupr_s(); }