Module: wine Branch: master Commit: 53869e19ebb0d74909b9efb81a54a4571b5460b8 URL: http://source.winehq.org/git/wine.git/?a=commit;h=53869e19ebb0d74909b9efb81a...
Author: Piotr Caban piotr@codeweavers.com Date: Tue Sep 2 13:50:44 2014 +0200
msvcrt: Add _strnset_s implementation.
---
dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr110/msvcr110.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/msvcrt.spec | 2 +- dlls/msvcrt/string.c | 24 ++++++++++++++++++++++++ dlls/msvcrt/tests/string.c | 33 +++++++++++++++++++++++++++++++++ 7 files changed, 62 insertions(+), 5 deletions(-)
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 7135638..f8062f9 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1350,7 +1350,7 @@ @ cdecl _strnicoll(str str long) MSVCRT__strnicoll @ cdecl _strnicoll_l(str str long ptr) MSVCRT__strnicoll_l @ cdecl _strnset(str long long) MSVCRT__strnset -@ stub _strnset_s +@ cdecl _strnset_s(str long long long) MSVCRT__strnset_s @ cdecl _strrev(str) MSVCRT__strrev @ cdecl _strset(str long) @ stub _strset_s diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 39ad037..6a328eb 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -1708,7 +1708,7 @@ @ cdecl _strnicoll(str str long) MSVCRT__strnicoll @ cdecl _strnicoll_l(str str long ptr) MSVCRT__strnicoll_l @ cdecl _strnset(str long long) MSVCRT__strnset -@ stub _strnset_s +@ cdecl _strnset_s(str long long long) MSVCRT__strnset_s @ cdecl _strrev(str) MSVCRT__strrev @ cdecl _strset(str long) @ stub _strset_s diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 302abe5..3902c85 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -1030,7 +1030,7 @@ @ cdecl _strnicoll(str str long) MSVCRT__strnicoll @ cdecl _strnicoll_l(str str long ptr) MSVCRT__strnicoll_l @ cdecl _strnset(str long long) MSVCRT__strnset -@ stub _strnset_s +@ cdecl _strnset_s(str long long long) MSVCRT__strnset_s @ cdecl _strrev(str) MSVCRT__strrev @ cdecl _strset(str long) @ stub _strset_s diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 28d37d1..fa19f40 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -1005,7 +1005,7 @@ @ cdecl _strnicoll(str str long) MSVCRT__strnicoll @ cdecl _strnicoll_l(str str long ptr) MSVCRT__strnicoll_l @ cdecl _strnset(str long long) MSVCRT__strnset -@ stub _strnset_s +@ cdecl _strnset_s(str long long long) MSVCRT__strnset_s @ cdecl _strrev(str) MSVCRT__strrev @ cdecl _strset(str long) @ stub _strset_s diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 2349580..01788e1 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -971,7 +971,7 @@ @ cdecl _strnicoll(str str long) MSVCRT__strnicoll @ cdecl _strnicoll_l(str str long ptr) MSVCRT__strnicoll_l @ cdecl _strnset(str long long) MSVCRT__strnset -# stub _strnset_s(str long long long) +@ cdecl _strnset_s(str long long long) MSVCRT__strnset_s @ cdecl _strrev(str) MSVCRT__strrev @ cdecl _strset(str long) # stub _strset_s(str long long) diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c index 60e00c9..bacab00 100644 --- a/dlls/msvcrt/string.c +++ b/dlls/msvcrt/string.c @@ -174,6 +174,30 @@ char* CDECL MSVCRT__strupr(char *str) }
/********************************************************************* + * _strnset_s (MSVCRT.@) + */ +int CDECL MSVCRT__strnset_s(char *str, MSVCRT_size_t size, int c, MSVCRT_size_t count) +{ + MSVCRT_size_t i; + + if(!str && !size && !count) return 0; + if(!MSVCRT_CHECK_PMT(str != NULL)) return MSVCRT_EINVAL; + if(!MSVCRT_CHECK_PMT(size > 0)) return MSVCRT_EINVAL; + + for(i=0; i<size-1 && i<count; i++) { + if(!str[i]) return 0; + str[i] = c; + } + for(; i<size; i++) + if(!str[i]) return 0; + + str[0] = 0; + MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0); + *MSVCRT__errno() = MSVCRT_EINVAL; + return MSVCRT_EINVAL; +} + +/********************************************************************* * _strnset (MSVCRT.@) */ char* CDECL MSVCRT__strnset(char* str, int value, MSVCRT_size_t len) diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 6604819..5b9d951 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -89,6 +89,7 @@ static int (__cdecl *p_tolower)(int); static size_t (__cdecl *p_mbrlen)(const char*, size_t, mbstate_t*); static size_t (__cdecl *p_mbrtowc)(wchar_t*, const char*, size_t, mbstate_t*); static int (__cdecl *p__atodbl_l)(_CRT_DOUBLE*,char*,_locale_t); +static int (__cdecl *p__strnset_s)(char*,size_t,int,size_t);
#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) @@ -2716,6 +2717,36 @@ static void test_strxfrm(void) setlocale(LC_ALL, "C"); }
+static void test__strnset_s(void) +{ + char buf[5] = {0}; + int r; + + if(!p__strnset_s) { + win_skip("_strnset_s not available\n"); + return; + } + + r = p__strnset_s(NULL, 0, 'a', 0); + ok(r == 0, "r = %d\n", r); + + buf[0] = buf[1] = buf[2] = 'b'; + r = p__strnset_s(buf, sizeof(buf), 'a', 2); + ok(r == 0, "r = %d\n", r); + ok(!strcmp(buf, "aab"), "buf = %s\n", buf); + + r = p__strnset_s(buf, 0, 'a', 0); + ok(r == EINVAL, "r = %d\n", r); + + r = p__strnset_s(NULL, 0, 'a', 1); + ok(r == EINVAL, "r = %d\n", r); + + buf[3] = 'b'; + r = p__strnset_s(buf, sizeof(buf)-1, 'c', 2); + ok(r == EINVAL, "r = %d\n", r); + ok(!buf[0] && buf[1]=='c' && buf[2]=='b', "buf = %s\n", buf); +} + START_TEST(string) { char mem[100]; @@ -2763,6 +2794,7 @@ START_TEST(string) p_mbrtowc = (void*)GetProcAddress(hMsvcrt, "mbrtowc"); p_mbsrtowcs = (void*)GetProcAddress(hMsvcrt, "mbsrtowcs"); p__atodbl_l = (void*)GetProcAddress(hMsvcrt, "_atodbl_l"); + p__strnset_s = (void*)GetProcAddress(hMsvcrt, "_strnset_s");
/* MSVCRT memcpy behaves like memmove for overlapping moves, MFC42 CString::Insert seems to rely on that behaviour */ @@ -2816,4 +2848,5 @@ START_TEST(string) test_atoi(); test_strncpy(); test_strxfrm(); + test__strnset_s(); }