[RFC 4/5] kernelbase/expansion: Implement sortkey expansion
Fabian Maurer
dark.shadow4 at web.de
Sat Apr 11 14:45:48 CDT 2020
---
dlls/kernel32/tests/locale.c | 3 +++
dlls/kernelbase/locale.c | 45 +++++++++++++++++++++++++++++++++---
2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index 01ba3c0cb6..6437f043f7 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -3216,6 +3216,9 @@ static const struct sorting_test_entry unicode_sorting_tests[] =
/* 86 */ { L"en-US", NORM_IGNORENONSPACE, L"\x31a2", L"\x3110", CSTR_EQUAL }, /* NORM_IGNORENONSPACE */
/* 87 */ { L"en-US", NORM_IGNORENONSPACE, L"\x1342", L"\x133a", CSTR_EQUAL }, /* NORM_IGNORENONSPACE */
/* 88 */ { L"en-US", NORM_IGNORENONSPACE, L"\x16a4", L"\x16a5", CSTR_EQUAL }, /* NORM_IGNORENONSPACE */
+ /* 89 */ { L"en-US", 0, L"\x00c6", L"\x0041\x0045", CSTR_EQUAL }, /* Expansion */
+ /* 90 */ { L"en-US", 0, L"\x0f5c", L"\x0f5b\x0fb7", CSTR_EQUAL }, /* Expansion */
+ /* 91 */ { L"en-US", 0, L"\x05f0", L"\x05d5\x05d5", CSTR_EQUAL }, /* Expansion */
};
static void test_unicode_sorting(void)
diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index 789e90cbf5..a02d1bf855 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -2471,6 +2471,13 @@ typedef struct _character_info
BYTE weight_case;
} character_info;
+typedef struct _character_info_expansion
+{
+ int character;
+ int character_result1;
+ int character_result2;
+} character_info_expansion;
+
typedef struct _weight_main_info
{
BYTE script_member;
@@ -2571,6 +2578,8 @@ typedef struct _sortkey_data
static BOOL get_char(sortkey_data* data, character_info* info, WCHAR ch)
{
DWORD value = sort.keys[ch];
+ if ((WORD)value == 0x200) /* Expansion */
+ return FALSE;
info->weight_case = value >> 24;
info->weight_diacritic = (value >> 16) & 0xff;
@@ -2579,6 +2588,28 @@ static BOOL get_char(sortkey_data* data, character_info* info, WCHAR ch)
return info->script_member != 0;
}
+static BOOL get_expansion(character_info_expansion* info, WCHAR ch)
+{
+ DWORD pos_info = sort.keys[ch];
+ int count = (WORD)pos_info;
+ int pos = pos_info >> 16;
+ const DWORD* ptr;
+ const WCHAR* p;
+ int count_expansion;
+ if (count != 0x200)
+ return FALSE;
+ ptr = (const DWORD *)(sort.guids + sort.guid_count);
+ count_expansion = *ptr++;
+ if (pos >= count_expansion)
+ return FALSE;
+ p = (const WCHAR *)(ptr + pos);
+ info->character = ch;
+ info->character_result1 = p[0];
+ info->character_result2 = p[1];
+ return TRUE;
+}
+
+
static void sortkey_data_init(sortkey_data* data, int flags, const WCHAR* locale, BOOL is_compare_string)
{
data->flags = flags;
@@ -2642,14 +2673,21 @@ static void diacritic_weights_add(sortkey_data* data, const character_info* info
/* Main sortkey logic */
-static void sortkey_handle_default_character(sortkey_data* data, WCHAR c)
+static BOOL sortkey_handle_default_character(sortkey_data* data, WCHAR c)
{
weight_main_info weightmain;
character_info info;
+ character_info_expansion expansion;
if (!get_char(data, &info, c))
{
- return;
+ if (get_expansion(&expansion, c))
+ {
+ sortkey_handle_default_character(data, (WCHAR)expansion.character_result1);
+ sortkey_handle_default_character(data, (WCHAR)expansion.character_result2);
+ return TRUE;
+ }
+ return FALSE;
}
weightmain = create_weight_main(info.script_member, info.weight_primary);
@@ -2661,6 +2699,7 @@ static void sortkey_handle_default_character(sortkey_data* data, WCHAR c)
main_weights_add(data, &weightmain);
case_weights_add(data, info.weight_case);
+ return TRUE;
}
static void sortkey_handle_japanese_character(sortkey_data* data, weight_main_info* weightmain, const character_info* info, const character_info* info_other)
@@ -2701,7 +2740,7 @@ static BOOL sortkey_handle_character(sortkey_data* data, WCHAR c, const WCHAR* s
if (!get_char(data, &info, c))
{
- return FALSE;
+ return sortkey_handle_default_character(data, c);
}
switch (info.script_member)
--
2.26.0
More information about the wine-devel
mailing list