From: Daniel Lehman Subject: [PATCH v2 2/4] kernel32: Handle Turkish/Azeri I. Message-Id: <20190213083808.6747-2-dlehman25@gmail.com> Date: Wed, 13 Feb 2019 00:38:06 -0800 In-Reply-To: <20190213083808.6747-1-dlehman25@gmail.com> References: <20190213083808.6747-1-dlehman25@gmail.com> Signed-off-by: Daniel Lehman --- dlls/kernel32/locale.c | 25 ++++++++++++++++++-- dlls/kernel32/tests/locale.c | 44 ++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c index 9f539ddd53..742aae1916 100644 --- a/dlls/kernel32/locale.c +++ b/dlls/kernel32/locale.c @@ -3433,6 +3433,17 @@ static INT map_to_halfwidth(WCHAR c, LPWSTR dst, INT dstlen) return 1; } +static inline BOOL uses_dotted_i(const WCHAR *locale) +{ + static const WCHAR azCyrlazW[] = { 'a','z','-','C','y','r','l','-','a','z',0 }; + static const WCHAR azLatnazW[] = { 'a','z','-','L','a','t','n','-','a','z',0 }; + static const WCHAR trTRW[] = {'t','r','-','T','R',0}; + + return !strcmpiW(locale, trTRW) || + !strcmpiW(locale, azLatnazW) || + !strcmpiW(locale, azCyrlazW); +} + /************************************************************************* * LCMapStringEx (KERNEL32.@) * @@ -3653,7 +3664,12 @@ INT WINAPI LCMapStringEx(LPCWSTR name, DWORD flags, LPCWSTR src, INT srclen, LPW { for (len = dstlen, dst_ptr = dst; srclen && len; src++, srclen--) { - *dst_ptr++ = toupperW(*src); + if ((*src == 'i') && (flags & LCMAP_LINGUISTIC_CASING) && uses_dotted_i(name)) + *dst_ptr++ = 0x0130; + else if ((*src == 0x0131) && !(flags & LCMAP_LINGUISTIC_CASING)) + *dst_ptr++ = *src; + else + *dst_ptr++ = toupperW(*src); len--; } } @@ -3661,7 +3677,12 @@ INT WINAPI LCMapStringEx(LPCWSTR name, DWORD flags, LPCWSTR src, INT srclen, LPW { for (len = dstlen, dst_ptr = dst; srclen && len; src++, srclen--) { - *dst_ptr++ = tolowerW(*src); + if ((*src == 'I') && (flags & LCMAP_LINGUISTIC_CASING) && uses_dotted_i(name)) + *dst_ptr++ = 0x0131; + else if ((*src == 0x0130) && !(flags & LCMAP_LINGUISTIC_CASING)) + *dst_ptr++ = *src; + else + *dst_ptr++ = tolowerW(*src); len--; } } diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index 5b7b5fe1dc..9ca7f5f5e3 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -5796,8 +5796,6 @@ static void test_SpecialCasing(void) WCHAR ch; WCHAR exp; /* 0 if self */ WCHAR exp_ling; /* 0 if exp */ - BOOL todo; - BOOL todo_ling; } tests[] = { {deDEW, LCMAP_UPPERCASE, 0x00DF}, /* LATIN SMALL LETTER SHARP S */ @@ -5906,29 +5904,29 @@ static void test_SpecialCasing(void) {enUSW, LCMAP_UPPERCASE, 'i', 'I'}, /* LATIN SMALL LETTER I */ {ltLTW, LCMAP_UPPERCASE, 'i', 'I'}, /* LATIN SMALL LETTER I */ - {trTRW, LCMAP_UPPERCASE, 'i', 'I', 0x0130, FALSE, TRUE}, /* LATIN SMALL LETTER I */ - {TRTRW, LCMAP_UPPERCASE, 'i', 'I', 0x0130, FALSE, TRUE}, /* LATIN SMALL LETTER I */ - {azCyrlazW, LCMAP_UPPERCASE, 'i', 'I', 0x0130, FALSE, TRUE}, /* LATIN SMALL LETTER I */ - {azLatnazW, LCMAP_UPPERCASE, 'i', 'I', 0x0130, FALSE, TRUE}, /* LATIN SMALL LETTER I */ + {trTRW, LCMAP_UPPERCASE, 'i', 'I', 0x0130}, /* LATIN SMALL LETTER I */ + {TRTRW, LCMAP_UPPERCASE, 'i', 'I', 0x0130}, /* LATIN SMALL LETTER I */ + {azCyrlazW, LCMAP_UPPERCASE, 'i', 'I', 0x0130}, /* LATIN SMALL LETTER I */ + {azLatnazW, LCMAP_UPPERCASE, 'i', 'I', 0x0130}, /* LATIN SMALL LETTER I */ {enUSW, LCMAP_LOWERCASE, 'I', 'i'}, /* LATIN CAPITAL LETTER I */ {ltLTW, LCMAP_LOWERCASE, 'I', 'i'}, /* LATIN CAPITAL LETTER I */ - {trTRW, LCMAP_LOWERCASE, 'I', 'i', 0x0131, FALSE, TRUE}, /* LATIN CAPITAL LETTER I */ - {TRTRW, LCMAP_LOWERCASE, 'I', 'i', 0x0131, FALSE, TRUE}, /* LATIN CAPITAL LETTER I */ - {azCyrlazW, LCMAP_LOWERCASE, 'I', 'i', 0x0131, FALSE, TRUE}, /* LATIN CAPITAL LETTER I */ - {azLatnazW, LCMAP_LOWERCASE, 'I', 'i', 0x0131, FALSE, TRUE}, /* LATIN CAPITAL LETTER I */ - - {enUSW, LCMAP_LOWERCASE, 0x0130,0,'i', TRUE}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ - {trTRW, LCMAP_LOWERCASE, 0x0130,0,'i', TRUE}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ - {TRTRW, LCMAP_LOWERCASE, 0x0130,0,'i', TRUE}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ - {azCyrlazW, LCMAP_LOWERCASE, 0x0130,0,'i', TRUE}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ - {azLatnazW, LCMAP_LOWERCASE, 0x0130,0,'i', TRUE}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ - - {enUSW, LCMAP_UPPERCASE, 0x0131,0,'I', TRUE}, /* LATIN SMALL LETTER DOTLESS I */ - {trTRW, LCMAP_UPPERCASE, 0x0131,0,'I', TRUE}, /* LATIN SMALL LETTER DOTLESS I */ - {TRTRW, LCMAP_UPPERCASE, 0x0131,0,'I', TRUE}, /* LATIN SMALL LETTER DOTLESS I */ - {azCyrlazW, LCMAP_UPPERCASE, 0x0131,0,'I', TRUE}, /* LATIN SMALL LETTER DOTLESS I */ - {azLatnazW, LCMAP_UPPERCASE, 0x0131,0,'I', TRUE}, /* LATIN SMALL LETTER DOTLESS I */ + {trTRW, LCMAP_LOWERCASE, 'I', 'i', 0x0131}, /* LATIN CAPITAL LETTER I */ + {TRTRW, LCMAP_LOWERCASE, 'I', 'i', 0x0131}, /* LATIN CAPITAL LETTER I */ + {azCyrlazW, LCMAP_LOWERCASE, 'I', 'i', 0x0131}, /* LATIN CAPITAL LETTER I */ + {azLatnazW, LCMAP_LOWERCASE, 'I', 'i', 0x0131}, /* LATIN CAPITAL LETTER I */ + + {enUSW, LCMAP_LOWERCASE, 0x0130,0,'i'}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ + {trTRW, LCMAP_LOWERCASE, 0x0130,0,'i'}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ + {TRTRW, LCMAP_LOWERCASE, 0x0130,0,'i'}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ + {azCyrlazW, LCMAP_LOWERCASE, 0x0130,0,'i'}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ + {azLatnazW, LCMAP_LOWERCASE, 0x0130,0,'i'}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ + + {enUSW, LCMAP_UPPERCASE, 0x0131,0,'I'}, /* LATIN SMALL LETTER DOTLESS I */ + {trTRW, LCMAP_UPPERCASE, 0x0131,0,'I'}, /* LATIN SMALL LETTER DOTLESS I */ + {TRTRW, LCMAP_UPPERCASE, 0x0131,0,'I'}, /* LATIN SMALL LETTER DOTLESS I */ + {azCyrlazW, LCMAP_UPPERCASE, 0x0131,0,'I'}, /* LATIN SMALL LETTER DOTLESS I */ + {azLatnazW, LCMAP_UPPERCASE, 0x0131,0,'I'}, /* LATIN SMALL LETTER DOTLESS I */ }; if (!pLCMapStringEx) @@ -5944,7 +5942,6 @@ static void test_SpecialCasing(void) ok(ret == 1, "expected 1, got %d for %04x for %s\n", ret, tests[i].ch, wine_dbgstr_w(tests[i].lang)); exp = tests[i].exp ? tests[i].exp : tests[i].ch; - todo_wine_if(tests[i].todo) ok(buffer[0] == exp || broken(buffer[0] != exp), "expected %04x, got %04x for %04x for %s\n", exp, buffer[0], tests[i].ch, wine_dbgstr_w(tests[i].lang)); @@ -5955,7 +5952,6 @@ static void test_SpecialCasing(void) ok(ret == 1, "expected 1, got %d for %04x for %s\n", ret, tests[i].ch, wine_dbgstr_w(tests[i].lang)); exp = tests[i].exp_ling ? tests[i].exp_ling : exp; - todo_wine_if(tests[i].todo_ling) ok(buffer[0] == exp || broken(buffer[0] != exp), "expected %04x, got %04x for %04x for %s\n", exp, buffer[0], tests[i].ch, wine_dbgstr_w(tests[i].lang)); -- 2.17.1