1
/********************************************************************
3
* Copyright (c) 2001, International Business Machines Corporation and
4
* others. All Rights Reserved.
5
********************************************************************/
6
/*******************************************************************************
10
*******************************************************************************/
12
* These are the tests specific to ICU 1.8 and above, that I didn't know where
17
#include "unicode/utypes.h"
18
#include "unicode/ucol.h"
19
#include "unicode/ucoleitr.h"
20
#include "unicode/uloc.h"
24
#include "unicode/ustring.h"
30
#include "unicode/parseerr.h"
32
#define MAX_TOKEN_LEN 16
33
#define RULE_BUFFER_LEN 8192
35
typedef int tst_strcoll(void *collator, const int object,
36
const UChar *source, const int sLen,
37
const UChar *target, const int tLen);
41
* Return an integer array containing all of the collation orders
42
* returned by calls to next on the specified iterator
44
static int32_t* getOrders(UCollationElements *iter, int32_t *orderLength)
48
int32_t maxSize = 100;
51
int32_t *orders =(int32_t*)malloc(sizeof(int32_t) * maxSize);
55
while ((order=ucol_next(iter, &status)) != UCOL_NULLORDER)
60
temp = (int32_t*)malloc(sizeof(int32_t) * maxSize);
62
memcpy(temp, orders, size * sizeof(int32_t));
68
orders[size++] = order;
71
if (maxSize > size && size > 0)
73
temp = (int32_t*)malloc(sizeof(int32_t) * size);
75
memcpy(temp, orders, size * sizeof(int32_t));
86
static void backAndForth(UCollationElements *iter)
88
/* Run through the iterator forwards and stick it into an array */
90
UErrorCode status = U_ZERO_ERROR;
91
int32_t orderLength = 0;
93
orders= getOrders(iter, &orderLength);
96
/* Now go through it backwards and make sure we get the same values */
100
/* synwee : changed */
101
while ((o = ucol_previous(iter, &status)) != UCOL_NULLORDER)
103
if (o != orders[-- index])
109
while (index > 0 && orders[-- index] == 0)
112
if (o != orders[index])
114
log_err("Mismatch at index : %d\n", index);
121
while (index != 0 && orders[index - 1] == 0) {
127
log_err("Didn't get back to beginning - index is %d\n", index);
131
while ((o = ucol_next(iter, &status)) != UCOL_NULLORDER)
133
log_err("Error at %d\n", o);
136
while ((o = ucol_previous(iter, &status)) != UCOL_NULLORDER)
138
log_err("Error at %d\n", o);
146
const static char cnt1[][10] = {
160
const static char cnt2[][10] = {
172
static void IncompleteCntTest(void)
174
UErrorCode status = U_ZERO_ERROR;
179
UCollator *coll = NULL;
180
uint32_t i = 0, j = 0;
183
u_uastrcpy(temp, " & Z < ABC < Q < B");
185
coll = ucol_openRules(temp, u_strlen(temp), UCOL_OFF, UCOL_DEFAULT_STRENGTH, NULL,&status);
187
if(U_SUCCESS(status)) {
188
size = sizeof(cnt1)/sizeof(cnt1[0]);
189
for(i = 0; i < size-1; i++) {
190
for(j = i+1; j < size; j++) {
191
UCollationElements *iter;
192
u_uastrcpy(t1, cnt1[i]);
193
u_uastrcpy(t2, cnt1[j]);
194
doTest(coll, t1, t2, UCOL_LESS);
195
/* synwee : added collation element iterator test */
196
iter = ucol_openElements(coll, t2, u_strlen(t2), &status);
197
if (U_FAILURE(status)) {
198
log_err("Creation of iterator failed\n");
210
u_uastrcpy(temp, " & Z < DAVIS < MARK <DAV");
211
coll = ucol_openRules(temp, u_strlen(temp), UCOL_OFF, UCOL_DEFAULT_STRENGTH,NULL, &status);
213
if(U_SUCCESS(status)) {
214
size = sizeof(cnt2)/sizeof(cnt2[0]);
215
for(i = 0; i < size-1; i++) {
216
for(j = i+1; j < size; j++) {
217
UCollationElements *iter;
218
u_uastrcpy(t1, cnt2[i]);
219
u_uastrcpy(t2, cnt2[j]);
220
doTest(coll, t1, t2, UCOL_LESS);
222
/* synwee : added collation element iterator test */
223
iter = ucol_openElements(coll, t2, u_strlen(t2), &status);
224
if (U_FAILURE(status)) {
225
log_err("Creation of iterator failed\n");
239
const static char shifted[][20] = {
251
const static UCollationResult shiftedTert[] = {
263
const static char nonignorable[][20] = {
275
static void BlackBirdTest(void) {
276
UErrorCode status = U_ZERO_ERROR;
280
uint32_t i = 0, j = 0;
282
UCollator *coll = ucol_open("en_US", &status);
284
ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
285
ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status);
287
if(U_SUCCESS(status)) {
288
size = sizeof(nonignorable)/sizeof(nonignorable[0]);
289
for(i = 0; i < size-1; i++) {
290
for(j = i+1; j < size; j++) {
291
u_uastrcpy(t1, nonignorable[i]);
292
u_uastrcpy(t2, nonignorable[j]);
293
doTest(coll, t1, t2, UCOL_LESS);
298
ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
299
ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_QUATERNARY, &status);
301
if(U_SUCCESS(status)) {
302
size = sizeof(shifted)/sizeof(shifted[0]);
303
for(i = 0; i < size-1; i++) {
304
for(j = i+1; j < size; j++) {
305
u_uastrcpy(t1, shifted[i]);
306
u_uastrcpy(t2, shifted[j]);
307
doTest(coll, t1, t2, UCOL_LESS);
312
ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_TERTIARY, &status);
313
if(U_SUCCESS(status)) {
314
size = sizeof(shifted)/sizeof(shifted[0]);
315
for(i = 1; i < size; i++) {
316
u_uastrcpy(t1, shifted[i-1]);
317
u_uastrcpy(t2, shifted[i]);
318
doTest(coll, t1, t2, shiftedTert[i]);
325
const static UChar testSourceCases[][MAX_TOKEN_LEN] = {
326
{0x0041/*'A'*/, 0x0300, 0x0301, 0x0000},
327
{0x0041/*'A'*/, 0x0300, 0x0316, 0x0000},
328
{0x0041/*'A'*/, 0x0300, 0x0000},
329
{0x00C0, 0x0301, 0x0000},
330
/* this would work with forced normalization */
331
{0x00C0, 0x0316, 0x0000}
334
const static UChar testTargetCases[][MAX_TOKEN_LEN] = {
335
{0x0041/*'A'*/, 0x0301, 0x0300, 0x0000},
336
{0x0041/*'A'*/, 0x0316, 0x0300, 0x0000},
338
{0x0041/*'A'*/, 0x0301, 0x0300, 0x0000},
339
/* this would work with forced normalization */
340
{0x0041/*'A'*/, 0x0316, 0x0300, 0x0000}
343
const static UCollationResult results[] = {
351
static void FunkyATest(void)
355
UErrorCode status = U_ZERO_ERROR;
356
UCollator *myCollation;
357
myCollation = ucol_open("en_US", &status);
358
if(U_FAILURE(status)){
359
log_err("ERROR: in creation of rule based collator: %s\n", myErrorName(status));
362
log_verbose("Testing some A letters, for some reason\n");
363
ucol_setAttribute(myCollation, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
364
ucol_setStrength(myCollation, UCOL_TERTIARY);
365
for (i = 0; i < 4 ; i++)
367
doTest(myCollation, testSourceCases[i], testTargetCases[i], results[i]);
369
ucol_close(myCollation);
372
UColAttributeValue caseFirst[] = {
379
UColAttributeValue alternateHandling[] = {
384
UColAttributeValue caseLevel[] = {
389
UColAttributeValue strengths[] = {
397
static const char * strengthsC[] = {
406
static const char * caseFirstC[] = {
413
static const char * alternateHandlingC[] = {
414
"UCOL_NON_IGNORABLE",
418
static const char * caseLevelC[] = {
423
/* not used currently - does not test only prints */
424
static void PrintMarkDavis(void)
426
UErrorCode status = U_ZERO_ERROR;
428
uint8_t sortkey[256];
429
UCollator *coll = ucol_open("en_US", &status);
430
uint32_t h,i,j,k, sortkeysize;
435
log_verbose("PrintMarkDavis");
437
u_uastrcpy(m, "Mark Davis");
443
for(i = 0; i<sizem; i++) {
444
fprintf(stderr, "\\u%04X ", m[i]);
446
fprintf(stderr, "\n");
448
for(h = 0; h<sizeof(caseFirst)/sizeof(caseFirst[0]); h++) {
449
ucol_setAttribute(coll, UCOL_CASE_FIRST, caseFirst[i], &status);
450
fprintf(stderr, "caseFirst: %s\n", caseFirstC[h]);
452
for(i = 0; i<sizeof(alternateHandling)/sizeof(alternateHandling[0]); i++) {
453
ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, alternateHandling[i], &status);
454
fprintf(stderr, " AltHandling: %s\n", alternateHandlingC[i]);
456
for(j = 0; j<sizeof(caseLevel)/sizeof(caseLevel[0]); j++) {
457
ucol_setAttribute(coll, UCOL_CASE_LEVEL, caseLevel[j], &status);
458
fprintf(stderr, " caseLevel: %s\n", caseLevelC[j]);
460
for(k = 0; k<sizeof(strengths)/sizeof(strengths[0]); k++) {
461
ucol_setAttribute(coll, UCOL_STRENGTH, strengths[k], &status);
462
sortkeysize = ucol_getSortKey(coll, m, sizem, sortkey, 256);
463
fprintf(stderr, " strength: %s\n Sortkey: ", strengthsC[k]);
464
fprintf(stderr, "%s\n", ucol_sortKeyToString(coll, sortkey, buffer, &len));
475
static void BillFairmanTest(void) {
477
** check for actual locale via ICU resource bundles
479
** lp points to the original locale ("fr_FR_....")
482
UResourceBundle *lr,*cr;
483
UErrorCode lec = U_ZERO_ERROR;
484
const char *lp = "fr_FR_you_ll_never_find_this_locale";
486
log_verbose("BillFairmanTest\n");
488
lr = ures_open(NULL,lp,&lec);
490
cr = ures_getByKey(lr,"CollationElements",0,&lec);
492
lp = ures_getLocale(cr,&lec);
494
if (U_SUCCESS(lec)) {
495
if(strcmp(lp, "fr") != 0) {
496
log_err("Wrong locale for French Collation Data, expected \"fr\" got %s", lp);
506
static void testPrimary(UCollator* col, const UChar* p,const UChar* q){
507
UChar source[256] = { '\0'};
508
UChar target[256] = { '\0'};
512
UChar preP = (*p>0x0400 && *p<0x0500)?0x00e1:0x491;
513
UChar preQ = (*p>0x0400 && *p<0x0500)?0x0041:0x413;
515
/*log_verbose("Testing primary\n");*/
517
doTest(col, p, q, UCOL_LESS);
519
UCollationResult result = ucol_strcoll(col,p,u_strlen(p),q,u_strlen(q));
521
if(result!=UCOL_LESS){
522
aescstrdup(p,utfSource,256);
523
aescstrdup(q,utfTarget,256);
524
fprintf(file,"Primary failed source: %s target: %s \n", utfSource,utfTarget);
528
u_strcpy(source+1,p);
530
u_strcpy(target+1,q);
531
doTest(col, source, target, UCOL_LESS);
533
fprintf(file,"Primary swamps 2nd failed source: %s target: %s \n", utfSource,utfTarget);
537
static void testSecondary(UCollator* col, const UChar* p,const UChar* q){
538
UChar source[256] = { '\0'};
539
UChar target[256] = { '\0'};
541
/*log_verbose("Testing secondary\n");*/
543
doTest(col, p, q, UCOL_LESS);
545
fprintf(file,"secondary failed source: %s target: %s \n", utfSource,utfTarget);
548
u_strcpy(source+1,p);
550
u_strcpy(target+1,q);
552
doTest(col, source, target, UCOL_LESS);
554
fprintf(file,"secondary swamps 3rd failed source: %s target: %s \n",utfSource,utfTarget);
559
source[u_strlen(p)] = 0x62;
560
source[u_strlen(p)+1] = 0;
564
target[u_strlen(q)] = 0x61;
565
target[u_strlen(q)+1] = 0;
567
doTest(col, source, target, UCOL_GREATER);
570
fprintf(file,"secondary is swamped by 1 failed source: %s target: %s \n",utfSource,utfTarget);
574
static void testTertiary(UCollator* col, const UChar* p,const UChar* q){
575
UChar source[256] = { '\0'};
576
UChar target[256] = { '\0'};
578
/*log_verbose("Testing tertiary\n");*/
580
doTest(col, p, q, UCOL_LESS);
582
fprintf(file,"Tertiary failed source: %s target: %s \n",utfSource,utfTarget);
585
u_strcpy(source+1,p);
587
u_strcpy(target+1,q);
589
doTest(col, source, target, UCOL_LESS);
591
fprintf(file,"Tertiary swamps 4th failed source: %s target: %s \n", utfSource,utfTarget);
595
source[u_strlen(p)] = 0xE0;
596
source[u_strlen(p)+1] = 0;
599
target[u_strlen(q)] = 0x61;
600
target[u_strlen(q)+1] = 0;
602
doTest(col, source, target, UCOL_GREATER);
605
fprintf(file,"Tertiary is swamped by 3rd failed source: %s target: %s \n",utfSource,utfTarget);
609
static void testEquality(UCollator* col, const UChar* p,const UChar* q){
611
UChar source[256] = { '\0'};
612
UChar target[256] = { '\0'};
615
doTest(col, p, q, UCOL_EQUAL);
617
fprintf(file,"Primary failed source: %s target: %s \n", utfSource,utfTarget);
621
static void testCollator(UCollator *coll, UErrorCode *status) {
622
const UChar *rules = NULL, *current = NULL;
624
uint32_t strength = 0;
625
uint32_t chOffset = 0; uint32_t chLen = 0;
626
uint32_t exOffset = 0; uint32_t exLen = 0;
627
uint32_t prefixOffset = 0; uint32_t prefixLen = 0;
628
uint32_t firstEx = 0;
629
/* uint32_t rExpsLen = 0; */
630
uint32_t firstLen = 0;
631
UBool varT = FALSE; UBool top_ = TRUE;
633
UBool startOfRules = TRUE;
634
UBool lastReset = FALSE;
635
UBool before = FALSE;
643
UChar *rulesCopy = NULL;
644
UParseError parseError;
647
rules = ucol_getRules(coll, &ruleLen);
648
if(U_SUCCESS(*status) && ruleLen > 0) {
649
rulesCopy = (UChar *)uprv_malloc((ruleLen+UCOL_TOK_EXTRA_RULE_SPACE_SIZE)*sizeof(UChar));
650
uprv_memcpy(rulesCopy, rules, ruleLen*sizeof(UChar));
651
src.source = src.current = rulesCopy;
652
src.end = rulesCopy+ruleLen;
653
src.extraCurrent = src.end;
654
src.extraEnd = src.end+UCOL_TOK_EXTRA_RULE_SPACE_SIZE;
655
*first = *second = 0;
657
while ((current = ucol_tok_parseNextToken(&src, startOfRules,&parseError, status)) != NULL) {
658
strength = src.parsedToken.strength;
659
chOffset = src.parsedToken.charsOffset;
660
chLen = src.parsedToken.charsLen;
661
exOffset = src.parsedToken.extensionOffset;
662
exLen = src.parsedToken.extensionLen;
663
prefixOffset = src.parsedToken.prefixOffset;
664
prefixLen = src.parsedToken.prefixLen;
665
specs = src.parsedToken.flags;
667
startOfRules = FALSE;
668
varT = (UBool)((specs & UCOL_TOK_VARIABLE_TOP) != 0);
669
top_ = (UBool)((specs & UCOL_TOK_TOP) != 0);
670
if(top_) { /* if reset is on top, we should just continue */
673
u_strncpy(second,rulesCopy+chOffset, chLen);
676
if(exLen > 0 && firstEx == 0) {
677
u_strncat(first, rulesCopy+exOffset, exLen);
678
first[firstLen+exLen] = 0;
681
if(lastReset == TRUE && prefixLen != 0) {
682
u_strncpy(first+prefixLen, first, firstLen);
683
u_strncpy(first, rulesCopy+prefixOffset, prefixLen);
684
first[firstLen+prefixLen] = 0;
685
firstLen = firstLen+prefixLen;
688
if(before == TRUE) { /* swap first and second */
689
u_strcpy(tempB, first);
690
u_strcpy(first, second);
691
u_strcpy(second, tempB);
706
testEquality(coll,first,second);
709
testPrimary(coll,first,second);
712
testSecondary(coll,first,second);
715
testTertiary(coll,first,second);
719
before = (UBool)((specs & UCOL_TOK_BEFORE) != 0);
725
if(before == TRUE && strength != UCOL_TOK_RESET) { /* first and second were swapped */
730
u_strcpy(first, second);
733
uprv_free(rulesCopy);
737
static int ucaTest(void *collator, const int object, const UChar *source, const int sLen, const UChar *target, const int tLen) {
738
UCollator *UCA = (UCollator *)collator;
739
return ucol_strcoll(UCA, source, sLen, target, tLen);
743
static int winTest(void *collator, const int object, const UChar *source, const int sLen, const UChar *target, const int tLen) {
745
LCID lcid = (LCID)collator;
746
return CompareString(lcid, 0, source, sLen, target, tLen);
753
static UCollationResult swampEarlier(tst_strcoll* func, void *collator, int opts,
755
const UChar *s, const uint32_t sLen,
756
const UChar *t, const uint32_t tLen) {
757
UChar source[256] = {0};
758
UChar target[256] = {0};
761
u_strcpy(source+1, s);
763
u_strcpy(target+1, t);
765
return func(collator, opts, source, sLen+1, target, tLen+1);
768
static UCollationResult swampLater(tst_strcoll* func, void *collator, int opts,
770
const UChar *s, const uint32_t sLen,
771
const UChar *t, const uint32_t tLen) {
772
UChar source[256] = {0};
773
UChar target[256] = {0};
780
return func(collator, opts, source, sLen+1, target, tLen+1);
783
static uint32_t probeStrength(tst_strcoll* func, void *collator, int opts,
784
const UChar *s, const uint32_t sLen,
785
const UChar *t, const uint32_t tLen,
786
UCollationResult result) {
787
/*UChar fPrimary = 0x6d;*/
788
/*UChar sPrimary = 0x6e;*/
789
UChar fSecondary = 0x310d;
790
UChar sSecondary = 0x31a3;
791
UChar fTertiary = 0x310f;
792
UChar sTertiary = 0x31b7;
794
UCollationResult oposite;
795
if(result == UCOL_EQUAL) {
796
return UCOL_IDENTICAL;
797
} else if(result == UCOL_GREATER) {
800
oposite = UCOL_GREATER;
803
if(swampEarlier(func, collator, opts, sSecondary, fSecondary, s, sLen, t, tLen) == result) {
805
} else if((swampEarlier(func, collator, opts, sTertiary, 0x310f, s, sLen, t, tLen) == result) &&
806
(swampEarlier(func, collator, opts, 0x310f, sTertiary, s, sLen, t, tLen) == result)) {
807
return UCOL_SECONDARY;
808
} else if((swampLater(func, collator, opts, sTertiary, fTertiary, s, sLen, t, tLen) == result) &&
809
(swampLater(func, collator, opts, fTertiary, sTertiary, s, sLen, t, tLen) == result)) {
810
return UCOL_TERTIARY;
811
} else if((swampLater(func, collator, opts, sTertiary, 0x310f, s, sLen, t, tLen) == oposite) &&
812
(swampLater(func, collator, opts, fTertiary, sTertiary, s, sLen, t, tLen) == oposite)) {
813
return UCOL_QUATERNARY;
815
return UCOL_IDENTICAL;
819
static char *getRelationSymbol(UCollationResult res, uint32_t strength, char *buffer) {
822
if(res == UCOL_EQUAL || strength == 0xdeadbeef) {
826
} else if(res == UCOL_GREATER) {
827
for(i = 0; i<strength+1; i++) {
830
buffer[strength+1] = '\0';
832
for(i = 0; i<strength+1; i++) {
835
buffer[strength+1] = '\0';
843
static void logFailure (const char *platform, const char *test,
844
const UChar *source, const uint32_t sLen,
845
const UChar *target, const uint32_t tLen,
846
UCollationResult realRes, uint32_t realStrength,
847
UCollationResult expRes, uint32_t expStrength, UBool error) {
851
char sEsc[256], s[256], tEsc[256], t[256], b[256], output[256], relation[256];
853
*sEsc = *tEsc = *s = *t = 0;
855
log_err("Difference between expected and generated order. Run test with -v for more info\n");
857
for(i = 0; i<sLen; i++) {
858
sprintf(b, "%04X", source[i]);
863
if(source[i] < 0x80) {
864
sprintf(b, "(%c)", source[i]);
868
for(i = 0; i<tLen; i++) {
869
sprintf(b, "%04X", target[i]);
874
if(target[i] < 0x80) {
875
sprintf(b, "(%c)", target[i]);
880
strcpy(output, "[[ ");
881
strcat(output, sEsc);
882
strcat(output, getRelationSymbol(expRes, expStrength, relation));
883
strcat(output, tEsc);
885
strcat(output, " : ");
887
strcat(output, sEsc);
888
strcat(output, getRelationSymbol(realRes, realStrength, relation));
889
strcat(output, tEsc);
890
strcat(output, " ]] ");
892
log_verbose("%s", output);
896
strcpy(output, "DIFF: ");
899
strcat(output, " : ");
902
strcat(output, test);
903
strcat(output, ": ");
905
strcat(output, sEsc);
906
strcat(output, getRelationSymbol(expRes, expStrength, relation));
907
strcat(output, tEsc);
911
strcat(output, platform);
912
strcat(output, ": ");
914
strcat(output, sEsc);
915
strcat(output, getRelationSymbol(realRes, realStrength, relation));
916
strcat(output, tEsc);
918
log_verbose("%s\n", output);
923
static void printOutRules(const UChar *rules) {
924
uint32_t len = u_strlen(rules);
929
fprintf(stdout, "Rules:");
931
for(i = 0; i<len; i++) {
932
if(rules[i]<0x7f && rules[i]>=0x20) {
933
toPrint = (char)rules[i];
936
fprintf(stdout, "\n&");
937
} else if(toPrint == ';') {
938
fprintf(stdout, "<<");
940
} else if(toPrint == ',') {
941
fprintf(stdout, "<<<");
944
fprintf(stdout, "%c", toPrint);
947
} else if(rules[i]<0x3400 || rules[i]>=0xa000) {
948
fprintf(stdout, "\\u%04X", rules[i]);
952
fprintf(stdout, "\n");
962
static uint32_t testSwitch(tst_strcoll* func, void *collator, int opts, uint32_t strength, const UChar *first, const UChar *second, const char* msg, UBool error) {
964
UCollationResult realResult;
965
uint32_t realStrength;
967
uint32_t sLen = u_strlen(first);
968
uint32_t tLen = u_strlen(second);
970
realResult = func(collator, opts, first, sLen, second, tLen);
971
realStrength = probeStrength(func, collator, opts, first, sLen, second, tLen, realResult);
973
if(strength == UCOL_IDENTICAL && realResult != UCOL_IDENTICAL) {
974
logFailure(msg, "tailoring", first, sLen, second, tLen, realResult, realStrength, UCOL_EQUAL, strength, error);
976
} else if(realResult != UCOL_LESS || realStrength != strength) {
977
logFailure(msg, "tailoring", first, sLen, second, tLen, realResult, realStrength, UCOL_LESS, strength, error);
984
static void testAgainstUCA(UCollator *coll, UCollator *UCA, const char *refName, UBool error, UErrorCode *status) {
985
const UChar *rules = NULL, *current = NULL;
987
uint32_t strength = 0;
988
uint32_t chOffset = 0; uint32_t chLen = 0;
989
uint32_t exOffset = 0; uint32_t exLen = 0;
990
uint32_t prefixOffset = 0; uint32_t prefixLen = 0;
991
/* uint32_t rExpsLen = 0; */
992
uint32_t firstLen = 0, secondLen = 0;
993
UBool varT = FALSE; UBool top_ = TRUE;
995
UBool startOfRules = TRUE;
1001
UChar *rulesCopy = NULL;
1003
uint32_t UCAdiff = 0;
1004
uint32_t Windiff = 1;
1005
UParseError parseError;
1009
rules = ucol_getRules(coll, &ruleLen);
1011
/*printOutRules(rules);*/
1013
if(U_SUCCESS(*status) && ruleLen > 0) {
1014
rulesCopy = (UChar *)uprv_malloc((ruleLen+UCOL_TOK_EXTRA_RULE_SPACE_SIZE)*sizeof(UChar));
1015
uprv_memcpy(rulesCopy, rules, ruleLen*sizeof(UChar));
1016
src.source = src.current = rulesCopy;
1017
src.end = rulesCopy+ruleLen;
1018
src.extraCurrent = src.end;
1019
src.extraEnd = src.end+UCOL_TOK_EXTRA_RULE_SPACE_SIZE;
1020
*first = *second = 0;
1022
while ((current = ucol_tok_parseNextToken(&src, startOfRules, &parseError,status)) != NULL) {
1023
strength = src.parsedToken.strength;
1024
chOffset = src.parsedToken.charsOffset;
1025
chLen = src.parsedToken.charsLen;
1026
exOffset = src.parsedToken.extensionOffset;
1027
exLen = src.parsedToken.extensionLen;
1028
prefixOffset = src.parsedToken.prefixOffset;
1029
prefixLen = src.parsedToken.prefixLen;
1030
specs = src.parsedToken.flags;
1032
startOfRules = FALSE;
1033
varT = (UBool)((specs & UCOL_TOK_VARIABLE_TOP) != 0);
1034
top_ = (UBool)((specs & UCOL_TOK_TOP) != 0);
1036
u_strncpy(second,rulesCopy+chOffset, chLen);
1041
u_strncat(first, rulesCopy+exOffset, exLen);
1042
first[firstLen+exLen] = 0;
1046
if(strength != UCOL_TOK_RESET) {
1047
if((*first<0x3400 || *first>=0xa000) && (*second<0x3400 || *second>=0xa000)) {
1048
UCAdiff += testSwitch(&ucaTest, (void *)UCA, 0, strength, first, second, refName, error);
1049
/*Windiff += testSwitch(&winTest, (void *)lcid, 0, strength, first, second, "Win32");*/
1055
u_strcpy(first, second);
1058
if(UCAdiff != 0 && Windiff != 0) {
1062
log_verbose("No immediate difference with %s!\n", refName);
1065
log_verbose("No immediate difference with Win32!\n");
1067
uprv_free(rulesCopy);
1071
static void testCEs(UCollator *coll, UErrorCode *status) {
1073
const UChar *rules = NULL, *current = NULL;
1074
int32_t ruleLen = 0;
1076
uint32_t strength = 0;
1077
uint32_t maxStrength = UCOL_IDENTICAL;
1078
uint32_t baseCE, baseContCE, nextCE, nextContCE, currCE, currContCE;
1080
uint32_t lastContCE;
1083
uint32_t chOffset = 0; uint32_t chLen = 0;
1084
uint32_t exOffset = 0; uint32_t exLen = 0;
1085
uint32_t prefixOffset = 0; uint32_t prefixLen = 0;
1086
uint32_t oldOffset = 0;
1088
/* uint32_t rExpsLen = 0; */
1089
/* uint32_t firstLen = 0; */
1091
UBool varT = FALSE; UBool top_ = TRUE;
1092
UBool startOfRules = TRUE;
1093
UColTokenParser src;
1095
UParseError parseError;
1096
UChar *rulesCopy = NULL;
1099
baseCE=baseContCE=nextCE=nextContCE=currCE=currContCE=lastCE=lastContCE = UCOL_NOT_FOUND;
1103
rules = ucol_getRules(coll, &ruleLen);
1105
ucol_initInverseUCA(status);
1107
if(U_SUCCESS(*status) && ruleLen > 0) {
1108
rulesCopy = (UChar *)uprv_malloc((ruleLen+UCOL_TOK_EXTRA_RULE_SPACE_SIZE)*sizeof(UChar));
1109
uprv_memcpy(rulesCopy, rules, ruleLen*sizeof(UChar));
1110
src.source = src.current = rulesCopy;
1111
src.end = rulesCopy+ruleLen;
1112
src.extraCurrent = src.end;
1113
src.extraEnd = src.end+UCOL_TOK_EXTRA_RULE_SPACE_SIZE;
1115
while ((current = ucol_tok_parseNextToken(&src, startOfRules, &parseError,status)) != NULL) {
1116
strength = src.parsedToken.strength;
1117
chOffset = src.parsedToken.charsOffset;
1118
chLen = src.parsedToken.charsLen;
1119
exOffset = src.parsedToken.extensionOffset;
1120
exLen = src.parsedToken.extensionLen;
1121
prefixOffset = src.parsedToken.prefixOffset;
1122
prefixLen = src.parsedToken.prefixLen;
1123
specs = src.parsedToken.flags;
1125
startOfRules = FALSE;
1126
varT = (UBool)((specs & UCOL_TOK_VARIABLE_TOP) != 0);
1127
top_ = (UBool)((specs & UCOL_TOK_TOP) != 0);
1129
init_collIterate(coll, rulesCopy+chOffset, chLen, &c);
1131
currCE = ucol_getNextCE(coll, &c, status);
1132
if(currCE == 0 && UCOL_ISTHAIPREVOWEL(*(rulesCopy+chOffset))) {
1133
log_verbose("Thai prevowel detected. Will pick next CE\n");
1134
currCE = ucol_getNextCE(coll, &c, status);
1137
currContCE = ucol_getNextCE(coll, &c, status);
1138
if(!isContinuation(currContCE)) {
1142
if(strength == UCOL_TOK_RESET) {
1144
nextCE = baseCE = currCE = UCOL_RESET_TOP_VALUE;
1145
nextContCE = baseContCE = currContCE = 0;
1147
nextCE = baseCE = currCE;
1148
nextContCE = baseContCE = currContCE;
1150
maxStrength = UCOL_IDENTICAL;
1152
if(strength < maxStrength) {
1153
maxStrength = strength;
1154
if(baseCE == UCOL_RESET_TOP_VALUE) {
1155
log_verbose("Resetting to [top]\n");
1156
nextCE = UCOL_NEXT_TOP_VALUE;
1159
result = ucol_inv_getNextCE(baseCE & 0xFFFFFF3F, baseContCE, &nextCE, &nextContCE, maxStrength);
1162
if(isTailored(coll, *(rulesCopy+oldOffset), status)) {
1163
log_verbose("Reset is tailored codepoint %04X, don't know how to continue, taking next test\n", *(rulesCopy+oldOffset));
1166
log_err("couldn't find the CE\n");
1172
currCE &= 0xFFFFFF3F;
1173
currContCE &= 0xFFFFFFBF;
1175
if(maxStrength == UCOL_IDENTICAL) {
1176
if(baseCE != currCE || baseContCE != currContCE) {
1177
log_err("current CE (initial strength UCOL_EQUAL)\n");
1180
if(strength == UCOL_IDENTICAL) {
1181
if(lastCE != currCE || lastContCE != currContCE) {
1182
log_err("current CE (initial strength UCOL_EQUAL)\n");
1185
if(currCE > nextCE || (currCE == nextCE && currContCE >= nextContCE)) {
1186
log_err("current CE is not less than base CE\n");
1188
if(currCE < lastCE || (currCE == lastCE && currContCE <= lastContCE)) {
1189
log_err("sequence of generated CEs is broken\n");
1196
oldOffset = chOffset;
1197
lastCE = currCE & 0xFFFFFF3F;
1198
lastContCE = currContCE & 0xFFFFFFBF;
1200
uprv_free(rulesCopy);
1205
/* these locales are now picked from index RB */
1206
static const char* localesToTest[] = {
1207
"ar", "bg", "ca", "cs", "da",
1208
"el", "en_BE", "en_US_POSIX",
1209
"es", "et", "fi", "fr", "hi",
1210
"hr", "hu", "is", "iw", "ja",
1211
"ko", "lt", "lv", "mk", "mt",
1212
"nb", "nn", "nn_NO", "pl", "ro",
1213
"ru", "sh", "sk", "sl", "sq",
1214
"sr", "sv", "th", "tr", "uk",
1219
static const char* rulesToTest[] = {
1221
/* Cui Mins rules */
1222
"<o,O<p,P<q,Q<'?'/u<r,R<u,U", /*"<o,O<p,P<q,Q<r,R<u,U & Qu<'?'",*/
1223
"<o,O<p,P<q,Q;'?'/u<r,R<u,U", /*"<o,O<p,P<q,Q<r,R<u,U & Qu;'?'",*/
1224
"<o,O<p,P<q,Q,'?'/u<r,R<u,U", /*"<o,O<p,P<q,Q<r,R<u,U&'Qu','?'",*/
1225
"<3<4<5<c,C<f,F<m,M<o,O<p,P<q,Q;'?'/u<r,R<u,U", /*"<'?'<3<4<5<a,A<f,F<m,M<o,O<p,P<q,Q<r,R<u,U & Qu;'?'",*/
1226
"<'?';Qu<3<4<5<c,C<f,F<m,M<o,O<p,P<q,Q<r,R<u,U", /*"<'?'<3<4<5<a,A<f,F<m,M<o,O<p,P<q,Q<r,R<u,U & '?';Qu",*/
1227
"<3<4<5<c,C<f,F<m,M<o,O<p,P<q,Q;'?'/um<r,R<u,U", /*"<'?'<3<4<5<a,A<f,F<m,M<o,O<p,P<q,Q<r,R<u,U & Qum;'?'",*/
1228
"<'?';Qum<3<4<5<c,C<f,F<m,M<o,O<p,P<q,Q<r,R<u,U" /*"<'?'<3<4<5<a,A<f,F<m,M<o,O<p,P<q,Q<r,R<u,U & '?';Qum"*/
1231
static UBool hasCollationElements(const char *locName) {
1233
UErrorCode status = U_ZERO_ERROR;
1234
UResourceBundle *ColEl = NULL;
1236
UResourceBundle *loc = ures_open(NULL, locName, &status);;
1238
if(U_SUCCESS(status)) {
1239
status = U_ZERO_ERROR;
1240
ColEl = ures_getByKey(loc, "CollationElements", ColEl, &status);
1241
if(status == U_ZERO_ERROR) { /* do the test - there are real elements */
1253
static void TestCollations(void) {
1254
int32_t noOfLoc = uloc_countAvailable();
1255
int32_t i = 0, j = 0;
1257
UErrorCode status = U_ZERO_ERROR;
1263
const char *locName = NULL;
1264
UCollator *coll = NULL;
1265
UCollator *UCA = ucol_open("", &status);
1266
UColAttributeValue oldStrength = ucol_getAttribute(UCA, UCOL_STRENGTH, &status);
1267
ucol_setAttribute(UCA, UCOL_STRENGTH, UCOL_QUATERNARY, &status);
1269
for(i = 0; i<noOfLoc; i++) {
1270
status = U_ZERO_ERROR;
1271
locName = uloc_getAvailable(i);
1272
if(uprv_strcmp("ja", locName) == 0) {
1273
log_verbose("Don't know how to test prefixes\n");
1276
if(hasCollationElements(locName)) {
1277
nameSize = uloc_getDisplayName(locName, NULL, name, 256, &status);
1278
for(j = 0; j<nameSize; j++) {
1279
cName[j] = (char)name[j];
1281
cName[nameSize] = 0;
1282
log_verbose("\nTesting locale %s (%s)\n", locName, cName);
1283
coll = ucol_open(locName, &status);
1284
testAgainstUCA(coll, UCA, "UCA", FALSE, &status);
1288
ucol_setAttribute(UCA, UCOL_STRENGTH, oldStrength, &status);
1292
static void RamsRulesTest(void) {
1293
UErrorCode status = U_ZERO_ERROR;
1295
UCollator *coll = NULL;
1296
/* UCollator *UCA = ucol_open("", &status); */
1299
int32_t noOfLoc = uloc_countAvailable();
1300
const char *locName = NULL;
1302
log_verbose("RamsRulesTest\n");
1304
for(i = 0; i<noOfLoc; i++) {
1305
status = U_ZERO_ERROR;
1306
locName = uloc_getAvailable(i);
1307
if(hasCollationElements(locName)) {
1308
if (uprv_strcmp("ja", locName)==0) {
1309
log_verbose("Don't know how to test Japanese because of prefixes\n");
1312
log_verbose("Testing locale %s\n", locName);
1313
coll = ucol_open(locName, &status);
1314
if(U_SUCCESS(status)) {
1315
if(coll->image->jamoSpecial == TRUE) {
1316
log_err("%s has special JAMOs\n", locName);
1318
ucol_setAttribute(coll, UCOL_CASE_FIRST, UCOL_OFF, &status);
1319
testCollator(coll, &status);
1320
testCEs(coll, &status);
1326
for(i = 0; i<sizeof(rulesToTest)/sizeof(rulesToTest[0]); i++) {
1327
log_verbose("Testing rule: %s\n", rulesToTest[i]);
1328
u_uastrcpy(rule, rulesToTest[i]);
1329
ruleLen = u_strlen(rule);
1330
coll = ucol_openRules(rule, ruleLen, UCOL_OFF, UCOL_TERTIARY, NULL,&status);
1331
if(U_SUCCESS(status)) {
1332
testCollator(coll, &status);
1333
testCEs(coll, &status);
1340
static void IsTailoredTest(void) {
1341
UErrorCode status = U_ZERO_ERROR;
1343
UCollator *coll = NULL;
1345
UChar tailored[2048];
1346
UChar notTailored[2048];
1347
uint32_t ruleLen, tailoredLen, notTailoredLen;
1349
log_verbose("IsTailoredTest\n");
1351
u_uastrcpy(rule, "&Z < A, B, C;c < d");
1352
ruleLen = u_strlen(rule);
1354
u_uastrcpy(tailored, "ABCcd");
1355
tailoredLen = u_strlen(tailored);
1357
u_uastrcpy(notTailored, "ZabD");
1358
notTailoredLen = u_strlen(notTailored);
1360
coll = ucol_openRules(rule, ruleLen, UCOL_OFF, UCOL_TERTIARY, NULL,&status);
1361
if(U_SUCCESS(status)) {
1362
for(i = 0; i<tailoredLen; i++) {
1363
if(!isTailored(coll, tailored[i], &status)) {
1364
log_err("%i: %04X should be tailored - it is reported as not\n", i, tailored[i]);
1367
for(i = 0; i<notTailoredLen; i++) {
1368
if(isTailored(coll, notTailored[i], &status)) {
1369
log_err("%i: %04X should not be tailored - it is reported as it is\n", i, notTailored[i]);
1376
static void genericOrderingTestWithResult(UCollator *coll, const char *s[], uint32_t size, UCollationResult result) {
1377
UChar t1[2048] = {0};
1378
UChar t2[2048] = {0};
1379
UCollationElements *iter;
1380
UErrorCode status = U_ZERO_ERROR;
1382
uint32_t i = 0, j = 0;
1383
log_verbose("testing sequence:\n");
1384
for(i = 0; i < size; i++) {
1385
log_verbose("%s\n", s[i]);
1388
iter = ucol_openElements(coll, t1, u_strlen(t1), &status);
1389
if (U_FAILURE(status)) {
1390
log_err("Creation of iterator failed\n");
1392
for(i = 0; i < size-1; i++) {
1393
for(j = i+1; j < size; j++) {
1394
u_unescape(s[i], t1, 2048);
1395
u_unescape(s[j], t2, 2048);
1396
doTest(coll, t1, t2, result);
1397
/* synwee : added collation element iterator test */
1398
ucol_setText(iter, t1, u_strlen(t1), &status);
1400
ucol_setText(iter, t2, u_strlen(t2), &status);
1404
ucol_closeElements(iter);
1407
static void genericOrderingTest(UCollator *coll, const char *s[], uint32_t size) {
1408
genericOrderingTestWithResult(coll, s, size, UCOL_LESS);
1411
static void genericLocaleStarter(const char *locale, const char *s[], uint32_t size) {
1412
UErrorCode status = U_ZERO_ERROR;
1413
UCollator *coll = ucol_open(locale, &status);
1415
log_verbose("Locale starter for %s\n", locale);
1417
if(U_SUCCESS(status)) {
1418
genericOrderingTest(coll, s, size);
1420
log_err("Unable to open collator for locale %s\n", locale);
1426
/* currently not used with options */
1427
static void genericRulesStarterWithOptions(const char *rules, const char *s[], uint32_t size, const UColAttribute *attrs, const UColAttributeValue *values, uint32_t attsize) {
1428
UErrorCode status = U_ZERO_ERROR;
1429
UChar rlz[RULE_BUFFER_LEN] = { 0 };
1430
uint32_t rlen = u_unescape(rules, rlz, RULE_BUFFER_LEN);
1433
UCollator *coll = ucol_openRules(rlz, rlen, UCOL_DEFAULT, UCOL_DEFAULT,NULL, &status);
1435
log_verbose("Rules starter for %s\n", rules);
1437
if(U_SUCCESS(status)) {
1438
log_verbose("Setting attributes\n");
1439
for(i = 0; i < attsize; i++) {
1440
ucol_setAttribute(coll, attrs[i], values[i], &status);
1443
genericOrderingTest(coll, s, size);
1445
log_err("Unable to open collator with rules %s\n", rules);
1451
static void genericLocaleStarterWithOptions(const char *locale, const char *s[], uint32_t size, const UColAttribute *attrs, const UColAttributeValue *values, uint32_t attsize) {
1452
UErrorCode status = U_ZERO_ERROR;
1455
UCollator *coll = ucol_open(locale, &status);
1457
log_verbose("Locale starter for %s\n", locale);
1459
if(U_SUCCESS(status)) {
1461
log_verbose("Setting attributes\n");
1462
for(i = 0; i < attsize; i++) {
1463
ucol_setAttribute(coll, attrs[i], values[i], &status);
1466
genericOrderingTest(coll, s, size);
1468
log_err("Unable to open collator for locale %s\n", locale);
1473
static void genericRulesTestWithResult(const char *rules, const char *s[], uint32_t size, UCollationResult result) {
1474
UErrorCode status = U_ZERO_ERROR;
1475
UChar rlz[RULE_BUFFER_LEN] = { 0 };
1476
uint32_t rlen = u_unescape(rules, rlz, RULE_BUFFER_LEN);
1478
UCollator *coll = NULL;
1479
coll = ucol_openRules(rlz, rlen, UCOL_DEFAULT, UCOL_DEFAULT,NULL, &status);
1480
log_verbose("Rules starter for %s\n", rules);
1482
if(U_SUCCESS(status)) {
1483
genericOrderingTestWithResult(coll, s, size, result);
1486
log_err("Unable to open collator with rules %s\n", rules);
1490
static void genericRulesStarter(const char *rules, const char *s[], uint32_t size) {
1491
genericRulesTestWithResult(rules, s, size, UCOL_LESS);
1494
const static char chTest[][20] = {
1497
"ca", "cb", "cx", "cy", "CZ",
1498
"c\\u030C", "C\\u030C",
1501
"ha", "Ha", "harly", "hb", "HB", "hx", "HX", "hy", "HY",
1502
"ch", "cH", "Ch", "CH",
1503
"cha", "charly", "che", "chh", "chch", "chr",
1506
"r\\u030C", "R\\u030C",
1509
"s\\u030C", "S\\u030C",
1511
"z\\u030C", "Z\\u030C"
1514
static void TestChMove(void) {
1515
UChar t1[256] = {0};
1516
UChar t2[256] = {0};
1518
uint32_t i = 0, j = 0;
1520
UErrorCode status = U_ZERO_ERROR;
1522
UCollator *coll = ucol_open("cs", &status);
1524
if(U_SUCCESS(status)) {
1525
size = sizeof(chTest)/sizeof(chTest[0]);
1526
for(i = 0; i < size-1; i++) {
1527
for(j = i+1; j < size; j++) {
1528
u_unescape(chTest[i], t1, 256);
1529
u_unescape(chTest[j], t2, 256);
1530
doTest(coll, t1, t2, UCOL_LESS);
1535
log_err("Can't open collator");
1540
const static char impTest[][20] = {
1550
static void TestImplicitTailoring(void) {
1551
UChar t1[256] = {0};
1552
UChar t2[256] = {0};
1554
const char *rule = "&\\u4e00 < a <<< A < b <<< B";
1556
uint32_t i = 0, j = 0;
1558
uint32_t ruleLen = 0;
1559
UErrorCode status = U_ZERO_ERROR;
1560
UCollator *coll = NULL;
1561
ruleLen = u_unescape(rule, t1, 256);
1563
coll = ucol_openRules(t1, ruleLen, UCOL_OFF, UCOL_TERTIARY,NULL, &status);
1565
if(U_SUCCESS(status)) {
1566
size = sizeof(impTest)/sizeof(impTest[0]);
1567
for(i = 0; i < size-1; i++) {
1568
for(j = i+1; j < size; j++) {
1569
u_unescape(impTest[i], t1, 256);
1570
u_unescape(impTest[j], t2, 256);
1571
doTest(coll, t1, t2, UCOL_LESS);
1576
log_err("Can't open collator");
1581
static void TestFCDProblem(void) {
1582
UChar t1[256] = {0};
1583
UChar t2[256] = {0};
1585
const char *s1 = "\\u0430\\u0306\\u0325";
1586
const char *s2 = "\\u04D1\\u0325";
1588
UErrorCode status = U_ZERO_ERROR;
1589
UCollator *coll = ucol_open("", &status);
1590
u_unescape(s1, t1, 256);
1591
u_unescape(s2, t2, 256);
1593
ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
1594
doTest(coll, t1, t2, UCOL_EQUAL);
1596
ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
1597
doTest(coll, t1, t2, UCOL_EQUAL);
1602
#define NORM_BUFFER_TEST_LEN 32
1605
UChar NFC[NORM_BUFFER_TEST_LEN];
1606
UChar NFD[NORM_BUFFER_TEST_LEN];
1609
static void TestComposeDecompose(void) {
1610
int32_t noOfLoc = uloc_countAvailable();
1611
int32_t i = 0, j = 0;
1613
UErrorCode status = U_ZERO_ERROR;
1615
const char *locName = NULL;
1619
tester **t = uprv_malloc(0x30000 * sizeof(tester *));
1620
uint32_t noCases = 0;
1621
UCollator *coll = NULL;
1623
UChar comp[NORM_BUFFER_TEST_LEN];
1626
t[0] = (tester *)uprv_malloc(sizeof(tester));
1628
for(u = 0; u < 0x30000; u++) {
1630
UTF_APPEND_CHAR_UNSAFE(comp, len, u);
1631
nfcSize = unorm_normalize(comp, len, UNORM_NFC, 0, t[noCases]->NFC, NORM_BUFFER_TEST_LEN, &status);
1632
nfdSize = unorm_normalize(comp, len, UNORM_NFD, 0, t[noCases]->NFD, NORM_BUFFER_TEST_LEN, &status);
1634
if(nfcSize != nfdSize || (uprv_memcmp(t[noCases]->NFC, t[noCases]->NFD, nfcSize * sizeof(UChar)) != 0)
1635
|| (len != nfdSize || (uprv_memcmp(comp, t[noCases]->NFD, nfdSize * sizeof(UChar)) != 0))) {
1637
if(len != nfdSize || (uprv_memcmp(comp, t[noCases]->NFD, nfdSize * sizeof(UChar)) != 0)) {
1638
u_strncpy(t[noCases]->NFC, comp, len);
1639
t[noCases]->NFC[len] = 0;
1642
t[noCases] = (tester *)uprv_malloc(sizeof(tester));
1643
uprv_memset(t[noCases], 0, sizeof(tester));
1647
log_verbose("Testing UCA extensively\n");
1648
coll = ucol_open("", &status);
1649
for(u=0; u<noCases; u++) {
1650
if(!ucol_equal(coll, t[u]->NFC, -1, t[u]->NFD, -1)) {
1651
log_err("Failure: codePoint %05X fails TestComposeDecompose in the UCA\n", t[u]->u);
1652
doTest(coll, t[u]->NFC, t[u]->NFD, UCOL_EQUAL);
1656
for(u = 0; u < 0x30000; u++) {
1658
log_verbose("%08X ", u);
1660
uprv_memset(t[noCases], 0, sizeof(tester));
1663
UTF_APPEND_CHAR_UNSAFE(comp, len, u);
1665
nfcSize = unorm_normalize(comp, len, UNORM_NFC, 0, t[noCases]->NFC, NORM_BUFFER_TEST_LEN, &status);
1666
nfdSize = unorm_normalize(comp, len, UNORM_NFD, 0, t[noCases]->NFD, NORM_BUFFER_TEST_LEN, &status);
1667
doTest(coll, comp, t[noCases]->NFD, UCOL_EQUAL);
1668
doTest(coll, comp, t[noCases]->NFC, UCOL_EQUAL);
1674
log_verbose("Testing locales, number of cases = %i\n", noCases);
1675
for(i = 0; i<noOfLoc; i++) {
1676
status = U_ZERO_ERROR;
1677
locName = uloc_getAvailable(i);
1678
if(hasCollationElements(locName)) {
1681
int32_t nameSize = uloc_getDisplayName(locName, NULL, name, sizeof(cName), &status);
1683
for(j = 0; j<nameSize; j++) {
1684
cName[j] = (char)name[j];
1686
cName[nameSize] = 0;
1687
log_verbose("\nTesting locale %s (%s)\n", locName, cName);
1689
coll = ucol_open(locName, &status);
1690
ucol_setStrength(coll, UCOL_IDENTICAL);
1692
for(u=0; u<noCases; u++) {
1693
if(!ucol_equal(coll, t[u]->NFC, -1, t[u]->NFD, -1)) {
1694
log_err("Failure: codePoint %05X fails TestComposeDecompose for locale %s\n", t[u]->u, cName);
1695
doTest(coll, t[u]->NFC, t[u]->NFD, UCOL_EQUAL);
1701
for(u = 0; u <= noCases; u++) {
1707
static void TestEmptyRule(void) {
1708
UErrorCode status = U_ZERO_ERROR;
1709
UChar rulez[] = { 0 };
1710
UCollator *coll = ucol_openRules(rulez, 0, UCOL_OFF, UCOL_TERTIARY,NULL, &status);
1715
static void TestUCARules(void) {
1716
UErrorCode status = U_ZERO_ERROR;
1719
UCollator *UCAfromRules = NULL;
1720
UCollator *coll = ucol_open("", &status);
1721
uint32_t ruleLen = ucol_getRulesEx(coll, UCOL_FULL_RULES, rules, 256);
1723
log_verbose("TestUCARules\n");
1725
rules = (UChar *)malloc((ruleLen+1)*sizeof(UChar));
1726
ruleLen = ucol_getRulesEx(coll, UCOL_FULL_RULES, rules, ruleLen);
1728
log_verbose("Rules length is %d\n", ruleLen);
1729
UCAfromRules = ucol_openRules(rules, ruleLen, UCOL_OFF, UCOL_TERTIARY, NULL,&status);
1730
if(U_SUCCESS(status)) {
1731
ucol_close(UCAfromRules);
1733
log_verbose("Unable to create a collator from UCARules!\n");
1736
u_unescape(blah, b, 256);
1737
ucol_getSortKey(coll, b, 1, res, 256);
1746
/* Pinyin tonal order */
1748
A < .. (\u0101) < .. (\u00e1) < .. (\u01ce) < .. (\u00e0)
1749
(w/macron)< (w/acute)< (w/caron)< (w/grave)
1750
E < .. (\u0113) < .. (\u00e9) < .. (\u011b) < .. (\u00e8)
1751
I < .. (\u012b) < .. (\u00ed) < .. (\u01d0) < .. (\u00ec)
1752
O < .. (\u014d) < .. (\u00f3) < .. (\u01d2) < .. (\u00f2)
1753
U < .. (\u016b) < .. (\u00fa) < .. (\u01d4) < .. (\u00f9)
1754
< .. (\u01d6) < .. (\u01d8) < .. (\u01da) < .. (\u01dc) <
1757
However, in testing we got the following order:
1758
A < .. (\u00e1) < .. (\u00e0) < .. (\u01ce) < .. (\u0101)
1759
(w/acute)< (w/grave)< (w/caron)< (w/macron)
1760
E < .. (\u00e9) < .. (\u00e8) < .. (\u00ea) < .. (\u011b) <
1762
I < .. (\u00ed) < .. (\u00ec) < .. (\u01d0) < .. (\u012b)
1763
O < .. (\u00f3) < .. (\u00f2) < .. (\u01d2) < .. (\u014d)
1764
U < .. (\u00fa) < .. (\u00f9) < .. (\u01d4) < .. (\u00fc) <
1766
< .. (\u01dc) < .. (\u01da) < .. (\u01d6) < .. (\u016b)
1769
static void TestBefore(void) {
1770
const static char *data[] = {
1771
"\\u0101", "\\u00e1", "\\u01ce", "\\u00e0", "A",
1772
"\\u0113", "\\u00e9", "\\u011b", "\\u00e8", "E",
1773
"\\u012b", "\\u00ed", "\\u01d0", "\\u00ec", "I",
1774
"\\u014d", "\\u00f3", "\\u01d2", "\\u00f2", "O",
1775
"\\u016b", "\\u00fa", "\\u01d4", "\\u00f9", "U",
1776
"\\u01d6", "\\u01d8", "\\u01da", "\\u01dc", "\\u00fc"
1778
genericRulesStarter(
1779
"&[before 1]a<\\u0101<\\u00e1<\\u01ce<\\u00e0"
1780
"&[before 1]e<\\u0113<\\u00e9<\\u011b<\\u00e8"
1781
"&[before 1]i<\\u012b<\\u00ed<\\u01d0<\\u00ec"
1782
"&[before 1]o<\\u014d<\\u00f3<\\u01d2<\\u00f2"
1783
"&[before 1]u<\\u016b<\\u00fa<\\u01d4<\\u00f9"
1784
"&u<\\u01d6<\\u01d8<\\u01da<\\u01dc<\\u00fc",
1785
data, sizeof(data)/sizeof(data[0]));
1788
static void TestJ784(void) {
1789
const static char *data[] = {
1790
"A", "\\u0101", "\\u00e1", "\\u01ce", "\\u00e0",
1791
"E", "\\u0113", "\\u00e9", "\\u011b", "\\u00e8",
1792
"I", "\\u012b", "\\u00ed", "\\u01d0", "\\u00ec",
1793
"O", "\\u014d", "\\u00f3", "\\u01d2", "\\u00f2",
1794
"U", "\\u016b", "\\u00fa", "\\u01d4", "\\u00f9",
1796
"\\u01d6", "\\u01d8", "\\u01da", "\\u01dc"
1798
genericLocaleStarter("zh", data, sizeof(data)/sizeof(data[0]));
1802
static void TestJ831(void) {
1803
const static char *data[] = {
1809
genericLocaleStarter("lv", data, sizeof(data)/sizeof(data[0]));
1812
static void TestJ815(void) {
1813
const static char *data[] = {
1829
genericLocaleStarter("fr", data, sizeof(data)/sizeof(data[0]));
1830
genericRulesStarter("[backwards 2]&A<<\\u00e6/e<<<\\u00c6/E", data, sizeof(data)/sizeof(data[0]));
1835
"& a < b < c < d& r < c", "& a < b < d& r < c",
1836
"& a < b < c < d& c < m", "& a < b < c < m < d",
1837
"& a < b < c < d& a < m", "& a < m < b < c < d",
1838
"& a <<< b << c < d& a < m", "& a <<< b << c < m < d",
1839
"& a < b < c < d& [before 1] c < m", "& a < b < m < c < d",
1840
"& a < b <<< c << d <<< e& [before 3] e <<< x", "& a < b <<< c << d <<< x <<< e",
1841
"& a < b <<< c << d <<< e& [before 2] e <<< x", "& a < b <<< c <<< x << d <<< e",
1842
"& a < b <<< c << d <<< e& [before 1] e <<< x", "& a <<< x < b <<< c << d <<< e",
1843
"& a < b <<< c << d <<< e <<< f < g& [before 1] g < x", "& a < b <<< c << d <<< e <<< f < x < g",
1845
static void TestRedundantRules(void) {
1848
const static char *rules[] = {
1849
"& a <<< b <<< c << d <<< e& [before 1] e <<< x",
1850
"& a < b <<< c << d <<< e& [before 1] e <<< x",
1851
"& a < b < c < d& [before 1] c < m",
1852
"& a < b <<< c << d <<< e& [before 3] e <<< x",
1853
"& a < b <<< c << d <<< e& [before 2] e <<< x",
1854
"& a < b <<< c << d <<< e <<< f < g& [before 1] g < x",
1855
"& a <<< b << c < d& a < m",
1856
"&a<b<<b\\u0301 &z<b",
1859
"& a < b < c < d& r < c",
1860
"& a < b < c < d& r < c",
1861
"& a < b < c < d& c < m",
1862
"& a < b < c < d& a < m"
1865
const static char *expectedRules[] = {
1867
"& a <<< x < b <<< c << d <<< e",
1868
"& a < b < m < c < d",
1869
"& a < b <<< c << d <<< x <<< e",
1870
"& a < b <<< c <<< x << d <<< e",
1871
"& a < b <<< c << d <<< e <<< f < x < g",
1872
"& a <<< b << c < m < d",
1876
"& a < b < d& r < c",
1877
"& a < b < d& r < c",
1878
"& a < b < c < m < d",
1879
"& a < m < b < c < d"
1882
const static char *testdata[][8] = {
1884
{"a", "x", "b", "c", "d", "e"},
1885
{"a", "b", "m", "c", "d"},
1886
{"a", "b", "c", "d", "x", "e"},
1887
{"a", "b", "c", "x", "d", "e"},
1888
{"a", "b", "c", "d", "e", "f", "x", "g"},
1889
{"a", "b", "c", "m", "d"},
1890
{"a", "b\\u0301", "z", "b"},
1895
{"a", "b", "c", "m", "d"},
1896
{"a", "m", "b", "c", "d"}
1899
const static uint32_t testdatalen[] = {
1918
UCollator *credundant = NULL;
1919
UCollator *cresulting = NULL;
1920
UErrorCode status = U_ZERO_ERROR;
1921
UChar rlz[2048] = { 0 };
1924
for(i = 0; i<sizeof(rules)/sizeof(rules[0]); i++) {
1925
log_verbose("testing rule %s, expected to be %s\n", rules[i], expectedRules[i]);
1926
rlen = u_unescape(rules[i], rlz, 2048);
1928
credundant = ucol_openRules(rlz, rlen, UCOL_DEFAULT, UCOL_DEFAULT, NULL,&status);
1929
rlen = u_unescape(expectedRules[i], rlz, 2048);
1930
cresulting = ucol_openRules(rlz, rlen, UCOL_DEFAULT, UCOL_DEFAULT, NULL,&status);
1932
testAgainstUCA(cresulting, credundant, "expected", TRUE, &status);
1934
ucol_close(credundant);
1935
ucol_close(cresulting);
1937
log_verbose("testing using data\n");
1939
genericRulesStarter(rules[i], testdata[i], testdatalen[i]);
1944
static void TestExpansionSyntax(void) {
1947
const static char *rules[] = {
1948
"&AE <<< a << b <<< c &d <<< f",
1949
"&AE <<< a <<< b << c << d < e < f <<< g",
1950
"&AE <<< B <<< C / D <<< F"
1953
const static char *expectedRules[] = {
1954
"&A <<< a / E << b / E <<< c /E &d <<< f",
1955
"&A <<< a / E <<< b / E << c / E << d / E < e < f <<< g",
1956
"&A <<< B / E <<< C / ED <<< F / E"
1959
const static char *testdata[][8] = {
1960
{"AE", "a", "b", "c"},
1961
{"AE", "a", "b", "c", "d", "e", "f", "g"},
1962
{"AE", "B", "C"} /* / ED <<< F / E"},*/
1965
const static uint32_t testdatalen[] = {
1973
UCollator *credundant = NULL;
1974
UCollator *cresulting = NULL;
1975
UErrorCode status = U_ZERO_ERROR;
1976
UChar rlz[2048] = { 0 };
1979
for(i = 0; i<sizeof(rules)/sizeof(rules[0]); i++) {
1980
log_verbose("testing rule %s, expected to be %s\n", rules[i], expectedRules[i]);
1981
rlen = u_unescape(rules[i], rlz, 2048);
1983
credundant = ucol_openRules(rlz, rlen, UCOL_DEFAULT, UCOL_DEFAULT, NULL, &status);
1984
rlen = u_unescape(expectedRules[i], rlz, 2048);
1985
cresulting = ucol_openRules(rlz, rlen, UCOL_DEFAULT, UCOL_DEFAULT, NULL,&status);
1987
/* testAgainstUCA still doesn't handle expansions correctly, so this is not run */
1988
/* as a hard error test, but only in information mode */
1989
testAgainstUCA(cresulting, credundant, "expected", FALSE, &status);
1991
ucol_close(credundant);
1992
ucol_close(cresulting);
1994
log_verbose("testing using data\n");
1996
genericRulesStarter(rules[i], testdata[i], testdatalen[i]);
2000
static void TestCase(void)
2002
const static UChar gRules[MAX_TOKEN_LEN] =
2003
/*" & 0 < 1,\u2461<a,A"*/
2004
{ 0x0026, 0x0030, 0x003C, 0x0031, 0x002C, 0x2460, 0x003C, 0x0061, 0x002C, 0x0041, 0x0000 };
2006
const static UChar testCase[][MAX_TOKEN_LEN] =
2008
/*0*/ {0x0031 /*'1'*/, 0x0061/*'a'*/, 0x0000},
2009
/*1*/ {0x0031 /*'1'*/, 0x0041/*'A'*/, 0x0000},
2010
/*2*/ {0x2460 /*circ'1'*/, 0x0061/*'a'*/, 0x0000},
2011
/*3*/ {0x2460 /*circ'1'*/, 0x0041/*'A'*/, 0x0000}
2014
const static UCollationResult caseTestResults[][9] =
2016
{ UCOL_LESS, UCOL_LESS, UCOL_LESS, 0, UCOL_LESS, UCOL_LESS, 0, 0, UCOL_LESS },
2017
{ UCOL_GREATER, UCOL_LESS, UCOL_LESS, 0, UCOL_LESS, UCOL_LESS, 0, 0, UCOL_GREATER },
2018
{ UCOL_LESS, UCOL_LESS, UCOL_LESS, 0, UCOL_GREATER, UCOL_LESS, 0, 0, UCOL_LESS },
2019
{ UCOL_GREATER, UCOL_LESS, UCOL_GREATER, 0, UCOL_LESS, UCOL_LESS, 0, 0, UCOL_GREATER }
2023
const static UColAttributeValue caseTestAttributes[][2] =
2025
{ UCOL_LOWER_FIRST, UCOL_OFF},
2026
{ UCOL_UPPER_FIRST, UCOL_OFF},
2027
{ UCOL_LOWER_FIRST, UCOL_ON},
2028
{ UCOL_UPPER_FIRST, UCOL_ON}
2032
UErrorCode status = U_ZERO_ERROR;
2033
UCollator *myCollation;
2034
myCollation = ucol_open("en_US", &status);
2035
if(U_FAILURE(status)){
2036
log_err("ERROR: in creation of rule based collator: %s\n", myErrorName(status));
2039
log_verbose("Testing different case settings\n");
2040
ucol_setStrength(myCollation, UCOL_TERTIARY);
2042
for(k = 0; k<4; k++) {
2043
ucol_setAttribute(myCollation, UCOL_CASE_FIRST, caseTestAttributes[k][0], &status);
2044
ucol_setAttribute(myCollation, UCOL_CASE_LEVEL, caseTestAttributes[k][1], &status);
2045
log_verbose("Case first = %d, Case level = %d\n", caseTestAttributes[k][0], caseTestAttributes[k][1]);
2046
for (i = 0; i < 3 ; i++) {
2047
for(j = i+1; j<4; j++) {
2048
doTest(myCollation, testCase[i], testCase[j], caseTestResults[k][3*i+j-1]);
2052
ucol_close(myCollation);
2054
myCollation = ucol_openRules(gRules, u_strlen(gRules), UCOL_OFF, UCOL_TERTIARY,NULL, &status);
2055
if(U_FAILURE(status)){
2056
log_err("ERROR: in creation of rule based collator: %s\n", myErrorName(status));
2059
log_verbose("Testing different case settings with custom rules\n");
2060
ucol_setStrength(myCollation, UCOL_TERTIARY);
2062
for(k = 0; k<4; k++) {
2063
ucol_setAttribute(myCollation, UCOL_CASE_FIRST, caseTestAttributes[k][0], &status);
2064
ucol_setAttribute(myCollation, UCOL_CASE_LEVEL, caseTestAttributes[k][1], &status);
2065
for (i = 0; i < 3 ; i++) {
2066
for(j = i+1; j<4; j++) {
2067
log_verbose("k:%d, i:%d, j:%d\n", k, i, j);
2068
doTest(myCollation, testCase[i], testCase[j], caseTestResults[k][3*i+j-1]);
2072
ucol_close(myCollation);
2074
const static char *lowerFirst[] = {
2090
const static char *upperFirst[] = {
2105
log_verbose("mixed case test\n");
2106
log_verbose("lower first, case level off\n");
2107
genericRulesStarter("[casefirst lower]&H<ch<<<Ch<<<CH", lowerFirst, sizeof(lowerFirst)/sizeof(lowerFirst[0]));
2108
log_verbose("upper first, case level off\n");
2109
genericRulesStarter("[casefirst upper]&H<ch<<<Ch<<<CH", upperFirst, sizeof(upperFirst)/sizeof(upperFirst[0]));
2110
log_verbose("lower first, case level on\n");
2111
genericRulesStarter("[casefirst lower][caselevel on]&H<ch<<<Ch<<<CH", lowerFirst, sizeof(lowerFirst)/sizeof(lowerFirst[0]));
2112
log_verbose("upper first, case level on\n");
2113
genericRulesStarter("[casefirst upper][caselevel on]&H<ch<<<Ch<<<CH", upperFirst, sizeof(upperFirst)/sizeof(upperFirst[0]));
2118
static void TestIncrementalNormalize(void) {
2121
/* UChar baseB = 0x42;*/
2122
UChar ccMix[] = {0x316, 0x321, 0x300};
2124
0x316 is combining grave accent below, cc=220
2125
0x321 is combining palatalized hook below, cc=202
2126
0x300 is combining grave accent, cc=230
2134
UErrorCode status = U_ZERO_ERROR;
2135
UCollationResult result;
2138
/* Test 1. Run very long unnormalized strings, to force overflow of*/
2139
/* most buffers along the way.*/
2143
strA = uprv_malloc((maxSLen+1) * sizeof(UChar));
2144
strB = uprv_malloc((maxSLen+1) * sizeof(UChar));
2146
coll = ucol_open("en_US", &status);
2147
ucol_setNormalization(coll, UNORM_NFD);
2149
/* for (sLen = 4; sLen<maxSLen; sLen++) { */
2150
for (sLen = 1000; sLen<1001; sLen++) {
2153
for (i=1; i<=sLen-1; i++) {
2154
strA[i] = ccMix[i % 3];
2155
strB[sLen-i] = ccMix[i % 3];
2160
ucol_setStrength(coll, UCOL_TERTIARY); /* Do test with default strength, which runs*/
2161
doTest(coll, strA, strB, UCOL_EQUAL); /* optimized functions in the impl*/
2162
ucol_setStrength(coll, UCOL_IDENTICAL); /* Do again with the slow, general impl.*/
2163
doTest(coll, strA, strB, UCOL_EQUAL);
2170
/* Test 2: Non-normal sequence in a string that extends to the last character*/
2171
/* of the string. Checks a couple of edge cases.*/
2174
UChar strA[] = {0x41, 0x41, 0x300, 0x316, 0};
2175
UChar strB[] = {0x41, 0xc0, 0x316, 0};
2176
ucol_setStrength(coll, UCOL_TERTIARY);
2177
doTest(coll, strA, strB, UCOL_EQUAL);
2180
/* Test 3: Non-normal sequence is terminated by a surrogate pair.*/
2183
UChar strA[] = {0x41, 0x41, 0x300, 0x316, 0xD801, 0xDC00, 0};
2184
UChar strB[] = {0x41, 0xc0, 0x316, 0xD800, 0xDC00, 0};
2185
ucol_setStrength(coll, UCOL_TERTIARY);
2186
doTest(coll, strA, strB, UCOL_GREATER);
2189
/* Test 4: Imbedded nulls do not terminate a string when length is specified.*/
2192
UChar strA[] = {0x41, 0x00, 0x42, 0x00};
2193
UChar strB[] = {0x41, 0x00, 0x00, 0x00};
2200
result = ucol_strcoll(coll, strA, -3, strB, -3);
2201
if (result != UCOL_GREATER) {
2202
log_err("ERROR 1 in test 4\n");
2204
result = ucol_strcoll(coll, strA, -1, strB, -1);
2205
if (result != UCOL_EQUAL) {
2206
log_err("ERROR 2 in test 4\n");
2209
ucol_getSortKey(coll, strA, 3, (uint8_t *)sortKeyA, sizeof(sortKeyA));
2210
ucol_getSortKey(coll, strA, -1, (uint8_t *)sortKeyAz, sizeof(sortKeyAz));
2211
ucol_getSortKey(coll, strB, 3, (uint8_t *)sortKeyB, sizeof(sortKeyB));
2212
ucol_getSortKey(coll, strB, -1, (uint8_t *)sortKeyBz, sizeof(sortKeyBz));
2214
r = strcmp(sortKeyA, sortKeyAz);
2216
log_err("Error 3 in test 4\n");
2218
r = strcmp(sortKeyA, sortKeyB);
2220
log_err("Error 4 in test 4\n");
2222
r = strcmp(sortKeyAz, sortKeyBz);
2224
log_err("Error 5 in test 4\n");
2227
ucol_setStrength(coll, UCOL_IDENTICAL);
2228
ucol_getSortKey(coll, strA, 3, (uint8_t *)sortKeyA, sizeof(sortKeyA));
2229
ucol_getSortKey(coll, strA, -1, (uint8_t *)sortKeyAz, sizeof(sortKeyAz));
2230
ucol_getSortKey(coll, strB, 3, (uint8_t *)sortKeyB, sizeof(sortKeyB));
2231
ucol_getSortKey(coll, strB, -1, (uint8_t *)sortKeyBz, sizeof(sortKeyBz));
2233
r = strcmp(sortKeyA, sortKeyAz);
2235
log_err("Error 6 in test 4\n");
2237
r = strcmp(sortKeyA, sortKeyB);
2239
log_err("Error 7 in test 4\n");
2241
r = strcmp(sortKeyAz, sortKeyBz);
2243
log_err("Error 8 in test 4\n");
2245
ucol_setStrength(coll, UCOL_TERTIARY);
2249
/* Test 5: Null characters in non-normal source strings.*/
2252
UChar strA[] = {0x41, 0x41, 0x300, 0x316, 0x00, 0x42, 0x00};
2253
UChar strB[] = {0x41, 0x41, 0x300, 0x316, 0x00, 0x00, 0x00};
2260
result = ucol_strcoll(coll, strA, 6, strB, 6);
2261
if (result != UCOL_GREATER) {
2262
log_err("ERROR 1 in test 5\n");
2264
result = ucol_strcoll(coll, strA, -1, strB, -1);
2265
if (result != UCOL_EQUAL) {
2266
log_err("ERROR 2 in test 5\n");
2269
ucol_getSortKey(coll, strA, 6, (uint8_t *)sortKeyA, sizeof(sortKeyA));
2270
ucol_getSortKey(coll, strA, -1, (uint8_t *)sortKeyAz, sizeof(sortKeyAz));
2271
ucol_getSortKey(coll, strB, 6, (uint8_t *)sortKeyB, sizeof(sortKeyB));
2272
ucol_getSortKey(coll, strB, -1, (uint8_t *)sortKeyBz, sizeof(sortKeyBz));
2274
r = strcmp(sortKeyA, sortKeyAz);
2276
log_err("Error 3 in test 5\n");
2278
r = strcmp(sortKeyA, sortKeyB);
2280
log_err("Error 4 in test 5\n");
2282
r = strcmp(sortKeyAz, sortKeyBz);
2284
log_err("Error 5 in test 5\n");
2287
ucol_setStrength(coll, UCOL_IDENTICAL);
2288
ucol_getSortKey(coll, strA, 6, (uint8_t *)sortKeyA, sizeof(sortKeyA));
2289
ucol_getSortKey(coll, strA, -1, (uint8_t *)sortKeyAz, sizeof(sortKeyAz));
2290
ucol_getSortKey(coll, strB, 6, (uint8_t *)sortKeyB, sizeof(sortKeyB));
2291
ucol_getSortKey(coll, strB, -1, (uint8_t *)sortKeyBz, sizeof(sortKeyBz));
2293
r = strcmp(sortKeyA, sortKeyAz);
2295
log_err("Error 6 in test 5\n");
2297
r = strcmp(sortKeyA, sortKeyB);
2299
log_err("Error 7 in test 5\n");
2301
r = strcmp(sortKeyAz, sortKeyBz);
2303
log_err("Error 8 in test 5\n");
2305
ucol_setStrength(coll, UCOL_TERTIARY);
2309
/* Test 6: Null character as base of a non-normal combining sequence.*/
2312
UChar strA[] = {0x41, 0x0, 0x300, 0x316, 0x41, 0x302, 0x00};
2313
UChar strB[] = {0x41, 0x0, 0x302, 0x316, 0x41, 0x300, 0x00};
2315
result = ucol_strcoll(coll, strA, 5, strB, 5);
2316
if (result != UCOL_LESS) {
2317
log_err("Error 1 in test 6\n");
2319
result = ucol_strcoll(coll, strA, -1, strB, -1);
2320
if (result != UCOL_EQUAL) {
2321
log_err("Error 2 in test 6\n");
2331
static void TestGetCaseBit(void) {
2332
static const char *caseBitData[] = {
2333
"a", "A", "ch", "Ch", "CH",
2334
"\\uFF9E", "\\u0009"
2337
static const uint8_t results[] = {
2338
UCOL_LOWER_CASE, UCOL_UPPER_CASE, UCOL_LOWER_CASE, UCOL_MIXED_CASE, UCOL_UPPER_CASE,
2339
UCOL_UPPER_CASE, UCOL_LOWER_CASE
2342
uint32_t i, blen = 0;
2344
UErrorCode status = U_ZERO_ERROR;
2345
UCollator *UCA = ucol_open("", &status);
2348
for(i = 0; i<sizeof(results)/sizeof(results[0]); i++) {
2349
blen = u_unescape(caseBitData[i], b, 256);
2350
res = ucol_uprv_getCaseBits(UCA, b, blen, &status);
2351
if(results[i] != res) {
2352
log_err("Expected case = %02X, got %02X for %04X\n", results[i], res, b[0]);
2358
static void TestHangulTailoring(void) {
2359
static const char *koreanData[] = {
2360
"\\uac00", "\\u4f3d", "\\u4f73", "\\u5047", "\\u50f9", "\\u52a0", "\\u53ef", "\\u5475",
2361
"\\u54e5", "\\u5609", "\\u5ac1", "\\u5bb6", "\\u6687", "\\u67b6", "\\u67b7", "\\u67ef",
2362
"\\u6b4c", "\\u73c2", "\\u75c2", "\\u7a3c", "\\u82db", "\\u8304", "\\u8857", "\\u8888",
2363
"\\u8a36", "\\u8cc8", "\\u8dcf", "\\u8efb", "\\u8fe6", "\\u99d5",
2364
"\\u4EEE", "\\u50A2", "\\u5496", "\\u54FF", "\\u5777", "\\u5B8A", "\\u659D", "\\u698E",
2365
"\\u6A9F", "\\u73C8", "\\u7B33", "\\u801E", "\\u8238", "\\u846D", "\\u8B0C"
2369
"&\\uac00 <<< \\u4f3d <<< \\u4f73 <<< \\u5047 <<< \\u50f9 <<< \\u52a0 <<< \\u53ef <<< \\u5475 "
2370
"<<< \\u54e5 <<< \\u5609 <<< \\u5ac1 <<< \\u5bb6 <<< \\u6687 <<< \\u67b6 <<< \\u67b7 <<< \\u67ef "
2371
"<<< \\u6b4c <<< \\u73c2 <<< \\u75c2 <<< \\u7a3c <<< \\u82db <<< \\u8304 <<< \\u8857 <<< \\u8888 "
2372
"<<< \\u8a36 <<< \\u8cc8 <<< \\u8dcf <<< \\u8efb <<< \\u8fe6 <<< \\u99d5 "
2373
"<<< \\u4EEE <<< \\u50A2 <<< \\u5496 <<< \\u54FF <<< \\u5777 <<< \\u5B8A <<< \\u659D <<< \\u698E "
2374
"<<< \\u6A9F <<< \\u73C8 <<< \\u7B33 <<< \\u801E <<< \\u8238 <<< \\u846D <<< \\u8B0C";
2377
UErrorCode status = U_ZERO_ERROR;
2378
UChar rlz[2048] = { 0 };
2379
uint32_t rlen = u_unescape(rules, rlz, 2048);
2381
UCollator *coll = ucol_openRules(rlz, rlen, UCOL_DEFAULT, UCOL_DEFAULT,NULL, &status);
2383
log_verbose("Using start of korean rules\n");
2385
if(U_SUCCESS(status)) {
2386
genericOrderingTest(coll, koreanData, sizeof(koreanData)/sizeof(koreanData[0]));
2388
log_err("Unable to open collator with rules %s\n", rules);
2391
log_verbose("Setting jamoSpecial to TRUE and testing once more\n");
2392
((UCATableHeader *)coll->image)->jamoSpecial = TRUE; /* don't try this at home */
2393
genericOrderingTest(coll, koreanData, sizeof(koreanData)/sizeof(koreanData[0]));
2397
log_verbose("Using ko__LOTUS locale\n");
2398
genericLocaleStarter("ko__LOTUS", koreanData, sizeof(koreanData)/sizeof(koreanData[0]));
2401
static void TestCompressOverlap(void) {
2404
UErrorCode status = U_ZERO_ERROR;
2411
coll = ucol_open("", &status);
2413
if (U_FAILURE(status)) {
2414
log_err("Collator can't be created\n");
2417
while (count < 149) {
2418
secstr[count] = 0x0020; /* [06, 05, 05] */
2419
tertstr[count] = 0x0020;
2423
/* top down compression ----------------------------------- */
2424
secstr[count] = 0x0332; /* [, 87, 05] */
2425
tertstr[count] = 0x3000; /* [06, 05, 07] */
2427
/* no compression secstr should have 150 secondary bytes, tertstr should
2428
have 150 tertiary bytes.
2429
with correct overlapping compression, secstr should have 4 secondary
2430
bytes, tertstr should have > 2 tertiary bytes */
2431
resultlen = ucol_getSortKey(coll, secstr, 150, (uint8_t *)result, 250);
2432
tempptr = uprv_strchr(result, 1) + 1;
2433
while (*(tempptr + 1) != 1) {
2434
/* the last secondary collation element is not checked since it is not
2435
part of the compression */
2436
if (*tempptr < UCOL_COMMON_TOP2 - UCOL_TOP_COUNT2) {
2437
log_err("Secondary compression overlapped\n");
2442
/* tertiary top/bottom/common for en_US is similar to the secondary
2443
top/bottom/common */
2444
resultlen = ucol_getSortKey(coll, tertstr, 150, (uint8_t *)result, 250);
2445
tempptr = uprv_strrchr(result, 1) + 1;
2446
while (*(tempptr + 1) != 0) {
2447
/* the last secondary collation element is not checked since it is not
2448
part of the compression */
2449
if (*tempptr < coll->tertiaryTop - coll->tertiaryTopCount) {
2450
log_err("Tertiary compression overlapped\n");
2455
/* bottom up compression ------------------------------------- */
2458
resultlen = ucol_getSortKey(coll, secstr, 150, (uint8_t *)result, 250);
2459
tempptr = uprv_strchr(result, 1) + 1;
2460
while (*(tempptr + 1) != 1) {
2461
/* the last secondary collation element is not checked since it is not
2462
part of the compression */
2463
if (*tempptr > UCOL_COMMON_BOT2 + UCOL_BOT_COUNT2) {
2464
log_err("Secondary compression overlapped\n");
2469
/* tertiary top/bottom/common for en_US is similar to the secondary
2470
top/bottom/common */
2471
resultlen = ucol_getSortKey(coll, tertstr, 150, (uint8_t *)result, 250);
2472
tempptr = uprv_strrchr(result, 1) + 1;
2473
while (*(tempptr + 1) != 0) {
2474
/* the last secondary collation element is not checked since it is not
2475
part of the compression */
2476
if (*tempptr > coll->tertiaryBottom + coll->tertiaryBottomCount) {
2477
log_err("Tertiary compression overlapped\n");
2485
static void TestCyrillicTailoring(void) {
2486
static const char *test[] = {
2491
genericLocaleStarter("ru", test, 3);
2492
genericRulesStarter("&\\u0410 = \\u0410", test, 3);
2493
genericRulesStarter("&Z < \\u0410", test, 3);
2494
genericRulesStarter("&\\u0410 = \\u0410 < \\u04d0", test, 3);
2495
genericRulesStarter("&Z < \\u0410 < \\u04d0", test, 3);
2496
genericRulesStarter("&\\u0410 = \\u0410 < \\u0410\\u0301", test, 3);
2497
genericRulesStarter("&Z < \\u0410 < \\u0410\\u0301", test, 3);
2500
static void TestContraction(void) {
2501
const static char *testrules[] = {
2503
"&A = A\\u0306/\\u0306",
2506
const static UChar testdata[][2] = {
2507
{0x0041 /* 'A' */, 0x0042 /* 'B' */},
2508
{0x0041 /* 'A' */, 0x0306 /* combining breve */},
2509
{0x0063 /* 'c' */, 0x0068 /* 'h' */}
2511
const static UChar testdata2[][2] = {
2512
{0x0063 /* 'c' */, 0x0067 /* 'g' */},
2513
{0x0063 /* 'c' */, 0x0068 /* 'h' */},
2514
{0x0063 /* 'c' */, 0x006C /* 'l' */}
2516
const static char *testrules3[] = {
2517
"&z < xyz &xyzw << B",
2518
"&z < xyz &xyz << B / w",
2519
"&z < ch &achm << B",
2520
"&z < ch &a << B / chm",
2521
"&\\ud800\\udc00w << B",
2522
"&\\ud800\\udc00 << B / w",
2523
"&a\\ud800\\udc00m << B",
2524
"&a << B / \\ud800\\udc00m",
2527
UErrorCode status = U_ZERO_ERROR;
2529
UChar rule[256] = {0};
2533
for (i = 0; i < sizeof(testrules) / sizeof(testrules[0]); i ++) {
2534
UCollationElements *iter1;
2536
log_verbose("Rule %s for testing\n", testrules[i]);
2537
rlen = u_unescape(testrules[i], rule, 32);
2538
coll = ucol_openRules(rule, rlen, UCOL_ON, UCOL_TERTIARY,NULL, &status);
2539
if (U_FAILURE(status)) {
2540
log_err("Collator creation failed %s\n", testrules[i]);
2543
iter1 = ucol_openElements(coll, testdata[i], 2, &status);
2544
if (U_FAILURE(status)) {
2545
log_err("Collation iterator creation failed\n");
2549
UCollationElements *iter2 = ucol_openElements(coll,
2553
if (U_FAILURE(status)) {
2554
log_err("Collation iterator creation failed\n");
2557
ce = ucol_next(iter2, &status);
2558
while (ce != UCOL_NULLORDER) {
2559
if ((uint32_t)ucol_next(iter1, &status) != ce) {
2560
log_err("Collation elements in contraction split does not match\n");
2563
ce = ucol_next(iter2, &status);
2566
ucol_closeElements(iter2);
2568
if (ucol_next(iter1, &status) != UCOL_NULLORDER) {
2569
log_err("Collation elements not exhausted\n");
2572
ucol_closeElements(iter1);
2576
rlen = u_unescape("& a < b < c < ch < d & c = ch / h", rule, 256);
2577
coll = ucol_openRules(rule, rlen, UCOL_ON, UCOL_TERTIARY,NULL, &status);
2578
if (ucol_strcoll(coll, testdata2[0], 2, testdata2[1], 2) != UCOL_LESS) {
2579
log_err("Expected \\u%04x\\u%04x < \\u%04x\\u%04x\n",
2580
testdata2[0][0], testdata2[0][1], testdata2[1][0],
2584
if (ucol_strcoll(coll, testdata2[1], 2, testdata2[2], 2) != UCOL_LESS) {
2585
log_err("Expected \\u%04x\\u%04x < \\u%04x\\u%04x\n",
2586
testdata2[1][0], testdata2[1][1], testdata2[2][0],
2592
for (i = 0; i < sizeof(testrules3) / sizeof(testrules3[0]); i += 2) {
2595
UCollationElements *iter1,
2597
UChar ch = 0x0042 /* 'B' */;
2599
rlen = u_unescape(testrules3[i], rule, 32);
2600
coll1 = ucol_openRules(rule, rlen, UCOL_ON, UCOL_TERTIARY,NULL, &status);
2601
rlen = u_unescape(testrules3[i + 1], rule, 32);
2602
coll2 = ucol_openRules(rule, rlen, UCOL_ON, UCOL_TERTIARY,NULL, &status);
2603
if (U_FAILURE(status)) {
2604
log_err("Collator creation failed %s\n", testrules[i]);
2607
iter1 = ucol_openElements(coll1, &ch, 1, &status);
2608
iter2 = ucol_openElements(coll2, &ch, 1, &status);
2609
if (U_FAILURE(status)) {
2610
log_err("Collation iterator creation failed\n");
2613
ce = ucol_next(iter1, &status);
2614
if (U_FAILURE(status)) {
2615
log_err("Retrieving ces failed\n");
2618
while (ce != UCOL_NULLORDER) {
2619
if (ce != (uint32_t)ucol_next(iter2, &status)) {
2620
log_err("CEs does not match\n");
2623
ce = ucol_next(iter1, &status);
2624
if (U_FAILURE(status)) {
2625
log_err("Retrieving ces failed\n");
2629
if (ucol_next(iter2, &status) != UCOL_NULLORDER) {
2630
log_err("CEs not exhausted\n");
2633
ucol_closeElements(iter1);
2634
ucol_closeElements(iter2);
2640
static void TestExpansion(void) {
2641
const static char *testrules[] = {
2642
"&J << K / B & K << M",
2645
const static UChar testdata[][3] = {
2646
{0x004A /*'J'*/, 0x0041 /*'A'*/, 0},
2647
{0x004D /*'M'*/, 0x0041 /*'A'*/, 0},
2648
{0x004B /*'K'*/, 0x0041 /*'A'*/, 0},
2649
{0x004B /*'K'*/, 0x0043 /*'C'*/, 0},
2650
{0x004A /*'J'*/, 0x0043 /*'C'*/, 0},
2651
{0x004D /*'M'*/, 0x0043 /*'C'*/, 0}
2654
UErrorCode status = U_ZERO_ERROR;
2656
UChar rule[256] = {0};
2660
for (i = 0; i < sizeof(testrules) / sizeof(testrules[0]); i ++) {
2662
log_verbose("Rule %s for testing\n", testrules[i]);
2663
rlen = u_unescape(testrules[i], rule, 32);
2664
coll = ucol_openRules(rule, rlen, UCOL_ON, UCOL_TERTIARY,NULL, &status);
2665
if (U_FAILURE(status)) {
2666
log_err("Collator creation failed %s\n", testrules[i]);
2670
for (j = 0; j < 5; j ++) {
2671
doTest(coll, testdata[j], testdata[j + 1], UCOL_LESS);
2678
/* this test tests the current limitations of the engine */
2679
/* it always fail, so it is disabled by default */
2680
static void TestLimitations(void) {
2681
/* recursive expansions */
2683
static const char *rule = "&a=b/c&d=c/e";
2684
static const char *tlimit01[] = {"add","b","adf"};
2685
static const char *tlimit02[] = {"aa","b","af"};
2686
log_verbose("recursive expansions\n");
2687
genericRulesStarter(rule, tlimit01, sizeof(tlimit01)/sizeof(tlimit01[0]));
2688
genericRulesStarter(rule, tlimit02, sizeof(tlimit02)/sizeof(tlimit02[0]));
2690
/* contractions spanning expansions */
2692
static const char *rule = "&a<<<c/e&g<<<eh";
2693
static const char *tlimit01[] = {"ad","c","af","f","ch","h"};
2694
static const char *tlimit02[] = {"ad","c","ch","af","f","h"};
2695
log_verbose("contractions spanning expansions\n");
2696
genericRulesStarter(rule, tlimit01, sizeof(tlimit01)/sizeof(tlimit01[0]));
2697
genericRulesStarter(rule, tlimit02, sizeof(tlimit02)/sizeof(tlimit02[0]));
2699
/* normalization: nulls in contractions */
2701
static const char *rule = "&a<<<\\u0000\\u0302";
2702
static const char *tlimit01[] = {"a","\\u0000\\u0302\\u0327"};
2703
static const char *tlimit02[] = {"\\u0000\\u0302\\u0327","a"};
2704
static const UColAttribute att[] = { UCOL_DECOMPOSITION_MODE };
2705
static const UColAttributeValue valOn[] = { UCOL_ON };
2706
static const UColAttributeValue valOff[] = { UCOL_OFF };
2708
log_verbose("NULL in contractions\n");
2709
genericRulesStarterWithOptions(rule, tlimit01, 2, att, valOn, 1);
2710
genericRulesStarterWithOptions(rule, tlimit02, 2, att, valOn, 1);
2711
genericRulesStarterWithOptions(rule, tlimit01, 2, att, valOff, 1);
2712
genericRulesStarterWithOptions(rule, tlimit02, 2, att, valOff, 1);
2715
/* normalization: contractions spanning normalization */
2717
static const char *rule = "&a<<<\\u0000\\u0302";
2718
static const char *tlimit01[] = {"a","\\u0000\\u0302\\u0327"};
2719
static const char *tlimit02[] = {"\\u0000\\u0302\\u0327","a"};
2720
static const UColAttribute att[] = { UCOL_DECOMPOSITION_MODE };
2721
static const UColAttributeValue valOn[] = { UCOL_ON };
2722
static const UColAttributeValue valOff[] = { UCOL_OFF };
2724
log_verbose("contractions spanning normalization\n");
2725
genericRulesStarterWithOptions(rule, tlimit01, 2, att, valOn, 1);
2726
genericRulesStarterWithOptions(rule, tlimit02, 2, att, valOn, 1);
2727
genericRulesStarterWithOptions(rule, tlimit01, 2, att, valOff, 1);
2728
genericRulesStarterWithOptions(rule, tlimit02, 2, att, valOff, 1);
2733
/*static const char *rule2 = "&\\u2010<x=[variable top]<z";*/
2734
static const char *rule = "&\\u2010<x<[variable top]=z";
2735
/*static const char *rule3 = "&' '<x<[variable top]=z";*/
2736
static const char *tlimit01[] = {" ", "z", "zb", "a", " b", "xb", "b", "c" };
2737
static const char *tlimit02[] = {"-", "-x", "x","xb", "-z", "z", "zb", "-a", "a", "-b", "b", "c"};
2738
static const char *tlimit03[] = {" ", "xb", "z", "zb", "a", " b", "b", "c" };
2739
static const UColAttribute att[] = { UCOL_ALTERNATE_HANDLING, UCOL_STRENGTH };
2740
static const UColAttributeValue valOn[] = { UCOL_SHIFTED, UCOL_QUATERNARY };
2741
static const UColAttributeValue valOff[] = { UCOL_NON_IGNORABLE, UCOL_TERTIARY };
2743
log_verbose("variable top\n");
2744
genericRulesStarterWithOptions(rule, tlimit03, sizeof(tlimit03)/sizeof(tlimit03[0]), att, valOn, sizeof(att)/sizeof(att[0]));
2745
genericRulesStarterWithOptions(rule, tlimit01, sizeof(tlimit01)/sizeof(tlimit01[0]), att, valOn, sizeof(att)/sizeof(att[0]));
2746
genericRulesStarterWithOptions(rule, tlimit02, sizeof(tlimit02)/sizeof(tlimit02[0]), att, valOn, sizeof(att)/sizeof(att[0]));
2747
genericRulesStarterWithOptions(rule, tlimit01, sizeof(tlimit01)/sizeof(tlimit01[0]), att, valOff, sizeof(att)/sizeof(att[0]));
2748
genericRulesStarterWithOptions(rule, tlimit02, sizeof(tlimit02)/sizeof(tlimit02[0]), att, valOff, sizeof(att)/sizeof(att[0]));
2753
static const char *rule = "&c<ch<<<cH<<<Ch<<<CH";
2754
static const char *tlimit01[] = {"c","CH","Ch","cH","ch"};
2755
static const char *tlimit02[] = {"c","CH","cH","Ch","ch"};
2756
static const UColAttribute att[] = { UCOL_CASE_FIRST};
2757
static const UColAttributeValue valOn[] = { UCOL_UPPER_FIRST};
2758
/*static const UColAttributeValue valOff[] = { UCOL_OFF};*/
2759
log_verbose("case level\n");
2760
genericRulesStarterWithOptions(rule, tlimit01, sizeof(tlimit01)/sizeof(tlimit01[0]), att, valOn, sizeof(att)/sizeof(att[0]));
2761
genericRulesStarterWithOptions(rule, tlimit02, sizeof(tlimit02)/sizeof(tlimit02[0]), att, valOn, sizeof(att)/sizeof(att[0]));
2762
/*genericRulesStarterWithOptions(rule, tlimit01, sizeof(tlimit01)/sizeof(tlimit01[0]), att, valOff, sizeof(att)/sizeof(att[0]));*/
2763
/*genericRulesStarterWithOptions(rule, tlimit02, sizeof(tlimit02)/sizeof(tlimit02[0]), att, valOff, sizeof(att)/sizeof(att[0]));*/
2769
static void TestBocsuCoverage(void) {
2770
UErrorCode status = U_ZERO_ERROR;
2771
const char *testString = "\\u0041\\u0441\\u4441\\U00044441\\u4441\\u0441\\u0041";
2772
UChar test[256] = {0};
2773
uint32_t tlen = u_unescape(testString, test, 32);
2774
uint8_t key[256] = {0};
2777
UCollator *coll = ucol_open("", &status);
2778
ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_IDENTICAL, &status);
2780
klen = ucol_getSortKey(coll, test, tlen, key, 256);
2785
static void TestVariableTopSetting(void) {
2786
UErrorCode status = U_ZERO_ERROR;
2787
const UChar *current = NULL;
2788
uint32_t varTopOriginal = 0, varTop1, varTop2;
2789
UCollator *coll = ucol_open("", &status);
2791
uint32_t strength = 0;
2793
uint32_t chOffset = 0;
2795
uint32_t exOffset = 0;
2797
uint32_t oldChOffset = 0;
2798
uint32_t oldChLen = 0;
2799
uint32_t oldExOffset = 0;
2800
uint32_t oldExLen = 0;
2801
uint32_t prefixOffset = 0;
2802
uint32_t prefixLen = 0;
2804
UBool startOfRules = TRUE;
2805
UColTokenParser src;
2808
UChar *rulesCopy = NULL;
2811
UCollationResult result;
2813
UChar first[256] = { 0 };
2814
UChar second[256] = { 0 };
2815
UParseError parseError;
2818
log_verbose("Slide variable top over UCARules\n");
2819
rulesLen = ucol_getRulesEx(coll, UCOL_FULL_RULES, rulesCopy, 0);
2820
rulesCopy = (UChar *)uprv_malloc((rulesLen+UCOL_TOK_EXTRA_RULE_SPACE_SIZE)*sizeof(UChar));
2821
rulesLen = ucol_getRulesEx(coll, UCOL_FULL_RULES, rulesCopy, rulesLen+UCOL_TOK_EXTRA_RULE_SPACE_SIZE);
2823
if(U_SUCCESS(status) && rulesLen > 0) {
2824
ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
2825
src.source = src.current = rulesCopy;
2826
src.end = rulesCopy+rulesLen;
2827
src.extraCurrent = src.end;
2828
src.extraEnd = src.end+UCOL_TOK_EXTRA_RULE_SPACE_SIZE;
2830
while ((current = ucol_tok_parseNextToken(&src, startOfRules, &parseError,&status)) != NULL) {
2831
strength = src.parsedToken.strength;
2832
chOffset = src.parsedToken.charsOffset;
2833
chLen = src.parsedToken.charsLen;
2834
exOffset = src.parsedToken.extensionOffset;
2835
exLen = src.parsedToken.extensionLen;
2836
prefixOffset = src.parsedToken.prefixOffset;
2837
prefixLen = src.parsedToken.prefixLen;
2838
specs = src.parsedToken.flags;
2840
startOfRules = FALSE;
2842
log_verbose("%04X %d ", *(rulesCopy+chOffset), chLen);
2844
if(strength == UCOL_PRIMARY) {
2845
status = U_ZERO_ERROR;
2846
varTopOriginal = ucol_getVariableTop(coll, &status);
2847
varTop1 = ucol_setVariableTop(coll, rulesCopy+oldChOffset, oldChLen, &status);
2848
if(U_FAILURE(status)) {
2849
if(status == U_PRIMARY_TOO_LONG_ERROR) {
2850
log_verbose("= Expected failure for %04X =", *(rulesCopy+oldChOffset));
2852
log_err("Unexpected failure setting variable top for %04X at offset %d. Error %s\n", *(rulesCopy+oldChOffset), oldChOffset, u_errorName(status));
2856
varTop2 = ucol_getVariableTop(coll, &status);
2857
if((varTop1 & 0xFFFF0000) != (varTop2 & 0xFFFF0000)) {
2858
log_err("cannot retrieve set varTop value!\n");
2862
if((varTop1 & 0xFFFF0000) > 0 && oldExLen == 0) {
2864
u_strncpy(first, rulesCopy+oldChOffset, oldChLen);
2865
u_strncpy(first+oldChLen, rulesCopy+chOffset, chLen);
2866
u_strncpy(first+oldChLen+chLen, rulesCopy+oldChOffset, oldChLen);
2867
first[2*oldChLen+chLen] = 0;
2870
u_strncpy(second, rulesCopy+chOffset, chLen);
2872
} else { /* This is skipped momentarily, but should work once UCARules are fully UCA conformant */
2873
u_strncpy(second, rulesCopy+oldExOffset, oldExLen);
2874
u_strncpy(second+oldChLen, rulesCopy+chOffset, chLen);
2875
u_strncpy(second+oldChLen+chLen, rulesCopy+oldExOffset, oldExLen);
2876
second[2*oldExLen+chLen] = 0;
2878
result = ucol_strcoll(coll, first, -1, second, -1);
2879
if(result == UCOL_EQUAL) {
2880
doTest(coll, first, second, UCOL_EQUAL);
2882
log_verbose("Suspicious strcoll result for %04X and %04X\n", *(rulesCopy+oldChOffset), *(rulesCopy+chOffset));
2886
if(strength != UCOL_TOK_RESET) {
2887
oldChOffset = chOffset;
2889
oldExOffset = exOffset;
2895
log_err("Unexpected failure getting rules %s\n", u_errorName(status));
2898
if (U_FAILURE(status)) {
2899
log_err("Error parsing rules %s\n", u_errorName(status));
2902
status = U_ZERO_ERROR;
2904
log_verbose("Testing setting variable top to contractions\n");
2906
/* uint32_t tailoredCE = UCOL_NOT_FOUND; */
2907
UChar *conts = (UChar *)((uint8_t *)coll->image + coll->image->contractionUCACombos);
2908
while(*conts != 0) {
2909
if(*(conts+2) == 0) {
2910
varTop1 = ucol_setVariableTop(coll, conts, -1, &status);
2912
varTop1 = ucol_setVariableTop(coll, conts, 3, &status);
2914
if(U_FAILURE(status)) {
2915
log_err("Couldn't set variable top to a contraction\n");
2920
status = U_ZERO_ERROR;
2926
ucol_setVariableTop(coll, first, -1, &status);
2928
if(U_SUCCESS(status)) {
2929
log_err("Invalid contraction succeded in setting variable top!\n");
2934
log_verbose("Test restoring variable top\n");
2936
status = U_ZERO_ERROR;
2937
ucol_restoreVariableTop(coll, varTopOriginal, &status);
2938
if(varTopOriginal != ucol_getVariableTop(coll, &status)) {
2939
log_err("Couldn't restore old variable top\n");
2942
log_verbose("Testing calling with error set\n");
2944
status = U_INTERNAL_PROGRAM_ERROR;
2945
varTop1 = ucol_setVariableTop(coll, first, 1, &status);
2946
varTop2 = ucol_getVariableTop(coll, &status);
2947
ucol_restoreVariableTop(coll, varTop2, &status);
2948
varTop1 = ucol_setVariableTop(NULL, first, 1, &status);
2949
varTop2 = ucol_getVariableTop(NULL, &status);
2950
ucol_restoreVariableTop(NULL, varTop2, &status);
2951
if(status != U_INTERNAL_PROGRAM_ERROR) {
2952
log_err("Bad reaction to passed error!\n");
2954
uprv_free(rulesCopy);
2958
static void TestNonChars(void) {
2959
static const char *test[] = {
2961
"\\uFFFE", "\\uFFFF",
2962
"\\U0001FFFE", "\\U0001FFFF",
2963
"\\U0002FFFE", "\\U0002FFFF",
2964
"\\U0003FFFE", "\\U0003FFFF",
2965
"\\U0004FFFE", "\\U0004FFFF",
2966
"\\U0005FFFE", "\\U0005FFFF",
2967
"\\U0006FFFE", "\\U0006FFFF",
2968
"\\U0007FFFE", "\\U0007FFFF",
2969
"\\U0008FFFE", "\\U0008FFFF",
2970
"\\U0009FFFE", "\\U0009FFFF",
2971
"\\U000AFFFE", "\\U000AFFFF",
2972
"\\U000BFFFE", "\\U000BFFFF",
2973
"\\U000CFFFE", "\\U000CFFFF",
2974
"\\U000DFFFE", "\\U000DFFFF",
2975
"\\U000EFFFE", "\\U000EFFFF",
2976
"\\U000FFFFE", "\\U000FFFFF",
2977
"\\U0010FFFE", "\\U0010FFFF"
2979
UErrorCode status = U_ZERO_ERROR;
2980
UCollator *coll = ucol_open("en_US", &status);
2982
log_verbose("Test non characters\n");
2984
if(U_SUCCESS(status)) {
2985
genericOrderingTestWithResult(coll, test, 35, UCOL_EQUAL);
2987
log_err("Unable to open collator\n");
2993
static void TestExtremeCompression(void) {
2994
static char *test[4];
2997
for(i = 0; i<4; i++) {
2998
test[i] = (char *)uprv_malloc(2048*sizeof(char));
2999
uprv_memset(test[i], 'a', 2046*sizeof(char));
3000
test[i][2046] = (char)('a'+i);
3004
genericLocaleStarter("en_US", (const char **)test, 4);
3006
for(i = 0; i<4; i++) {
3011
static void TestSurrogates(void) {
3012
static const char *test[] = {
3013
"z","\\ud900\\udc25", "\\ud805\\udc50",
3014
"\\ud800\\udc00y", "\\ud800\\udc00r",
3015
"\\ud800\\udc00f", "\\ud800\\udc00",
3016
"\\ud800\\udc00c", "\\ud800\\udc00b",
3017
"\\ud800\\udc00fa", "\\ud800\\udc00fb",
3022
static const char *rule =
3023
"&z < \\ud900\\udc25 < \\ud805\\udc50"
3024
"< \\ud800\\udc00y < \\ud800\\udc00r"
3025
"< \\ud800\\udc00f << \\ud800\\udc00"
3026
"< \\ud800\\udc00fa << \\ud800\\udc00fb"
3027
"< \\ud800\\udc00a < c < b" ;
3029
genericRulesStarter(rule, test, 14);
3032
/* This is a test for prefix implementation, used by JIS X 4061 collation rules */
3033
static void TestPrefix(void) {
3038
const char *data[50];
3045
"&z<<<\\ud900\\udc25|a",
3046
{"aa", "az", "\\ud900\\udc25z", "\\ud900\\udc25a", "zz"}, 4 },
3050
for(i = 0; i<(sizeof(tests)/sizeof(tests[0])); i++) {
3051
genericRulesStarter(tests[i].rules, tests[i].data, tests[i].len);
3055
/* This test uses data suplied by Masashiko Maedera to test the implementation */
3056
/* JIS X 4061 collation order implementation */
3057
static void TestNewJapanese(void) {
3059
static const char *test1[] = {
3060
"\\u30b7\\u30e3\\u30fc\\u30ec",
3061
"\\u30b7\\u30e3\\u30a4",
3062
"\\u30b7\\u30e4\\u30a3",
3063
"\\u30b7\\u30e3\\u30ec",
3064
"\\u3061\\u3087\\u3053",
3065
"\\u3061\\u3088\\u3053",
3066
"\\u30c1\\u30e7\\u30b3\\u30ec\\u30fc\\u30c8",
3067
"\\u3066\\u30fc\\u305f",
3068
"\\u30c6\\u30fc\\u30bf",
3069
"\\u30c6\\u30a7\\u30bf",
3070
"\\u3066\\u3048\\u305f",
3071
"\\u3067\\u30fc\\u305f",
3072
"\\u30c7\\u30fc\\u30bf",
3073
"\\u30c7\\u30a7\\u30bf",
3074
"\\u3067\\u3048\\u305f",
3075
"\\u3066\\u30fc\\u305f\\u30fc",
3076
"\\u30c6\\u30fc\\u30bf\\u30a1",
3077
"\\u30c6\\u30a7\\u30bf\\u30fc",
3078
"\\u3066\\u3047\\u305f\\u3041",
3079
"\\u3066\\u3048\\u305f\\u30fc",
3080
"\\u3067\\u30fc\\u305f\\u30fc",
3081
"\\u30c7\\u30fc\\u30bf\\u30a1",
3082
"\\u3067\\u30a7\\u305f\\u30a1",
3083
"\\u30c7\\u3047\\u30bf\\u3041",
3084
"\\u30c7\\u30a8\\u30bf\\u30a2",
3086
"\\u3073\\u3085\\u3042",
3087
"\\u3074\\u3085\\u3042",
3088
"\\u3073\\u3085\\u3042\\u30fc",
3089
"\\u30d3\\u30e5\\u30a2\\u30fc",
3090
"\\u3074\\u3085\\u3042\\u30fc",
3091
"\\u30d4\\u30e5\\u30a2\\u30fc",
3092
"\\u30d2\\u30e5\\u30a6",
3093
"\\u30d2\\u30e6\\u30a6",
3094
"\\u30d4\\u30e5\\u30a6\\u30a2",
3095
"\\u3073\\u3085\\u30fc\\u3042\\u30fc",
3096
"\\u30d3\\u30e5\\u30fc\\u30a2\\u30fc",
3097
"\\u30d3\\u30e5\\u30a6\\u30a2\\u30fc",
3098
"\\u3072\\u3085\\u3093",
3099
"\\u3074\\u3085\\u3093",
3100
"\\u3075\\u30fc\\u308a",
3101
"\\u30d5\\u30fc\\u30ea",
3102
"\\u3075\\u3045\\u308a",
3103
"\\u3075\\u30a5\\u308a",
3104
"\\u3075\\u30a5\\u30ea",
3105
"\\u30d5\\u30a6\\u30ea",
3106
"\\u3076\\u30fc\\u308a",
3107
"\\u30d6\\u30fc\\u30ea",
3108
"\\u3076\\u3045\\u308a",
3109
"\\u30d6\\u30a5\\u308a",
3110
"\\u3077\\u3046\\u308a",
3111
"\\u30d7\\u30a6\\u30ea",
3112
"\\u3075\\u30fc\\u308a\\u30fc",
3113
"\\u30d5\\u30a5\\u30ea\\u30fc",
3114
"\\u3075\\u30a5\\u308a\\u30a3",
3115
"\\u30d5\\u3045\\u308a\\u3043",
3116
"\\u30d5\\u30a6\\u30ea\\u30fc",
3117
"\\u3075\\u3046\\u308a\\u3043",
3118
"\\u30d6\\u30a6\\u30ea\\u30a4",
3119
"\\u3077\\u30fc\\u308a\\u30fc",
3120
"\\u3077\\u30a5\\u308a\\u30a4",
3121
"\\u3077\\u3046\\u308a\\u30fc",
3122
"\\u30d7\\u30a6\\u30ea\\u30a4",
3138
static const char *test2[] = {
3139
"\\u306f\\u309d", /* H\\u309d */
3140
"\\u30cf\\u30fd", /* K\\u30fd */
3141
"\\u306f\\u306f", /* HH */
3142
"\\u306f\\u30cf", /* HK */
3143
"\\u30cf\\u30cf", /* KK */
3144
"\\u306f\\u309e", /* H\\u309e */
3145
"\\u30cf\\u30fe", /* K\\u30fe */
3146
"\\u306f\\u3070", /* HH\\u309b */
3147
"\\u30cf\\u30d0", /* KK\\u309b */
3148
"\\u306f\\u3071", /* HH\\u309c */
3149
"\\u30cf\\u3071", /* KH\\u309c */
3150
"\\u30cf\\u30d1", /* KK\\u309c */
3151
"\\u3070\\u309d", /* H\\u309b\\u309d */
3152
"\\u30d0\\u30fd", /* K\\u309b\\u30fd */
3153
"\\u3070\\u306f", /* H\\u309bH */
3154
"\\u30d0\\u30cf", /* K\\u309bK */
3155
"\\u3070\\u309e", /* H\\u309b\\u309e */
3156
"\\u30d0\\u30fe", /* K\\u309b\\u30fe */
3157
"\\u3070\\u3070", /* H\\u309bH\\u309b */
3158
"\\u30d0\\u3070", /* K\\u309bH\\u309b */
3159
"\\u30d0\\u30d0", /* K\\u309bK\\u309b */
3160
"\\u3070\\u3071", /* H\\u309bH\\u309c */
3161
"\\u30d0\\u30d1", /* K\\u309bK\\u309c */
3162
"\\u3071\\u309d", /* H\\u309c\\u309d */
3163
"\\u30d1\\u30fd", /* K\\u309c\\u30fd */
3164
"\\u3071\\u306f", /* H\\u309cH */
3165
"\\u30d1\\u30cf", /* K\\u309cK */
3166
"\\u3071\\u3070", /* H\\u309cH\\u309b */
3167
"\\u3071\\u30d0", /* H\\u309cK\\u309b */
3168
"\\u30d1\\u30d0", /* K\\u309cK\\u309b */
3169
"\\u3071\\u3071", /* H\\u309cH\\u309c */
3170
"\\u30d1\\u30d1", /* K\\u309cK\\u309c */
3173
static const char *test3[] = {
3201
"\\u30b7\\u30e3\\u30fc\\u30ec",
3204
static const UColAttribute att[] = { UCOL_ALTERNATE_HANDLING};
3205
static const UColAttributeValue valShifted[] = { UCOL_SHIFTED };
3207
genericLocaleStarter("ja", test1, sizeof(test1)/sizeof(test1[0]));
3208
genericLocaleStarter("ja", test2, sizeof(test2)/sizeof(test2[0]));
3209
/*genericLocaleStarter("ja", test3, sizeof(test3)/sizeof(test3[0]));*/
3210
genericLocaleStarterWithOptions("ja", test1, sizeof(test1)/sizeof(test1[0]), att, valShifted, 1);
3211
genericLocaleStarterWithOptions("ja", test2, sizeof(test2)/sizeof(test2[0]), att, valShifted, 1);
3214
static void TestStrCollIdenticalPrefix(void) {
3215
const char* rule = "&\\ud9b0\\udc70=\\ud9b0\\udc71";
3216
const char* test[] = {
3220
genericRulesTestWithResult(rule, test, sizeof(test)/sizeof(test[0]), UCOL_EQUAL);
3222
/* Contractions should have all their canonically equivalent */
3223
/* strings included */
3224
static void TestContractionClosure(void) {
3227
const char *data[50];
3230
{ "&b=\\u00e4\\u00e4",
3231
{ "b", "\\u00e4\\u00e4", "a\\u0308a\\u0308", "\\u00e4a\\u0308", "a\\u0308\\u00e4" }, 5},
3233
{ "b", "\\u00C5", "A\\u030A", "\\u212B" }, 4},
3238
for(i = 0; i<(sizeof(tests)/sizeof(tests[0])); i++) {
3239
genericRulesTestWithResult(tests[i].rules, tests[i].data, tests[i].len, UCOL_EQUAL);
3243
/* This tests also fails*/
3244
static void TestBeforePrefixFailure(void) {
3247
const char *data[50];
3251
"&[before 3]\\uff41 <<< x",
3252
{"x", "\\uff41"}, 2 },
3253
{ "&\\u30A7=\\u30A7=\\u3047=\\uff6a"
3254
"&\\u30A8=\\u30A8=\\u3048=\\uff74"
3255
"&[before 3]\\u30a7<<<\\u30a9",
3256
{"\\u30a9", "\\u30a7"}, 2 },
3257
{ "&[before 3]\\u30a7<<<\\u30a9"
3258
"&\\u30A7=\\u30A7=\\u3047=\\uff6a"
3259
"&\\u30A8=\\u30A8=\\u3048=\\uff74",
3260
{"\\u30a9", "\\u30a7"}, 2 },
3265
for(i = 0; i<(sizeof(tests)/sizeof(tests[0])); i++) {
3266
genericRulesStarter(tests[i].rules, tests[i].data, tests[i].len);
3271
"&\\u30A7=\\u30A7=\\u3047=\\uff6a"
3272
"&\\u30A8=\\u30A8=\\u3048=\\uff74"
3273
"&[before 3]\\u30a7<<<\\u30c6|\\u30fc";
3275
"&[before 3]\\u30a7<<<\\u30c6|\\u30fc"
3276
"&\\u30A7=\\u30A7=\\u3047=\\uff6a"
3277
"&\\u30A8=\\u30A8=\\u3048=\\uff74";
3278
const char* test[] = {
3279
"\\u30c6\\u30fc\\u30bf",
3280
"\\u30c6\\u30a7\\u30bf",
3282
genericRulesStarter(rule1, test, sizeof(test)/sizeof(test[0]));
3283
genericRulesStarter(rule2, test, sizeof(test)/sizeof(test[0]));
3284
/* this piece of code should be in some sort of verbose mode */
3285
/* it gets the collation elements for elements and prints them */
3286
/* This is useful when trying to see whether the problem is */
3288
UErrorCode status = U_ZERO_ERROR;
3290
UCollationElements *it = NULL;
3293
uint32_t uStringLen;
3294
UCollator *coll = NULL;
3296
uStringLen = u_unescape(rule1, string, 256);
3298
coll = ucol_openRules(string, uStringLen, UCOL_DEFAULT, UCOL_DEFAULT, NULL, &status);
3300
/*coll = ucol_open("ja_JP_JIS", &status);*/
3301
it = ucol_openElements(coll, string, 0, &status);
3303
for(i = 0; i < sizeof(test)/sizeof(test[0]); i++) {
3304
log_verbose("%s\n", test[i]);
3305
uStringLen = u_unescape(test[i], string, 256);
3306
ucol_setText(it, string, uStringLen, &status);
3308
while((CE=ucol_next(it, &status)) != UCOL_NULLORDER) {
3309
log_verbose("%08X\n", CE);
3315
ucol_closeElements(it);
3321
static void TestPrefixCompose(void) {
3323
"&\\u30a7<<<\\u30ab|\\u30fc=\\u30ac|\\u30fc";
3325
const char* test[] = {
3326
"\\u30c6\\u30fc\\u30bf",
3327
"\\u30c6\\u30a7\\u30bf",
3331
UErrorCode status = U_ZERO_ERROR;
3333
/*UCollationElements *it = NULL;*/
3336
uint32_t uStringLen;
3337
UCollator *coll = NULL;
3339
uStringLen = u_unescape(rule1, string, 256);
3341
coll = ucol_openRules(string, uStringLen, UCOL_DEFAULT, UCOL_DEFAULT, NULL, &status);
3348
static int tMemCmp(const uint8_t *first, const uint8_t *second) {
3349
int32_t firstLen = uprv_strlen((const char *)first);
3350
int32_t secondLen = uprv_strlen((const char *)second);
3351
return uprv_memcmp(first, second, uprv_min(firstLen, secondLen));
3356
static void TestMergeSortKeys(void) {
3357
UErrorCode status = U_ZERO_ERROR;
3359
const char* cases[] = {
3364
uint32_t casesSize = sizeof(cases)/sizeof(cases[0]);
3365
const char* prefix = "foo";
3366
const char* suffix = "egg";
3367
char outBuff1[256], outBuff2[256];
3369
uint8_t **sortkeys = (uint8_t **)uprv_malloc(casesSize*sizeof(uint8_t *));
3370
uint8_t **mergedPrefixkeys = (uint8_t **)uprv_malloc(casesSize*sizeof(uint8_t *));
3371
uint8_t **mergedSuffixkeys = (uint8_t **)uprv_malloc(casesSize*sizeof(uint8_t *));
3372
uint32_t *sortKeysLen = (uint32_t *)uprv_malloc(casesSize*sizeof(uint32_t));
3373
uint8_t prefixKey[256], suffixKey[256];
3374
uint32_t prefixKeyLen = 0, suffixKeyLen = 0, i = 0;
3376
uint32_t unescapedLen = 0, l1 = 0, l2 = 0;
3377
UColAttributeValue strength;
3379
UCollator *coll = ucol_open("en", &status);
3380
log_verbose("ucol_mergeSortkeys test\n");
3381
log_verbose("Testing order of the test cases\n");
3382
genericLocaleStarter("en", cases, casesSize);
3384
for(i = 0; i<casesSize; i++) {
3385
sortkeys[i] = (uint8_t *)uprv_malloc(256*sizeof(uint8_t));
3386
mergedPrefixkeys[i] = (uint8_t *)uprv_malloc(256*sizeof(uint8_t));
3387
mergedSuffixkeys[i] = (uint8_t *)uprv_malloc(256*sizeof(uint8_t));
3390
unescapedLen = u_unescape(prefix, buffer, 256);
3391
prefixKeyLen = ucol_getSortKey(coll, buffer, unescapedLen, prefixKey, 256);
3393
unescapedLen = u_unescape(suffix, buffer, 256);
3394
suffixKeyLen = ucol_getSortKey(coll, buffer, unescapedLen, suffixKey, 256);
3396
log_verbose("Massaging data with prefixes and different strengths\n");
3397
strength = UCOL_PRIMARY;
3398
while(strength <= UCOL_IDENTICAL) {
3399
log_verbose("Strength %s\n", strengthsC[strength<=UCOL_QUATERNARY?strength:4]);
3400
ucol_setAttribute(coll, UCOL_STRENGTH, strength, &status);
3401
for(i = 0; i<casesSize; i++) {
3402
unescapedLen = u_unescape(cases[i], buffer, 256);
3403
sortKeysLen[i] = ucol_getSortKey(coll, buffer, unescapedLen, sortkeys[i], 256);
3404
ucol_mergeSortkeys(prefixKey, prefixKeyLen, sortkeys[i], sortKeysLen[i], mergedPrefixkeys[i], 256);
3405
ucol_mergeSortkeys(sortkeys[i], sortKeysLen[i], suffixKey, suffixKeyLen, mergedSuffixkeys[i], 256);
3407
if(tMemCmp(mergedPrefixkeys[i-1], mergedPrefixkeys[i]) >= 0) {
3408
log_err("Error while comparing prefixed keys @ strength %s:\n", strengthsC[strength<=UCOL_QUATERNARY?strength:4]);
3410
ucol_sortKeyToString(coll, mergedPrefixkeys[i-1], outBuff1, &l1),
3411
ucol_sortKeyToString(coll, mergedPrefixkeys[i], outBuff2, &l2));
3413
if(tMemCmp(mergedSuffixkeys[i-1], mergedSuffixkeys[i]) >= 0) {
3414
log_err("Error while comparing suffixed keys @ strength %s:\n", strengthsC[strength<=UCOL_QUATERNARY?strength:4]);
3416
ucol_sortKeyToString(coll, mergedSuffixkeys[i-1], outBuff1, &l1),
3417
ucol_sortKeyToString(coll, mergedSuffixkeys[i], outBuff2, &l2));
3421
if(strength == UCOL_QUATERNARY) {
3422
strength = UCOL_IDENTICAL;
3429
uint8_t smallBuf[3];
3430
uint32_t reqLen = 0;
3431
log_verbose("testing buffer overflow\n");
3432
reqLen = ucol_mergeSortkeys(prefixKey, prefixKeyLen, suffixKey, suffixKeyLen, smallBuf, 3);
3433
if(reqLen != (prefixKeyLen+suffixKeyLen-1)) {
3434
log_err("Wrong preflight size for merged sortkey\n");
3439
for(i = 0; i<casesSize; i++) {
3440
uprv_free(sortkeys[i]);
3441
uprv_free(mergedPrefixkeys[i]);
3442
uprv_free(mergedSuffixkeys[i]);
3444
uprv_free(sortkeys);
3445
uprv_free(mergedPrefixkeys);
3446
uprv_free(mergedSuffixkeys);
3447
uprv_free(sortKeysLen);
3449
/* need to finish this up */
3453
[last variable] last variable value
3454
[last primary ignorable] largest CE for primary ignorable
3455
[last secondary ignorable] largest CE for secondary ignorable
3456
[last tertiary ignorable] largest CE for tertiary ignorable
3457
[top] guaranteed to be above all implicit CEs, for now and in the future (in 1.8)
3460
static void TestRuleOptions(void) {
3463
const char *data[50];
3466
{ "&[last variable]<z"
3467
"&[last primary ignorable]<x"
3468
"&[last secondary ignorable]<<y"
3469
"&[last tertiary ignorable]<<<w"
3471
{"\\ufffb", "w", "y", "\\u20e3", "x", "\\u137c", "z", "u"}, 7 },
3472
{ "&[before 1][first tertiary ignorable]<<<k",
3473
{ "\\u0000", "k"}, 2}, /* you cannot go before first tertiary ignorable */
3474
/* - all befores here amount to zero */
3475
{ "&[before 3][last primary ignorable]<<<k",
3476
{ "k", "\\u20e3"}, 2},
3481
for(i = 0; i<(sizeof(tests)/sizeof(tests[0])); i++) {
3482
genericRulesStarter(tests[i].rules, tests[i].data, tests[i].len);
3486
void addMiscCollTest(TestNode** root)
3489
addTest(root, &TestRuleOptions, "tscoll/cmsccoll/TestRuleOptions");
3490
addTest(root, &TestBeforePrefixFailure, "tscoll/cmsccoll/TestBeforePrefixFailure");
3491
addTest(root, &TestContractionClosure, "tscoll/cmsccoll/TestContractionClosure");
3492
addTest(root, &TestMergeSortKeys, "tscoll/cmsccoll/TestMergeSortKeys");
3493
addTest(root, &TestPrefixCompose, "tscoll/cmsccoll/TestPrefixCompose");
3494
addTest(root, &TestStrCollIdenticalPrefix, "tscoll/cmsccoll/TestStrCollIdenticalPrefix");
3495
addTest(root, &TestPrefix, "tscoll/cmsccoll/TestPrefix");
3496
addTest(root, &TestNewJapanese, "tscoll/cmsccoll/TestNewJapanese");
3497
/*addTest(root, &TestLimitations, "tscoll/cmsccoll/TestLimitations");*/
3498
addTest(root, &TestNonChars, "tscoll/cmsccoll/TestNonChars");
3499
addTest(root, &TestExtremeCompression, "tscoll/cmsccoll/TestExtremeCompression");
3500
addTest(root, &TestSurrogates, "tscoll/cmsccoll/TestSurrogates");
3501
addTest(root, &TestVariableTopSetting, "tscoll/cmsccoll/TestVariableTopSetting");
3502
addTest(root, &TestBocsuCoverage, "tscoll/cmsccoll/TestBocsuCoverage");
3503
addTest(root, &TestCyrillicTailoring, "tscoll/cmsccoll/TestCyrillicTailoring");
3504
addTest(root, &TestCase, "tscoll/cmsccoll/TestCase");
3505
addTest(root, &IncompleteCntTest, "tscoll/cmsccoll/IncompleteCntTest");
3506
addTest(root, &BlackBirdTest, "tscoll/cmsccoll/BlackBirdTest");
3507
addTest(root, &FunkyATest, "tscoll/cmsccoll/FunkyATest");
3508
addTest(root, &BillFairmanTest, "tscoll/cmsccoll/BillFairmanTest");
3509
addTest(root, &RamsRulesTest, "tscoll/cmsccoll/RamsRulesTest");
3510
addTest(root, &IsTailoredTest, "tscoll/cmsccoll/IsTailoredTest");
3511
addTest(root, &TestCollations, "tscoll/cmsccoll/TestCollations");
3512
addTest(root, &TestChMove, "tscoll/cmsccoll/TestChMove");
3513
addTest(root, &TestImplicitTailoring, "tscoll/cmsccoll/TestImplicitTailoring");
3514
addTest(root, &TestFCDProblem, "tscoll/cmsccoll/TestFCDProblem");
3515
addTest(root, &TestEmptyRule, "tscoll/cmsccoll/TestEmptyRule");
3516
addTest(root, &TestJ784, "tscoll/cmsccoll/TestJ784");
3517
addTest(root, &TestJ815, "tscoll/cmsccoll/TestJ815");
3518
addTest(root, &TestJ831, "tscoll/cmsccoll/TestJ831");
3519
addTest(root, &TestBefore, "tscoll/cmsccoll/TestBefore");
3520
addTest(root, &TestRedundantRules, "tscoll/cmsccoll/TestRedundantRules");
3521
addTest(root, &TestExpansionSyntax, "tscoll/cmsccoll/TestExpansionSyntax");
3522
addTest(root, &TestHangulTailoring, "tscoll/cmsccoll/TestHangulTailoring");
3523
addTest(root, &TestUCARules, "tscoll/cmsccoll/TestUCARules");
3524
addTest(root, &TestIncrementalNormalize, "tscoll/cmsccoll/TestIncrementalNormalize");
3525
addTest(root, &TestComposeDecompose, "tscoll/cmsccoll/TestComposeDecompose");
3526
addTest(root, &TestCompressOverlap, "tscoll/cmsccoll/TestCompressOverlap");
3527
addTest(root, &TestContraction, "tscoll/cmsccoll/TestContraction");
3528
addTest(root, &TestExpansion, "tscoll/cmsccoll/TestExpansion");
3529
/*addTest(root, &PrintMarkDavis, "tscoll/cmsccoll/PrintMarkDavis");*/ /* this test doesn't test - just prints sortkeys */
3530
/*addTest(root, &TestGetCaseBit, "tscoll/cmsccoll/TestGetCaseBit");*/ /*this one requires internal things to be exported */