From 332d5954ed0335dc54040dd67942494ae942d224 Mon Sep 17 00:00:00 2001 From: Konrad Rzepecki Date: Sun, 20 Mar 2011 02:19:02 +0100 Subject: [PATCH] msvcrt: Implement _mbslwr_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 a4589e1a1f..1812407efa 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -921,7 +921,7 @@ @ stub _mbslen_l @ cdecl _mbslwr(str) msvcrt._mbslwr @ stub _mbslwr_l -@ stub _mbslwr_s +@ cdecl _mbslwr_s(str long) msvcrt._mbslwr_s @ stub _mbslwr_s_l @ cdecl _mbsnbcat(str str long) msvcrt._mbsnbcat @ stub _mbsnbcat_l diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index b491d872a0..8b58e7d950 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -767,7 +767,7 @@ @ stub _mbslen_l @ cdecl _mbslwr(str) msvcrt._mbslwr @ stub _mbslwr_l -@ stub _mbslwr_s +@ cdecl _mbslwr_s(str long) msvcrt._mbslwr_s @ stub _mbslwr_s_l @ cdecl _mbsnbcat(str str long) msvcrt._mbsnbcat @ stub _mbsnbcat_l diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index d1cae36ab9..d18651ddbb 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -755,7 +755,7 @@ @ stub _mbslen_l @ cdecl _mbslwr(str) msvcrt._mbslwr @ stub _mbslwr_l -@ stub _mbslwr_s +@ cdecl _mbslwr_s(str long) msvcrt._mbslwr_s @ stub _mbslwr_s_l @ cdecl _mbsnbcat(str str long) msvcrt._mbsnbcat @ stub _mbsnbcat_l diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index 081aa88962..2a2ac7222d 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -1543,6 +1543,46 @@ unsigned char* CDECL _mbslwr(unsigned char* s) } +/********************************************************************* + * _mbslwr_s(MSVCRT.@) + */ +int CDECL _mbslwr_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 = _mbctolower(_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 = tolower(*s); + if (*s) + { + *s = '\0'; + *MSVCRT__errno() = MSVCRT_EINVAL; + return MSVCRT_EINVAL; + } + return 0; +} + + /********************************************************************* * _mbsupr(MSVCRT.@) */ diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index e43c3f5338..103142eed5 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -703,7 +703,7 @@ # stub _mbslen_l @ cdecl _mbslwr(str) # stub _mbslwr_l -# stub _mbslwr_s +@ cdecl _mbslwr_s(str long) # stub _mbslwr_s_l @ cdecl _mbsnbcat(str str long) # stub _mbsnbcat_l diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index e23107793c..f3d8dc4e84 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -77,6 +77,7 @@ 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); +static errno_t (__cdecl *p_mbslwr_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) @@ -1769,6 +1770,63 @@ static void test__mbsupr_s(void) } +static void test__mbslwr_s(void) +{ + errno_t ret; + unsigned char buffer[20]; + + if (!p_mbslwr_s) + { + win_skip("Skipping _mbslwr_s tests\n"); + return; + } + + errno = EBADF; + ret = p_mbslwr_s(NULL, 0); + ok(ret == 0, "Expected _mbslwr_s to return 0, got %d\n", ret); + + errno = EBADF; + ret = p_mbslwr_s(NULL, sizeof(buffer)); + ok(ret == EINVAL, "Expected _mbslwr_s to return EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + + errno = EBADF; + ret = p_mbslwr_s(buffer, 0); + ok(ret == EINVAL, "Expected _mbslwr_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_mbslwr_s(buffer, sizeof("ABCDEFGH")); + ok(ret == 0, "Expected _mbslwr_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_mbslwr_s(buffer, sizeof(buffer)); + ok(ret == 0, "Expected _mbslwr_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_mbslwr_s(buffer, 4); + ok(ret == EINVAL, "Expected _mbslwr_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_mbslwr_s(buffer, sizeof(buffer)); + ok(ret == 0, "Expected _mbslwr_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; @@ -1880,6 +1938,7 @@ START_TEST(string) 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"); + p_mbslwr_s = (void*)GetProcAddress(hMsvcrt, "_mbslwr_s"); /* MSVCRT memcpy behaves like memmove for overlapping moves, MFC42 CString::Insert seems to rely on that behaviour */ @@ -1921,4 +1980,5 @@ START_TEST(string) test__ultoa_s(); test__wcslwr_s(); test__mbsupr_s(); + test__mbslwr_s(); }