[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 |   45 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/msvcrt/wcs.c          |   24 +++++++++++++++++++++++
 3 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 8f8ccf4..b332451 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(wstr 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..8aa7136 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,48 @@ 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};
+    static wchar_t szComp1[] = {'H','e','l','l','o',0};
+    static wchar_t szComp2[] = {'H','e','l','l','o','H','e','l','l','o',0};
+    static wchar_t szComp3[] = {'H','e','l','l','o','H','e','l','l','o','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);
+    ok(lstrcmpW(szDest, szComp1) == 0, "szDest != szComp1\n");
+
+    ret = p_wcscat_s(szDest, 16, szSrc);
+    ok(ret == S_OK, "expected S_OK got %d\n", ret);
+    ok(lstrcmpW(szDest, szComp2) == 0, "szDest != szComp2\n");
+
+    ret = p_wcscat_s(szDest, 16, szSrc);
+    ok(ret == S_OK, "expected S_OK got %d\n", ret);
+    ok(lstrcmpW(szDest, szComp3) == 0, "szDest != szComp3\n");
+
+    ret = p_wcscat_s(szDest, 16, szSrc);
+    ok(ret == ERANGE, "expected ERANGE got %d\n", ret);
+    ok(lstrcmpW(szDest, szComp3) == 0, "szDest != szComp3\n");
+}
+
 START_TEST(string)
 {
     char mem[100];
@@ -620,6 +663,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 +688,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


--------------090904020609080706050204--




More information about the wine-patches mailing list