[RFC 2/5] kernelbase/locale: Implement sortkey punctuation

Fabian Maurer dark.shadow4 at web.de
Sat Apr 11 14:45:46 CDT 2020


---
 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




More information about the wine-devel mailing list