[PATCH 4/5] kernelbase/expansion: Implement sortkey expansion

Fabian Maurer dark.shadow4 at web.de
Tue Apr 28 13:17:47 CDT 2020


Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
 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 5796fdbf9a..8c976e70fc 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -3219,6 +3219,9 @@ static const struct sorting_test_entry unicode_sorting_tests[] =
     /*  89 */ { L"en-US", NORM_IGNORENONSPACE, L"\x31a2", L"\x3110", CSTR_EQUAL }, /* NORM_IGNORENONSPACE */
     /*  90 */ { L"en-US", NORM_IGNORENONSPACE, L"\x1342", L"\x133a", CSTR_EQUAL }, /* NORM_IGNORENONSPACE */
     /*  91 */ { L"en-US", NORM_IGNORENONSPACE, L"\x16a4", L"\x16a5", CSTR_EQUAL }, /* NORM_IGNORENONSPACE */
+    /*  92 */ { L"en-US", 0, L"\x00c6", L"\x0041\x0045", CSTR_EQUAL }, /* Expansion */
+    /*  93 */ { L"en-US", 0, L"\x0f5c", L"\x0f5b\x0fb7", CSTR_EQUAL }, /* Expansion */
+    /*  94 */ { 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 40b5f521e0..a12b8bdb30 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;
@@ -2582,6 +2589,8 @@ static void LIST_ADD(list* name, const void *value)
 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;
@@ -2590,6 +2599,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;
@@ -2653,14 +2684,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);
@@ -2672,6 +2710,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)
@@ -2712,7 +2751,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.2




More information about the wine-devel mailing list