Alexandre Julliard : kernelbase: Add support for SORT_DIGITSASNUMBERS in sortkeys.

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


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

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

kernelbase: Add support for SORT_DIGITSASNUMBERS in sortkeys.

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

---

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

diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index 179f0436578..ec6e7047be6 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -3318,6 +3318,56 @@ static int get_compression_weights( UINT compression, const WCHAR *compr_tables[
     return 0;
 }
 
+/* get the zero digit for the digit character range that contains 'ch' */
+static WCHAR get_digit_zero_char( WCHAR ch )
+{
+    static const WCHAR zeroes[] =
+    {
+        0x0030, 0x0660, 0x06f0, 0x0966, 0x09e6, 0x0a66, 0x0ae6, 0x0b66, 0x0be6, 0x0c66,
+        0x0ce6, 0x0d66, 0x0e50, 0x0ed0, 0x0f20, 0x1040, 0x1090, 0x17e0, 0x1810, 0x1946,
+        0x1bb0, 0x1c40, 0x1c50, 0xa620, 0xa8d0, 0xa900, 0xaa50, 0xff10
+    };
+    int min = 0, max = ARRAY_SIZE( zeroes ) - 1;
+
+    while (min <= max)
+    {
+        int pos = (min + max) / 2;
+        if (zeroes[pos] <= ch && zeroes[pos] + 9 >= ch) return zeroes[pos];
+        if (zeroes[pos] < ch) min = pos + 1;
+        else max = pos - 1;
+    }
+    return 0;
+}
+
+/* append weights for digits when using SORT_DIGITSASNUMBERS */
+/* return the number of extra chars to skip */
+static int append_digit_weights( struct sortkey *key, const WCHAR *src, UINT srclen )
+{
+    UINT i, zero, len, lzero;
+    BYTE val, values[19];
+
+    if (!(zero = get_digit_zero_char( *src ))) return -1;
+
+    values[0] = *src - zero;
+    for (len = 1; len < ARRAY_SIZE(values) && len < srclen; len++)
+    {
+        if (src[len] < zero || src[len] > zero + 9) break;
+        values[len] = src[len] - zero;
+    }
+    for (lzero = 0; lzero < len; lzero++) if (values[lzero]) break;
+
+    append_sortkey( key, SCRIPT_DIGIT );
+    append_sortkey( key, 2 );
+    append_sortkey( key, 2 + len - lzero );
+    for (i = lzero, val = 2; i < len; i++)
+    {
+        if ((len - i) % 2) append_sortkey( key, (val << 4) + values[i] + 2 );
+        else val = values[i] + 2;
+    }
+    append_sortkey( key, 0xfe - lzero );
+    return len - 1;
+}
+
 /* append the extra weights for kana prolonged sound / repeat marks */
 static int append_extra_kana_weights( struct sortkey keys[4], const WCHAR *src, int pos, UINT except,
                                       BYTE case_mask, union char_weights *weights )
@@ -3614,6 +3664,19 @@ static int append_weights( const struct sortguid *sortid, DWORD flags,
         append_sortkey( &s->key_case, weights._case );
         break;
 
+    case SCRIPT_DIGIT:
+        if (flags & SORT_DIGITSASNUMBERS)
+        {
+            int len = append_digit_weights( &s->key_primary, src + pos, srclen - pos );
+            if (len >= 0)
+            {
+                ret += len;
+                append_sortkey( &s->key_diacritic, weights.diacritic );
+                append_sortkey( &s->key_case, weights._case );
+                break;
+            }
+        }
+        /* fall through */
     default:
         append_normal_weights( sortid, &s->key_primary, &s->key_diacritic, &s->key_case, weights, flags );
         break;




More information about the wine-cvs mailing list