+// © 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
*
#include <stdio.h>
#include "unicode/utypes.h"
+#include "unicode/utf16.h"
#include "utrie.h"
#include "cstring.h"
#include "cmemory.h"
#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;
UChar32 limit;
uint32_t value;
} CheckRange;
-struct{
- double bogus; /* needed for aligining the storage */
- uint8_t storage[10000000];
-} storageHolder;
static uint32_t U_CALLCONV
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;
}
}
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);
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);
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;
}
errorCode=U_ZERO_ERROR;
- length=utrie_serialize(newTrie, storage, 1000000,
+ length=utrie_serialize(newTrie, storage, DEFAULT_STORAGE_SIZE,
dataIs32 ? _testFoldedValue32 : _testFoldedValue16,
(UBool)!dataIs32,
&errorCode);
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 {
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 };
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;
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)) {
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) {
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);
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 {
{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},
{0xa7, 0x1234},
{0x3400, 0},
{0x9fa6, 0x6162},
- {0xdada, 0x3132},
- {0xeeee, 0x27},
+ {0xda9e, 0x3132},
+ {0xdada, 0},
+ {0xeeee, 0x87ff},
{0x11111,1},
{0x44444,0x6162},
{0xf0003,0},
{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},
{0x72, 0x5555},
{0xdd, 3},
{0xde, 4},
+ {0x201, 0},
+ {0x220, 6},
+ {0x221, 0},
+ {0x240, 6},
+ {0x241, 0},
+ {0x260, 6},
{0x2f833,0},
{0x2f987,0x7a},
{0x2fa98,5},
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