libwine: Decompose characters before comparing in wine_compare_string.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2019-05-21 17:19:48 +02:00 committed by Alexandre Julliard
parent ac5ac588f3
commit 40a1a9e9a2
2 changed files with 41 additions and 31 deletions

View File

@ -1975,7 +1975,7 @@ static void test_CompareStringA(void)
/* \xB9 character lies between a and b */
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);
ok(ret == CSTR_LESS_THAN, "\'\\xB9\' character should be smaller than \'b\'\n");
@ -2047,14 +2047,14 @@ static void test_CompareStringW(void)
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);
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);
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);
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);
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);
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[] = {
},
{ /* 3 */
"tr-TR", 0,
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE
},
{ /* 4 */
"tr-TR", 0,
@ -2115,7 +2115,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
},
{ /* 7 */
"tr-TR", NORM_IGNORECASE,
{'i',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE
{'i',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE
},
{ /* 8 */
"tr-TR", NORM_IGNORECASE,
@ -2123,7 +2123,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
},
{ /* 9 */
"tr-TR", NORM_IGNORECASE,
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE
},
{ /* 10 */
"tr-TR", NORM_IGNORECASE,
@ -2148,7 +2148,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
},
{ /* 15 */
"tr-TR", NORM_LINGUISTIC_CASING,
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE
},
{ /* 16 */
"tr-TR", NORM_LINGUISTIC_CASING,
@ -2173,7 +2173,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
},
{ /* 21 */
"tr-TR", LINGUISTIC_IGNORECASE,
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, TRUE
{'I',0}, {0x130,0}, CSTR_LESS_THAN, -1, FALSE
},
{ /* 22 */
"tr-TR", LINGUISTIC_IGNORECASE,
@ -2190,7 +2190,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
},
{ /* 25 */
"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 */
"tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE,
@ -2198,7 +2198,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
},
{ /* 27 */
"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 */
"tr-TR", NORM_LINGUISTIC_CASING | NORM_IGNORECASE,
@ -2223,7 +2223,7 @@ static const struct comparestringex_test comparestringex_tests[] = {
},
{ /* 33 */
"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 */
"tr-TR", NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE,

View File

@ -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,
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;
/* 32-bit collation element table format:
@ -191,20 +204,21 @@ static inline int compare_weights(int flags, const WCHAR *str1, int len1,
*/
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)
{
int skip = 0;
/* FIXME: not tested */
if (get_char_typeW(*str1) & (C1_PUNCT | C1_SPACE))
if (get_char_typeW(dstr1[dpos1]) & (C1_PUNCT | C1_SPACE))
{
str1++;
len1--;
inc_str_pos(&str1, &len1, &dpos1, &dlen1);
skip = 1;
}
if (get_char_typeW(*str2) & (C1_PUNCT | C1_SPACE))
if (!dlen2 && get_char_typeW(dstr2[dpos2]) & (C1_PUNCT | C1_SPACE))
{
str2++;
len2--;
inc_str_pos(&str2, &len2, &dpos2, &dlen2);
skip = 1;
}
if (skip) continue;
@ -215,32 +229,28 @@ static inline int compare_weights(int flags, const WCHAR *str1, int len1,
*/
if (type == UNICODE_WEIGHT && !(flags & SORT_STRINGSORT))
{
if (*str1 == '-' || *str1 == '\'')
if (dstr1[dpos1] == '-' || dstr1[dpos1] == '\'')
{
if (*str2 != '-' && *str2 != '\'')
if (dstr2[dpos2] != '-' && dstr2[dpos2] != '\'')
{
str1++;
len1--;
inc_str_pos(&str1, &len1, &dpos1, &dlen1);
continue;
}
}
else if (*str2 == '-' || *str2 == '\'')
else if (dstr2[dpos2] == '-' || dstr2[dpos2] == '\'')
{
str2++;
len2--;
inc_str_pos(&str2, &len2, &dpos2, &dlen2);
continue;
}
}
ce1 = get_weight(*str1, type);
ce2 = get_weight(*str2, type);
ce1 = get_weight(dstr1[dpos1], type);
ce2 = get_weight(dstr2[dpos2], type);
if (ce1 - ce2) return ce1 - ce2;
str1++;
str2++;
len1--;
len2--;
inc_str_pos(&str1, &len1, &dpos1, &dlen1);
inc_str_pos(&str2, &len2, &dpos2, &dlen2);
}
while (len1 && !*str1)
{