[PATCH] mlang: Only match the start of the name is allowed for Rfc1766ToLcid

Detlef Riekenberg wine.dev at web.de
Sat Jul 18 17:15:30 CDT 2009


---
 dlls/mlang/mlang.c       |   65 +++++++++++++++++++++++++++++++++++++++++-----
 dlls/mlang/tests/mlang.c |   60 +++++++++++++++++------------------------
 2 files changed, 83 insertions(+), 42 deletions(-)

diff --git a/dlls/mlang/mlang.c b/dlls/mlang/mlang.c
index c28e695..bb595cc 100644
--- a/dlls/mlang/mlang.c
+++ b/dlls/mlang/mlang.c
@@ -1214,10 +1214,14 @@ HRESULT WINAPI LcidToRfc1766W(
     return lcid_to_rfc1766W(lcid, pszRfc1766, nChar);
 }
 
-static HRESULT lcid_from_rfc1766(IEnumRfc1766 *iface, LCID *lcid, LPCWSTR rfc1766)
+static HRESULT lcid_from_rfc1766(IEnumRfc1766 *iface, LCID *lcid, LPCWSTR rfc1766, BOOL lazy)
 {
     RFC1766INFO info;
+    WCHAR shortname[MAX_RFC1766_NAME + 1];
     ULONG num;
+    LCID best_lcid = 0;
+    DWORD best_len = 0;
+    LPWSTR ptr;
 
     while (IEnumRfc1766_Next(iface, 1, &info, &num) == S_OK)
     {
@@ -1226,13 +1230,60 @@ static HRESULT lcid_from_rfc1766(IEnumRfc1766 *iface, LCID *lcid, LPCWSTR rfc176
             *lcid = info.lcid;
             return S_OK;
         }
-        if (strlenW(rfc1766) == 2 && !memcmp(info.wszRfc1766, rfc1766, 2 * sizeof(WCHAR)))
+
+        /* prefer specific name over the generic name when the supplied rfc1766 was not found */
+        if (lazy &&
+            lstrlenW(info.wszRfc1766) > best_len &&
+            !strncmpiW(rfc1766, info.wszRfc1766, lstrlenW(info.wszRfc1766)))
         {
-            *lcid = PRIMARYLANGID(info.lcid);
-            return S_OK;
+            best_len = lstrlenW(info.wszRfc1766);
+
+            /* en: SUBLANG_NEUTRAL, others (de, it, fr, ...): SUBLANG_DEFAULT */
+            if (PRIMARYLANGID(info.lcid) == LANG_ENGLISH)
+                best_lcid = LANG_ENGLISH;
+            else
+                best_lcid = info.lcid;
+
+        }
+
+        lstrcpynW(shortname, rfc1766, MAX_RFC1766_NAME);
+        shortname[MAX_RFC1766_NAME] = '\0';
+        ptr = strchrW(shortname, '-');
+        if (lazy && ptr) ptr[0] = 0;
+
+        /* accept language entries (de), when we only have language-country entries (de-de) */
+        if (strlenW(shortname) == 2 && !memcmp(info.wszRfc1766, shortname, 2 * sizeof(WCHAR)))
+        {
+            TRACE("guess lcid 0x%06x: %-9s / %s\n", info.lcid,
+                    debugstr_w(info.wszRfc1766), debugstr_w(info.wszLocaleName));
+
+            if (!best_lcid) {
+                best_len = 2;
+                /* ar, zh, en: SUBLANG_NEUTRAL, others (de, it, fr, ...): SUBLANG_DEFAULT */
+                switch PRIMARYLANGID(info.lcid)
+                {
+                    case LANG_ARABIC:
+                        best_lcid = LANG_ARABIC;
+                        break;
+                    case LANG_CHINESE:
+                        best_lcid = LANG_CHINESE;
+                        break;
+                    case LANG_ENGLISH:
+                        best_lcid = LANG_ENGLISH;
+                        break;
+                    default:
+                        best_lcid = info.lcid;
+                }
+            }
         }
     }
 
+    if (best_lcid) {
+        TRACE("=> using lcid: 0x%04x\n", best_lcid);
+
+        *lcid = best_lcid;
+        return S_OK;
+    }
     return E_FAIL;
 }
 
@@ -1250,7 +1301,7 @@ HRESULT WINAPI Rfc1766ToLcidW(LCID *pLocale, LPCWSTR pszRfc1766)
     if (FAILED(hr))
         return hr;
 
-    hr = lcid_from_rfc1766(enumrfc1766, pLocale, pszRfc1766);
+    hr = lcid_from_rfc1766(enumrfc1766, pLocale, pszRfc1766, TRUE);
     IEnumRfc1766_Release(enumrfc1766);
 
     return hr;
