Commit 40a1a9e9 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

libwine: Decompose characters before comparing in wine_compare_string.

parent ac5ac588
...@@ -1975,7 +1975,7 @@ static void test_CompareStringA(void) ...@@ -1975,7 +1975,7 @@ static void test_CompareStringA(void)
/* \xB9 character lies between a and b */ /* \xB9 character lies between a and b */
ret = CompareStringA(lcid, 0, "a", 1, "\xB9", 1); ret = CompareStringA(lcid, 0, "a", 1, "\xB9", 1);
todo_wine ok(ret == CSTR_LESS_THAN, "\'\\xB9\' character should be greater than \'a\'\n"); ok(ret == CSTR_LESS_THAN, "\'\\xB9\' character should be greater than \'a\'\n");
ret = CompareStringA(lcid, 0, "\xB9", 1, "b", 1); ret = CompareStringA(lcid, 0, "\xB9", 1, "b", 1);
ok(ret == CSTR_LESS_THAN, "\'\\xB9\' character should be smaller than \'b\'\n"); ok(ret == CSTR_LESS_THAN, "\'\\xB9\' character should be smaller than \'b\'\n");
...@@ -2047,14 +2047,14 @@ static void test_CompareStringW(void) ...@@ -2047,14 +2047,14 @@ static void test_CompareStringW(void)
ret = CompareStringW(CP_ACP, 0, ABC_EE, 4, A_ACUTE_BC_DECOMP, 5); ret = CompareStringW(CP_ACP, 0, ABC_EE, 4, A_ACUTE_BC_DECOMP, 5);
todo_wine ok(ret == CSTR_LESS_THAN, "expected CSTR_LESS_THAN, got %d\n", ret); todo_wine ok(ret == CSTR_LESS_THAN, "expected CSTR_LESS_THAN, got %d\n", ret);
ret = CompareStringW(CP_ACP, 0, A_ACUTE_BC, 4, A_ACUTE_BC_DECOMP, 5); ret = CompareStringW(CP_ACP, 0, A_ACUTE_BC, 4, A_ACUTE_BC_DECOMP, 5);
todo_wine ok(ret == CSTR_EQUAL, "expected CSTR_EQUAL, got %d\n", ret); ok(ret == CSTR_EQUAL, "expected CSTR_EQUAL, got %d\n", ret);
ret = CompareStringW(CP_ACP, NORM_IGNORENONSPACE, ABC_EE, 3, A_ACUTE_BC, 4); ret = CompareStringW(CP_ACP, NORM_IGNORENONSPACE, ABC_EE, 3, A_ACUTE_BC, 4);
ok(ret == CSTR_EQUAL, "expected CSTR_EQUAL, got %d\n", ret); todo_wine ok(ret == CSTR_EQUAL, "expected CSTR_EQUAL, got %d\n", ret);
ret = CompareStringW(CP_ACP, NORM_IGNORENONSPACE, ABC_EE, 4, A_ACUTE_BC_DECOMP, 5); ret = CompareStringW(CP_ACP, NORM_IGNORENONSPACE, ABC_EE, 4, A_ACUTE_BC_DECOMP, 5);
todo_wine ok(ret == CSTR_EQUAL, "expected CSTR_EQUAL, got %d\n", ret); todo_wine ok(ret == CSTR_EQUAL, "expected CSTR_EQUAL, got %d\n", ret);
ret = CompareStringW(CP_ACP, NORM_IGNORENONSPACE, A_ACUTE_BC, 4, A_ACUTE_BC_DECOMP, 5); ret = CompareStringW(CP_ACP, NORM_IGNORENONSPACE, A_ACUTE_BC, 4, A_ACUTE_BC_DECOMP, 5);
todo_wine ok(ret == CSTR_EQUAL, "expected CSTR_EQUAL, got %d\n", ret); ok(ret == CSTR_EQUAL, "expected CSTR_EQUAL, got %d\n", ret);
ret = CompareStringW(CP_ACP, 0, ABC_EE, 4, A_NULL_BC, 4); ret = CompareStringW(CP_ACP, 0, ABC_EE, 4, A_NULL_BC, 4);
todo_wine ok(ret == CSTR_EQUAL, "expected CSTR_LESS_THAN, got %d\n", ret); todo_wine ok(ret == CSTR_EQUAL, "expected CSTR_LESS_THAN, got %d\n", ret);
...@@ -2098,7 +2098,7 @@ static const struct comparestringex_test comparestringex_tests[] = { ...@@ -2098,7 +2098,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
}, },
{ /* 3 */ { /* 3 */
"tr-TR", 0, "tr-TR", 0,
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE {'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE
}, },
{ /* 4 */ { /* 4 */
"tr-TR", 0, "tr-TR", 0,
...@@ -2115,7 +2115,7 @@ static const struct comparestringex_test comparestringex_tests[] = { ...@@ -2115,7 +2115,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
}, },
{ /* 7 */ { /* 7 */
"tr-TR", NORM_IGNORECASE, "tr-TR", NORM_IGNORECASE,
{'i',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE {'i',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE
}, },
{ /* 8 */ { /* 8 */
"tr-TR", NORM_IGNORECASE, "tr-TR", NORM_IGNORECASE,
...@@ -2123,7 +2123,7 @@ static const struct comparestringex_test comparestringex_tests[] = { ...@@ -2123,7 +2123,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
}, },
{ /* 9 */ { /* 9 */
"tr-TR", NORM_IGNORECASE, "tr-TR", NORM_IGNORECASE,
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE {'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE
}, },
{ /* 10 */ { /* 10 */
"tr-TR", NORM_IGNORECASE, "tr-TR", NORM_IGNORECASE,
...@@ -2148,7 +2148,7 @@ static const struct comparestringex_test comparestringex_tests[] = { ...@@ -2148,7 +2148,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
}, },
{ /* 15 */ { /* 15 */
"tr-TR", NORM_LINGUISTIC_CASING, "tr-TR", NORM_LINGUISTIC_CASING,
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE {'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE
}, },
{ /* 16 */ { /* 16 */
"tr-TR", NORM_LINGUISTIC_CASING, "tr-TR", NORM_LINGUISTIC_CASING,
...@@ -2173,7 +2173,7 @@ static const struct comparestringex_test comparestringex_tests[] = { ...@@ -2173,7 +2173,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
}, },
{ /* 21 */ { /* 21 */
"tr-TR", LINGUISTIC_IGNORECASE, "tr-TR", LINGUISTIC_IGNORECASE,
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE {'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE
}, },
{ /* 22 */ { /* 22 */
"tr-TR", LINGUISTIC_IGNORECASE, "tr-TR", LINGUISTIC_IGNORECASE,
...@@ -2190,7 +2190,7 @@ static const struct comparestringex_test comparestringex_tests[] = { ...@@ -2190,7 +2190,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
}, },
{ /* 25 */ { /* 25 */
"tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE, "tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE,
{'i',0}, {0x130,0}, CSTR_EQUAL, CSTR_LESS_THAN, FALSE {'i',0}, {0x130,0}, CSTR_EQUAL, CSTR_LESS_THAN, TRUE
}, },
{ /* 26 */ { /* 26 */
"tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE, "tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE,
...@@ -2198,7 +2198,7 @@ static const struct comparestringex_test comparestringex_tests[] = { ...@@ -2198,7 +2198,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
}, },
{ /* 27 */ { /* 27 */
"tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE, "tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE,
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE {'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE
}, },
{ /* 28 */ { /* 28 */
"tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE, "tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE,
...@@ -2223,7 +2223,7 @@ static const struct comparestringex_test comparestringex_tests[] = { ...@@ -2223,7 +2223,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
}, },
{ /* 33 */ { /* 33 */
"tr-TR", NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE, "tr-TR", NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE,
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE {'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE
}, },
{ /* 34 */ { /* 34 */
"tr-TR", NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE, "tr-TR", NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE,
......
...@@ -180,9 +180,22 @@ static unsigned int get_weight(WCHAR ch, enum weight type) ...@@ -180,9 +180,22 @@ static unsigned int get_weight(WCHAR ch, enum weight type)
} }
} }
static void inc_str_pos(const WCHAR **str, int *len, int *dpos, int *dlen)
{
(*dpos)++;
if (*dpos == *dlen)
{
*dpos = *dlen = 0;
(*str)++;
(*len)--;
}
}
static inline int compare_weights(int flags, const WCHAR *str1, int len1, static inline int compare_weights(int flags, const WCHAR *str1, int len1,
const WCHAR *str2, int len2, enum weight type) const WCHAR *str2, int len2, enum weight type)
{ {
int dpos1 = 0, dpos2 = 0, dlen1 = 0, dlen2 = 0;
WCHAR dstr1[4], dstr2[4];
unsigned int ce1, ce2; unsigned int ce1, ce2;
/* 32-bit collation element table format: /* 32-bit collation element table format:
...@@ -191,20 +204,21 @@ static inline int compare_weights(int flags, const WCHAR *str1, int len1, ...@@ -191,20 +204,21 @@ static inline int compare_weights(int flags, const WCHAR *str1, int len1,
*/ */
while (len1 > 0 && len2 > 0) while (len1 > 0 && len2 > 0)
{ {
if (!dlen1) dlen1 = wine_decompose(0, *str1, dstr1, 4);
if (!dlen2) dlen2 = wine_decompose(0, *str2, dstr2, 4);
if (flags & NORM_IGNORESYMBOLS) if (flags & NORM_IGNORESYMBOLS)
{ {
int skip = 0; int skip = 0;
/* FIXME: not tested */ /* FIXME: not tested */
if (get_char_typeW(*str1) & (C1_PUNCT | C1_SPACE)) if (get_char_typeW(dstr1[dpos1]) & (C1_PUNCT | C1_SPACE))
{ {
str1++; inc_str_pos(&str1, &len1, &dpos1, &dlen1);
len1--;
skip = 1; skip = 1;
} }
if (get_char_typeW(*str2) & (C1_PUNCT | C1_SPACE)) if (!dlen2 && get_char_typeW(dstr2[dpos2]) & (C1_PUNCT | C1_SPACE))
{ {
str2++; inc_str_pos(&str2, &len2, &dpos2, &dlen2);
len2--;
skip = 1; skip = 1;
} }
if (skip) continue; if (skip) continue;
...@@ -215,32 +229,28 @@ static inline int compare_weights(int flags, const WCHAR *str1, int len1, ...@@ -215,32 +229,28 @@ static inline int compare_weights(int flags, const WCHAR *str1, int len1,
*/ */
if (type == UNICODE_WEIGHT && !(flags & SORT_STRINGSORT)) if (type == UNICODE_WEIGHT && !(flags & SORT_STRINGSORT))
{ {
if (*str1 == '-' || *str1 == '\'') if (dstr1[dpos1] == '-' || dstr1[dpos1] == '\'')
{ {
if (*str2 != '-' && *str2 != '\'') if (dstr2[dpos2] != '-' && dstr2[dpos2] != '\'')
{ {
str1++; inc_str_pos(&str1, &len1, &dpos1, &dlen1);
len1--;
continue; continue;
} }
} }
else if (*str2 == '-' || *str2 == '\'') else if (dstr2[dpos2] == '-' || dstr2[dpos2] == '\'')
{ {
str2++; inc_str_pos(&str2, &len2, &dpos2, &dlen2);
len2--;
continue; continue;
} }
} }
ce1 = get_weight(*str1, type); ce1 = get_weight(dstr1[dpos1], type);
ce2 = get_weight(*str2, type); ce2 = get_weight(dstr2[dpos2], type);
if (ce1 - ce2) return ce1 - ce2; if (ce1 - ce2) return ce1 - ce2;
str1++; inc_str_pos(&str1, &len1, &dpos1, &dlen1);
str2++; inc_str_pos(&str2, &len2, &dpos2, &dlen2);
len1--;
len2--;
} }
while (len1 && !*str1) while (len1 && !*str1)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment