[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