Module: wine Branch: master Commit: 0b3175cb24a6ae9c3a1f6c97c9cc24dea5b8a1c3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=0b3175cb24a6ae9c3a1f6c97c9...
Author: Konrad Rzepecki hannibal@astral.lodz.pl Date: Sun Mar 20 02:17:12 2011 +0100
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 473f663..a4589e1 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 9da91db..b491d87 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 96d4589..d1cae36 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 5767242..081aa88 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -1572,6 +1572,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.@) */ MSVCRT_size_t CDECL _mbsspn(const unsigned char* string, const unsigned char* set) diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index c324dea..e43c3f5 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 dfa38e6..e231077 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(); }