Alexandre Julliard : kernelbase: Add support for character expansion in sortkeys.

Alexandre Julliard julliard at winehq.org
Mon May 30 15:34:56 CDT 2022


Module: wine
Branch: master
Commit: 9605f5870ad70076f70d29c78091cb9f9ca6ac92
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=9605f5870ad70076f70d29c78091cb9f9ca6ac92

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon May 30 13:02:09 2022 +0200

kernelbase: Add support for character expansion in sortkeys.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernelbase/locale.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index 08842cf2c08..8eaa5f5fb3c 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -337,6 +337,11 @@ struct sortguid
 #define FLAG_DOUBLECOMPRESSION  0x20
 #define FLAG_INVERSECASING      0x40
 
+struct sort_expansion
+{
+    WCHAR exp[2];
+};
+
 union char_weights
 {
     UINT val;
@@ -388,11 +393,13 @@ static struct
 {
     UINT                           version;         /* NLS version */
     UINT                           guid_count;      /* number of sort GUIDs */
+    UINT                           exp_count;       /* number of character expansions */
     const UINT                    *keys;            /* sortkey table, indexed by char */
     const USHORT                  *casemap;         /* casemap table, in l_intl.nls format */
     const WORD                    *ctypes;          /* CT_CTYPE1,2,3 values */
     const BYTE                    *ctype_idx;       /* index to map char to ctypes array entry */
     const struct sortguid         *guids;           /* table of sort GUIDs */
+    const struct sort_expansion   *expansions;      /* character expansions */
 } sort;
 
 static CRITICAL_SECTION locale_section;
@@ -475,6 +482,10 @@ static void load_sortdefault_nls(void)
     sort.guid_count = table[1];
     sort.guids = (struct sortguid *)(table + 2);
 
+    table = (UINT *)(sort.guids + sort.guid_count);
+    sort.exp_count = table[0];
+    sort.expansions = (struct sort_expansion *)(table + 1);
+
     locale_sorts = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,
                                     locale_table->nb_lcnames * sizeof(*locale_sorts) );
 }
@@ -3207,6 +3218,23 @@ static void append_nonspace_weights( struct sortkey *key, union char_weights wei
     else append_sortkey( key, weights.diacritic );
 }
 
+static void append_expansion_weights( const struct sortguid *sortid, struct sortkey *key_primary,
+                                      struct sortkey *key_diacritic, struct sortkey *key_case,
+                                      union char_weights weights, DWORD flags, BOOL is_compare )
+{
+    /* sortkey and comparison behave differently here */
+    if (is_compare)
+    {
+        if (weights.script == SCRIPT_UNSORTABLE) return;
+        if (weights.script == SCRIPT_NONSPACE_MARK)
+        {
+            append_nonspace_weights( key_diacritic, weights, flags );
+            return;
+        }
+    }
+    append_normal_weights( sortid, key_primary, key_diacritic, key_case, weights, flags );
+}
+
 /* put one of the elements of a sortkey into the dst buffer */
 static int put_sortkey( BYTE *dst, int dstlen, int pos, const struct sortkey *key, BYTE terminator )
 {
@@ -3290,6 +3318,7 @@ static int append_weights( const struct sortguid *sortid, DWORD flags,
                            const WCHAR *compr_tables[8], struct sortkey_state *s, BOOL is_compare )
 {
     union char_weights weights = get_char_weights( src[pos], except );
+    WCHAR idx = (weights.val >> 16) & ~(CASE_COMPR_6 << 8);  /* expansion index */
     int ret = 1;
 
     weights._case &= case_mask;
@@ -3303,6 +3332,21 @@ static int append_weights( const struct sortguid *sortid, DWORD flags,
         append_nonspace_weights( &s->key_diacritic, weights, flags );
         break;
 
+    case SCRIPT_EXPANSION:
+        while (weights.script == SCRIPT_EXPANSION)
+        {
+            weights = get_char_weights( sort.expansions[idx].exp[0], except );
+            weights._case &= case_mask;
+            append_expansion_weights( sortid, &s->key_primary, &s->key_diacritic,
+                                      &s->key_case, weights, flags, is_compare );
+            weights = get_char_weights( sort.expansions[idx].exp[1], except );
+            idx = weights.val >> 16;
+            weights._case &= case_mask;
+        }
+        append_expansion_weights( sortid, &s->key_primary, &s->key_diacritic,
+                                  &s->key_case, weights, flags, is_compare );
+        break;
+
     case SCRIPT_EXTENSION_A:
         append_sortkey( &s->key_primary, 0xfd );
         append_sortkey( &s->key_primary, 0xff );




More information about the wine-cvs mailing list