]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/cintltst/trietest.c
ICU-64260.0.1.tar.gz
[apple/icu.git] / icuSources / test / cintltst / trietest.c
index 3231879a2114d6bb487abdc75f82ca4b7d7d60e5..bf770a10fa49e6ecba939d3c1c74b57e36ce68d7 100644 (file)
@@ -1,12 +1,14 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
 *
-*   Copyright (C) 2001, International Business Machines
+*   Copyright (C) 2001-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
 *   file name:  trietest.c
-*   encoding:   US-ASCII
+*   encoding:   UTF-8
 *   tab size:   8 (not used)
 *   indentation:4
 *
@@ -16,6 +18,7 @@
 
 #include <stdio.h>
 #include "unicode/utypes.h"
+#include "unicode/utf16.h"
 #include "utrie.h"
 #include "cstring.h"
 #include "cmemory.h"
@@ -31,8 +34,6 @@
 #define u_errorName(errorCode) "some error code"
 #endif
 
-#define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
-
 /* Values for setting possibly overlapping, out-of-order ranges of values */
 typedef struct SetRange {
     UChar32 start, limit;
@@ -49,10 +50,6 @@ typedef struct CheckRange {
     UChar32 limit;
     uint32_t value;
 } CheckRange;
-struct{
-    double bogus; /* needed for aligining the storage */
-    uint8_t storage[10000000];
-} storageHolder;
 
 
 static uint32_t U_CALLCONV
@@ -160,7 +157,7 @@ testTrieIteration(const char *testName,
         c=checkRanges[i].limit;
         if(c!=0) {
             --c;
-            UTF_APPEND_CHAR_UNSAFE(s, length, c);
+            U16_APPEND_UNSAFE(s, length, c);
             values[countValues++]=checkRanges[i].value;
         }
     }
@@ -183,7 +180,7 @@ testTrieIteration(const char *testName,
         if(
             c2==0 ?
                 c!=*(p-1) :
-                !UTF_IS_LEAD(c) || !UTF_IS_TRAIL(c2) || c!=*(p-2) || c2!=*(p-1)
+                !U16_IS_LEAD(c) || !U16_IS_TRAIL(c2) || c!=*(p-2) || c2!=*(p-1)
         ) {
             log_err("error: wrong (c, c2) from UTRIE_NEXT(%s): (U+%04lx, U+%04lx)\n",
                     testName, c, c2);
@@ -247,7 +244,7 @@ testTrieIteration(const char *testName,
         if(
             c2==0 ?
                 c!=*p:
-                !UTF_IS_LEAD(c) || !UTF_IS_TRAIL(c2) || c!=*p || c2!=*(p+1)
+                !U16_IS_LEAD(c) || !U16_IS_TRAIL(c2) || c!=*p || c2!=*(p+1)
         ) {
             log_err("error: wrong (c, c2) from UTRIE_PREVIOUS(%s): (U+%04lx, U+%04lx)\n",
                     testName, c, c2);
@@ -270,10 +267,13 @@ testTrieRangesWithMalloc(const char *testName,
     UErrorCode errorCode;
     UBool overwrite, ok;
     uint8_t* storage =NULL;
-    storage = (uint8_t*) uprv_malloc(sizeof(uint8_t)*100000);
+    static const int32_t DEFAULT_STORAGE_SIZE = 32768;
+    storage = (uint8_t*) uprv_malloc(sizeof(uint8_t)*DEFAULT_STORAGE_SIZE);
 
     log_verbose("\ntesting Trie '%s'\n", testName);
-    newTrie=utrie_open(NULL, NULL, 2000, checkRanges[0].value, latin1Linear);
+    newTrie=utrie_open(NULL, NULL, 2000,
+                       checkRanges[0].value, checkRanges[0].value,
+                       latin1Linear);
 
     /* set values from setRanges[] */
     ok=TRUE;
@@ -315,7 +315,7 @@ testTrieRangesWithMalloc(const char *testName,
     }
 
     errorCode=U_ZERO_ERROR;
-    length=utrie_serialize(newTrie, storage, 1000000,
+    length=utrie_serialize(newTrie, storage, DEFAULT_STORAGE_SIZE,
                            dataIs32 ? _testFoldedValue32 : _testFoldedValue16,
                            (UBool)!dataIs32,
                            &errorCode);
@@ -385,7 +385,7 @@ testTrieRangesWithMalloc(const char *testName,
                     log_err("error: unserialized trie(%s).fromBMP(U+%04lx)==0x%lx instead of 0x%lx\n",
                             testName, start, value2, value);
                 }
-                if(!UTF_IS_LEAD(start)) {
+                if(!U16_IS_LEAD(start)) {
                     if(dataIs32) {
                         value2=UTRIE_GET32_FROM_LEAD(&trie, start);
                     } else {
@@ -446,7 +446,12 @@ testTrieRanges(const char *testName,
                const SetRange setRanges[], int32_t countSetRanges,
                const CheckRange checkRanges[], int32_t countCheckRanges,
                UBool dataIs32, UBool latin1Linear) {
+    union{
+        double bogus; /* needed for aligining the storage */
+        uint8_t storage[32768];
+    } storageHolder;
     UTrieGetFoldingOffset *getFoldingOffset;
+    UNewTrieGetFoldedValue *getFoldedValue;
     const CheckRange *enumRanges;
     UNewTrie *newTrie;
     UTrie trie={ 0 };
@@ -457,7 +462,9 @@ testTrieRanges(const char *testName,
     UBool overwrite, ok;
 
     log_verbose("\ntesting Trie '%s'\n", testName);
-    newTrie=utrie_open(NULL, NULL, 2000, checkRanges[0].value, latin1Linear);
+    newTrie=utrie_open(NULL, NULL, 2000,
+                       checkRanges[0].value, checkRanges[0].value,
+                       latin1Linear);
 
     /* set values from setRanges[] */
     ok=TRUE;
@@ -494,13 +501,24 @@ testTrieRanges(const char *testName,
 
     if(dataIs32) {
         getFoldingOffset=_testFoldingOffset32;
+        getFoldedValue=_testFoldedValue32;
     } else {
         getFoldingOffset=_testFoldingOffset16;
+        getFoldedValue=_testFoldedValue16;
+    }
+
+    /*
+     * code coverage for utrie.c/defaultGetFoldedValue(),
+     * pick some combination of parameters for selecting the UTrie defaults
+     */
+    if(!dataIs32 && latin1Linear) {
+        getFoldingOffset=NULL;
+        getFoldedValue=NULL;
     }
 
     errorCode=U_ZERO_ERROR;
     length=utrie_serialize(newTrie, storageHolder.storage, sizeof(storageHolder.storage),
-                           dataIs32 ? _testFoldedValue32 : _testFoldedValue16,
+                           getFoldedValue,
                            (UBool)!dataIs32,
                            &errorCode);
     if(U_FAILURE(errorCode)) {
@@ -508,6 +526,11 @@ testTrieRanges(const char *testName,
         utrie_close(newTrie);
         return;
     }
+    if (length >= (int32_t)sizeof(storageHolder.storage)) {
+        log_err("error: utrie_serialize(%s) needs more memory\n", testName);
+        utrie_close(newTrie);
+        return;
+    }
 
     /* test linear Latin-1 range from utrie_getData() */
     if(latin1Linear) {
@@ -537,7 +560,9 @@ testTrieRanges(const char *testName,
         log_err("error: utrie_unserialize() failed, %s\n", u_errorName(errorCode));
         return;
     }
-    trie.getFoldingOffset=getFoldingOffset;
+    if(getFoldingOffset!=NULL) {
+        trie.getFoldingOffset=getFoldingOffset;
+    }
 
     if(dataIs32!=(trie.data32!=NULL)) {
         log_err("error: trie serialization (%s) did not preserve 32-bitness\n", testName);
@@ -569,7 +594,7 @@ testTrieRanges(const char *testName,
                     log_err("error: unserialized trie(%s).fromBMP(U+%04lx)==0x%lx instead of 0x%lx\n",
                             testName, start, value2, value);
                 }
-                if(!UTF_IS_LEAD(start)) {
+                if(!U16_IS_LEAD(start)) {
                     if(dataIs32) {
                         value2=UTRIE_GET32_FROM_LEAD(&trie, start);
                     } else {
@@ -682,11 +707,11 @@ setRanges1[]={
     {0x20,   0xa7,       0x1234, FALSE},
     {0xa7,   0x3400,     0,      FALSE},
     {0x3400, 0x9fa6,     0x6162, FALSE},
-    {0x9fa6, 0xdada,     0x3132, FALSE},
-    {0xdada, 0xeeee,     0x27,   FALSE},
+    {0x9fa6, 0xda9e,     0x3132, FALSE},
+    {0xdada, 0xeeee,     0x87ff, FALSE}, /* try to disrupt _testFoldingOffset16() */
     {0xeeee, 0x11111,    1,      FALSE},
     {0x11111, 0x44444,   0x6162, FALSE},
-    {0x44444, 0xf0003,   0,      FALSE},
+    {0x44444, 0x60003,   0,      FALSE},
     {0xf0003, 0xf0004,   0xf,    FALSE},
     {0xf0004, 0xf0006,   0x10,   FALSE},
     {0xf0006, 0xf0007,   0x11,   FALSE},
@@ -701,8 +726,9 @@ checkRanges1[]={
     {0xa7,   0x1234},
     {0x3400, 0},
     {0x9fa6, 0x6162},
-    {0xdada, 0x3132},
-    {0xeeee, 0x27},
+    {0xda9e, 0x3132},
+    {0xdada, 0},
+    {0xeeee, 0x87ff},
     {0x11111,1},
     {0x44444,0x6162},
     {0xf0003,0},
@@ -720,6 +746,9 @@ setRanges2[]={
     {0x2f800,0x2fedc,    0x7a,   TRUE},
     {0x72,   0xdd,       3,      TRUE},
     {0xdd,   0xde,       4,      FALSE},
+    {0x201,  0x220,      6,      TRUE},  /* 3 consecutive blocks with the same pattern but discontiguous value ranges */
+    {0x221,  0x240,      6,      TRUE},
+    {0x241,  0x260,      6,      TRUE},
     {0x2f987,0x2fa98,    5,      TRUE},
     {0x2f777,0x2f833,    0,      TRUE},
     {0x2f900,0x2ffee,    1,      FALSE},
@@ -733,6 +762,12 @@ checkRanges2[]={
     {0x72,   0x5555},
     {0xdd,   3},
     {0xde,   4},
+    {0x201,  0},
+    {0x220,  6},
+    {0x221,  0},
+    {0x240,  6},
+    {0x241,  0},
+    {0x260,  6},
     {0x2f833,0},
     {0x2f987,0x7a},
     {0x2fa98,5},
@@ -766,28 +801,87 @@ checkRanges3[]={
 static void
 TrieTest(void) {
     testTrieRanges4("set1",
-        setRanges1, ARRAY_LENGTH(setRanges1),
-        checkRanges1, ARRAY_LENGTH(checkRanges1));
+        setRanges1, UPRV_LENGTHOF(setRanges1),
+        checkRanges1, UPRV_LENGTHOF(checkRanges1));
     testTrieRanges4("set2-overlap",
-        setRanges2, ARRAY_LENGTH(setRanges2),
-        checkRanges2, ARRAY_LENGTH(checkRanges2));
+        setRanges2, UPRV_LENGTHOF(setRanges2),
+        checkRanges2, UPRV_LENGTHOF(checkRanges2));
     testTrieRanges4("set3-initial-9",
-        setRanges3, ARRAY_LENGTH(setRanges3),
-        checkRanges3, ARRAY_LENGTH(checkRanges3));
+        setRanges3, UPRV_LENGTHOF(setRanges3),
+        checkRanges3, UPRV_LENGTHOF(checkRanges3));
+}
+
+/* test utrie_unserializeDummy() -------------------------------------------- */
+
+static int32_t U_CALLCONV
+dummyGetFoldingOffset(uint32_t data) {
+    return -1; /* never get non-initialValue data for supplementary code points */
+}
+
+static void
+dummyTest(UBool make16BitTrie) {
+    int32_t mem[UTRIE_DUMMY_SIZE/4];
+
+    UTrie trie;
+    UErrorCode errorCode;
+    UChar32 c;
+
+    uint32_t value, initialValue, leadUnitValue;
+
+    if(make16BitTrie) {
+        initialValue=0x313;
+        leadUnitValue=0xaffe;
+    } else {
+        initialValue=0x01234567;
+        leadUnitValue=0x89abcdef;
+    }
+
+    errorCode=U_ZERO_ERROR;
+    utrie_unserializeDummy(&trie, mem, sizeof(mem), initialValue, leadUnitValue, make16BitTrie, &errorCode);
+    if(U_FAILURE(errorCode)) {
+        log_err("utrie_unserializeDummy(make16BitTrie=%d) failed - %s\n", make16BitTrie, u_errorName(errorCode));
+        return;
+    }
+    trie.getFoldingOffset=dummyGetFoldingOffset;
+
+    /* test that all code points have initialValue */
+    for(c=0; c<=0x10ffff; ++c) {
+        if(make16BitTrie) {
+            UTRIE_GET16(&trie, c, value);
+        } else {
+            UTRIE_GET32(&trie, c, value);
+        }
+        if(value!=initialValue) {
+            log_err("UTRIE_GET%s(dummy, U+%04lx)=0x%lx instead of 0x%lx\n",
+                make16BitTrie ? "16" : "32", (long)c, (long)value, (long)initialValue);
+        }
+    }
+
+    /* test that the lead surrogate code units have leadUnitValue */
+    for(c=0xd800; c<=0xdbff; ++c) {
+        if(make16BitTrie) {
+            value=UTRIE_GET16_FROM_LEAD(&trie, c);
+        } else {
+            value=UTRIE_GET32_FROM_LEAD(&trie, c);
+        }
+        if(value!=leadUnitValue) {
+            log_err("UTRIE_GET%s_FROM_LEAD(dummy, U+%04lx)=0x%lx instead of 0x%lx\n",
+                make16BitTrie ? "16" : "32", (long)c, (long)value, (long)leadUnitValue);
+        }
+    }
+}
+
+static void
+DummyTrieTest(void) {
+    dummyTest(TRUE);
+    dummyTest(FALSE);
 }
 
-#if 1
 void
 addTrieTest(TestNode** root);
 
 void
 addTrieTest(TestNode** root) {
-    addTest(root, &TrieTest, "tsutil/TrieTest");
+    addTest(root, &TrieTest, "tsutil/trietest/TrieTest");
+    addTest(root, &DummyTrieTest, "tsutil/trietest/DummyTrieTest");
 }
-#else
-/* standalone utrie development */
-int main(int argc, const char *argv[]) {
-    TrieTest();
-    return 0;
-}
-#endif