]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/cintltst/trietest.c
ICU-8.11.tar.gz
[apple/icu.git] / icuSources / test / cintltst / trietest.c
CommitLineData
b75a7d8f
A
1/*
2******************************************************************************
3*
73c04bcf 4* Copyright (C) 2001-2005, International Business Machines
b75a7d8f
A
5* Corporation and others. All Rights Reserved.
6*
7******************************************************************************
8* file name: trietest.c
9* encoding: US-ASCII
10* tab size: 8 (not used)
11* indentation:4
12*
13* created on: 2001nov20
14* created by: Markus W. Scherer
15*/
16
17#include <stdio.h>
18#include "unicode/utypes.h"
19#include "utrie.h"
20#include "cstring.h"
21#include "cmemory.h"
22
23#if 1
24#include "cintltst.h"
25#else
26/* definitions from standalone utrie development */
27#define log_err printf
28#define log_verbose printf
29
30#undef u_errorName
31#define u_errorName(errorCode) "some error code"
32#endif
33
34#define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
35
36/* Values for setting possibly overlapping, out-of-order ranges of values */
37typedef struct SetRange {
38 UChar32 start, limit;
39 uint32_t value;
40 UBool overwrite;
41} SetRange;
42
43/*
44 * Values for testing:
45 * value is set from the previous boundary's limit to before
46 * this boundary's limit
47 */
48typedef struct CheckRange {
49 UChar32 limit;
50 uint32_t value;
51} CheckRange;
52struct{
53 double bogus; /* needed for aligining the storage */
54 uint8_t storage[10000000];
55} storageHolder;
56
57
58static uint32_t U_CALLCONV
59_testFoldedValue32(UNewTrie *trie, UChar32 start, int32_t offset) {
60 uint32_t foldedValue, value;
61 UChar32 limit;
62 UBool inBlockZero;
63
64 foldedValue=0;
65
66 limit=start+0x400;
67 while(start<limit) {
68 value=utrie_get32(trie, start, &inBlockZero);
69 if(inBlockZero) {
70 start+=UTRIE_DATA_BLOCK_LENGTH;
71 } else {
72 foldedValue|=value;
73 ++start;
74 }
75 }
76
77 if(foldedValue!=0) {
78 return ((uint32_t)offset<<16)|foldedValue;
79 } else {
80 return 0;
81 }
82}
83
84static int32_t U_CALLCONV
85_testFoldingOffset32(uint32_t data) {
86 return (int32_t)(data>>16);
87}
88
89static uint32_t U_CALLCONV
90_testFoldedValue16(UNewTrie *trie, UChar32 start, int32_t offset) {
91 uint32_t foldedValue, value;
92 UChar32 limit;
93 UBool inBlockZero;
94
95 foldedValue=0;
96
97 limit=start+0x400;
98 while(start<limit) {
99 value=utrie_get32(trie, start, &inBlockZero);
100 if(inBlockZero) {
101 start+=UTRIE_DATA_BLOCK_LENGTH;
102 } else {
103 foldedValue|=value;
104 ++start;
105 }
106 }
107
108 if(foldedValue!=0) {
109 return (uint32_t)(offset|0x8000);
110 } else {
111 return 0;
112 }
113}
114
115static int32_t U_CALLCONV
116_testFoldingOffset16(uint32_t data) {
117 if(data&0x8000) {
118 return (int32_t)(data&0x7fff);
119 } else {
120 return 0;
121 }
122}
123
124static uint32_t U_CALLCONV
125_testEnumValue(const void *context, uint32_t value) {
126 return value^0x5555;
127}
128
129static UBool U_CALLCONV
130_testEnumRange(const void *context, UChar32 start, UChar32 limit, uint32_t value) {
131 const CheckRange **pb=(const CheckRange **)context;
132 const CheckRange *b=(*pb)++;
133
134 value^=0x5555;
135 if(start!=(b-1)->limit || limit!=b->limit || value!=b->value) {
136 log_err("error: utrie_enum() delivers wrong range [U+%04lx..U+%04lx[.0x%lx instead of [U+%04lx..U+%04lx[.0x%lx\n",
137 start, limit, value,
138 (b-1)->limit, b->limit, b->value);
139 }
140 return TRUE;
141}
142
143static void
144testTrieIteration(const char *testName,
145 const UTrie *trie,
146 const CheckRange checkRanges[], int32_t countCheckRanges) {
147 UChar s[100];
148 uint32_t values[30];
149
150 const UChar *p, *limit;
151
152 uint32_t value;
153 UChar32 c;
154 int32_t i, length, countValues;
155 UChar c2;
156
157 /* write a string */
158 length=countValues=0;
159 for(i=0; i<countCheckRanges; ++i) {
160 c=checkRanges[i].limit;
161 if(c!=0) {
162 --c;
163 UTF_APPEND_CHAR_UNSAFE(s, length, c);
164 values[countValues++]=checkRanges[i].value;
165 }
166 }
167 limit=s+length;
168
169 /* try forward */
170 p=s;
171 i=0;
172 while(p<limit) {
173 c=c2=0x33;
174 if(trie->data32!=NULL) {
175 UTRIE_NEXT32(trie, p, limit, c, c2, value);
176 } else {
177 UTRIE_NEXT16(trie, p, limit, c, c2, value);
178 }
179 if(value!=values[i]) {
180 log_err("error: wrong value from UTRIE_NEXT(%s)(U+%04lx, U+%04lx): 0x%lx instead of 0x%lx\n",
181 testName, c, c2, value, values[i]);
182 }
183 if(
184 c2==0 ?
185 c!=*(p-1) :
186 !UTF_IS_LEAD(c) || !UTF_IS_TRAIL(c2) || c!=*(p-2) || c2!=*(p-1)
187 ) {
188 log_err("error: wrong (c, c2) from UTRIE_NEXT(%s): (U+%04lx, U+%04lx)\n",
189 testName, c, c2);
190 continue;
191 }
192 if(c2!=0) {
193 int32_t offset;
194
195 if(trie->data32==NULL) {
196 value=UTRIE_GET16_FROM_LEAD(trie, c);
197 offset=trie->getFoldingOffset(value);
198 if(offset>0) {
199 value=UTRIE_GET16_FROM_OFFSET_TRAIL(trie, offset, c2);
200 } else {
201 value=trie->initialValue;
202 }
203 } else {
204 value=UTRIE_GET32_FROM_LEAD(trie, c);
205 offset=trie->getFoldingOffset(value);
206 if(offset>0) {
207 value=UTRIE_GET32_FROM_OFFSET_TRAIL(trie, offset, c2);
208 } else {
209 value=trie->initialValue;
210 }
211 }
212 if(value!=values[i]) {
213 log_err("error: wrong value from UTRIE_GETXX_FROM_OFFSET_TRAIL(%s)(U+%04lx, U+%04lx): 0x%lx instead of 0x%lx\n",
214 testName, c, c2, value, values[i]);
215 }
216 }
217 if(c2!=0) {
218 value=0x44;
219 if(trie->data32==NULL) {
220 UTRIE_GET16_FROM_PAIR(trie, c, c2, value);
221 } else {
222 UTRIE_GET32_FROM_PAIR(trie, c, c2, value);
223 }
224 if(value!=values[i]) {
225 log_err("error: wrong value from UTRIE_GETXX_FROM_PAIR(%s)(U+%04lx, U+%04lx): 0x%lx instead of 0x%lx\n",
226 testName, c, c2, value, values[i]);
227 }
228 }
229 ++i;
230 }
231
232 /* try backward */
233 p=limit;
234 i=countValues;
235 while(s<p) {
236 --i;
237 c=c2=0x33;
238 if(trie->data32!=NULL) {
239 UTRIE_PREVIOUS32(trie, s, p, c, c2, value);
240 } else {
241 UTRIE_PREVIOUS16(trie, s, p, c, c2, value);
242 }
243 if(value!=values[i]) {
244 log_err("error: wrong value from UTRIE_PREVIOUS(%s)(U+%04lx, U+%04lx): 0x%lx instead of 0x%lx\n",
245 testName, c, c2, value, values[i]);
246 }
247 if(
248 c2==0 ?
249 c!=*p:
250 !UTF_IS_LEAD(c) || !UTF_IS_TRAIL(c2) || c!=*p || c2!=*(p+1)
251 ) {
252 log_err("error: wrong (c, c2) from UTRIE_PREVIOUS(%s): (U+%04lx, U+%04lx)\n",
253 testName, c, c2);
254 }
255 }
256}
257
258static void
259testTrieRangesWithMalloc(const char *testName,
260 const SetRange setRanges[], int32_t countSetRanges,
261 const CheckRange checkRanges[], int32_t countCheckRanges,
262 UBool dataIs32, UBool latin1Linear) {
263 UTrieGetFoldingOffset *getFoldingOffset;
264 const CheckRange *enumRanges;
265 UNewTrie *newTrie;
266 UTrie trie={ 0 };
267 uint32_t value, value2;
268 UChar32 start, limit;
269 int32_t i, length;
270 UErrorCode errorCode;
271 UBool overwrite, ok;
272 uint8_t* storage =NULL;
273 storage = (uint8_t*) uprv_malloc(sizeof(uint8_t)*100000);
274
275 log_verbose("\ntesting Trie '%s'\n", testName);
374ca955
A
276 newTrie=utrie_open(NULL, NULL, 2000,
277 checkRanges[0].value, checkRanges[0].value,
278 latin1Linear);
b75a7d8f
A
279
280 /* set values from setRanges[] */
281 ok=TRUE;
282 for(i=0; i<countSetRanges; ++i) {
283 start=setRanges[i].start;
284 limit=setRanges[i].limit;
285 value=setRanges[i].value;
286 overwrite=setRanges[i].overwrite;
287 if((limit-start)==1 && overwrite) {
288 ok&=utrie_set32(newTrie, start, value);
289 } else {
290 ok&=utrie_setRange32(newTrie, start, limit, value, overwrite);
291 }
292 }
293 if(!ok) {
294 log_err("error: setting values into a trie failed (%s)\n", testName);
295 return;
296 }
297
298 /* verify that all these values are in the new Trie */
299 start=0;
300 for(i=0; i<countCheckRanges; ++i) {
301 limit=checkRanges[i].limit;
302 value=checkRanges[i].value;
303
304 while(start<limit) {
305 if(value!=utrie_get32(newTrie, start, NULL)) {
306 log_err("error: newTrie(%s)[U+%04lx]==0x%lx instead of 0x%lx\n",
307 testName, start, utrie_get32(newTrie, start, NULL), value);
308 }
309 ++start;
310 }
311 }
312
313 if(dataIs32) {
314 getFoldingOffset=_testFoldingOffset32;
315 } else {
316 getFoldingOffset=_testFoldingOffset16;
317 }
318
319 errorCode=U_ZERO_ERROR;
320 length=utrie_serialize(newTrie, storage, 1000000,
321 dataIs32 ? _testFoldedValue32 : _testFoldedValue16,
322 (UBool)!dataIs32,
323 &errorCode);
324 if(U_FAILURE(errorCode)) {
325 log_err("error: utrie_serialize(%s) failed: %s\n", testName, u_errorName(errorCode));
326 utrie_close(newTrie);
327 return;
328 }
329
330 /* test linear Latin-1 range from utrie_getData() */
331 if(latin1Linear) {
332 uint32_t *data;
333 int32_t dataLength;
334
335 data=utrie_getData(newTrie, &dataLength);
336 start=0;
337 for(i=0; i<countCheckRanges && start<=0xff; ++i) {
338 limit=checkRanges[i].limit;
339 value=checkRanges[i].value;
340
341 while(start<limit && start<=0xff) {
342 if(value!=data[UTRIE_DATA_BLOCK_LENGTH+start]) {
343 log_err("error: newTrie(%s).latin1Data[U+%04lx]==0x%lx instead of 0x%lx\n",
344 testName, start, data[UTRIE_DATA_BLOCK_LENGTH+start], value);
345 }
346 ++start;
347 }
348 }
349 }
350
351 utrie_close(newTrie);
352
353 errorCode=U_ZERO_ERROR;
354 if(!utrie_unserialize(&trie, storage, length, &errorCode)) {
355 log_err("error: utrie_unserialize() failed, %s\n", u_errorName(errorCode));
356 return;
357 }
358 trie.getFoldingOffset=getFoldingOffset;
359
360 if(dataIs32!=(trie.data32!=NULL)) {
361 log_err("error: trie serialization (%s) did not preserve 32-bitness\n", testName);
362 }
363 if(latin1Linear!=trie.isLatin1Linear) {
364 log_err("error: trie serialization (%s) did not preserve Latin-1-linearity\n", testName);
365 }
366
367 /* verify that all these values are in the unserialized Trie */
368 start=0;
369 for(i=0; i<countCheckRanges; ++i) {
370 limit=checkRanges[i].limit;
371 value=checkRanges[i].value;
372
373 if(start==0xd800) {
374 /* skip surrogates */
375 start=limit;
376 continue;
377 }
378
379 while(start<limit) {
380 if(start<=0xffff) {
381 if(dataIs32) {
382 value2=UTRIE_GET32_FROM_BMP(&trie, start);
383 } else {
384 value2=UTRIE_GET16_FROM_BMP(&trie, start);
385 }
386 if(value!=value2) {
387 log_err("error: unserialized trie(%s).fromBMP(U+%04lx)==0x%lx instead of 0x%lx\n",
388 testName, start, value2, value);
389 }
390 if(!UTF_IS_LEAD(start)) {
391 if(dataIs32) {
392 value2=UTRIE_GET32_FROM_LEAD(&trie, start);
393 } else {
394 value2=UTRIE_GET16_FROM_LEAD(&trie, start);
395 }
396 if(value!=value2) {
397 log_err("error: unserialized trie(%s).fromLead(U+%04lx)==0x%lx instead of 0x%lx\n",
398 testName, start, value2, value);
399 }
400 }
401 }
402 if(dataIs32) {
403 UTRIE_GET32(&trie, start, value2);
404 } else {
405 UTRIE_GET16(&trie, start, value2);
406 }
407 if(value!=value2) {
408 log_err("error: unserialized trie(%s).get(U+%04lx)==0x%lx instead of 0x%lx\n",
409 testName, start, value2, value);
410 }
411 ++start;
412 }
413 }
414
415 /* enumerate and verify all ranges */
416 enumRanges=checkRanges+1;
417 utrie_enum(&trie, _testEnumValue, _testEnumRange, &enumRanges);
418
419 /* test linear Latin-1 range */
420 if(trie.isLatin1Linear) {
421 if(trie.data32!=NULL) {
422 const uint32_t *latin1=UTRIE_GET32_LATIN1(&trie);
423
424 for(start=0; start<0x100; ++start) {
425 if(latin1[start]!=UTRIE_GET32_FROM_LEAD(&trie, start)) {
426 log_err("error: (%s) trie.latin1[U+%04lx]=0x%lx!=0x%lx=trie.get32(U+%04lx)\n",
427 testName, start, latin1[start], UTRIE_GET32_FROM_LEAD(&trie, start), start);
428 }
429 }
430 } else {
431 const uint16_t *latin1=UTRIE_GET16_LATIN1(&trie);
432
433 for(start=0; start<0x100; ++start) {
434 if(latin1[start]!=UTRIE_GET16_FROM_LEAD(&trie, start)) {
435 log_err("error: (%s) trie.latin1[U+%04lx]=0x%lx!=0x%lx=trie.get16(U+%04lx)\n",
436 testName, start, latin1[start], UTRIE_GET16_FROM_LEAD(&trie, start), start);
437 }
438 }
439 }
440 }
441
442 testTrieIteration(testName, &trie, checkRanges, countCheckRanges);
443 uprv_free(storage);
444}
445
446static void
447testTrieRanges(const char *testName,
448 const SetRange setRanges[], int32_t countSetRanges,
449 const CheckRange checkRanges[], int32_t countCheckRanges,
450 UBool dataIs32, UBool latin1Linear) {
451 UTrieGetFoldingOffset *getFoldingOffset;
73c04bcf 452 UNewTrieGetFoldedValue *getFoldedValue;
b75a7d8f
A
453 const CheckRange *enumRanges;
454 UNewTrie *newTrie;
455 UTrie trie={ 0 };
456 uint32_t value, value2;
457 UChar32 start, limit;
458 int32_t i, length;
459 UErrorCode errorCode;
460 UBool overwrite, ok;
461
462 log_verbose("\ntesting Trie '%s'\n", testName);
374ca955
A
463 newTrie=utrie_open(NULL, NULL, 2000,
464 checkRanges[0].value, checkRanges[0].value,
465 latin1Linear);
b75a7d8f
A
466
467 /* set values from setRanges[] */
468 ok=TRUE;
469 for(i=0; i<countSetRanges; ++i) {
470 start=setRanges[i].start;
471 limit=setRanges[i].limit;
472 value=setRanges[i].value;
473 overwrite=setRanges[i].overwrite;
474 if((limit-start)==1 && overwrite) {
475 ok&=utrie_set32(newTrie, start, value);
476 } else {
477 ok&=utrie_setRange32(newTrie, start, limit, value, overwrite);
478 }
479 }
480 if(!ok) {
481 log_err("error: setting values into a trie failed (%s)\n", testName);
482 return;
483 }
484
485 /* verify that all these values are in the new Trie */
486 start=0;
487 for(i=0; i<countCheckRanges; ++i) {
488 limit=checkRanges[i].limit;
489 value=checkRanges[i].value;
490
491 while(start<limit) {
492 if(value!=utrie_get32(newTrie, start, NULL)) {
493 log_err("error: newTrie(%s)[U+%04lx]==0x%lx instead of 0x%lx\n",
494 testName, start, utrie_get32(newTrie, start, NULL), value);
495 }
496 ++start;
497 }
498 }
499
500 if(dataIs32) {
501 getFoldingOffset=_testFoldingOffset32;
73c04bcf 502 getFoldedValue=_testFoldedValue32;
b75a7d8f
A
503 } else {
504 getFoldingOffset=_testFoldingOffset16;
73c04bcf
A
505 getFoldedValue=_testFoldedValue16;
506 }
507
508 /*
509 * code coverage for utrie.c/defaultGetFoldedValue(),
510 * pick some combination of parameters for selecting the UTrie defaults
511 */
512 if(!dataIs32 && latin1Linear) {
513 getFoldingOffset=NULL;
514 getFoldedValue=NULL;
b75a7d8f
A
515 }
516
517 errorCode=U_ZERO_ERROR;
518 length=utrie_serialize(newTrie, storageHolder.storage, sizeof(storageHolder.storage),
73c04bcf 519 getFoldedValue,
b75a7d8f
A
520 (UBool)!dataIs32,
521 &errorCode);
522 if(U_FAILURE(errorCode)) {
523 log_err("error: utrie_serialize(%s) failed: %s\n", testName, u_errorName(errorCode));
524 utrie_close(newTrie);
525 return;
526 }
527
528 /* test linear Latin-1 range from utrie_getData() */
529 if(latin1Linear) {
530 uint32_t *data;
531 int32_t dataLength;
532
533 data=utrie_getData(newTrie, &dataLength);
534 start=0;
535 for(i=0; i<countCheckRanges && start<=0xff; ++i) {
536 limit=checkRanges[i].limit;
537 value=checkRanges[i].value;
538
539 while(start<limit && start<=0xff) {
540 if(value!=data[UTRIE_DATA_BLOCK_LENGTH+start]) {
541 log_err("error: newTrie(%s).latin1Data[U+%04lx]==0x%lx instead of 0x%lx\n",
542 testName, start, data[UTRIE_DATA_BLOCK_LENGTH+start], value);
543 }
544 ++start;
545 }
546 }
547 }
548
549 utrie_close(newTrie);
550
551 errorCode=U_ZERO_ERROR;
552 if(!utrie_unserialize(&trie, storageHolder.storage, length, &errorCode)) {
553 log_err("error: utrie_unserialize() failed, %s\n", u_errorName(errorCode));
554 return;
555 }
73c04bcf
A
556 if(getFoldingOffset!=NULL) {
557 trie.getFoldingOffset=getFoldingOffset;
558 }
b75a7d8f
A
559
560 if(dataIs32!=(trie.data32!=NULL)) {
561 log_err("error: trie serialization (%s) did not preserve 32-bitness\n", testName);
562 }
563 if(latin1Linear!=trie.isLatin1Linear) {
564 log_err("error: trie serialization (%s) did not preserve Latin-1-linearity\n", testName);
565 }
566
567 /* verify that all these values are in the unserialized Trie */
568 start=0;
569 for(i=0; i<countCheckRanges; ++i) {
570 limit=checkRanges[i].limit;
571 value=checkRanges[i].value;
572
573 if(start==0xd800) {
574 /* skip surrogates */
575 start=limit;
576 continue;
577 }
578
579 while(start<limit) {
580 if(start<=0xffff) {
581 if(dataIs32) {
582 value2=UTRIE_GET32_FROM_BMP(&trie, start);
583 } else {
584 value2=UTRIE_GET16_FROM_BMP(&trie, start);
585 }
586 if(value!=value2) {
587 log_err("error: unserialized trie(%s).fromBMP(U+%04lx)==0x%lx instead of 0x%lx\n",
588 testName, start, value2, value);
589 }
590 if(!UTF_IS_LEAD(start)) {
591 if(dataIs32) {
592 value2=UTRIE_GET32_FROM_LEAD(&trie, start);
593 } else {
594 value2=UTRIE_GET16_FROM_LEAD(&trie, start);
595 }
596 if(value!=value2) {
597 log_err("error: unserialized trie(%s).fromLead(U+%04lx)==0x%lx instead of 0x%lx\n",
598 testName, start, value2, value);
599 }
600 }
601 }
602 if(dataIs32) {
603 UTRIE_GET32(&trie, start, value2);
604 } else {
605 UTRIE_GET16(&trie, start, value2);
606 }
607 if(value!=value2) {
608 log_err("error: unserialized trie(%s).get(U+%04lx)==0x%lx instead of 0x%lx\n",
609 testName, start, value2, value);
610 }
611 ++start;
612 }
613 }
614
615 /* enumerate and verify all ranges */
616 enumRanges=checkRanges+1;
617 utrie_enum(&trie, _testEnumValue, _testEnumRange, &enumRanges);
618
619 /* test linear Latin-1 range */
620 if(trie.isLatin1Linear) {
621 if(trie.data32!=NULL) {
622 const uint32_t *latin1=UTRIE_GET32_LATIN1(&trie);
623
624 for(start=0; start<0x100; ++start) {
625 if(latin1[start]!=UTRIE_GET32_FROM_LEAD(&trie, start)) {
626 log_err("error: (%s) trie.latin1[U+%04lx]=0x%lx!=0x%lx=trie.get32(U+%04lx)\n",
627 testName, start, latin1[start], UTRIE_GET32_FROM_LEAD(&trie, start), start);
628 }
629 }
630 } else {
631 const uint16_t *latin1=UTRIE_GET16_LATIN1(&trie);
632
633 for(start=0; start<0x100; ++start) {
634 if(latin1[start]!=UTRIE_GET16_FROM_LEAD(&trie, start)) {
635 log_err("error: (%s) trie.latin1[U+%04lx]=0x%lx!=0x%lx=trie.get16(U+%04lx)\n",
636 testName, start, latin1[start], UTRIE_GET16_FROM_LEAD(&trie, start), start);
637 }
638 }
639 }
640 }
641
642 testTrieIteration(testName, &trie, checkRanges, countCheckRanges);
643}
644
645static void
646testTrieRanges2(const char *testName,
647 const SetRange setRanges[], int32_t countSetRanges,
648 const CheckRange checkRanges[], int32_t countCheckRanges,
649 UBool dataIs32) {
650 char name[40];
651
652 testTrieRanges(testName,
653 setRanges, countSetRanges,
654 checkRanges, countCheckRanges,
655 dataIs32, FALSE);
656 testTrieRangesWithMalloc(testName,
657 setRanges, countSetRanges,
658 checkRanges, countCheckRanges,
659 dataIs32, FALSE);
660
661 uprv_strcpy(name, testName);
662 uprv_strcat(name, "-latin1Linear");
663 testTrieRanges(name,
664 setRanges, countSetRanges,
665 checkRanges, countCheckRanges,
666 dataIs32, TRUE);
667 testTrieRangesWithMalloc(name,
668 setRanges, countSetRanges,
669 checkRanges, countCheckRanges,
670 dataIs32, TRUE);
671}
672
673static void
674testTrieRanges4(const char *testName,
675 const SetRange setRanges[], int32_t countSetRanges,
676 const CheckRange checkRanges[], int32_t countCheckRanges) {
677 char name[40];
678
679 uprv_strcpy(name, testName);
680 uprv_strcat(name, ".32");
681 testTrieRanges2(name,
682 setRanges, countSetRanges,
683 checkRanges, countCheckRanges,
684 TRUE);
685
686 uprv_strcpy(name, testName);
687 uprv_strcat(name, ".16");
688 testTrieRanges2(name,
689 setRanges, countSetRanges,
690 checkRanges, countCheckRanges,
691 FALSE);
692}
693
694/* test data ----------------------------------------------------------------*/
695
696/* set consecutive ranges, even with value 0 */
697static const SetRange
698setRanges1[]={
699 {0, 0x20, 0, FALSE},
700 {0x20, 0xa7, 0x1234, FALSE},
701 {0xa7, 0x3400, 0, FALSE},
702 {0x3400, 0x9fa6, 0x6162, FALSE},
374ca955
A
703 {0x9fa6, 0xda9e, 0x3132, FALSE},
704 {0xdada, 0xeeee, 0x87ff, FALSE}, /* try to disrupt _testFoldingOffset16() */
b75a7d8f
A
705 {0xeeee, 0x11111, 1, FALSE},
706 {0x11111, 0x44444, 0x6162, FALSE},
374ca955 707 {0x44444, 0x60003, 0, FALSE},
b75a7d8f
A
708 {0xf0003, 0xf0004, 0xf, FALSE},
709 {0xf0004, 0xf0006, 0x10, FALSE},
710 {0xf0006, 0xf0007, 0x11, FALSE},
711 {0xf0007, 0xf0020, 0x12, FALSE},
712 {0xf0020, 0x110000, 0, FALSE}
713};
714
715static const CheckRange
716checkRanges1[]={
717 {0, 0}, /* dummy start range to make _testEnumRange() simpler */
718 {0x20, 0},
719 {0xa7, 0x1234},
720 {0x3400, 0},
721 {0x9fa6, 0x6162},
374ca955
A
722 {0xda9e, 0x3132},
723 {0xdada, 0},
724 {0xeeee, 0x87ff},
b75a7d8f
A
725 {0x11111,1},
726 {0x44444,0x6162},
727 {0xf0003,0},
728 {0xf0004,0xf},
729 {0xf0006,0x10},
730 {0xf0007,0x11},
731 {0xf0020,0x12},
732 {0x110000, 0}
733};
734
735/* set some interesting overlapping ranges */
736static const SetRange
737setRanges2[]={
738 {0x21, 0x7f, 0x5555, TRUE},
739 {0x2f800,0x2fedc, 0x7a, TRUE},
740 {0x72, 0xdd, 3, TRUE},
741 {0xdd, 0xde, 4, FALSE},
742 {0x2f987,0x2fa98, 5, TRUE},
743 {0x2f777,0x2f833, 0, TRUE},
744 {0x2f900,0x2ffee, 1, FALSE},
745 {0x2ffee,0x2ffef, 2, TRUE}
746};
747
748static const CheckRange
749checkRanges2[]={
750 {0, 0}, /* dummy start range to make _testEnumRange() simpler */
751 {0x21, 0},
752 {0x72, 0x5555},
753 {0xdd, 3},
754 {0xde, 4},
755 {0x2f833,0},
756 {0x2f987,0x7a},
757 {0x2fa98,5},
758 {0x2fedc,0x7a},
759 {0x2ffee,1},
760 {0x2ffef,2},
761 {0x110000, 0}
762};
763
764/* use a non-zero initial value */
765static const SetRange
766setRanges3[]={
767 {0x31, 0xa4, 1, FALSE},
768 {0x3400, 0x6789, 2, FALSE},
769 {0x30000,0x34567,9, TRUE},
770 {0x45678,0x56789,3, TRUE}
771};
772
773static const CheckRange
774checkRanges3[]={
775 {0, 9}, /* dummy start range, also carries the initial value */
776 {0x31, 9},
777 {0xa4, 1},
778 {0x3400, 9},
779 {0x6789, 2},
780 {0x45678,9},
781 {0x56789,3},
782 {0x110000,9}
783};
784
785static void
786TrieTest(void) {
787 testTrieRanges4("set1",
788 setRanges1, ARRAY_LENGTH(setRanges1),
789 checkRanges1, ARRAY_LENGTH(checkRanges1));
790 testTrieRanges4("set2-overlap",
791 setRanges2, ARRAY_LENGTH(setRanges2),
792 checkRanges2, ARRAY_LENGTH(checkRanges2));
793 testTrieRanges4("set3-initial-9",
794 setRanges3, ARRAY_LENGTH(setRanges3),
795 checkRanges3, ARRAY_LENGTH(checkRanges3));
796}
797
73c04bcf
A
798/* test utrie_unserializeDummy() -------------------------------------------- */
799
800static int32_t U_CALLCONV
801dummyGetFoldingOffset(uint32_t data) {
802 return -1; /* never get non-initialValue data for supplementary code points */
803}
804
805static void
806dummyTest(UBool make16BitTrie) {
807 static int32_t mem[UTRIE_DUMMY_SIZE/4];
808
809 UTrie trie;
810 UErrorCode errorCode;
811 UChar32 c;
812
813 uint32_t value, initialValue, leadUnitValue;
814
815 if(make16BitTrie) {
816 initialValue=0x313;
817 leadUnitValue=0xaffe;
818 } else {
819 initialValue=0x01234567;
820 leadUnitValue=0x89abcdef;
821 }
822
823 errorCode=U_ZERO_ERROR;
824 utrie_unserializeDummy(&trie, mem, sizeof(mem), initialValue, leadUnitValue, make16BitTrie, &errorCode);
825 if(U_FAILURE(errorCode)) {
826 log_err("utrie_unserializeDummy(make16BitTrie=%d) failed - %s\n", make16BitTrie, u_errorName(errorCode));
827 return;
828 }
829 trie.getFoldingOffset=dummyGetFoldingOffset;
830
831 /* test that all code points have initialValue */
832 for(c=0; c<=0x10ffff; ++c) {
833 if(make16BitTrie) {
834 UTRIE_GET16(&trie, c, value);
835 } else {
836 UTRIE_GET32(&trie, c, value);
837 }
838 if(value!=initialValue) {
839 log_err("UTRIE_GET%s(dummy, U+%04lx)=0x%lx instead of 0x%lx\n",
840 make16BitTrie ? "16" : "32", (long)c, (long)value, (long)initialValue);
841 }
842 }
843
844 /* test that the lead surrogate code units have leadUnitValue */
845 for(c=0xd800; c<=0xdbff; ++c) {
846 if(make16BitTrie) {
847 value=UTRIE_GET16_FROM_LEAD(&trie, c);
848 } else {
849 value=UTRIE_GET32_FROM_LEAD(&trie, c);
850 }
851 if(value!=leadUnitValue) {
852 log_err("UTRIE_GET%s_FROM_LEAD(dummy, U+%04lx)=0x%lx instead of 0x%lx\n",
853 make16BitTrie ? "16" : "32", (long)c, (long)value, (long)leadUnitValue);
854 }
855 }
856}
857
858static void
859DummyTrieTest(void) {
860 dummyTest(TRUE);
861 dummyTest(FALSE);
862}
863
b75a7d8f
A
864void
865addTrieTest(TestNode** root);
866
867void
868addTrieTest(TestNode** root) {
374ca955 869 addTest(root, &TrieTest, "tsutil/trietest/TrieTest");
73c04bcf 870 addTest(root, &DummyTrieTest, "tsutil/trietest/DummyTrieTest");
b75a7d8f 871}