Andrew Nguyen : msvcrt: Implement _strlwr_s.

Alexandre Julliard julliard at winehq.org
Mon Oct 11 13:15:16 CDT 2010


Module: wine
Branch: master
Commit: 41ab8251266299e2d22551f9d333bcaa5cb1b85e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=41ab8251266299e2d22551f9d333bcaa5cb1b85e

Author: Andrew Nguyen <anguyen at codeweavers.com>
Date:   Mon Oct 11 05:25:23 2010 -0500

msvcrt: Implement _strlwr_s.

---

 dlls/msvcr100/msvcr100.spec |    2 +-
 dlls/msvcr80/msvcr80.spec   |    2 +-
 dlls/msvcr90/msvcr90.spec   |    2 +-
 dlls/msvcrt/msvcrt.spec     |    2 +-
 dlls/msvcrt/string.c        |   35 +++++++++++++++++++++++++
 dlls/msvcrt/tests/string.c  |   60 +++++++++++++++++++++++++++++++++++++++++++
 include/msvcrt/string.h     |    1 +
 7 files changed, 100 insertions(+), 4 deletions(-)

diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index eb8028d..60211ab 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -1142,7 +1142,7 @@
 @ stub _stricoll_l
 @ cdecl _strlwr(str) msvcrt._strlwr
 @ stub _strlwr_l
-@ stub _strlwr_s
+@ cdecl _strlwr_s(ptr long) msvcrt._strlwr_s
 @ stub _strlwr_s_l
 @ stub _strncoll
 @ stub _strncoll_l
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index b5be55f..4b0363f 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -996,7 +996,7 @@
 @ stub _stricoll_l
 @ cdecl _strlwr(str) msvcrt._strlwr
 @ stub _strlwr_l
-@ stub _strlwr_s
+@ cdecl _strlwr_s(ptr long) msvcrt._strlwr_s
 @ stub _strlwr_s_l
 @ stub _strncoll
 @ stub _strncoll_l
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index 5647b13..967db82 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -982,7 +982,7 @@
 @ stub _stricoll_l
 @ cdecl _strlwr(str) msvcrt._strlwr
 @ stub _strlwr_l
-@ stub _strlwr_s
+@ cdecl _strlwr_s(ptr long) msvcrt._strlwr_s
 @ stub _strlwr_s_l
 @ stub _strncoll
 @ stub _strncoll_l
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index b964724..e6a8670 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -917,7 +917,7 @@
 # stub _stricoll_l
 @ cdecl _strlwr(str) ntdll._strlwr
 # stub _strlwr_l
-# stub _strlwr_s
+@ cdecl _strlwr_s(ptr long)
 # stub _strlwr_s_l
 @ stub _strncoll #(str str long)
 # stub _strncoll_l
diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c
index 0b1beae..02bd0a5 100644
--- a/dlls/msvcrt/string.c
+++ b/dlls/msvcrt/string.c
@@ -51,6 +51,41 @@ char* CDECL _strdup(const char* str)
 }
 
 /*********************************************************************
+ *		_strlwr_s (MSVCRT.@)
+ */
+int CDECL _strlwr_s(char *str, MSVCRT_size_t len)
+{
+    char *ptr = str;
+
+    if (!str || !len)
+    {
+        *MSVCRT__errno() = MSVCRT_EINVAL;
+        return MSVCRT_EINVAL;
+    }
+
+    while (len && *ptr)
+    {
+        len--;
+        ptr++;
+    }
+
+    if (!len)
+    {
+        str[0] = '\0';
+        *MSVCRT__errno() = MSVCRT_EINVAL;
+        return MSVCRT_EINVAL;
+    }
+
+    while (*str)
+    {
+        *str = tolower(*str);
+        str++;
+    }
+
+    return 0;
+}
+
+/*********************************************************************
  *		_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 4955f75..a7d033a 100644
--- a/dlls/msvcrt/tests/string.c
+++ b/dlls/msvcrt/tests/string.c
@@ -60,6 +60,7 @@ static int (__cdecl *pwcstombs_s)(size_t*,char*,size_t,const wchar_t*,size_t);
 static int (__cdecl *pmbstowcs_s)(size_t*,wchar_t*,size_t,const char*,size_t);
 static errno_t (__cdecl *p_gcvt_s)(char*,size_t,double,int);
 static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,int);
+static errno_t (__cdecl *p_strlwr_s)(char*,size_t);
 static int *p__mb_cur_max;
 static unsigned char *p_mbctype;
 
@@ -1370,6 +1371,63 @@ static void test__itoa_s(void)
        buffer);
 }
 
+static void test__strlwr_s(void)
+{
+    errno_t ret;
+    char buffer[20];
+
+    if (!p_strlwr_s)
+    {
+        win_skip("Skipping _strlwr_s tests\n");
+        return;
+    }
+
+    errno = EBADF;
+    ret = p_strlwr_s(NULL, 0);
+    ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
+    ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
+
+    errno = EBADF;
+    ret = p_strlwr_s(NULL, sizeof(buffer));
+    ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
+    ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
+
+    errno = EBADF;
+    ret = p_strlwr_s(buffer, 0);
+    ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
+    ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
+
+    strcpy(buffer, "GoRrIsTeR");
+    errno = EBADF;
+    ret = p_strlwr_s(buffer, 5);
+    ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
+    ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
+    ok(!memcmp(buffer, "\0oRrIsTeR", sizeof("\0oRrIsTeR")),
+       "Expected the output buffer to be \"gorrIsTeR\"\n");
+
+    strcpy(buffer, "GoRrIsTeR");
+    errno = EBADF;
+    ret = p_strlwr_s(buffer, sizeof("GoRrIsTeR") - 1);
+    ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
+    ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
+    ok(!memcmp(buffer, "\0oRrIsTeR", sizeof("\0oRrIsTeR")),
+       "Expected the output buffer to be \"gorrIsTeR\"\n");
+
+    strcpy(buffer, "GoRrIsTeR");
+    ret = p_strlwr_s(buffer, sizeof("GoRrIsTeR"));
+    ok(ret == 0, "Expected _strlwr_s to return 0, got %d\n", ret);
+    ok(!strcmp(buffer, "gorrister"),
+       "Expected the output buffer to be \"gorrister\", got \"%s\"\n",
+       buffer);
+
+    memcpy(buffer, "GoRrIsTeR\0ELLEN", sizeof("GoRrIsTeR\0ELLEN"));
+    ret = p_strlwr_s(buffer, sizeof(buffer));
+    ok(ret == 0, "Expected _strlwr_s to return 0, got %d\n", ret);
+    ok(!memcmp(buffer, "gorrister\0ELLEN", sizeof("gorrister\0ELLEN")),
+       "Expected the output buffer to be \"gorrister\\0ELLEN\", got \"%s\"\n",
+       buffer);
+}
+
 START_TEST(string)
 {
     char mem[100];
@@ -1396,6 +1454,7 @@ START_TEST(string)
     pwcstombs_s = (void *)GetProcAddress(hMsvcrt, "wcstombs_s");
     p_gcvt_s = (void *)GetProcAddress(hMsvcrt, "_gcvt_s");
     p_itoa_s = (void *)GetProcAddress(hMsvcrt, "_itoa_s");
+    p_strlwr_s = (void *)GetProcAddress(hMsvcrt, "_strlwr_s");
 
     /* MSVCRT memcpy behaves like memmove for overlapping moves,
        MFC42 CString::Insert seems to rely on that behaviour */
@@ -1431,4 +1490,5 @@ START_TEST(string)
     test_mbstowcs();
     test_gcvt();
     test__itoa_s();
+    test__strlwr_s();
 }
diff --git a/include/msvcrt/string.h b/include/msvcrt/string.h
index 614fa85..8ab459b 100644
--- a/include/msvcrt/string.h
+++ b/include/msvcrt/string.h
@@ -48,6 +48,7 @@ errno_t __cdecl strerror_s(char*,size_t,int);
 int   __cdecl _stricmp(const char*,const char*);
 int   __cdecl _stricoll(const char*,const char*);
 char* __cdecl _strlwr(char*);
+errno_t __cdecl _strlwr_s(char*,size_t);
 int   __cdecl _strnicmp(const char*,const char*,size_t);
 char* __cdecl _strnset(char*,int,size_t);
 char* __cdecl _strrev(char*);




More information about the wine-cvs mailing list