Alexandre Julliard : kernel32/tests: Optionally test the entire NormalizationTest.txt file.

Alexandre Julliard julliard at winehq.org
Tue Feb 4 15:33:20 CST 2020


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Feb  4 14:31:45 2020 +0100

kernel32/tests: Optionally test the entire NormalizationTest.txt file.

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

---

 dlls/kernel32/tests/locale.c | 115 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 113 insertions(+), 2 deletions(-)

diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index 76a993e6c3..36822d5acc 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -5862,6 +5862,36 @@ static void test_SetThreadUILanguage(void)
     "expected %d got %d\n", MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH_BELGIAN), res);
 }
 
+static int put_utf16( WCHAR *str, unsigned int c )
+{
+    if (c < 0x10000)
+    {
+        *str = c;
+        return 1;
+    }
+    c -= 0x10000;
+    str[0] = 0xd800 | (c >> 10);
+    str[1] = 0xdc00 | (c & 0x3ff);
+    return 2;
+}
+
+/* read a Unicode string from NormalizationTest.txt format; helper for test_NormalizeString */
+static int read_str( char *str, WCHAR res[32] )
+{
+    int pos = 0;
+    char *end;
+
+    while (*str && pos < 31)
+    {
+        unsigned int c = strtoul( str, &end, 16 );
+        pos += put_utf16( res + pos, c );
+        while (*end == ' ') end++;
+        str = end;
+    }
+    res[pos] = 0;
+    return pos;
+}
+
 static void test_NormalizeString(void)
 {
     /* part 0: specific cases */
@@ -6010,8 +6040,10 @@ static void test_NormalizeString(void)
     const struct test_data_normal *ptest = test_arr;
     const int norm_forms[] = { NormalizationC, NormalizationD, NormalizationKC, NormalizationKD };
     WCHAR dst[256];
+    BOOLEAN ret;
     NTSTATUS status;
     int dstlen, str_cmp, i, j;
+    FILE *f;
 
     if (!pNormalizeString)
     {
@@ -6057,8 +6089,6 @@ static void test_NormalizeString(void)
 
             if (pRtlNormalizeString)
             {
-                BOOLEAN ret = FALSE;
-
                 dstlen = 0;
                 status = pRtlNormalizeString( norm_forms[i], ptest->str, lstrlenW(ptest->str), NULL, &dstlen );
                 ok( !status, "%s:%d: failed %x\n", wine_dbgstr_w(ptest->str), i, status );
@@ -6072,6 +6102,7 @@ static void test_NormalizeString(void)
                 str_cmp = wcsncmp( ptest->expected[i], dst, dstlen );
                 ok( str_cmp == 0, "%s:%d: string incorrect got %s expect %s\n", wine_dbgstr_w(ptest->str), i,
                     wine_dbgstr_w(dst), wine_dbgstr_w(ptest->expected[i]) );
+                ret = FALSE;
                 status = pRtlIsNormalizedString( norm_forms[i], dst, dstlen, &ret );
                 todo_wine ok( !status, "%s:%d: failed %x\n", wine_dbgstr_w(ptest->str), i, status );
                 todo_wine ok( ret, "%s:%d: not normalized\n", wine_dbgstr_w(ptest->str), i );
@@ -6258,6 +6289,86 @@ static void test_NormalizeString(void)
             todo_wine ok( dstlen == 3, "%d: wrong len %d\n", i, dstlen );
         }
     }
+
+    /* optionally run the full test file from Unicode.org
+     * available at http://www.unicode.org/Public/UCD/latest/ucd/NormalizationTest.txt
+     */
+    if ((f = fopen( "NormalizationTest.txt", "r" )))
+    {
+        char *p, buffer[1024];
+        WCHAR str[3], srcW[32], dstW[32], resW[4][32];
+        int i, line = 0, part = 0, ch;
+        char tested[0x110000 / 8];
+
+        while (fgets( buffer, sizeof(buffer), f ))
+        {
+            line++;
+            if ((p = strchr( buffer, '#' ))) *p = 0;
+            if (!strncmp( buffer, "@Part", 5 ))
+            {
+                part = atoi( buffer + 5 );
+                continue;
+            }
+            if (!(p = strtok( buffer, ";" ))) continue;
+            read_str( p, srcW );
+            for (i = 0; i < 4; i++)
+            {
+                p = strtok( NULL, ";" );
+                read_str( p, &resW[i][0] );
+            }
+            if (part == 1)
+            {
+                ch = srcW[0];
+                if (ch >= 0xd800 && ch <= 0xdbff)
+                    ch = 0x10000 + ((srcW[0] & 0x3ff) << 10) + (srcW[1] & 0x3ff);
+                tested[ch / 8] |= 1 << (ch % 8);
+            }
+            for (i = 0; i < 4; i++)
+            {
+                memset( dstW, 0xcc, sizeof(dstW) );
+                dstlen = pNormalizeString( norm_forms[i], srcW, -1, dstW, ARRAY_SIZE(dstW) );
+                ok( !wcscmp( dstW, resW[i] ),
+                    "line %u form %u: wrong result %s for %s expected %s\n", line, i,
+                    wine_dbgstr_w( dstW ), wine_dbgstr_w( srcW ), wine_dbgstr_w( resW[i] ));
+            }
+        }
+        fclose( f );
+
+        /* test chars that are not in the @Part1 list */
+        for (ch = 0; ch < 0x110000; ch++)
+        {
+            if (tested[ch / 8] & (1 << (ch % 8))) continue;
+            str[put_utf16( str, ch )] = 0;
+            for (i = 0; i < 4; i++)
+            {
+                memset( dstW, 0xcc, sizeof(dstW) );
+                SetLastError( 0xdeadbeef );
+                dstlen = pNormalizeString( norm_forms[i], str, -1, dstW, ARRAY_SIZE(dstW) );
+                if ((ch >= 0xd800 && ch <= 0xdfff) ||
+                    (ch >= 0xfdd0 && ch <= 0xfdef) ||
+                    ((ch & 0xffff) >= 0xfffe))
+                {
+                    ok( dstlen <= 0, "char %04x form %u: wrong result %d %s expected error\n",
+                        ch, i, dstlen, wine_dbgstr_w( dstW ));
+                    ok( GetLastError() == ERROR_NO_UNICODE_TRANSLATION,
+                        "char %04x form %u: error %u\n", str[0], i, GetLastError() );
+                    status = pRtlIsNormalizedString( norm_forms[i], str, -1, &ret );
+                    ok( status == STATUS_NO_UNICODE_TRANSLATION,
+                        "char %04x form %u: failed %x\n", ch, i, status );
+                }
+                else
+                {
+                    ok( !wcscmp( dstW, str ),
+                        "char %04x form %u: wrong result %s expected unchanged\n",
+                        ch, i, wine_dbgstr_w( dstW ));
+                    ret = FALSE;
+                    status = pRtlIsNormalizedString( norm_forms[i], str, -1, &ret );
+                    ok( !status, "char %04x form %u: failed %x\n", ch, i, status );
+                    ok( ret, "char %04x form %u: not normalized\n", ch, i );
+                }
+            }
+        }
+    }
 }
 
 static void test_SpecialCasing(void)




More information about the wine-cvs mailing list