[PATCH v3] msvcrt: Support .{O|A}CP locale string.

Paul Gofman pgofman at codeweavers.com
Thu Sep 17 11:24:10 CDT 2020


Used by Marvel's Avengers.

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
v3:
    - add .ACP support;
    - handle as a special case;
    - use LOCALE_RETURN_NUMBER.
Supersedes 192825, 192830.

 dlls/msvcrt/locale.c       | 19 ++++++++++++++++---
 dlls/msvcrt/tests/locale.c | 13 +++++++++++++
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c
index 9a10ceabc4e..b68281ed661 100644
--- a/dlls/msvcrt/locale.c
+++ b/dlls/msvcrt/locale.c
@@ -1114,6 +1114,7 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
     unsigned short cp[6] = { 0 };
     const char *locale_name[6] = { 0 };
     int locale_len[6] = { 0 };
+    DWORD codepage;
     char buf[256];
     BOOL sname;
 #if _MSVCR_VER >= 100
@@ -1132,14 +1133,26 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
     } else if(!locale[0]) {
         lcid[0] = GetSystemDefaultLCID();
         GetLocaleInfoA(lcid[0], LOCALE_IDEFAULTANSICODEPAGE
-                |LOCALE_NOUSEROVERRIDE, buf, sizeof(buf));
-        cp[0] = atoi(buf);
+                | LOCALE_NOUSEROVERRIDE | LOCALE_RETURN_NUMBER, (char *)&codepage, sizeof(codepage));
+        cp[0] = codepage;
 
         for(i=1; i<6; i++) {
             lcid[i] = lcid[0];
             cp[i] = cp[0];
         }
-    } else if (locale[0] == 'L' && locale[1] == 'C' && locale[2] == '_') {
+    } else if(locale[0] == '.' && (locale[1] == 'O' || locale[1] == 'A')
+            && locale[2] == 'C' && locale[3] == 'P' && !locale[4]) {
+        lcid[0] = GetUserDefaultLCID();
+        GetLocaleInfoA(lcid[0], (locale[1] == 'O' ? LOCALE_IDEFAULTCODEPAGE : LOCALE_IDEFAULTANSICODEPAGE)
+                | LOCALE_RETURN_NUMBER, (char *)&codepage, sizeof(codepage));
+        cp[0] = codepage;
+
+        for(i=1; i<6; i++) {
+            lcid[i] = lcid[0];
+            cp[i] = cp[0];
+        }
+    }
+    else if (locale[0] == 'L' && locale[1] == 'C' && locale[2] == '_') {
         const char *p;
 
         while(1) {
diff --git a/dlls/msvcrt/tests/locale.c b/dlls/msvcrt/tests/locale.c
index 08abac00bed..cc94b899d1f 100644
--- a/dlls/msvcrt/tests/locale.c
+++ b/dlls/msvcrt/tests/locale.c
@@ -45,6 +45,7 @@ static void test_setlocale(void)
         "LC_MONETARY=Greek_Greece.1253;LC_NUMERIC=Polish_Poland.1250;LC_TIME=C";
 
     char *ret, buf[100];
+    char *ptr;
 
     ret = setlocale(20, "C");
     ok(ret == NULL, "ret = %s\n", ret);
@@ -612,6 +613,18 @@ static void test_setlocale(void)
         ok(!strcmp(ret, buf), "ret = %s, expected %s\n", ret, buf);
     }
 
+    ret = setlocale(LC_ALL, ".OCP");
+    ok(ret != NULL, "ret == NULL\n");
+    ptr = strchr(ret, '.');
+    GetLocaleInfoA(GetUserDefaultLCID(), LOCALE_IDEFAULTCODEPAGE, buf, sizeof(buf));
+    ok(ptr && !strcmp(ptr + 1, buf), "ret %s, buf %s.\n", ret, buf);
+
+    ret = setlocale(LC_ALL, ".ACP");
+    ok(ret != NULL, "ret == NULL\n");
+    ptr = strchr(ret, '.');
+    GetLocaleInfoA(GetUserDefaultLCID(), LOCALE_IDEFAULTANSICODEPAGE, buf, sizeof(buf));
+    ok(ptr && !strcmp(ptr + 1, buf), "ret %s, buf %s.\n", ret, buf);
+
     ret = setlocale(LC_ALL, "English_United States.UTF8");
     ok(ret == NULL, "ret != NULL\n");
 
-- 
2.26.2




More information about the wine-devel mailing list