@@ -2296,7 +2347,7 @@ static HRESULT WINAPI fnIMultiLanguage_GetLcidFromRfc1766(
     if (FAILED(hr))
         return hr;
 
-    hr = lcid_from_rfc1766(rfc1766, pLocale, bstrRfc1766);
+    hr = lcid_from_rfc1766(rfc1766, pLocale, bstrRfc1766, FALSE);
 
     IEnumRfc1766_Release(rfc1766);
     return hr;
@@ -2883,7 +2934,7 @@ static HRESULT WINAPI fnIMultiLanguage2_GetLcidFromRfc1766(
     if (FAILED(hr))
         return hr;
 
-    hr = lcid_from_rfc1766(rfc1766, pLocale, bstrRfc1766);
+    hr = lcid_from_rfc1766(rfc1766, pLocale, bstrRfc1766, FALSE);
 
     IEnumRfc1766_Release(rfc1766);
     return hr;
diff --git a/dlls/mlang/tests/mlang.c b/dlls/mlang/tests/mlang.c
index 26e89a0..196a9d2 100644
--- a/dlls/mlang/tests/mlang.c
+++ b/dlls/mlang/tests/mlang.c
@@ -59,6 +59,7 @@ typedef struct lcid_tag_table {
     HRESULT hr;
     LCID broken_lcid;
     LPCSTR broken_rfc;
+    LCID lazy_lcid;
 } lcid_table_entry;
 
 /* en, ar and zh use SUBLANG_NEUTRAL for the rfc1766 name without the country
@@ -71,6 +72,13 @@ static const lcid_table_entry  lcid_table[] = {
     {"-",     -1,       E_FAIL},
     {"e-",    -1,       E_FAIL},
 
+    /* Rfc1766ToLcid() match also a partial string */
+    {"ms-bad",  -1,     E_FAIL, 0, NULL, 0x043e},
+    {"en-them", -1,     E_FAIL, 0, NULL, 9},
+    {"de-chm",  -1,     E_FAIL, 0, NULL, 0x0807},
+    {"de-CHM",  -1,     E_FAIL, 0, NULL, 0x0807},
+    {"english", -1,     E_FAIL},
+
     {"ar",    1,        S_OK},
     {"zh",    4,        S_OK},
 
@@ -1082,9 +1090,6 @@ static void test_GetLcidFromRfc1766(IMultiLanguage2 *iML2)
     DWORD i;
 
     static WCHAR en[] = { 'e','n',0 };
-    static WCHAR en_them[] = { 'e','n','-','t','h','e','m',0 };
-    static WCHAR english[] = { 'e','n','g','l','i','s','h',0 };
-
 
     for(i = 0; i < sizeof(lcid_table) / sizeof(lcid_table[0]); i++) {
         lcid = -1;
@@ -1107,31 +1112,6 @@ static void test_GetLcidFromRfc1766(IMultiLanguage2 *iML2)
 
     ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, NULL);
     ok(ret == E_INVALIDARG, "GetLcidFromRfc1766 returned: %08x\n", ret);
-
-    ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, en_them);
-    ok((ret == E_FAIL || ret == S_FALSE), "GetLcidFromRfc1766 returned: %08x\n", ret);
-    if (ret == S_FALSE)
-    {
-        BSTR rfcstr;
-        static WCHAR en[] = {'e','n',0};
-
-        ret = IMultiLanguage2_GetRfc1766FromLcid(iML2, lcid, &rfcstr);
-        ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
-        ok_w2("Expected \"%s\",  got \"%s\"n", en, rfcstr);
-    }
-
-    ret = IMultiLanguage2_GetLcidFromRfc1766(iML2, &lcid, english);
-    ok((ret == E_FAIL || ret == S_FALSE), "GetLcidFromRfc1766 returned: %08x\n", ret);
-    if (ret == S_FALSE)
-    {
-        BSTR rfcstr;
-        static WCHAR en[] = {'e','n',0};
-
-        ret = IMultiLanguage2_GetRfc1766FromLcid(iML2, lcid, &rfcstr);
-        ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
-        ok_w2("Expected \"%s\",  got \"%s\"n", en, rfcstr);
-    }
-
 }
 
 static void test_Rfc1766ToLcid(void)
@@ -1144,14 +1124,24 @@ static void test_Rfc1766ToLcid(void)
         lcid = -1;
         ret = pRfc1766ToLcidA(&lcid, lcid_table[i].rfc1766);
 
-        /* IE <6.0 guess 0x412 (ko) from "kok" */
-        ok( (ret == lcid_table[i].hr) ||
-            broken(lcid_table[i].broken_lcid && (ret == S_FALSE)),
-            "#%02d: HRESULT 0x%x (expected 0x%x)\n", i, ret, lcid_table[i].hr);
+        if (lcid_table[i].lazy_lcid) {
+            ok(ret == S_OK || ret == S_FALSE,
+                "#%02d: HRESULT 0x%x (expected S_OK or S_FALSE)\n", i, ret);
 
-        ok( (lcid == lcid_table[i].lcid) ||
-            broken(lcid == lcid_table[i].broken_lcid),  /* IE <6.0 */
-            "#%02d: got LCID 0x%x (expected 0x%x)\n", i, lcid, lcid_table[i].lcid);
+            ok( (lcid == lcid_table[i].lazy_lcid),
+                "#%02d: got LCID 0x%x (expected 0x%x)\n", i, lcid, lcid_table[i].lazy_lcid);
+        }
+        else
+        {
+            /* IE <6.0 guess 0x412 (ko) from "kok" */
+            ok( (ret == lcid_table[i].hr) ||
+                broken(lcid_table[i].broken_lcid && (ret == S_FALSE)),
+                "#%02d: HRESULT 0x%x (expected 0x%x)\n", i, ret, lcid_table[i].hr);
+
+            ok( (lcid == lcid_table[i].lcid) ||
+                broken(lcid == lcid_table[i].broken_lcid),  /* IE <6.0 */
+                "#%02d: got LCID 0x%x (expected 0x%x)\n", i, lcid, lcid_table[i].lcid);
+        }
     }
 
     ret = pRfc1766ToLcidA(&lcid, NULL);
-- 
1.5.4.3


--=-4Y593uzNCInevruqtR4+--




More information about the wine-patches mailing list