Signed-off-by: Daniel Lehman dlehman25@gmail.com --- v2: - call LCMapString - rearrange and squash commits v3: - add static const to all test cases --- dlls/kernel32/tests/locale.c | 186 +++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+)
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index 126b08cc57..2627fc5de8 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -5784,6 +5784,191 @@ todo_wine_if(ptest->todo[i]) } }
+static void test_SpecialCasing(void) +{ + int ret, i; + WCHAR exp, buffer[8]; + 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 deDEW[] = {'d','e','-','D','E',0}; + static const WCHAR elGRW[] = {'e','l','-','G','R',0}; + static const WCHAR enUSW[] = {'e','n','-','U','S',0}; + static const WCHAR hyAMW[] = {'h','y','-','A','M',0}; + static const WCHAR ltLTW[] = {'l','t','-','L','T',0}; + static const WCHAR trTRW[] = {'t','r','-','T','R',0}; + static const WCHAR TRTRW[] = {'T','R','-','T','R',0}; + static const struct test { + const WCHAR *lang; + DWORD flags; + 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 */ + + {enUSW, LCMAP_UPPERCASE, 0xFB00}, /* LATIN SMALL LIGATURE FF */ + {enUSW, LCMAP_UPPERCASE, 0xFB01}, /* LATIN SMALL LIGATURE FI */ + {enUSW, LCMAP_UPPERCASE, 0xFB02}, /* LATIN SMALL LIGATURE FL */ + {enUSW, LCMAP_UPPERCASE, 0xFB03}, /* LATIN SMALL LIGATURE FFI */ + {enUSW, LCMAP_UPPERCASE, 0xFB04}, /* LATIN SMALL LIGATURE FFL */ + {enUSW, LCMAP_UPPERCASE, 0xFB05}, /* LATIN SMALL LIGATURE LONG S T */ + {enUSW, LCMAP_UPPERCASE, 0xFB06}, /* LATIN SMALL LIGATURE ST */ + + {hyAMW, LCMAP_UPPERCASE, 0x0587}, /* ARMENIAN SMALL LIGATURE ECH YIWN */ + {hyAMW, LCMAP_UPPERCASE, 0xFB13}, /* ARMENIAN SMALL LIGATURE MEN NOW */ + {hyAMW, LCMAP_UPPERCASE, 0xFB14}, /* ARMENIAN SMALL LIGATURE MEN ECH */ + {hyAMW, LCMAP_UPPERCASE, 0xFB15}, /* ARMENIAN SMALL LIGATURE MEN INI */ + {hyAMW, LCMAP_UPPERCASE, 0xFB16}, /* ARMENIAN SMALL LIGATURE VEW NOW */ + {hyAMW, LCMAP_UPPERCASE, 0xFB17}, /* ARMENIAN SMALL LIGATURE MEN XEH */ + + {enUSW, LCMAP_UPPERCASE, 0x0149}, /* LATIN SMALL LETTER N PRECEDED BY APOSTROPHE */ + {elGRW, LCMAP_UPPERCASE, 0x0390}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ + {elGRW, LCMAP_UPPERCASE, 0x03B0}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ + {enUSW, LCMAP_UPPERCASE, 0x01F0}, /* LATIN SMALL LETTER J WITH CARON */ + {enUSW, LCMAP_UPPERCASE, 0x1E96}, /* LATIN SMALL LETTER H WITH LINE BELOW */ + {enUSW, LCMAP_UPPERCASE, 0x1E97}, /* LATIN SMALL LETTER T WITH DIAERESIS */ + {enUSW, LCMAP_UPPERCASE, 0x1E98}, /* LATIN SMALL LETTER W WITH RING ABOVE */ + {enUSW, LCMAP_UPPERCASE, 0x1E99}, /* LATIN SMALL LETTER Y WITH RING ABOVE */ + {enUSW, LCMAP_UPPERCASE, 0x1E9A}, /* LATIN SMALL LETTER A WITH RIGHT HALF RING */ + {elGRW, LCMAP_UPPERCASE, 0x1F50}, /* GREEK SMALL LETTER UPSILON WITH PSILI */ + {elGRW, LCMAP_UPPERCASE, 0x1F52}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA */ + {elGRW, LCMAP_UPPERCASE, 0x1F54}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA */ + {elGRW, LCMAP_UPPERCASE, 0x1F56}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FB6}, /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FC6}, /* GREEK SMALL LETTER ETA WITH PERISPOMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FD2}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA */ + {elGRW, LCMAP_UPPERCASE, 0x1FD3}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA */ + {elGRW, LCMAP_UPPERCASE, 0x1FD6}, /* GREEK SMALL LETTER IOTA WITH PERISPOMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FD7}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FE2}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA */ + {elGRW, LCMAP_UPPERCASE, 0x1FE3}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA */ + {elGRW, LCMAP_UPPERCASE, 0x1FE4}, /* GREEK SMALL LETTER RHO WITH PSILI */ + {elGRW, LCMAP_UPPERCASE, 0x1FE6}, /* GREEK SMALL LETTER UPSILON WITH PERISPOMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FE7}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FF6}, /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI */ + + {elGRW, LCMAP_UPPERCASE, 0x1F80,0x1F88}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F81,0x1F89}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F82,0x1F8A}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F83,0x1F8B}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F84,0x1F8C}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F85,0x1F8D}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F86,0x1F8E}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F87,0x1F8F}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */ + + {elGRW, LCMAP_LOWERCASE, 0x1F88,0x1F80}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1F89,0x1F81}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1F8A,0x1F82}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1F8B,0x1F83}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1F8C,0x1F84}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1F8D,0x1F85}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1F8E,0x1F86}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1F8F,0x1F87}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */ + + {elGRW, LCMAP_UPPERCASE, 0x1F90,0x1F98}, /* GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F91,0x1F99}, /* GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F92,0x1F9A}, /* GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F93,0x1F9B}, /* GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F94,0x1F9C}, /* GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F95,0x1F9D}, /* GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F96,0x1F9E}, /* GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1F97,0x1F9F}, /* GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */ + + {elGRW, LCMAP_LOWERCASE, 0x1FA8,0x1FA0}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1FA9,0x1FA1}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1FAA,0x1FA2}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1FAB,0x1FA3}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1FAC,0x1FA4}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1FAD,0x1FA5}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1FAE,0x1FA6}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1FAF,0x1FA7}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */ + + {elGRW, LCMAP_UPPERCASE, 0x1FB3,0x1FBC}, /* GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1FBC,0x1FB3}, /* GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FC3,0x1FCC}, /* GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1FCC,0x1FC3}, /* GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FF3,0x1FFC}, /* GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI */ + {elGRW, LCMAP_LOWERCASE, 0x1FFC,0x1FF3}, /* GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI */ + + {elGRW, LCMAP_UPPERCASE, 0x1FB2}, /* GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FB4}, /* GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FC2}, /* GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FC4}, /* GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FF2}, /* GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FF4}, /* GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI */ + + {elGRW, LCMAP_UPPERCASE, 0x1FB7}, /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FC7}, /* GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI */ + {elGRW, LCMAP_UPPERCASE, 0x1FF7}, /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI */ + + {elGRW, LCMAP_LOWERCASE, 0x03A3,0x03C3}, /* GREEK CAPITAL LETTER SIGMA */ + + {ltLTW, LCMAP_LOWERCASE, 'J','j'}, /* LATIN CAPITAL LETTER J */ + {ltLTW, LCMAP_LOWERCASE, 0x012E,0x012F}, /* LATIN CAPITAL LETTER I WITH OGONEK */ + {ltLTW, LCMAP_LOWERCASE, 0x00CC,0x00EC}, /* LATIN CAPITAL LETTER I WITH GRAVE */ + {ltLTW, LCMAP_LOWERCASE, 0x00CD,0x00ED}, /* LATIN CAPITAL LETTER I WITH ACUTE */ + {ltLTW, LCMAP_LOWERCASE, 0x0128,0x0129}, /* LATIN CAPITAL LETTER I WITH TILDE */ + + {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 */ + + {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 */ + }; + + if (!pLCMapStringEx) + { + win_skip("LCMapStringEx not available\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(tests); i++) { + memset(buffer, 0, sizeof(buffer)); + ret = pLCMapStringEx(tests[i].lang, tests[i].flags, + &tests[i].ch, 1, buffer, ARRAY_SIZE(buffer), NULL, NULL, 0); + 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)); + + memset(buffer, 0, sizeof(buffer)); + ret = pLCMapStringEx(tests[i].lang, tests[i].flags|LCMAP_LINGUISTIC_CASING, + &tests[i].ch, 1, buffer, ARRAY_SIZE(buffer), NULL, NULL, 0); + 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)); + } +} + START_TEST(locale) { InitFunctionPointers(); @@ -5834,6 +6019,7 @@ START_TEST(locale) test_FindStringOrdinal(); test_SetThreadUILanguage(); test_NormalizeString(); + test_SpecialCasing(); /* this requires collation table patch to make it MS compatible */ if (0) test_sorting(); }
Signed-off-by: Daniel Lehman dlehman25@gmail.com --- 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 eedb0bea73..e5cf1ba898 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 2627fc5de8..7e63c264b8 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -5803,8 +5803,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 */
@@ -5913,29 +5911,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) @@ -5951,7 +5949,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)); @@ -5962,7 +5959,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));
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=47626
Your paranoid android.
=== debian9 (32 bit WoW report) ===
kernel32: change.c:318: Test failed: should be ready
Signed-off-by: Daniel Lehman dlehman25@gmail.com --- dlls/msvcrt/tests/string.c | 215 +++++++++++++++++++++++++++++++++++++ dlls/msvcrt/wcs.c | 10 +- 2 files changed, 223 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index d0cc51bc4a..c8642ec53f 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -3678,6 +3678,220 @@ static void test_C_locale(void) } }
+static void test_SpecialCasing(void) +{ + int i; + wint_t ret, exp; + _locale_t locale; + struct test { + const char *lang; + wint_t ch; + wint_t exp; /* 0 if self */ + }; + + static const struct test ucases[] = { + {"English", 'I', 'i'}, /* LATIN CAPITAL LETTER I */ + {"English", 0x0130}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ + + {"Turkish", 'I', 'i'}, /* LATIN CAPITAL LETTER I */ + {"Turkish", 0x0130}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ + + {"Greek", 0x1F88, 0x1F80}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI */ + {"Greek", 0x1F89, 0x1F81}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F8A, 0x1F82}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F8B, 0x1F83}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F8C, 0x1F84}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F8D, 0x1F85}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F8E, 0x1F86}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */ + {"Greek", 0x1F8F, 0x1F87}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */ + + {"Greek", 0x1F98, 0x1F90}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI */ + {"Greek", 0x1F99, 0x1F91}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F9A, 0x1F92}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F9B, 0x1F93}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F9C, 0x1F94}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F9D, 0x1F95}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F9E, 0x1F96}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */ + {"Greek", 0x1F9F, 0x1F97}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */ + + {"Greek", 0x1FA8, 0x1FA0}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI */ + {"Greek", 0x1FA9, 0x1FA1}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI */ + {"Greek", 0x1FAA, 0x1FA2}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI */ + {"Greek", 0x1FAB, 0x1FA3}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI */ + {"Greek", 0x1FAC, 0x1FA4}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI */ + {"Greek", 0x1FAD, 0x1FA5}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI */ + {"Greek", 0x1FAE, 0x1FA6}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */ + {"Greek", 0x1FAF, 0x1FA7}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */ + + {"Greek", 0x1FBC, 0x1FB3}, /* GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI */ + {"Greek", 0x1FCC, 0x1FC3}, /* GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI */ + {"Greek", 0x1FFC, 0x1FF3}, /* GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI */ + }; + static const struct test lcases[] = { + {"English", 'i', 'I'}, /* LATIN SMALL LETTER I */ + {"English", 0x0131}, /* LATIN SMALL LETTER DOTLESS I */ + + {"Turkish", 'i', 'I'}, /* LATIN SMALL LETTER I */ + {"Turkish", 0x0131}, /* LATIN SMALL LETTER DOTLESS I */ + + {"German", 0x00DF}, /* LATIN SMALL LETTER SHARP S */ + + {"English", 0xFB00}, /* LATIN SMALL LIGATURE FF */ + {"English", 0xFB01}, /* LATIN SMALL LIGATURE FI */ + {"English", 0xFB02}, /* LATIN SMALL LIGATURE FL */ + {"English", 0xFB03}, /* LATIN SMALL LIGATURE FFI */ + {"English", 0xFB04}, /* LATIN SMALL LIGATURE FFL */ + {"English", 0xFB05}, /* LATIN SMALL LIGATURE LONG ST */ + {"English", 0xFB06}, /* LATIN SMALL LIGATURE ST */ + + {"Armenian", 0x0587}, /* ARMENIAN SMALL LIGATURE ECH YIWN */ + {"Armenian", 0xFB13}, /* ARMENIAN SMALL LIGATURE MEN NOW */ + {"Armenian", 0xFB14}, /* ARMENIAN SMALL LIGATURE MEN ECH */ + {"Armenian", 0xFB15}, /* ARMENIAN SMALL LIGATURE MEN INI */ + {"Armenian", 0xFB16}, /* ARMENIAN SMALL LIGATURE VEW NOW */ + {"Armenian", 0xFB17}, /* ARMENIAN SMALL LIGATURE MEN XEH */ + + {"Armenian", 0x0587}, /* ARMENIAN SMALL LIGATURE ECH YIWN */ + {"Armenian", 0xFB13}, /* ARMENIAN SMALL LIGATURE MEN NOW */ + {"Armenian", 0xFB14}, /* ARMENIAN SMALL LIGATURE MEN ECH */ + {"Armenian", 0xFB15}, /* ARMENIAN SMALL LIGATURE MEN INI */ + {"Armenian", 0xFB16}, /* ARMENIAN SMALL LIGATURE VEW NOW */ + {"Armenian", 0xFB17}, /* ARMENIAN SMALL LIGATURE MEN XEH */ + + {"English", 0x0149}, /* LATIN SMALL LETTER N PRECEDED BY APOSTROPHE */ + {"Greek", 0x0390}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ + {"Greek", 0x03B0}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ + {"English", 0x01F0}, /* LATIN SMALL LETTER J WITH CARON */ + {"English", 0x1E96}, /* LATIN SMALL LETTER H WITH LINE BELOW */ + {"English", 0x1E97}, /* LATIN SMALL LETTER T WITH DIAERESIS */ + {"English", 0x1E98}, /* LATIN SMALL LETTER W WITH RING ABOVE */ + {"English", 0x1E99}, /* LATIN SMALL LETTER Y WITH RING ABOVE */ + {"English", 0x1E9A}, /* LATIN SMALL LETTER A WITH RIGHT HALF RING */ + {"Greek", 0x1F50}, /* GREEK SMALL LETTER UPSILON WITH PSILI */ + {"Greek", 0x1F52}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA */ + {"Greek", 0x1F54}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA */ + {"Greek", 0x1F56}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI */ + {"Greek", 0x1FB6}, /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI */ + {"Greek", 0x1FC6}, /* GREEK SMALL LETTER ETA WITH PERISPOMENI */ + {"Greek", 0x1FD2}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA */ + {"Greek", 0x1FD3}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA */ + {"Greek", 0x1FD6}, /* GREEK SMALL LETTER IOTA WITH PERISPOMENI */ + {"Greek", 0x1FD7}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI */ + {"Greek", 0x1FE2}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA */ + {"Greek", 0x1FE3}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA */ + {"Greek", 0x1FE4}, /* GREEK SMALL LETTER RHO WITH PSILI */ + {"Greek", 0x1FE6}, /* GREEK SMALL LETTER UPSILON WITH PERISPOMENI */ + {"Greek", 0x1FE7}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI */ + {"Greek", 0x1FF6}, /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI */ + + {"Greek", 0x1F80, 0x1F88}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI */ + {"Greek", 0x1F81, 0x1F89}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F82, 0x1F8A}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F83, 0x1F8B}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F84, 0x1F8C}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F85, 0x1F8D}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F86, 0x1F8E}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */ + {"Greek", 0x1F87, 0x1F8F}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */ + + {"Greek", 0x1F90, 0x1F98}, /* GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI */ + {"Greek", 0x1F91, 0x1F99}, /* GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F92, 0x1F9A}, /* GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F93, 0x1F9B}, /* GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F94, 0x1F9C}, /* GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F95, 0x1F9D}, /* GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F96, 0x1F9E}, /* GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */ + {"Greek", 0x1F97, 0x1F9F}, /* GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */ + + {"Greek", 0x1FA0, 0x1FA8}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI */ + {"Greek", 0x1FA1, 0x1FA9}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FA2, 0x1FAA}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FA3, 0x1FAB}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FA4, 0x1FAC}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FA5, 0x1FAD}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FA6, 0x1FAE}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */ + {"Greek", 0x1FA7, 0x1FAF}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */ + + {"Greek", 0x1FB3, 0x1FBC}, /* GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI */ + {"Greek", 0x1FC3, 0x1FCC}, /* GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI */ + {"Greek", 0x1FF3, 0x1FFC}, /* GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI */ + + {"Greek", 0x1FB2}, /* GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FB4}, /* GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FC2}, /* GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FC4}, /* GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FF2}, /* GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FF4}, /* GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI */ + + {"Greek", 0x1FB7}, /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI */ + {"Greek", 0x1FC7}, /* GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI */ + {"Greek", 0x1FF7}, /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI */ + }; + + for (i = 0; i < ARRAY_SIZE(ucases); i++) { + if (!setlocale(LC_ALL, ucases[i].lang)) { + win_skip("skipping special case tests for %s\n", ucases[i].lang); + continue; + } + + ret = p_towlower(ucases[i].ch); + exp = ucases[i].exp ? ucases[i].exp : ucases[i].ch; + ok(ret == exp || broken(ret != exp), /* WinXP/2k3/Vista/2k8 */ + "expected lowercase %x, got %x for locale %s\n", + exp, ret, ucases[i].lang); + } + + for (i = 0; i < ARRAY_SIZE(lcases); i++) { + if (!setlocale(LC_ALL, lcases[i].lang)) { + win_skip("skipping special case tests for %s\n", lcases[i].lang); + continue; + } + + ret = p_towupper(lcases[i].ch); + exp = lcases[i].exp ? lcases[i].exp : lcases[i].ch; + ok(ret == exp || broken(ret != exp), /* WinXP/2k3/Vista/2k8 */ + "expected uppercase %x, got %x for locale %s\n", + exp, ret, lcases[i].lang); + } + + setlocale(LC_ALL, "C"); + + if (!p__towlower_l || !p__towupper_l || !p__create_locale) + { + win_skip("_towlower_l/_towupper_l/_create_locale not available\n"); + return; + } + + /* test _towlower_l creating locale */ + for (i = 0; i < ARRAY_SIZE(ucases); i++) { + if (!(locale = p__create_locale(LC_ALL, ucases[i].lang))) { + win_skip("locale %s not available. skipping\n", ucases[i].lang); + continue; + } + + ret = p__towlower_l(ucases[i].ch, locale); + exp = ucases[i].exp ? ucases[i].exp : ucases[i].ch; + ok(ret == exp, "expected lowercase %x, got %x for locale %s\n", + exp, ret, ucases[i].lang); + + p__free_locale(locale); + } + + /* test _towupper_l creating locale */ + for (i = 0; i < ARRAY_SIZE(lcases); i++) { + if (!(locale = p__create_locale(LC_ALL, lcases[i].lang))) { + win_skip("locale %s not available. skipping\n", lcases[i].lang); + continue; + } + + ret = p__towupper_l(lcases[i].ch, locale); + exp = lcases[i].exp ? lcases[i].exp : lcases[i].ch; + ok(ret == exp, "expected uppercase %x, got %x for locale %s\n", + exp, ret, lcases[i].lang); + + p__free_locale(locale); + } +} + START_TEST(string) { char mem[100]; @@ -3812,4 +4026,5 @@ START_TEST(string) test__tcsnicoll(); test___strncnt(); test_C_locale(); + test_SpecialCasing(); } diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 28e82ec303..08a21c516a 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -2479,6 +2479,7 @@ MSVCRT_size_t CDECL MSVCRT_wcsnlen(const MSVCRT_wchar_t *s, MSVCRT_size_t maxlen int CDECL MSVCRT__towupper_l(MSVCRT_wint_t c, MSVCRT__locale_t locale) { MSVCRT_pthreadlocinfo locinfo; + WCHAR wc;
if(!locale) locinfo = get_locinfo(); @@ -2491,7 +2492,9 @@ int CDECL MSVCRT__towupper_l(MSVCRT_wint_t c, MSVCRT__locale_t locale) return c; }
- return toupperW(c); + if(LCMapStringW(locinfo->lc_handle[MSVCRT_LC_CTYPE], LCMAP_UPPERCASE, &c, 1, &wc, 1)) + return wc; + return c; }
/********************************************************************* @@ -2508,6 +2511,7 @@ int CDECL MSVCRT_towupper(MSVCRT_wint_t c) int CDECL MSVCRT__towlower_l(MSVCRT_wint_t c, MSVCRT__locale_t locale) { MSVCRT_pthreadlocinfo locinfo; + WCHAR wc;
if(!locale) locinfo = get_locinfo(); @@ -2520,7 +2524,9 @@ int CDECL MSVCRT__towlower_l(MSVCRT_wint_t c, MSVCRT__locale_t locale) return c; }
- return tolowerW(c); + if(LCMapStringW(locinfo->lc_handle[MSVCRT_LC_CTYPE], LCMAP_LOWERCASE, &c, 1, &wc, 1)) + return wc; + return c; }
/*********************************************************************
Signed-off-by: Daniel Lehman dlehman25@gmail.com --- dlls/ucrtbase/tests/string.c | 211 +++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+)
diff --git a/dlls/ucrtbase/tests/string.c b/dlls/ucrtbase/tests/string.c index 38aa6b3fa3..e4c4033663 100644 --- a/dlls/ucrtbase/tests/string.c +++ b/dlls/ucrtbase/tests/string.c @@ -357,6 +357,216 @@ static void test_C_locale(void) } }
+static void test_SpecialCasing(void) +{ + int i; + wint_t ret, exp; + _locale_t locale; + struct test { + const char *lang; + wint_t ch; + wint_t exp; + }; + + static const struct test ucases[] = { + {"English", 'I', 'i'}, /* LATIN CAPITAL LETTER I */ + {"English", 0x0130}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ + + {"Turkish", 'I', 'i'}, /* LATIN CAPITAL LETTER I */ + {"Turkish", 0x0130}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */ + + {"Greek", 0x1F88, 0x1F80}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI */ + {"Greek", 0x1F89, 0x1F81}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F8A, 0x1F82}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F8B, 0x1F83}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F8C, 0x1F84}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F8D, 0x1F85}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F8E, 0x1F86}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */ + {"Greek", 0x1F8F, 0x1F87}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */ + + {"Greek", 0x1F98, 0x1F90}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI */ + {"Greek", 0x1F99, 0x1F91}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F9A, 0x1F92}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F9B, 0x1F93}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F9C, 0x1F94}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F9D, 0x1F95}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI */ + {"Greek", 0x1F9E, 0x1F96}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */ + {"Greek", 0x1F9F, 0x1F97}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */ + + {"Greek", 0x1FA8, 0x1FA0}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI */ + {"Greek", 0x1FA9, 0x1FA1}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI */ + {"Greek", 0x1FAA, 0x1FA2}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI */ + {"Greek", 0x1FAB, 0x1FA3}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI */ + {"Greek", 0x1FAC, 0x1FA4}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI */ + {"Greek", 0x1FAD, 0x1FA5}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI */ + {"Greek", 0x1FAE, 0x1FA6}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */ + {"Greek", 0x1FAF, 0x1FA7}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */ + + {"Greek", 0x1FBC, 0x1FB3}, /* GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI */ + {"Greek", 0x1FCC, 0x1FC3}, /* GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI */ + {"Greek", 0x1FFC, 0x1FF3}, /* GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI */ + }; + static const struct test lcases[] = { + {"English", 'i', 'I'}, /* LATIN SMALL LETTER I */ + {"English", 0x0131}, /* LATIN SMALL LETTER DOTLESS I */ + + {"Turkish", 'i', 'I'}, /* LATIN SMALL LETTER I */ + {"Turkish", 0x0131}, /* LATIN SMALL LETTER DOTLESS I */ + + {"German", 0x00DF}, /* LATIN SMALL LETTER SHARP S */ + + {"English", 0xFB00}, /* LATIN SMALL LIGATURE FF */ + {"English", 0xFB01}, /* LATIN SMALL LIGATURE FI */ + {"English", 0xFB02}, /* LATIN SMALL LIGATURE FL */ + {"English", 0xFB03}, /* LATIN SMALL LIGATURE FFI */ + {"English", 0xFB04}, /* LATIN SMALL LIGATURE FFL */ + {"English", 0xFB05}, /* LATIN SMALL LIGATURE LONG ST */ + {"English", 0xFB06}, /* LATIN SMALL LIGATURE ST */ + + {"Armenian", 0x0587}, /* ARMENIAN SMALL LIGATURE ECH YIWN */ + {"Armenian", 0xFB13}, /* ARMENIAN SMALL LIGATURE MEN NOW */ + {"Armenian", 0xFB14}, /* ARMENIAN SMALL LIGATURE MEN ECH */ + {"Armenian", 0xFB15}, /* ARMENIAN SMALL LIGATURE MEN INI */ + {"Armenian", 0xFB16}, /* ARMENIAN SMALL LIGATURE VEW NOW */ + {"Armenian", 0xFB17}, /* ARMENIAN SMALL LIGATURE MEN XEH */ + + {"Armenian", 0x0587}, /* ARMENIAN SMALL LIGATURE ECH YIWN */ + {"Armenian", 0xFB13}, /* ARMENIAN SMALL LIGATURE MEN NOW */ + {"Armenian", 0xFB14}, /* ARMENIAN SMALL LIGATURE MEN ECH */ + {"Armenian", 0xFB15}, /* ARMENIAN SMALL LIGATURE MEN INI */ + {"Armenian", 0xFB16}, /* ARMENIAN SMALL LIGATURE VEW NOW */ + {"Armenian", 0xFB17}, /* ARMENIAN SMALL LIGATURE MEN XEH */ + + {"English", 0x0149}, /* LATIN SMALL LETTER N PRECEDED BY APOSTROPHE */ + {"Greek", 0x0390}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ + {"Greek", 0x03B0}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ + {"English", 0x01F0}, /* LATIN SMALL LETTER J WITH CARON */ + {"English", 0x1E96}, /* LATIN SMALL LETTER H WITH LINE BELOW */ + {"English", 0x1E97}, /* LATIN SMALL LETTER T WITH DIAERESIS */ + {"English", 0x1E98}, /* LATIN SMALL LETTER W WITH RING ABOVE */ + {"English", 0x1E99}, /* LATIN SMALL LETTER Y WITH RING ABOVE */ + {"English", 0x1E9A}, /* LATIN SMALL LETTER A WITH RIGHT HALF RING */ + {"Greek", 0x1F50}, /* GREEK SMALL LETTER UPSILON WITH PSILI */ + {"Greek", 0x1F52}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA */ + {"Greek", 0x1F54}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA */ + {"Greek", 0x1F56}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI */ + {"Greek", 0x1FB6}, /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI */ + {"Greek", 0x1FC6}, /* GREEK SMALL LETTER ETA WITH PERISPOMENI */ + {"Greek", 0x1FD2}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA */ + {"Greek", 0x1FD3}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA */ + {"Greek", 0x1FD6}, /* GREEK SMALL LETTER IOTA WITH PERISPOMENI */ + {"Greek", 0x1FD7}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI */ + {"Greek", 0x1FE2}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA */ + {"Greek", 0x1FE3}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA */ + {"Greek", 0x1FE4}, /* GREEK SMALL LETTER RHO WITH PSILI */ + {"Greek", 0x1FE6}, /* GREEK SMALL LETTER UPSILON WITH PERISPOMENI */ + {"Greek", 0x1FE7}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI */ + {"Greek", 0x1FF6}, /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI */ + + {"Greek", 0x1F80, 0x1F88}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI */ + {"Greek", 0x1F81, 0x1F89}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F82, 0x1F8A}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F83, 0x1F8B}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F84, 0x1F8C}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F85, 0x1F8D}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F86, 0x1F8E}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */ + {"Greek", 0x1F87, 0x1F8F}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */ + + {"Greek", 0x1F90, 0x1F98}, /* GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI */ + {"Greek", 0x1F91, 0x1F99}, /* GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F92, 0x1F9A}, /* GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F93, 0x1F9B}, /* GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F94, 0x1F9C}, /* GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F95, 0x1F9D}, /* GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1F96, 0x1F9E}, /* GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */ + {"Greek", 0x1F97, 0x1F9F}, /* GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */ + + {"Greek", 0x1FA0, 0x1FA8}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI */ + {"Greek", 0x1FA1, 0x1FA9}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FA2, 0x1FAA}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FA3, 0x1FAB}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FA4, 0x1FAC}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FA5, 0x1FAD}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FA6, 0x1FAE}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */ + {"Greek", 0x1FA7, 0x1FAF}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */ + + {"Greek", 0x1FB3, 0x1FBC}, /* GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI */ + {"Greek", 0x1FC3, 0x1FCC}, /* GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI */ + {"Greek", 0x1FF3, 0x1FFC}, /* GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI */ + + {"Greek", 0x1FB2}, /* GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FB4}, /* GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FC2}, /* GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FC4}, /* GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FF2}, /* GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI */ + {"Greek", 0x1FF4}, /* GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI */ + + {"Greek", 0x1FB7}, /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI */ + {"Greek", 0x1FC7}, /* GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI */ + {"Greek", 0x1FF7}, /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI */ + }; + + for (i = 0; i < ARRAY_SIZE(ucases); i++) { + if (!p_setlocale(LC_ALL, ucases[i].lang)) { + win_skip("skipping special case tests for %s\n", ucases[i].lang); + continue; + } + + ret = p_towlower(ucases[i].ch); + exp = ucases[i].exp ? ucases[i].exp : ucases[i].ch; + ok(ret == exp || broken(ret != exp), /* Vista */ + "expected lowercase %x, got %x for locale %s\n", + exp, ret, ucases[i].lang); + } + + for (i = 0; i < ARRAY_SIZE(lcases); i++) { + if (!p_setlocale(LC_ALL, lcases[i].lang)) { + win_skip("skipping special case tests for %s\n", lcases[i].lang); + continue; + } + + ret = p_towupper(lcases[i].ch); + exp = lcases[i].exp ? lcases[i].exp : lcases[i].ch; + ok(ret == exp || broken(ret != exp), /* Vista */ + "expected uppercase %x, got %x for locale %s\n", + exp, ret, lcases[i].lang); + } + + p_setlocale(LC_ALL, "C"); + + /* test _towlower_l creating locale */ + for (i = 0; i < ARRAY_SIZE(ucases); i++) { + if (!(locale = p__create_locale(LC_ALL, ucases[i].lang))) { + win_skip("locale %s not available. skipping\n", ucases[i].lang); + continue; + } + + ret = p__towlower_l(ucases[i].ch, locale); + exp = ucases[i].exp ? ucases[i].exp : ucases[i].ch; + ok(ret == exp || broken(ret != exp), /* Vista */ + "expected lowercase %x, got %x for locale %s\n", + exp, ret, ucases[i].lang); + + p__free_locale(locale); + } + + /* test _towupper_l creating locale */ + for (i = 0; i < ARRAY_SIZE(lcases); i++) { + if (!(locale = p__create_locale(LC_ALL, lcases[i].lang))) { + win_skip("locale %s not available. skipping\n", lcases[i].lang); + continue; + } + + ret = p__towupper_l(lcases[i].ch, locale); + exp = lcases[i].exp ? lcases[i].exp : lcases[i].ch; + ok(ret == exp || broken(ret != exp), /* Vista */ + "expected uppercase %x, got %x for locale %s\n", + exp, ret, lcases[i].lang); + + p__free_locale(locale); + } +} + START_TEST(string) { if (!init()) return; @@ -365,4 +575,5 @@ START_TEST(string) test__memicmp_l(); test___strncnt(); test_C_locale(); + test_SpecialCasing(); }