[PATCH] msvcrt: Optimize _strlwr implementation in C locale.

Gijs Vermeulen gijsvrm at codeweavers.com
Wed Dec 4 03:04:46 CST 2019


Tests by Ambrož Bizjak.

Signed-off-by: Gijs Vermeulen <gijsvrm at codeweavers.com>
---
 dlls/msvcrt/string.c       | 24 +++++++++++++++++++++---
 dlls/msvcrt/tests/string.c |  8 ++++++++
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c
index fa5f7022c1..b78d93a917 100644
--- a/dlls/msvcrt/string.c
+++ b/dlls/msvcrt/string.c
@@ -56,6 +56,7 @@ char* CDECL MSVCRT__strdup(const char* str)
  */
 int CDECL MSVCRT__strlwr_s_l(char *str, MSVCRT_size_t len, MSVCRT__locale_t locale)
 {
+    MSVCRT_pthreadlocinfo locinfo;
     char *ptr = str;
 
     if (!str || !len)
@@ -77,10 +78,27 @@ int CDECL MSVCRT__strlwr_s_l(char *str, MSVCRT_size_t len, MSVCRT__locale_t loca
         return MSVCRT_EINVAL;
     }
 
-    while (*str)
+    if(!locale)
+        locinfo = get_locinfo();
+    else
+        locinfo = locale->locinfo;
+
+    if(!locinfo->lc_handle[MSVCRT_LC_CTYPE])
     {
-        *str = MSVCRT__tolower_l((unsigned char)*str, locale);
-        str++;
+        while (*str)
+        {
+            if (*str >= 'A' && *str <= 'Z')
+                *str -= 'A' - 'a';
+            str++;
+        }
+    }
+    else
+    {
+        while (*str)
+        {
+            *str = MSVCRT__tolower_l((unsigned char)*str, locale);
+            str++;
+        }
     }
 
     return 0;
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c
index d14c7f009c..f4c4657791 100644
--- a/dlls/msvcrt/tests/string.c
+++ b/dlls/msvcrt/tests/string.c
@@ -2411,6 +2411,9 @@ static void test__strlwr_s(void)
     ok(!memcmp(buffer, "gorrister\0ELLEN", sizeof("gorrister\0ELLEN")),
        "Expected the output buffer to be \"gorrister\\0ELLEN\", got \"%s\"\n",
        buffer);
+
+    ret = p_strlwr_s((char *)"already_lowercase", sizeof("already_lowercase"));
+    ok(ret == 0, "Expected _strlwr_s to return 0, got %d\n", ret);
 }
 
 static void test_wcsncat_s(void)
@@ -3596,6 +3599,7 @@ static void test__memicmp_l(void)
 static void test__strupr(void)
 {
     const char str[] = "123";
+    const char *const_p;
     char str2[4];
     char *mem, *p;
     DWORD prot;
@@ -3614,6 +3618,10 @@ static void test__strupr(void)
     ok(p == mem, "_strupr returned %p\n", p);
     ok(!strcmp(mem, "123"), "mem = %s\n", mem);
 
+    const_p = "ALREADY_UPPERCASE";
+    p = _strupr((char *)const_p);
+    ok(p == const_p, "_strupr returned %p\n", p);
+
     if(!setlocale(LC_ALL, "english")) {
         VirtualFree(mem, sizeof(str), MEM_RELEASE);
         win_skip("English locale _strupr tests\n");
-- 
2.24.0




More information about the wine-devel mailing list