From 302d63a2255907f9a7cc92b5479ba79202cc03ef Mon Sep 17 00:00:00 2001 From: Damjan Jovanovic Date: Mon, 18 Oct 2010 14:06:16 +0200 Subject: [PATCH] msvcrt: Implement wcsncat_s. --- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/msvcrt.spec | 2 +- dlls/msvcrt/tests/string.c | 37 +++++++++++++++++++++++++++ dlls/msvcrt/wcs.c | 50 +++++++++++++++++++++++++++++++++++++ 6 files changed, 91 insertions(+), 4 deletions(-) diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 3468cbb589a..6573f1c3725 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1640,7 +1640,7 @@ @ cdecl wcsftime(ptr long wstr ptr) msvcrt.wcsftime @ cdecl wcslen(wstr) msvcrt.wcslen @ cdecl wcsncat(wstr wstr long) msvcrt.wcsncat -@ stub wcsncat_s +@ cdecl wcsncat_s(wstr long wstr long) msvcrt.wcsncat_s @ cdecl wcsncmp(wstr wstr long) msvcrt.wcsncmp @ cdecl wcsncpy(ptr wstr long) msvcrt.wcsncpy @ cdecl wcsncpy_s(ptr long wstr long) msvcrt.wcsncpy_s diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 8f7069342f9..819ed0ade96 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -1494,7 +1494,7 @@ @ cdecl wcsftime(ptr long wstr ptr) msvcrt.wcsftime @ cdecl wcslen(wstr) msvcrt.wcslen @ cdecl wcsncat(wstr wstr long) msvcrt.wcsncat -@ stub wcsncat_s +@ cdecl wcsncat_s(wstr long wstr long) msvcrt.wcsncat_s @ cdecl wcsncmp(wstr wstr long) msvcrt.wcsncmp @ cdecl wcsncpy(ptr wstr long) msvcrt.wcsncpy @ cdecl wcsncpy_s(ptr long wstr long) msvcrt.wcsncpy_s diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index a9f6b0109fd..7a8123d783e 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -1478,7 +1478,7 @@ @ cdecl wcsftime(ptr long wstr ptr) msvcrt.wcsftime @ cdecl wcslen(wstr) msvcrt.wcslen @ cdecl wcsncat(wstr wstr long) msvcrt.wcsncat -@ stub wcsncat_s +@ cdecl wcsncat_s(wstr long wstr long) msvcrt.wcsncat_s @ cdecl wcsncmp(wstr wstr long) msvcrt.wcsncmp @ cdecl wcsncpy(ptr wstr long) msvcrt.wcsncpy @ cdecl wcsncpy_s(ptr long wstr long) msvcrt.wcsncpy_s diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index e6a8670ab40..c0f3d355338 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1440,7 +1440,7 @@ @ cdecl wcsftime(ptr long wstr ptr) MSVCRT_wcsftime @ cdecl wcslen(wstr) ntdll.wcslen @ cdecl wcsncat(wstr wstr long) ntdll.wcsncat -# stub wcsncat_s +@ cdecl wcsncat_s(wstr long wstr long) MSVCRT_wcsncat_s @ cdecl wcsncmp(wstr wstr long) ntdll.wcsncmp @ cdecl wcsncpy(ptr wstr long) ntdll.wcsncpy @ cdecl wcsncpy_s(ptr long wstr long) MSVCRT_wcsncpy_s diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index a7d033ab5e9..b56834512c6 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -52,6 +52,7 @@ static int (__cdecl *pstrcpy_s)(char *dst, size_t len, const char *src); static int (__cdecl *pstrcat_s)(char *dst, size_t len, const char *src); static int (__cdecl *p_mbsnbcpy_s)(unsigned char * dst, size_t size, const unsigned char * src, size_t count); static int (__cdecl *p_wcscpy_s)(wchar_t *wcDest, size_t size, const wchar_t *wcSrc); +static int (__cdecl *p_wcsncat_s)(wchar_t *dst, size_t elem, const wchar_t *src, size_t count); static int (__cdecl *p_wcsupr_s)(wchar_t *str, size_t size); static size_t (__cdecl *p_strnlen)(const char *, size_t); static __int64 (__cdecl *p_strtoi64)(const char *, char **, int); @@ -1428,6 +1429,40 @@ static void test__strlwr_s(void) buffer); } +static void test_wcsncat_s(void) +{ + static wchar_t abcW[] = {'a','b','c',0}; + int ret; + wchar_t dst[4]; + wchar_t src[4]; + + if (!p_wcsncat_s) + { + win_skip("skipping wcsncat_s tests\n"); + return; + } + + memcpy(src, abcW, sizeof(abcW)); + dst[0] = 0; + ret = p_wcsncat_s(NULL, 4, src, 4); + ok(ret == EINVAL, "err = %d\n", ret); + ret = p_wcsncat_s(dst, 0, src, 4); + ok(ret == EINVAL, "err = %d\n", ret); + ret = p_wcsncat_s(dst, 0, src, _TRUNCATE); + ok(ret == EINVAL, "err = %d\n", ret); + ret = p_wcsncat_s(dst, 4, NULL, 0); + ok(ret == 0, "err = %d\n", ret); + + dst[0] = 0; + ret = p_wcsncat_s(dst, 2, src, 4); + ok(ret == ERANGE, "err = %d\n", ret); + + dst[0] = 0; + ret = p_wcsncat_s(dst, 2, src, _TRUNCATE); + todo_wine ok(ret == 80, "err = %d\n", ret); + ok(dst[0] == 'a' && dst[1] == 0, "dst is %s\n", wine_dbgstr_w(dst)); +} + START_TEST(string) { char mem[100]; @@ -1446,6 +1481,7 @@ START_TEST(string) pstrcat_s = (void *)GetProcAddress( hMsvcrt,"strcat_s" ); p_mbsnbcpy_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcpy_s" ); p_wcscpy_s = (void *)GetProcAddress( hMsvcrt,"wcscpy_s" ); + p_wcsncat_s = (void *)GetProcAddress( hMsvcrt,"wcsncat_s" ); p_wcsupr_s = (void *)GetProcAddress( hMsvcrt,"_wcsupr_s" ); p_strnlen = (void *)GetProcAddress( hMsvcrt,"strnlen" ); p_strtoi64 = (void *)GetProcAddress(hMsvcrt, "_strtoi64"); @@ -1491,4 +1527,5 @@ START_TEST(string) test_gcvt(); test__itoa_s(); test__strlwr_s(); + test_wcsncat_s(); } diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 47a50b6f39f..98aa6c5656e 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -1580,6 +1580,56 @@ INT CDECL MSVCRT_wcscat_s(MSVCRT_wchar_t* dst, MSVCRT_size_t elem, const MSVCRT_ return MSVCRT_ERANGE; } +/********************************************************************* + * wcsncat_s (MSVCRT.@) + * + */ +INT CDECL MSVCRT_wcsncat_s(MSVCRT_wchar_t *dst, MSVCRT_size_t elem, + const MSVCRT_wchar_t *src, MSVCRT_size_t count) +{ + MSVCRT_size_t srclen; + MSVCRT_size_t i; + MSVCRT_wchar_t dststart; + + if (src == NULL && count > 0) + return MSVCRT_EINVAL; + if (dst == NULL) + return MSVCRT_EINVAL; + if (elem == 0) + return MSVCRT_EINVAL; + + for (i = 0; i < elem; i++) + { + dststart = i; + if (dst[i] == '\0') + break; + } + if (dststart == elem) + return MSVCRT_EINVAL; + + if (count == MSVCRT__TRUNCATE) + srclen = elem - dststart - 1; + else + srclen = count; + for (i = 0; i < srclen; i++) + { + if (src[i] == '\0') + { + srclen = i; + break; + } + } + + if (srclen < (elem - dststart)) + { + memcpy(&dst[dststart], src, srclen*sizeof(MSVCRT_wchar_t)); + dst[srclen] = '\0'; + return 0; + } + dst[0] = '\0'; + return MSVCRT_ERANGE; +} + /********************************************************************* * _wcstoi64_l (MSVCRT.@) *