--- dlls/kernel32/tests/locale.c | 17 ++++++++++++++++ dlls/kernelbase/locale.c | 39 ++++++++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index a451594b19..4b0c106cd2 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -3173,6 +3173,23 @@ static const struct sorting_test_entry unicode_sorting_tests[] = /* 43 */ { L"en-US", NORM_IGNORESYMBOLS, L"\x21da", L"\x21dc", CSTR_EQUAL }, /* NORM_IGNORESYMBOLS */ /* 44 */ { L"en-US", NORM_IGNORESYMBOLS, L"\x29fb", L"\x2295", CSTR_EQUAL }, /* NORM_IGNORESYMBOLS */ /* 45 */ { L"en-US", NORM_IGNORESYMBOLS, L"\x0092", L"\x009c", CSTR_EQUAL }, /* NORM_IGNORESYMBOLS */ + /* 46 */ { L"en-US", 0, L"\x001b", L"\x001c", CSTR_LESS_THAN }, /* Punctuation primary weight */ + /* 47 */ { L"en-US", 0, L"\x0005", L"\x0006", CSTR_LESS_THAN }, /* Punctuation primary weight */ + /* 48 */ { L"en-US", 0, L"\x0027", L"\xff07", CSTR_LESS_THAN, 0, TRUE }, /* Punctuation diacritic/case weight */ + /* 49 */ { L"en-US", 0, L"\x07f4", L"\x07f5", CSTR_LESS_THAN, 0, TRUE }, /* Punctuation diacritic/case weight */ + /* 50 */ { L"en-US", 0, L"\x207b", L"\x0008", CSTR_GREATER_THAN }, /* Punctuation diacritic/case weight */ + /* 51 */ { L"en-US", NORM_IGNORESYMBOLS, L"\x207b", L"\x0008", CSTR_EQUAL }, /* Punctuation NORM_IGNORESYMBOLS */ + /* 52 */ { L"en-US", NORM_IGNORESYMBOLS, L"\x0004", L"\x0011", CSTR_EQUAL }, /* Punctuation NORM_IGNORESYMBOLS */ + /* 53 */ { L"en-US", NORM_IGNORESYMBOLS | SORT_STRINGSORT, L"\x207b", L"\x0008", CSTR_EQUAL }, /* Punctuation NORM_IGNORESYMBOLS SORT_STRINGSORT */ + /* 54 */ { L"en-US", NORM_IGNORESYMBOLS | SORT_STRINGSORT, L"\x0004", L"\x0011", CSTR_EQUAL }, /* Punctuation NORM_IGNORESYMBOLS SORT_STRINGSORT */ + /* 55 */ { L"en-US", SORT_STRINGSORT, L"\x001a", L"\x001b", CSTR_LESS_THAN }, /* Punctuation SORT_STRINGSORT main weight */ + /* 56 */ { L"en-US", SORT_STRINGSORT, L"\x2027", L"\x2011", CSTR_GREATER_THAN }, /* Punctuation SORT_STRINGSORT main weight */ + /* 57 */ { L"en-US", SORT_STRINGSORT, L"\x3030", L"\x301c", CSTR_GREATER_THAN }, /* Punctuation SORT_STRINGSORT main weight */ + /* 58 */ { L"en-US", SORT_STRINGSORT, L"\x058a", L"\x2010", CSTR_GREATER_THAN }, /* Punctuation SORT_STRINGSORT diacritic weight */ + /* 59 */ { L"en-US", SORT_STRINGSORT, L"\x07F5", L"\x07F4", CSTR_GREATER_THAN }, /* Punctuation SORT_STRINGSORT diacritic weight */ + /* 60 */ { L"en-US", SORT_STRINGSORT, L"\xfe32", L"\x2013", CSTR_GREATER_THAN }, /* Punctuation SORT_STRINGSORT case weight */ + /* 61 */ { L"en-US", SORT_STRINGSORT, L"\xfe31", L"\xfe58", CSTR_GREATER_THAN }, /* Punctuation SORT_STRINGSORT case weight */ + /* 62 */ { L"en-US", SORT_STRINGSORT, L"\xff07", L"\x0027", CSTR_GREATER_THAN }, /* Punctuation SORT_STRINGSORT case weight */ };
static void test_unicode_sorting(void) diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c index af78f76e29..242caf6764 100644 --- a/dlls/kernelbase/locale.c +++ b/dlls/kernelbase/locale.c @@ -2478,6 +2478,12 @@ typedef struct _weight_main_info BYTE extra; } weight_main_info;
+typedef struct _weight_special_info +{ + BYTE script_member; + BYTE weight_primary; +} weight_special_info; + typedef struct _list { int extra_len; @@ -2495,6 +2501,7 @@ typedef struct _sortkey_data list weights_main; list weights_diacritic; list weights_case; + list weights_special; } sortkey_data;
/* List functions */ @@ -2571,6 +2578,7 @@ static void sortkey_data_init(sortkey_data* data, int flags, const WCHAR* locale LIST_INIT(data->weights_main, BYTE); LIST_INIT(data->weights_diacritic, BYTE); LIST_INIT(data->weights_case, BYTE); + LIST_INIT(data->weights_special, BYTE); }
static void sortkey_data_destroy(sortkey_data* data) @@ -2579,6 +2587,7 @@ static void sortkey_data_destroy(sortkey_data* data) LIST_DESTROY(data->weights_main); LIST_DESTROY(data->weights_diacritic); LIST_DESTROY(data->weights_case); + LIST_DESTROY(data->weights_special); }
static weight_main_info create_weight_main(BYTE script_member, BYTE weight_primary) @@ -2610,6 +2619,12 @@ static void main_weights_add(sortkey_data *data, weight_main_info* value) LIST_ADD(data->weights_main, BYTE, value->extra); }
+static void special_weights_add(sortkey_data* data, weight_special_info* value) +{ + LIST_ADD(data->weights_special, BYTE, value->script_member); + LIST_ADD(data->weights_special, BYTE, value->weight_primary); +} + static void diacritic_weights_add(sortkey_data* data, const character_info* info, BYTE value) { LIST_ADD(data->weights_diacritic, BYTE, value); @@ -2690,7 +2705,26 @@ static BOOL sortkey_handle_character(sortkey_data* data, WCHAR c, const WCHAR* s break;
case 6: /* Punctuation */ - /* TODO */ + if (flags & NORM_IGNORESYMBOLS) + break; + + if (flags & SORT_STRINGSORT) + { + weightmain = create_weight_main(info.script_member, info.weight_primary); + main_weights_add(data, &weightmain); + + diacritic_weights_add(data, &info, info.weight_diacritic); + + case_weights_add(data, info.weight_case); + } + else + { + weight_special_info special; + + special.script_member = info.weight_primary; + special.weight_primary = (BYTE)(info.weight_diacritic * 8 + info.weight_case); /* Logic found through testing, seems to work reliably */ + special_weights_add(data, &special); + } break;
case 7: /* Symbols */ @@ -2753,7 +2787,8 @@ static void sortkey_write_result(sortkey_data* data) LIST_ADD(data->key, BYTE, SORTKEY_SEPARATOR);
/* Special weights */ - /* TODO */ + + APPEND_LIST_TO_SORTKEY(data, weights_special, BYTE, *element, FALSE);
LIST_ADD(data->key, BYTE, SORTKEY_TERMINATOR); } -- 2.26.0