[PATCH] Implement wcscat_s
Alistair Leslie-Hughes
leslie_alistair at hotmail.com
Fri Mar 14 04:28:41 CDT 2008
---
dlls/msvcrt/msvcrt.spec | 1 +
dlls/msvcrt/tests/string.c | 38 ++++++++++++++++++++++++++++++++++++++
dlls/msvcrt/wcs.c | 24 ++++++++++++++++++++++++
3 files changed, 63 insertions(+), 0 deletions(-)
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 8f8ccf4..4bff698 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -758,6 +758,7 @@
@ cdecl vswprintf(ptr wstr ptr) MSVCRT_vswprintf
@ cdecl vwprintf(wstr ptr) MSVCRT_vwprintf
@ cdecl wcscat(wstr wstr) ntdll.wcscat
+@ cdecl wcscat_s(ptr long wstr) MSVCRT_wcscat_s
@ cdecl wcschr(wstr long) ntdll.wcschr
@ cdecl wcscmp(wstr wstr) ntdll.wcscmp
@ cdecl wcscoll(wstr wstr) MSVCRT_wcscoll
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c
index 926a9cf..c2ab5c0 100644
--- a/dlls/msvcrt/tests/string.c
+++ b/dlls/msvcrt/tests/string.c
@@ -51,6 +51,7 @@ static int (*pstrcpy_s)(char *dst, size_t len, const char *src);
static int (*pstrcat_s)(char *dst, size_t len, const char *src);
static int (*p_mbsnbcpy_s)(unsigned char * dst, size_t size, const unsigned char * src, size_t count);
static int (*p_wcscpy_s)(wchar_t *wcDest, size_t size, const wchar_t *wcSrc);
+static int (*p_wcscat_s)(wchar_t *wcDest, size_t size, const wchar_t *wcSrc);
#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)
@@ -604,6 +605,41 @@ static void test_wcscpy_s(void)
ok(szDestShort[0] == 0, "szDestShort[0] not 0\n");
}
+static void test_wcscat_s(void)
+{
+ static const wchar_t szLongText[] = { 'T','h','i','s','A','L','o','n','g','s','t','r','i','n','g','o',0 };
+ static wchar_t szSrc[] = {'H','e','l','l','o',0};
+ int ret;
+ static wchar_t szDest[16];
+
+ if(!p_wcscat_s)
+ {
+ skip("wcscat_s not found\n");
+ return;
+ }
+
+ ret = p_wcscat_s(szDest, 16, szLongText);
+ ok(ret == ERANGE, "expected ERANGE got %d\n", ret);
+
+ ret = p_wcscat_s(NULL, 8, szSrc);
+ ok(ret == EINVAL, "expected EINVAL got %d\n", ret);
+
+ ret = p_wcscat_s(szDest, 0, szSrc);
+ ok(ret == EINVAL, "expected EINVAL got %d\n", ret);
+
+ ret = p_wcscat_s(szDest, 16, szSrc);
+ ok(ret == S_OK, "expected S_OK got %d\n", ret);
+
+ ret = p_wcscat_s(szDest, 16, szSrc);
+ ok(ret == S_OK, "expected S_OK got %d\n", ret);
+
+ ret = p_wcscat_s(szDest, 16, szSrc);
+ ok(ret == S_OK, "expected S_OK got %d\n", ret);
+
+ ret = p_wcscat_s(szDest, 16, szSrc);
+ ok(ret == ERANGE, "expected ERANGE got %d\n", ret);
+}
+
START_TEST(string)
{
char mem[100];
@@ -620,6 +656,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_wcscat_s = (void *)GetProcAddress( hMsvcrt,"wcscat_s" );
/* MSVCRT memcpy behaves like memmove for overlapping moves,
MFC42 CString::Insert seems to rely on that behaviour */
@@ -644,4 +681,5 @@ START_TEST(string)
test__mbsnbcpy_s();
test_wcscpy_s();
+ test_wcscat_s();
}
diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c
index c6f3e95..eb23f38 100644
--- a/dlls/msvcrt/wcs.c
+++ b/dlls/msvcrt/wcs.c
@@ -1009,3 +1009,27 @@ INT CDECL MSVCRT_wcscpy_s( MSVCRT_wchar_t* wcDest, MSVCRT_size_t numElement, con
return 0;
}
+/*********************************************************************
+ * wcscat_s (MSVCRT.@)
+ */
+INT CDECL MSVCRT_wcscat_s( MSVCRT_wchar_t* wcDest, MSVCRT_size_t numElement, const MSVCRT_wchar_t *wcSrc)
+{
+ INT nlenSrc = 0;
+ INT nlenDest = 0;
+
+ if(numElement == 0 || wcDest == NULL || wcSrc == NULL)
+ return MSVCRT_EINVAL;
+
+ nlenDest = strlenW(wcDest);
+ nlenSrc = strlenW(wcSrc);
+
+ if(nlenDest + nlenSrc > numElement-1)
+ return MSVCRT_ERANGE;
+
+ memcpy(&wcDest[nlenDest], wcSrc, nlenSrc*sizeof(wchar_t));
+
+ wcDest[nlenDest + nlenSrc] = 0;
+
+ return 0;
+}
+
--
1.5.4.1
--------------030401090000050208030408--
More information about the wine-patches
mailing list