1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1997-2009, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ********************************************************************/ 6 /******************************************************************************* 7 * 8 * File CALLCOLL.C 9 * 10 * Modification History: 11 * Name Description 12 * Madhu Katragadda Ported for C API 13 ******************************************************************************** 14 */ 15 16 /* 17 * Important: This file is included into intltest/allcoll.cpp so that the 18 * test data is shared. This makes it easier to maintain the test data, 19 * especially since the Unicode data must be portable and quoted character 20 * literals will not work. 21 * If it is included, then there will be a #define INCLUDE_CALLCOLL_C 22 * that must prevent the actual code in here from being part of the 23 * allcoll.cpp compilation. 24 */ 25 26 /** 27 * CollationDummyTest is a third level test class. This tests creation of 28 * a customized collator object. For example, number 1 to be sorted 29 * equlivalent to word 'one'. 30 */ 31 32 #include <string.h> 33 #include <stdlib.h> 34 35 #include "unicode/utypes.h" 36 37 #if !UCONFIG_NO_COLLATION 38 39 #include "unicode/ucol.h" 40 #include "unicode/uloc.h" 41 #include "unicode/ures.h" 42 #include "unicode/udata.h" 43 #include "unicode/ucoleitr.h" 44 #include "unicode/ustring.h" 45 #include "unicode/uclean.h" 46 #include "unicode/putil.h" 47 #include "unicode/uenum.h" 48 49 #include "cintltst.h" 50 #include "ccolltst.h" 51 #include "callcoll.h" 52 #include "calldata.h" 53 #include "cstring.h" 54 #include "cmemory.h" 55 #include "ucol_imp.h" 56 57 /* set to 1 to test offsets in backAndForth() */ 58 #define TEST_OFFSETS 0 59 60 /* perform test with strength PRIMARY */ 61 static void TestPrimary(void); 62 63 /* perform test with strength SECONDARY */ 64 static void TestSecondary(void); 65 66 /* perform test with strength tertiary */ 67 static void TestTertiary(void); 68 69 /*perform tests with strength Identical */ 70 static void TestIdentical(void); 71 72 /* perform extra tests */ 73 static void TestExtra(void); 74 75 /* Test jitterbug 581 */ 76 static void TestJB581(void); 77 78 /* Test jitterbug 1401 */ 79 static void TestJB1401(void); 80 81 /* Test [variable top] in the rule syntax */ 82 static void TestVariableTop(void); 83 84 /* Test surrogates */ 85 static void TestSurrogates(void); 86 87 static void TestInvalidRules(void); 88 89 static void TestJitterbug1098(void); 90 91 static void TestFCDCrash(void); 92 93 static void TestJ5298(void); 94 95 const UCollationResult results[] = { 96 UCOL_LESS, 97 UCOL_LESS, /*UCOL_GREATER,*/ 98 UCOL_LESS, 99 UCOL_LESS, 100 UCOL_LESS, 101 UCOL_LESS, 102 UCOL_LESS, 103 UCOL_GREATER, 104 UCOL_GREATER, 105 UCOL_LESS, /* 10 */ 106 UCOL_GREATER, 107 UCOL_LESS, 108 UCOL_GREATER, 109 UCOL_GREATER, 110 UCOL_LESS, 111 UCOL_LESS, 112 UCOL_LESS, 113 /* test primary > 17 */ 114 UCOL_EQUAL, 115 UCOL_EQUAL, 116 UCOL_EQUAL, /* 20 */ 117 UCOL_LESS, 118 UCOL_LESS, 119 UCOL_EQUAL, 120 UCOL_EQUAL, 121 UCOL_EQUAL, 122 UCOL_LESS, 123 /* test secondary > 26 */ 124 UCOL_EQUAL, 125 UCOL_EQUAL, 126 UCOL_EQUAL, 127 UCOL_EQUAL, 128 UCOL_EQUAL, /* 30 */ 129 UCOL_EQUAL, 130 UCOL_LESS, 131 UCOL_EQUAL, /* 34 */ 132 UCOL_EQUAL, 133 UCOL_EQUAL, 134 UCOL_LESS /* 37 */ 135 }; 136 137 138 static 139 void uprv_appendByteToHexString(char *dst, uint8_t val) { 140 uint32_t len = (uint32_t)uprv_strlen(dst); 141 *(dst+len) = T_CString_itosOffset((val >> 4)); 142 *(dst+len+1) = T_CString_itosOffset((val & 0xF)); 143 *(dst+len+2) = 0; 144 } 145 146 /* this function makes a string with representation of a sortkey */ 147 static char* U_EXPORT2 sortKeyToString(const UCollator *coll, const uint8_t *sortkey, char *buffer, uint32_t *len) { 148 int32_t strength = UCOL_PRIMARY; 149 uint32_t res_size = 0; 150 UBool doneCase = FALSE; 151 152 char *current = buffer; 153 const uint8_t *currentSk = sortkey; 154 155 uprv_strcpy(current, "["); 156 157 while(strength <= UCOL_QUATERNARY && strength <= coll->strength) { 158 if(strength > UCOL_PRIMARY) { 159 uprv_strcat(current, " . "); 160 } 161 while(*currentSk != 0x01 && *currentSk != 0x00) { /* print a level */ 162 uprv_appendByteToHexString(current, *currentSk++); 163 uprv_strcat(current, " "); 164 } 165 if(coll->caseLevel == UCOL_ON && strength == UCOL_SECONDARY && doneCase == FALSE) { 166 doneCase = TRUE; 167 } else if(coll->caseLevel == UCOL_OFF || doneCase == TRUE || strength != UCOL_SECONDARY) { 168 strength ++; 169 } 170 if (*currentSk) { 171 uprv_appendByteToHexString(current, *currentSk++); /* This should print '01' */ 172 } 173 if(strength == UCOL_QUATERNARY && coll->alternateHandling == UCOL_NON_IGNORABLE) { 174 break; 175 } 176 } 177 178 if(coll->strength == UCOL_IDENTICAL) { 179 uprv_strcat(current, " . "); 180 while(*currentSk != 0) { 181 uprv_appendByteToHexString(current, *currentSk++); 182 uprv_strcat(current, " "); 183 } 184 185 uprv_appendByteToHexString(current, *currentSk++); 186 } 187 uprv_strcat(current, "]"); 188 189 if(res_size > *len) { 190 return NULL; 191 } 192 193 return buffer; 194 } 195 196 void addAllCollTest(TestNode** root) 197 { 198 addTest(root, &TestPrimary, "tscoll/callcoll/TestPrimary"); 199 addTest(root, &TestSecondary, "tscoll/callcoll/TestSecondary"); 200 addTest(root, &TestTertiary, "tscoll/callcoll/TestTertiary"); 201 addTest(root, &TestIdentical, "tscoll/callcoll/TestIdentical"); 202 addTest(root, &TestExtra, "tscoll/callcoll/TestExtra"); 203 addTest(root, &TestJB581, "tscoll/callcoll/TestJB581"); 204 addTest(root, &TestVariableTop, "tscoll/callcoll/TestVariableTop"); 205 addTest(root, &TestSurrogates, "tscoll/callcoll/TestSurrogates"); 206 addTest(root, &TestInvalidRules, "tscoll/callcoll/TestInvalidRules"); 207 addTest(root, &TestJB1401, "tscoll/callcoll/TestJB1401"); 208 addTest(root, &TestJitterbug1098, "tscoll/callcoll/TestJitterbug1098"); 209 addTest(root, &TestFCDCrash, "tscoll/callcoll/TestFCDCrash"); 210 addTest(root, &TestJ5298, "tscoll/callcoll/TestJ5298"); 211 } 212 213 UBool hasCollationElements(const char *locName) { 214 215 UErrorCode status = U_ZERO_ERROR; 216 217 UResourceBundle *loc = ures_open(U_ICUDATA_COLL, locName, &status);; 218 219 if(U_SUCCESS(status)) { 220 status = U_ZERO_ERROR; 221 loc = ures_getByKey(loc, "collations", loc, &status); 222 ures_close(loc); 223 if(status == U_ZERO_ERROR) { /* do the test - there are real elements */ 224 return TRUE; 225 } 226 } 227 return FALSE; 228 } 229 230 static UCollationResult compareUsingPartials(UCollator *coll, const UChar source[], int32_t sLen, const UChar target[], int32_t tLen, int32_t pieceSize, UErrorCode *status) { 231 int32_t partialSKResult = 0; 232 UCharIterator sIter, tIter; 233 uint32_t sState[2], tState[2]; 234 int32_t sSize = pieceSize, tSize = pieceSize; 235 /*int32_t i = 0;*/ 236 uint8_t sBuf[16384], tBuf[16384]; 237 if(pieceSize > 16384) { 238 log_err("Partial sortkey size buffer too small. Please consider increasing the buffer!\n"); 239 *status = U_BUFFER_OVERFLOW_ERROR; 240 return UCOL_EQUAL; 241 } 242 *status = U_ZERO_ERROR; 243 sState[0] = 0; sState[1] = 0; 244 tState[0] = 0; tState[1] = 0; 245 while(sSize == pieceSize && tSize == pieceSize && partialSKResult == 0) { 246 uiter_setString(&sIter, source, sLen); 247 uiter_setString(&tIter, target, tLen); 248 sSize = ucol_nextSortKeyPart(coll, &sIter, sState, sBuf, pieceSize, status); 249 tSize = ucol_nextSortKeyPart(coll, &tIter, tState, tBuf, pieceSize, status); 250 251 if(sState[0] != 0 || tState[0] != 0) { 252 /*log_verbose("State != 0 : %08X %08X\n", sState[0], tState[0]);*/ 253 } 254 /*log_verbose("%i ", i++);*/ 255 256 partialSKResult = memcmp(sBuf, tBuf, pieceSize); 257 } 258 259 if(partialSKResult < 0) { 260 return UCOL_LESS; 261 } else if(partialSKResult > 0) { 262 return UCOL_GREATER; 263 } else { 264 return UCOL_EQUAL; 265 } 266 } 267 268 static void doTestVariant(UCollator* myCollation, const UChar source[], const UChar target[], UCollationResult result) 269 { 270 int32_t sortklen1, sortklen2, sortklenmax, sortklenmin; 271 int temp=0, gSortklen1=0,gSortklen2=0; 272 UCollationResult compareResult, compareResulta, keyResult, compareResultIter = result; 273 uint8_t *sortKey1, *sortKey2, *sortKey1a, *sortKey2a; 274 uint32_t sLen = u_strlen(source); 275 uint32_t tLen = u_strlen(target); 276 char buffer[256]; 277 uint32_t len; 278 UErrorCode status = U_ZERO_ERROR; 279 UColAttributeValue norm = ucol_getAttribute(myCollation, UCOL_NORMALIZATION_MODE, &status); 280 281 UCharIterator sIter, tIter; 282 uiter_setString(&sIter, source, sLen); 283 uiter_setString(&tIter, target, tLen); 284 compareResultIter = ucol_strcollIter(myCollation, &sIter, &tIter, &status); 285 if(compareResultIter != result) { 286 log_err("different results in iterative comparison for UTF-16 encoded strings. %s, %s\n", aescstrdup(source,-1), aescstrdup(target,-1)); 287 } 288 289 /* convert the strings to UTF-8 and do try comparing with char iterator */ 290 if(QUICK <= 0) { /*!QUICK*/ 291 char utf8Source[256], utf8Target[256]; 292 int32_t utf8SourceLen = 0, utf8TargetLen = 0; 293 u_strToUTF8(utf8Source, 256, &utf8SourceLen, source, sLen, &status); 294 if(U_FAILURE(status)) { /* probably buffer is not big enough */ 295 log_verbose("Src UTF-8 buffer too small! Will not compare!\n"); 296 } else { 297 u_strToUTF8(utf8Target, 256, &utf8TargetLen, target, tLen, &status); 298 if(U_SUCCESS(status)) { /* probably buffer is not big enough */ 299 UCollationResult compareResultUTF8 = result, compareResultUTF8Norm = result; 300 /*UCharIterator sIter, tIter;*/ 301 /*log_verbose("Strings converted to UTF-8:%s, %s\n", aescstrdup(source,-1), aescstrdup(target,-1));*/ 302 uiter_setUTF8(&sIter, utf8Source, utf8SourceLen); 303 uiter_setUTF8(&tIter, utf8Target, utf8TargetLen); 304 /*uiter_setString(&sIter, source, sLen); 305 uiter_setString(&tIter, target, tLen);*/ 306 compareResultUTF8 = ucol_strcollIter(myCollation, &sIter, &tIter, &status); 307 ucol_setAttribute(myCollation, UCOL_NORMALIZATION_MODE, UCOL_ON, &status); 308 sIter.move(&sIter, 0, UITER_START); 309 tIter.move(&tIter, 0, UITER_START); 310 compareResultUTF8Norm = ucol_strcollIter(myCollation, &sIter, &tIter, &status); 311 ucol_setAttribute(myCollation, UCOL_NORMALIZATION_MODE, norm, &status); 312 if(compareResultUTF8 != compareResultIter) { 313 log_err("different results in iterative comparison for UTF-16 and UTF-8 encoded strings. %s, %s\n", aescstrdup(source,-1), aescstrdup(target,-1)); 314 } 315 if(compareResultUTF8 != compareResultUTF8Norm) { 316 log_err("different results in iterative when normalization is turned on with UTF-8 strings. %s, %s\n", aescstrdup(source,-1), aescstrdup(target,-1)); 317 } 318 } else { 319 log_verbose("Target UTF-8 buffer too small! Did not compare!\n"); 320 } 321 if(U_FAILURE(status)) { 322 log_verbose("UTF-8 strcoll failed! Ignoring result\n"); 323 } 324 } 325 } 326 327 /* testing the partial sortkeys */ 328 if(1) { /*!QUICK*/ 329 int32_t i = 0; 330 int32_t partialSizes[] = { 3, 1, 2, 4, 8, 20, 80 }; /* just size 3 in the quick mode */ 331 int32_t partialSizesSize = 1; 332 if(QUICK <= 0) { 333 partialSizesSize = 7; 334 } 335 /*log_verbose("partial sortkey test piecesize=");*/ 336 for(i = 0; i < partialSizesSize; i++) { 337 UCollationResult partialSKResult = result, partialNormalizedSKResult = result; 338 /*log_verbose("%i ", partialSizes[i]);*/ 339 340 partialSKResult = compareUsingPartials(myCollation, source, sLen, target, tLen, partialSizes[i], &status); 341 if(partialSKResult != result) { 342 log_err("Partial sortkey comparison returned wrong result (%i exp. %i): %s, %s (size %i)\n", 343 partialSKResult, result, 344 aescstrdup(source,-1), aescstrdup(target,-1), partialSizes[i]); 345 } 346 347 if(QUICK <= 0 && norm != UCOL_ON) { 348 /*log_verbose("N ");*/ 349 ucol_setAttribute(myCollation, UCOL_NORMALIZATION_MODE, UCOL_ON, &status); 350 partialNormalizedSKResult = compareUsingPartials(myCollation, source, sLen, target, tLen, partialSizes[i], &status); 351 ucol_setAttribute(myCollation, UCOL_NORMALIZATION_MODE, norm, &status); 352 if(partialSKResult != partialNormalizedSKResult) { 353 log_err("Partial sortkey comparison gets different result when normalization is on: %s, %s (size %i)\n", 354 aescstrdup(source,-1), aescstrdup(target,-1), partialSizes[i]); 355 } 356 } 357 } 358 /*log_verbose("\n");*/ 359 } 360 361 362 compareResult = ucol_strcoll(myCollation, source, sLen, target, tLen); 363 compareResulta = ucol_strcoll(myCollation, source, -1, target, -1); 364 if (compareResult != compareResulta) { 365 log_err("ucol_strcoll result from null terminated and explicit length strings differs.\n"); 366 } 367 368 sortklen1=ucol_getSortKey(myCollation, source, sLen, NULL, 0); 369 sortklen2=ucol_getSortKey(myCollation, target, tLen, NULL, 0); 370 371 sortklenmax = (sortklen1>sortklen2?sortklen1:sortklen2); 372 sortklenmin = (sortklen1<sortklen2?sortklen1:sortklen2); 373 374 sortKey1 =(uint8_t*)malloc(sizeof(uint8_t) * (sortklenmax+1)); 375 sortKey1a=(uint8_t*)malloc(sizeof(uint8_t) * (sortklenmax+1)); 376 ucol_getSortKey(myCollation, source, sLen, sortKey1, sortklen1+1); 377 ucol_getSortKey(myCollation, source, -1, sortKey1a, sortklen1+1); 378 379 sortKey2 =(uint8_t*)malloc(sizeof(uint8_t) * (sortklenmax+1)); 380 sortKey2a=(uint8_t*)malloc(sizeof(uint8_t) * (sortklenmax+1)); 381 ucol_getSortKey(myCollation, target, tLen, sortKey2, sortklen2+1); 382 ucol_getSortKey(myCollation, target, -1, sortKey2a, sortklen2+1); 383 384 /* Check that sort key generated with null terminated string is identical */ 385 /* to that generted with a length specified. */ 386 if (uprv_strcmp((const char *)sortKey1, (const char *)sortKey1a) != 0 || 387 uprv_strcmp((const char *)sortKey2, (const char *)sortKey2a) != 0 ) { 388 log_err("Sort Keys from null terminated and explicit length strings differ.\n"); 389 } 390 391 /*memcmp(sortKey1, sortKey2,sortklenmax);*/ 392 temp= uprv_strcmp((const char *)sortKey1, (const char *)sortKey2); 393 gSortklen1 = uprv_strlen((const char *)sortKey1)+1; 394 gSortklen2 = uprv_strlen((const char *)sortKey2)+1; 395 if(sortklen1 != gSortklen1){ 396 log_err("SortKey length does not match Expected: %i Got: %i\n",sortklen1, gSortklen1); 397 log_verbose("Generated sortkey: %s\n", sortKeyToString(myCollation, sortKey1, buffer, &len)); 398 } 399 if(sortklen2!= gSortklen2){ 400 log_err("SortKey length does not match Expected: %i Got: %i\n", sortklen2, gSortklen2); 401 log_verbose("Generated sortkey: %s\n", sortKeyToString(myCollation, sortKey2, buffer, &len)); 402 } 403 404 if(temp < 0) { 405 keyResult=UCOL_LESS; 406 } 407 else if(temp > 0) { 408 keyResult= UCOL_GREATER; 409 } 410 else { 411 keyResult = UCOL_EQUAL; 412 } 413 reportCResult( source, target, sortKey1, sortKey2, compareResult, keyResult, compareResultIter, result ); 414 free(sortKey1); 415 free(sortKey2); 416 free(sortKey1a); 417 free(sortKey2a); 418 419 } 420 421 void doTest(UCollator* myCollation, const UChar source[], const UChar target[], UCollationResult result) 422 { 423 if(myCollation) { 424 doTestVariant(myCollation, source, target, result); 425 if(result == UCOL_LESS) { 426 doTestVariant(myCollation, target, source, UCOL_GREATER); 427 } else if(result == UCOL_GREATER) { 428 doTestVariant(myCollation, target, source, UCOL_LESS); 429 } else { 430 doTestVariant(myCollation, target, source, UCOL_EQUAL); 431 } 432 } else { 433 log_data_err("No collator! Any data around?\n"); 434 } 435 } 436 437 438 /** 439 * Return an integer array containing all of the collation orders 440 * returned by calls to next on the specified iterator 441 */ 442 OrderAndOffset* getOrders(UCollationElements *iter, int32_t *orderLength) 443 { 444 UErrorCode status; 445 int32_t order; 446 int32_t maxSize = 100; 447 int32_t size = 0; 448 int32_t offset = ucol_getOffset(iter); 449 OrderAndOffset *temp; 450 OrderAndOffset *orders =(OrderAndOffset *)malloc(sizeof(OrderAndOffset) * maxSize); 451 status= U_ZERO_ERROR; 452 453 454 while ((order=ucol_next(iter, &status)) != UCOL_NULLORDER) 455 { 456 if (size == maxSize) 457 { 458 maxSize *= 2; 459 temp = (OrderAndOffset *)malloc(sizeof(OrderAndOffset) * maxSize); 460 461 memcpy(temp, orders, size * sizeof(OrderAndOffset)); 462 free(orders); 463 orders = temp; 464 465 } 466 467 orders[size].order = order; 468 orders[size].offset = offset; 469 470 offset = ucol_getOffset(iter); 471 size += 1; 472 } 473 474 if (maxSize > size && size > 0) 475 { 476 temp = (OrderAndOffset *)malloc(sizeof(OrderAndOffset) * size); 477 478 memcpy(temp, orders, size * sizeof(OrderAndOffset)); 479 free(orders); 480 orders = temp; 481 482 483 } 484 485 *orderLength = size; 486 return orders; 487 } 488 489 490 void 491 backAndForth(UCollationElements *iter) 492 { 493 /* Run through the iterator forwards and stick it into an array */ 494 int32_t index, o; 495 UErrorCode status = U_ZERO_ERROR; 496 int32_t orderLength = 0; 497 OrderAndOffset *orders = getOrders(iter, &orderLength); 498 499 500 /* Now go through it backwards and make sure we get the same values */ 501 index = orderLength; 502 ucol_reset(iter); 503 504 /* synwee : changed */ 505 while ((o = ucol_previous(iter, &status)) != UCOL_NULLORDER) { 506 int32_t offset = ucol_getOffset(iter); 507 508 index -= 1; 509 if (o != orders[index].order) { 510 if (o == 0) 511 index ++; 512 else { 513 while (index > 0 && orders[-- index].order == 0) { 514 /* nothing... */ 515 } 516 517 if (o != orders[index].order) { 518 log_err("Mismatched order at index %d: 0x%8.8X vs. 0x%8.8X\n", index, 519 orders[index].order, o); 520 goto bail; 521 } 522 } 523 } 524 525 #if TEST_OFFSETS 526 if (offset != orders[index].offset) { 527 log_err("Mismatched offset at index %d: %d vs. %d\n", index, 528 orders[index].offset, offset); 529 goto bail; 530 } 531 #endif 532 533 } 534 535 while (index != 0 && orders[index - 1].order == 0) { 536 index -= 1; 537 } 538 539 if (index != 0) { 540 log_err("Didn't get back to beginning - index is %d\n", index); 541 542 ucol_reset(iter); 543 log_err("\nnext: "); 544 545 if ((o = ucol_next(iter, &status)) != UCOL_NULLORDER) { 546 log_err("Error at %x\n", o); 547 } 548 549 log_err("\nprev: "); 550 551 if ((o = ucol_previous(iter, &status)) != UCOL_NULLORDER) { 552 log_err("Error at %x\n", o); 553 } 554 555 log_verbose("\n"); 556 } 557 558 bail: 559 free(orders); 560 } 561 562 void genericOrderingTestWithResult(UCollator *coll, const char * const s[], uint32_t size, UCollationResult result) { 563 UChar t1[2048] = {0}; 564 UChar t2[2048] = {0}; 565 UCollationElements *iter; 566 UErrorCode status = U_ZERO_ERROR; 567 568 uint32_t i = 0, j = 0; 569 log_verbose("testing sequence:\n"); 570 for(i = 0; i < size; i++) { 571 log_verbose("%s\n", s[i]); 572 } 573 574 iter = ucol_openElements(coll, t1, u_strlen(t1), &status); 575 if (U_FAILURE(status)) { 576 log_err("Creation of iterator failed\n"); 577 } 578 for(i = 0; i < size-1; i++) { 579 for(j = i+1; j < size; j++) { 580 u_unescape(s[i], t1, 2048); 581 u_unescape(s[j], t2, 2048); 582 doTest(coll, t1, t2, result); 583 /* synwee : added collation element iterator test */ 584 ucol_setText(iter, t1, u_strlen(t1), &status); 585 backAndForth(iter); 586 ucol_setText(iter, t2, u_strlen(t2), &status); 587 backAndForth(iter); 588 } 589 } 590 ucol_closeElements(iter); 591 } 592 593 void genericOrderingTest(UCollator *coll, const char * const s[], uint32_t size) { 594 genericOrderingTestWithResult(coll, s, size, UCOL_LESS); 595 } 596 597 void genericLocaleStarter(const char *locale, const char * const s[], uint32_t size) { 598 UErrorCode status = U_ZERO_ERROR; 599 UCollator *coll = ucol_open(locale, &status); 600 601 log_verbose("Locale starter for %s\n", locale); 602 603 if(U_SUCCESS(status)) { 604 genericOrderingTest(coll, s, size); 605 } else if(status == U_FILE_ACCESS_ERROR) { 606 log_data_err("Is your data around?\n"); 607 return; 608 } else { 609 log_err("Unable to open collator for locale %s\n", locale); 610 } 611 ucol_close(coll); 612 } 613 614 void genericLocaleStarterWithResult(const char *locale, const char * const s[], uint32_t size, UCollationResult result) { 615 UErrorCode status = U_ZERO_ERROR; 616 UCollator *coll = ucol_open(locale, &status); 617 618 log_verbose("Locale starter for %s\n", locale); 619 620 if(U_SUCCESS(status)) { 621 genericOrderingTestWithResult(coll, s, size, result); 622 } else if(status == U_FILE_ACCESS_ERROR) { 623 log_data_err("Is your data around?\n"); 624 return; 625 } else { 626 log_err("Unable to open collator for locale %s\n", locale); 627 } 628 ucol_close(coll); 629 } 630 631 /* currently not used with options */ 632 void genericRulesStarterWithOptionsAndResult(const char *rules, const char * const s[], uint32_t size, const UColAttribute *attrs, const UColAttributeValue *values, uint32_t attsize, UCollationResult result) { 633 UErrorCode status = U_ZERO_ERROR; 634 UChar rlz[RULE_BUFFER_LEN] = { 0 }; 635 uint32_t rlen = u_unescape(rules, rlz, RULE_BUFFER_LEN); 636 uint32_t i; 637 638 UCollator *coll = ucol_openRules(rlz, rlen, UCOL_DEFAULT, UCOL_DEFAULT,NULL, &status); 639 640 log_verbose("Rules starter for %s\n", rules); 641 642 if(U_SUCCESS(status)) { 643 log_verbose("Setting attributes\n"); 644 for(i = 0; i < attsize; i++) { 645 ucol_setAttribute(coll, attrs[i], values[i], &status); 646 } 647 648 genericOrderingTestWithResult(coll, s, size, result); 649 } else { 650 log_err_status(status, "Unable to open collator with rules %s\n", rules); 651 } 652 ucol_close(coll); 653 } 654 655 void genericLocaleStarterWithOptionsAndResult(const char *locale, const char * const s[], uint32_t size, const UColAttribute *attrs, const UColAttributeValue *values, uint32_t attsize, UCollationResult result) { 656 UErrorCode status = U_ZERO_ERROR; 657 uint32_t i; 658 659 UCollator *coll = ucol_open(locale, &status); 660 661 log_verbose("Locale starter for %s\n", locale); 662 663 if(U_SUCCESS(status)) { 664 665 log_verbose("Setting attributes\n"); 666 for(i = 0; i < attsize; i++) { 667 ucol_setAttribute(coll, attrs[i], values[i], &status); 668 } 669 670 genericOrderingTestWithResult(coll, s, size, result); 671 } else { 672 log_err_status(status, "Unable to open collator for locale %s\n", locale); 673 } 674 ucol_close(coll); 675 } 676 677 void genericLocaleStarterWithOptions(const char *locale, const char * const s[], uint32_t size, const UColAttribute *attrs, const UColAttributeValue *values, uint32_t attsize) { 678 genericLocaleStarterWithOptionsAndResult(locale, s, size, attrs, values, attsize, UCOL_LESS); 679 } 680 681 void genericRulesStarterWithResult(const char *rules, const char * const s[], uint32_t size, UCollationResult result) { 682 UErrorCode status = U_ZERO_ERROR; 683 UChar rlz[RULE_BUFFER_LEN] = { 0 }; 684 uint32_t rlen = u_unescape(rules, rlz, RULE_BUFFER_LEN); 685 686 UCollator *coll = NULL; 687 coll = ucol_openRules(rlz, rlen, UCOL_DEFAULT, UCOL_DEFAULT,NULL, &status); 688 log_verbose("Rules starter for %s\n", rules); 689 690 if(U_SUCCESS(status)) { 691 genericOrderingTestWithResult(coll, s, size, result); 692 ucol_close(coll); 693 } else if(status == U_FILE_ACCESS_ERROR) { 694 log_data_err("Is your data around?\n"); 695 } else { 696 log_err("Unable to open collator with rules %s\n", rules); 697 } 698 } 699 700 void genericRulesStarter(const char *rules, const char * const s[], uint32_t size) { 701 genericRulesStarterWithResult(rules, s, size, UCOL_LESS); 702 } 703 704 static void TestTertiary() 705 { 706 int32_t len,i; 707 UCollator *myCollation; 708 UErrorCode status=U_ZERO_ERROR; 709 static const char str[]="& C < ch, cH, Ch, CH & Five, 5 & Four, 4 & one, 1 & Ampersand; '&' & Two, 2 "; 710 UChar rules[sizeof(str)]; 711 len = strlen(str); 712 u_uastrcpy(rules, str); 713 714 myCollation=ucol_openRules(rules, len, UCOL_OFF, UCOL_DEFAULT_STRENGTH, NULL, &status); 715 if(U_FAILURE(status)){ 716 log_err_status(status, "ERROR: in creation of rule based collator :%s\n", myErrorName(status)); 717 return; 718 } 719 720 ucol_setStrength(myCollation, UCOL_TERTIARY); 721 for (i = 0; i < 17 ; i++) 722 { 723 doTest(myCollation, testSourceCases[i], testTargetCases[i], results[i]); 724 } 725 ucol_close(myCollation); 726 myCollation = 0; 727 } 728 729 static void TestPrimary( ) 730 { 731 int32_t len,i; 732 UCollator *myCollation; 733 UErrorCode status=U_ZERO_ERROR; 734 static const char str[]="& C < ch, cH, Ch, CH & Five, 5 & Four, 4 & one, 1 & Ampersand; '&' & Two, 2 "; 735 UChar rules[sizeof(str)]; 736 len = strlen(str); 737 u_uastrcpy(rules, str); 738 739 myCollation=ucol_openRules(rules, len, UCOL_OFF, UCOL_DEFAULT_STRENGTH,NULL, &status); 740 if(U_FAILURE(status)){ 741 log_err_status(status, "ERROR: in creation of rule based collator :%s\n", myErrorName(status)); 742 return; 743 } 744 ucol_setStrength(myCollation, UCOL_PRIMARY); 745 746 for (i = 17; i < 26 ; i++) 747 { 748 749 doTest(myCollation, testSourceCases[i], testTargetCases[i], results[i]); 750 } 751 ucol_close(myCollation); 752 myCollation = 0; 753 } 754 755 static void TestSecondary() 756 { 757 int32_t i; 758 int32_t len; 759 UCollator *myCollation; 760 UErrorCode status=U_ZERO_ERROR; 761 static const char str[]="& C < ch, cH, Ch, CH & Five, 5 & Four, 4 & one, 1 & Ampersand; '&' & Two, 2 "; 762 UChar rules[sizeof(str)]; 763 len = strlen(str); 764 u_uastrcpy(rules, str); 765 766 myCollation=ucol_openRules(rules, len, UCOL_OFF, UCOL_DEFAULT_STRENGTH,NULL, &status); 767 if(U_FAILURE(status)){ 768 log_err_status(status, "ERROR: in creation of rule based collator :%s\n", myErrorName(status)); 769 return; 770 } 771 ucol_setStrength(myCollation, UCOL_SECONDARY); 772 for (i = 26; i < 34 ; i++) 773 { 774 doTest(myCollation, testSourceCases[i], testTargetCases[i], results[i]); 775 } 776 ucol_close(myCollation); 777 myCollation = 0; 778 } 779 780 static void TestIdentical() 781 { 782 int32_t i; 783 int32_t len; 784 UCollator *myCollation; 785 UErrorCode status=U_ZERO_ERROR; 786 static const char str[]="& C < ch, cH, Ch, CH & Five, 5 & Four, 4 & one, 1 & Ampersand; '&' & Two, 2 "; 787 UChar rules[sizeof(str)]; 788 len = strlen(str); 789 u_uastrcpy(rules, str); 790 791 myCollation=ucol_openRules(rules, len, UCOL_OFF, UCOL_IDENTICAL, NULL,&status); 792 if(U_FAILURE(status)){ 793 log_err_status(status, "ERROR: in creation of rule based collator :%s\n", myErrorName(status)); 794 return; 795 } 796 for(i= 34; i<37; i++) 797 { 798 doTest(myCollation, testSourceCases[i], testTargetCases[i], results[i]); 799 } 800 ucol_close(myCollation); 801 myCollation = 0; 802 } 803 804 static void TestExtra() 805 { 806 int32_t i, j; 807 int32_t len; 808 UCollator *myCollation; 809 UErrorCode status = U_ZERO_ERROR; 810 static const char str[]="& C < ch, cH, Ch, CH & Five, 5 & Four, 4 & one, 1 & Ampersand; '&' & Two, 2 "; 811 UChar rules[sizeof(str)]; 812 len = strlen(str); 813 u_uastrcpy(rules, str); 814 815 myCollation=ucol_openRules(rules, len, UCOL_OFF, UCOL_DEFAULT_STRENGTH,NULL, &status); 816 if(U_FAILURE(status)){ 817 log_err_status(status, "ERROR: in creation of rule based collator :%s\n", myErrorName(status)); 818 return; 819 } 820 ucol_setStrength(myCollation, UCOL_TERTIARY); 821 for (i = 0; i < COUNT_TEST_CASES-1 ; i++) 822 { 823 for (j = i + 1; j < COUNT_TEST_CASES; j += 1) 824 { 825 826 doTest(myCollation, testCases[i], testCases[j], UCOL_LESS); 827 } 828 } 829 ucol_close(myCollation); 830 myCollation = 0; 831 } 832 833 static void TestJB581(void) 834 { 835 int32_t bufferLen = 0; 836 UChar source [100]; 837 UChar target [100]; 838 UCollationResult result = UCOL_EQUAL; 839 uint8_t sourceKeyArray [100]; 840 uint8_t targetKeyArray [100]; 841 int32_t sourceKeyOut = 0, 842 targetKeyOut = 0; 843 UCollator *myCollator = 0; 844 UErrorCode status = U_ZERO_ERROR; 845 846 /*u_uastrcpy(source, "This is a test.");*/ 847 /*u_uastrcpy(target, "THISISATEST.");*/ 848 u_uastrcpy(source, "THISISATEST."); 849 u_uastrcpy(target, "Thisisatest."); 850 851 myCollator = ucol_open("en_US", &status); 852 if (U_FAILURE(status)){ 853 log_err_status(status, "ERROR: Failed to create the collator : %s\n", u_errorName(status)); 854 return; 855 } 856 result = ucol_strcoll(myCollator, source, -1, target, -1); 857 /* result is 1, secondary differences only for ignorable space characters*/ 858 if (result != 1) 859 { 860 log_err("Comparing two strings with only secondary differences in C failed.\n"); 861 } 862 /* To compare them with just primary differences */ 863 ucol_setStrength(myCollator, UCOL_PRIMARY); 864 result = ucol_strcoll(myCollator, source, -1, target, -1); 865 /* result is 0 */ 866 if (result != 0) 867 { 868 log_err("Comparing two strings with no differences in C failed.\n"); 869 } 870 /* Now, do the same comparison with keys */ 871 sourceKeyOut = ucol_getSortKey(myCollator, source, -1, sourceKeyArray, 100); 872 targetKeyOut = ucol_getSortKey(myCollator, target, -1, targetKeyArray, 100); 873 bufferLen = ((targetKeyOut > 100) ? 100 : targetKeyOut); 874 if (memcmp(sourceKeyArray, targetKeyArray, bufferLen) != 0) 875 { 876 log_err("Comparing two strings with sort keys in C failed.\n"); 877 } 878 ucol_close(myCollator); 879 } 880 881 static void TestJB1401(void) 882 { 883 UCollator *myCollator = 0; 884 UErrorCode status = U_ZERO_ERROR; 885 static UChar NFD_UnsafeStartChars[] = { 886 0x0f73, /* Tibetan Vowel Sign II */ 887 0x0f75, /* Tibetan Vowel Sign UU */ 888 0x0f81, /* Tibetan Vowel Sign Reversed II */ 889 0 890 }; 891 int i; 892 893 894 myCollator = ucol_open("en_US", &status); 895 if (U_FAILURE(status)){ 896 log_err_status(status, "ERROR: Failed to create the collator : %s\n", u_errorName(status)); 897 return; 898 } 899 ucol_setAttribute(myCollator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status); 900 if (U_FAILURE(status)){ 901 log_err("ERROR: Failed to set normalization mode ON for collator.\n"); 902 return; 903 } 904 905 for (i=0; ; i++) { 906 UChar c; 907 UChar X[4]; 908 UChar Y[20]; 909 UChar Z[20]; 910 911 /* Get the next funny character to be tested, and set up the 912 * three test strings X, Y, Z, consisting of an A-grave + test char, 913 * in original form, NFD, and then NFC form. 914 */ 915 c = NFD_UnsafeStartChars[i]; 916 if (c==0) {break;} 917 918 X[0]=0xC0; X[1]=c; X[2]=0; /* \u00C0 is A Grave*/ 919 920 unorm_normalize(X, -1, UNORM_NFD, 0, Y, 20, &status); 921 unorm_normalize(Y, -1, UNORM_NFC, 0, Z, 20, &status); 922 if (U_FAILURE(status)){ 923 log_err("ERROR: Failed to normalize test of character %x\n", c); 924 return; 925 } 926 927 /* Collation test. All three strings should be equal. 928 * doTest does both strcoll and sort keys, with params in both orders. 929 */ 930 doTest(myCollator, X, Y, UCOL_EQUAL); 931 doTest(myCollator, X, Z, UCOL_EQUAL); 932 doTest(myCollator, Y, Z, UCOL_EQUAL); 933 934 /* Run collation element iterators over the three strings. Results should be same for each. 935 */ 936 { 937 UCollationElements *ceiX, *ceiY, *ceiZ; 938 int32_t ceX, ceY, ceZ; 939 int j; 940 941 ceiX = ucol_openElements(myCollator, X, -1, &status); 942 ceiY = ucol_openElements(myCollator, Y, -1, &status); 943 ceiZ = ucol_openElements(myCollator, Z, -1, &status); 944 if (U_FAILURE(status)) { 945 log_err("ERROR: uucol_openElements failed.\n"); 946 return; 947 } 948 949 for (j=0;; j++) { 950 ceX = ucol_next(ceiX, &status); 951 ceY = ucol_next(ceiY, &status); 952 ceZ = ucol_next(ceiZ, &status); 953 if (U_FAILURE(status)) { 954 log_err("ERROR: ucol_next failed for iteration #%d.\n", j); 955 break; 956 } 957 if (ceX != ceY || ceY != ceZ) { 958 log_err("ERROR: ucol_next failed for iteration #%d.\n", j); 959 break; 960 } 961 if (ceX == UCOL_NULLORDER) { 962 break; 963 } 964 } 965 ucol_closeElements(ceiX); 966 ucol_closeElements(ceiY); 967 ucol_closeElements(ceiZ); 968 } 969 } 970 ucol_close(myCollator); 971 } 972 973 974 975 /** 976 * Tests the [variable top] tag in rule syntax. Since the default [alternate] 977 * tag has the value shifted, any codepoints before [variable top] should give 978 * a primary ce of 0. 979 */ 980 static void TestVariableTop(void) 981 { 982 static const char str[] = "&z = [variable top]"; 983 int len = strlen(str); 984 UChar rules[sizeof(str)]; 985 UCollator *myCollation; 986 UCollator *enCollation; 987 UErrorCode status = U_ZERO_ERROR; 988 UChar source[1]; 989 UChar ch; 990 uint8_t result[20]; 991 uint8_t expected[20]; 992 993 u_uastrcpy(rules, str); 994 995 enCollation = ucol_open("en_US", &status); 996 if (U_FAILURE(status)) { 997 log_err_status(status, "ERROR: in creation of collator :%s\n", 998 myErrorName(status)); 999 return; 1000 } 1001 myCollation = ucol_openRules(rules, len, UCOL_OFF, 1002 UCOL_PRIMARY,NULL, &status); 1003 if (U_FAILURE(status)) { 1004 ucol_close(enCollation); 1005 log_err("ERROR: in creation of rule based collator :%s\n", 1006 myErrorName(status)); 1007 return; 1008 } 1009 1010 ucol_setStrength(enCollation, UCOL_PRIMARY); 1011 ucol_setAttribute(enCollation, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, 1012 &status); 1013 ucol_setAttribute(myCollation, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, 1014 &status); 1015 1016 if (ucol_getAttribute(myCollation, UCOL_ALTERNATE_HANDLING, &status) != 1017 UCOL_SHIFTED || U_FAILURE(status)) { 1018 log_err("ERROR: ALTERNATE_HANDLING value can not be set to SHIFTED\n"); 1019 } 1020 1021 uprv_memset(expected, 0, 20); 1022 1023 /* space is supposed to be a variable */ 1024 source[0] = ' '; 1025 len = ucol_getSortKey(enCollation, source, 1, result, 1026 sizeof(result)); 1027 1028 if (uprv_memcmp(expected, result, len) != 0) { 1029 log_err("ERROR: SHIFTED alternate does not return 0 for primary of space\n"); 1030 } 1031 1032 ch = 'a'; 1033 while (ch < 'z') { 1034 source[0] = ch; 1035 len = ucol_getSortKey(myCollation, source, 1, result, 1036 sizeof(result)); 1037 if (uprv_memcmp(expected, result, len) != 0) { 1038 log_err("ERROR: SHIFTED alternate does not return 0 for primary of %c\n", 1039 ch); 1040 } 1041 ch ++; 1042 } 1043 1044 ucol_close(enCollation); 1045 ucol_close(myCollation); 1046 enCollation = NULL; 1047 myCollation = NULL; 1048 } 1049 1050 /** 1051 * Tests surrogate support. 1052 * NOTE: This test used \\uD801\\uDC01 pair, which is now assigned to Desseret 1053 * Therefore, another (unassigned) code point was used for this test. 1054 */ 1055 static void TestSurrogates(void) 1056 { 1057 static const char str[] = 1058 "&z<'\\uD800\\uDC00'<'\\uD800\\uDC0A\\u0308'<A"; 1059 int len = strlen(str); 1060 int rlen = 0; 1061 UChar rules[sizeof(str)]; 1062 UCollator *myCollation; 1063 UCollator *enCollation; 1064 UErrorCode status = U_ZERO_ERROR; 1065 UChar source[][4] = 1066 {{'z', 0, 0}, {0xD800, 0xDC00, 0}, {0xD800, 0xDC0A, 0x0308, 0}, {0xD800, 0xDC02}}; 1067 UChar target[][4] = 1068 {{0xD800, 0xDC00, 0}, {0xD800, 0xDC0A, 0x0308, 0}, {'A', 0, 0}, {0xD800, 0xDC03}}; 1069 int count = 0; 1070 uint8_t enresult[20], myresult[20]; 1071 int enlen, mylen; 1072 1073 /* tests for open rules with surrogate rules */ 1074 rlen = u_unescape(str, rules, len); 1075 1076 enCollation = ucol_open("en_US", &status); 1077 if (U_FAILURE(status)) { 1078 log_err_status(status, "ERROR: in creation of collator :%s\n", 1079 myErrorName(status)); 1080 return; 1081 } 1082 myCollation = ucol_openRules(rules, rlen, UCOL_OFF, 1083 UCOL_TERTIARY,NULL, &status); 1084 if (U_FAILURE(status)) { 1085 ucol_close(enCollation); 1086 log_err("ERROR: in creation of rule based collator :%s\n", 1087 myErrorName(status)); 1088 return; 1089 } 1090 1091 /* 1092 this test is to verify the supplementary sort key order in the english 1093 collator 1094 */ 1095 log_verbose("start of english collation supplementary characters test\n"); 1096 while (count < 2) { 1097 doTest(enCollation, source[count], target[count], UCOL_LESS); 1098 count ++; 1099 } 1100 doTest(enCollation, source[count], target[count], UCOL_GREATER); 1101 1102 log_verbose("start of tailored collation supplementary characters test\n"); 1103 count = 0; 1104 /* tests getting collation elements for surrogates for tailored rules */ 1105 while (count < 4) { 1106 doTest(myCollation, source[count], target[count], UCOL_LESS); 1107 count ++; 1108 } 1109 1110 /* tests that \uD800\uDC02 still has the same value, not changed */ 1111 enlen = ucol_getSortKey(enCollation, source[3], 2, enresult, 20); 1112 mylen = ucol_getSortKey(myCollation, source[3], 2, myresult, 20); 1113 if (enlen != mylen || 1114 uprv_memcmp(enresult, myresult, enlen) != 0) { 1115 log_verbose("Failed : non-tailored supplementary characters should have the same value\n"); 1116 } 1117 1118 ucol_close(enCollation); 1119 ucol_close(myCollation); 1120 enCollation = NULL; 1121 myCollation = NULL; 1122 } 1123 1124 /* 1125 *### TODO: Add more invalid rules to test all different scenarios. 1126 * 1127 */ 1128 static void 1129 TestInvalidRules(){ 1130 #define MAX_ERROR_STATES 2 1131 1132 static const char* rulesArr[MAX_ERROR_STATES] = { 1133 "& C < ch, cH, Ch[this should fail]<d", 1134 "& C < ch, cH, & Ch[variable top]" 1135 }; 1136 static const char* preContextArr[MAX_ERROR_STATES] = { 1137 "his should fail", 1138 "& C < ch, cH, ", 1139 1140 }; 1141 static const char* postContextArr[MAX_ERROR_STATES] = { 1142 "<d", 1143 " Ch[variable t" 1144 }; 1145 int i; 1146 1147 for(i = 0;i<MAX_ERROR_STATES;i++){ 1148 UChar rules[1000] = { '\0' }; 1149 UChar preContextExp[1000] = { '\0' }; 1150 UChar postContextExp[1000] = { '\0' }; 1151 UParseError parseError; 1152 UErrorCode status = U_ZERO_ERROR; 1153 UCollator* coll=0; 1154 u_charsToUChars(rulesArr[i],rules,uprv_strlen(rulesArr[i])+1); 1155 u_charsToUChars(preContextArr[i],preContextExp,uprv_strlen(preContextArr[i])+1); 1156 u_charsToUChars(postContextArr[i],postContextExp,uprv_strlen(postContextArr[i])+1); 1157 /* clean up stuff in parseError */ 1158 u_memset(parseError.preContext,0x0000,U_PARSE_CONTEXT_LEN); 1159 u_memset(parseError.postContext,0x0000,U_PARSE_CONTEXT_LEN); 1160 /* open the rules and test */ 1161 coll = ucol_openRules(rules,u_strlen(rules),UCOL_OFF,UCOL_DEFAULT_STRENGTH,&parseError,&status); 1162 if(u_strcmp(parseError.preContext,preContextExp)!=0){ 1163 log_err_status(status, "preContext in UParseError for ucol_openRules does not match\n"); 1164 } 1165 if(u_strcmp(parseError.postContext,postContextExp)!=0){ 1166 log_err_status(status, "postContext in UParseError for ucol_openRules does not match\n"); 1167 } 1168 } 1169 } 1170 1171 static void 1172 TestJitterbug1098(){ 1173 UChar rule[1000]; 1174 UCollator* c1 = NULL; 1175 UErrorCode status = U_ZERO_ERROR; 1176 UParseError parseError; 1177 char preContext[200]={0}; 1178 char postContext[200]={0}; 1179 int i=0; 1180 const char* rules[] = { 1181 "&''<\\\\", 1182 "&\\'<\\\\", 1183 "&\\\"<'\\'", 1184 "&'\"'<\\'", 1185 '\0' 1186 1187 }; 1188 const UCollationResult results1098[] = { 1189 UCOL_LESS, 1190 UCOL_LESS, 1191 UCOL_LESS, 1192 UCOL_LESS, 1193 }; 1194 const UChar input[][2]= { 1195 {0x0027,0x005c}, 1196 {0x0027,0x005c}, 1197 {0x0022,0x005c}, 1198 {0x0022,0x0027}, 1199 }; 1200 UChar X[2] ={0}; 1201 UChar Y[2] ={0}; 1202 u_memset(parseError.preContext,0x0000,U_PARSE_CONTEXT_LEN); 1203 u_memset(parseError.postContext,0x0000,U_PARSE_CONTEXT_LEN); 1204 for(;rules[i]!=0;i++){ 1205 u_uastrcpy(rule, rules[i]); 1206 c1 = ucol_openRules(rule, u_strlen(rule), UCOL_OFF, UCOL_DEFAULT_STRENGTH, &parseError, &status); 1207 if(U_FAILURE(status)){ 1208 log_err_status(status, "Could not parse the rules syntax. Error: %s\n", u_errorName(status)); 1209 1210 if (status == U_PARSE_ERROR) { 1211 u_UCharsToChars(parseError.preContext,preContext,20); 1212 u_UCharsToChars(parseError.postContext,postContext,20); 1213 log_verbose("\n\tPre-Context: %s \n\tPost-Context:%s \n",preContext,postContext); 1214 } 1215 1216 return; 1217 } 1218 X[0] = input[i][0]; 1219 Y[0] = input[i][1]; 1220 doTest(c1,X,Y,results1098[i]); 1221 ucol_close(c1); 1222 } 1223 } 1224 1225 static void 1226 TestFCDCrash(void) { 1227 static const char *test[] = { 1228 "Gr\\u00F6\\u00DFe", 1229 "Grossist" 1230 }; 1231 1232 UErrorCode status = U_ZERO_ERROR; 1233 UCollator *coll = ucol_open("es", &status); 1234 if(U_FAILURE(status)) { 1235 log_err_status(status, "Couldn't open collator -> %s\n", u_errorName(status)); 1236 return; 1237 } 1238 ucol_close(coll); 1239 coll = NULL; 1240 ctest_resetICU(); 1241 coll = ucol_open("de_DE", &status); 1242 if(U_FAILURE(status)) { 1243 log_err_status(status, "Couldn't open collator -> %s\n", u_errorName(status)); 1244 return; 1245 } 1246 ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_ON, &status); 1247 genericOrderingTest(coll, test, 2); 1248 ucol_close(coll); 1249 } 1250 1251 /*static UBool 1252 find(UEnumeration* list, const char* str, UErrorCode* status){ 1253 const char* value = NULL; 1254 int32_t length=0; 1255 if(U_FAILURE(*status)){ 1256 return FALSE; 1257 } 1258 uenum_reset(list, status); 1259 while( (value= uenum_next(list, &length, status))!=NULL){ 1260 if(strcmp(value, str)==0){ 1261 return TRUE; 1262 } 1263 } 1264 return FALSE; 1265 }*/ 1266 1267 static void TestJ5298(void) 1268 { 1269 UErrorCode status = U_ZERO_ERROR; 1270 char input[256], output[256]; 1271 UBool isAvailable; 1272 int32_t i = 0; 1273 UEnumeration* values = NULL; 1274 const char *keywordValue = NULL; 1275 log_verbose("Number of collator locales returned : %i \n", ucol_countAvailable()); 1276 values = ucol_getKeywordValues("collation", &status); 1277 for (i = 0; i < ucol_countAvailable(); i++) { 1278 uenum_reset(values, &status); 1279 while ((keywordValue = uenum_next(values, NULL, &status)) != NULL) { 1280 strcpy(input, ucol_getAvailable(i)); 1281 if (strcmp(keywordValue, "standard") != 0) { 1282 strcat(input, "@collation="); 1283 strcat(input, keywordValue); 1284 } 1285 1286 ucol_getFunctionalEquivalent(output, 256, "collation", input, &isAvailable, &status); 1287 if (strcmp(input, output) == 0) { /* Unique locale, print it out */ 1288 log_verbose("%s, \n", output); 1289 } 1290 } 1291 } 1292 uenum_close(values); 1293 log_verbose("\n"); 1294 } 1295 #endif /* #if !UCONFIG_NO_COLLATION */ 1296 1297