Home | History | Annotate | Download | only in cintltst
      1 /********************************************************************
      2  * Copyright (c) 1997-2010 International Business Machines
      3  * Corporation and others. All Rights Reserved.
      4  ********************************************************************/
      5 /*****************************************************************************
      6 *
      7 * File CAPITEST.C
      8 *
      9 * Modification History:
     10 *        Name                     Description
     11 *     Madhu Katragadda             Ported for C API
     12 *     Brian Rower                  Added TestOpenVsOpenRules
     13 ******************************************************************************
     14 *//* C API TEST For COLLATOR */
     15 
     16 #include "unicode/utypes.h"
     17 
     18 #if !UCONFIG_NO_COLLATION
     19 
     20 #include <stdio.h>
     21 #include <stdlib.h>
     22 #include <string.h>
     23 #include "unicode/uloc.h"
     24 #include "unicode/ulocdata.h"
     25 #include "unicode/ustring.h"
     26 #include "unicode/ures.h"
     27 #include "unicode/ucoleitr.h"
     28 #include "cintltst.h"
     29 #include "capitst.h"
     30 #include "ccolltst.h"
     31 #include "putilimp.h"
     32 #include "cmemory.h"
     33 #include "cstring.h"
     34 
     35 static void TestAttribute(void);
     36 static void TestDefault(void);
     37 static void TestDefaultKeyword(void);
     38         int TestBufferSize();    /* defined in "colutil.c" */
     39 
     40 
     41 
     42 
     43 /* next two function is modified from "i18n/ucol.cpp" to avoid include "ucol_imp.h" */
     44 static void uprv_appendByteToHexString(char *dst, uint8_t val) {
     45   uint32_t len = (uint32_t)strlen(dst);
     46   sprintf(dst+len, "%02X", val);
     47 }
     48 
     49 static char* U_EXPORT2 ucol_sortKeyToString(const UCollator *coll, const uint8_t *sortkey, char *buffer, uint32_t *len) {
     50   int32_t strength = UCOL_PRIMARY;
     51   uint32_t res_size = 0;
     52   UBool doneCase = FALSE;
     53 
     54   char *current = buffer;
     55   const uint8_t *currentSk = sortkey;
     56 
     57   UErrorCode error_code = U_ZERO_ERROR;
     58 
     59   strcpy(current, "[");
     60 
     61   while(strength <= UCOL_QUATERNARY && strength <= ucol_getAttribute(coll,UCOL_STRENGTH, &error_code)) {
     62     if(U_FAILURE(error_code)) {
     63       log_err("ucol_getAttribute returned error: %s\n", u_errorName(error_code));
     64     }
     65     if(strength > UCOL_PRIMARY) {
     66       strcat(current, " . ");
     67     }
     68     while(*currentSk != 0x01 && *currentSk != 0x00) { /* print a level */
     69       uprv_appendByteToHexString(current, *currentSk++);
     70       strcat(current, " ");
     71     }
     72     if(ucol_getAttribute(coll,UCOL_CASE_LEVEL, &error_code) == UCOL_ON && strength == UCOL_SECONDARY && doneCase == FALSE) {
     73         doneCase = TRUE;
     74     } else if(ucol_getAttribute(coll,UCOL_CASE_LEVEL, &error_code) == UCOL_OFF || doneCase == TRUE || strength != UCOL_SECONDARY) {
     75       strength ++;
     76     }
     77     if(U_FAILURE(error_code)) {
     78       log_err("ucol_getAttribute returned error: %s\n", u_errorName(error_code));
     79     }
     80     uprv_appendByteToHexString(current, *currentSk++); /* This should print '01' */
     81     if(strength == UCOL_QUATERNARY && ucol_getAttribute(coll,UCOL_ALTERNATE_HANDLING, &error_code) == UCOL_NON_IGNORABLE) {
     82       break;
     83     }
     84   }
     85 
     86   if(ucol_getAttribute(coll,UCOL_STRENGTH, &error_code) == UCOL_IDENTICAL) {
     87     strcat(current, " . ");
     88     while(*currentSk != 0) {
     89       uprv_appendByteToHexString(current, *currentSk++);
     90       strcat(current, " ");
     91     }
     92 
     93     uprv_appendByteToHexString(current, *currentSk++);
     94   }
     95   if(U_FAILURE(error_code)) {
     96     log_err("ucol_getAttribute returned error: %s\n", u_errorName(error_code));
     97   }
     98   strcat(current, "]");
     99 
    100   if(res_size > *len) {
    101     return NULL;
    102   }
    103 
    104   return buffer;
    105 }
    106 /* end of  avoid include "ucol_imp.h" */
    107 
    108 
    109 void addCollAPITest(TestNode** root)
    110 {
    111     /* WEIVTODO: return tests here */
    112     addTest(root, &TestProperty,      "tscoll/capitst/TestProperty");
    113     addTest(root, &TestRuleBasedColl, "tscoll/capitst/TestRuleBasedColl");
    114     addTest(root, &TestCompare,       "tscoll/capitst/TestCompare");
    115     addTest(root, &TestSortKey,       "tscoll/capitst/TestSortKey");
    116     addTest(root, &TestHashCode,      "tscoll/capitst/TestHashCode");
    117     addTest(root, &TestElemIter,      "tscoll/capitst/TestElemIter");
    118     addTest(root, &TestGetAll,        "tscoll/capitst/TestGetAll");
    119     /*addTest(root, &TestGetDefaultRules, "tscoll/capitst/TestGetDefaultRules");*/
    120     addTest(root, &TestDecomposition, "tscoll/capitst/TestDecomposition");
    121     addTest(root, &TestSafeClone, "tscoll/capitst/TestSafeClone");
    122     addTest(root, &TestCloneBinary, "tscoll/capitst/TestCloneBinary");
    123     addTest(root, &TestGetSetAttr, "tscoll/capitst/TestGetSetAttr");
    124     addTest(root, &TestBounds, "tscoll/capitst/TestBounds");
    125     addTest(root, &TestGetLocale, "tscoll/capitst/TestGetLocale");
    126     addTest(root, &TestSortKeyBufferOverrun, "tscoll/capitst/TestSortKeyBufferOverrun");
    127     addTest(root, &TestAttribute, "tscoll/capitst/TestAttribute");
    128     addTest(root, &TestGetTailoredSet, "tscoll/capitst/TestGetTailoredSet");
    129     addTest(root, &TestMergeSortKeys, "tscoll/capitst/TestMergeSortKeys");
    130     addTest(root, &TestShortString, "tscoll/capitst/TestShortString");
    131     addTest(root, &TestGetContractionsAndUnsafes, "tscoll/capitst/TestGetContractionsAndUnsafes");
    132     addTest(root, &TestOpenBinary, "tscoll/capitst/TestOpenBinary");
    133     addTest(root, &TestDefault, "tscoll/capitst/TestDefault");
    134     addTest(root, &TestDefaultKeyword, "tscoll/capitst/TestDefaultKeyword");
    135     addTest(root, &TestOpenVsOpenRules, "tscoll/capitst/TestOpenVsOpenRules");
    136     addTest(root, &TestGetKeywordValuesForLocale, "tscoll/capitst/TestGetKeywordValuesForLocale");
    137 }
    138 
    139 void TestGetSetAttr(void) {
    140   UErrorCode status = U_ZERO_ERROR;
    141   UCollator *coll = ucol_open(NULL, &status);
    142   struct attrTest {
    143     UColAttribute att;
    144     UColAttributeValue val[5];
    145     uint32_t valueSize;
    146     UColAttributeValue nonValue;
    147   } attrs[] = {
    148     {UCOL_FRENCH_COLLATION, {UCOL_ON, UCOL_OFF}, 2, UCOL_SHIFTED},
    149     {UCOL_ALTERNATE_HANDLING, {UCOL_NON_IGNORABLE, UCOL_SHIFTED}, 2, UCOL_OFF},/* attribute for handling variable elements*/
    150     {UCOL_CASE_FIRST, {UCOL_OFF, UCOL_LOWER_FIRST, UCOL_UPPER_FIRST}, 3, UCOL_SHIFTED},/* who goes first, lower case or uppercase */
    151     {UCOL_CASE_LEVEL, {UCOL_ON, UCOL_OFF}, 2, UCOL_SHIFTED},/* do we have an extra case level */
    152     {UCOL_NORMALIZATION_MODE, {UCOL_ON, UCOL_OFF}, 2, UCOL_SHIFTED},/* attribute for normalization */
    153     {UCOL_DECOMPOSITION_MODE, {UCOL_ON, UCOL_OFF}, 2, UCOL_SHIFTED},
    154     {UCOL_STRENGTH,         {UCOL_PRIMARY, UCOL_SECONDARY, UCOL_TERTIARY, UCOL_QUATERNARY, UCOL_IDENTICAL}, 5, UCOL_SHIFTED},/* attribute for strength */
    155     {UCOL_HIRAGANA_QUATERNARY_MODE, {UCOL_ON, UCOL_OFF}, 2, UCOL_SHIFTED},/* when turned on, this attribute */
    156   };
    157   UColAttribute currAttr;
    158   UColAttributeValue value;
    159   uint32_t i = 0, j = 0;
    160 
    161   if (coll == NULL) {
    162     log_err_status(status, "Unable to open collator. %s\n", u_errorName(status));
    163     return;
    164   }
    165   for(i = 0; i<sizeof(attrs)/sizeof(attrs[0]); i++) {
    166     currAttr = attrs[i].att;
    167     ucol_setAttribute(coll, currAttr, UCOL_DEFAULT, &status);
    168     if(U_FAILURE(status)) {
    169       log_err_status(status, "ucol_setAttribute with the default value returned error: %s\n", u_errorName(status));
    170       break;
    171     }
    172     value = ucol_getAttribute(coll, currAttr, &status);
    173     if(U_FAILURE(status)) {
    174       log_err("ucol_getAttribute returned error: %s\n", u_errorName(status));
    175       break;
    176     }
    177     for(j = 0; j<attrs[i].valueSize; j++) {
    178       ucol_setAttribute(coll, currAttr, attrs[i].val[j], &status);
    179       if(U_FAILURE(status)) {
    180         log_err("ucol_setAttribute with the value %i returned error: %s\n", attrs[i].val[j], u_errorName(status));
    181         break;
    182       }
    183     }
    184     status = U_ZERO_ERROR;
    185     ucol_setAttribute(coll, currAttr, attrs[i].nonValue, &status);
    186     if(U_SUCCESS(status)) {
    187       log_err("ucol_setAttribute with the bad value didn't return an error\n");
    188       break;
    189     }
    190     status = U_ZERO_ERROR;
    191 
    192     ucol_setAttribute(coll, currAttr, value, &status);
    193     if(U_FAILURE(status)) {
    194       log_err("ucol_setAttribute with the default valuereturned error: %s\n", u_errorName(status));
    195       break;
    196     }
    197   }
    198   status = U_ZERO_ERROR;
    199   value = ucol_getAttribute(coll, UCOL_ATTRIBUTE_COUNT, &status);
    200   if(U_SUCCESS(status)) {
    201     log_err("ucol_getAttribute for UCOL_ATTRIBUTE_COUNT didn't return an error\n");
    202   }
    203   status = U_ZERO_ERROR;
    204   ucol_setAttribute(coll, UCOL_ATTRIBUTE_COUNT, UCOL_DEFAULT, &status);
    205   if(U_SUCCESS(status)) {
    206     log_err("ucol_setAttribute for UCOL_ATTRIBUTE_COUNT didn't return an error\n");
    207   }
    208   status = U_ZERO_ERROR;
    209   ucol_close(coll);
    210 }
    211 
    212 
    213 static void doAssert(int condition, const char *message)
    214 {
    215     if (condition==0) {
    216         log_err("ERROR :  %s\n", message);
    217     }
    218 }
    219 
    220 #if 0
    221 /* We don't have default rules, at least not in the previous sense */
    222 void TestGetDefaultRules(){
    223     uint32_t size=0;
    224     UErrorCode status=U_ZERO_ERROR;
    225     UCollator *coll=NULL;
    226     int32_t len1 = 0, len2=0;
    227     uint8_t *binColData = NULL;
    228 
    229     UResourceBundle *res = NULL;
    230     UResourceBundle *binColl = NULL;
    231     uint8_t *binResult = NULL;
    232 
    233 
    234     const UChar * defaultRulesArray=ucol_getDefaultRulesArray(&size);
    235     log_verbose("Test the function ucol_getDefaultRulesArray()\n");
    236 
    237     coll = ucol_openRules(defaultRulesArray, size, UCOL_ON, UCOL_PRIMARY, &status);
    238     if(U_SUCCESS(status) && coll !=NULL) {
    239         binColData = (uint8_t*)ucol_cloneRuleData(coll, &len1, &status);
    240 
    241     }
    242 
    243 
    244     status=U_ZERO_ERROR;
    245     res=ures_open(NULL, "root", &status);
    246     if(U_FAILURE(status)){
    247         log_err("ERROR: Failed to get resource for \"root Locale\" with %s", myErrorName(status));
    248         return;
    249     }
    250     binColl=ures_getByKey(res, "%%Collation", binColl, &status);
    251     if(U_SUCCESS(status)){
    252         binResult=(uint8_t*)ures_getBinary(binColl,  &len2, &status);
    253         if(U_FAILURE(status)){
    254             log_err("ERROR: ures_getBinary() failed\n");
    255         }
    256     }else{
    257         log_err("ERROR: ures_getByKey(locale(default), %%Collation) failed");
    258     }
    259 
    260 
    261     if(len1 != len2){
    262         log_err("Error: ucol_getDefaultRulesArray() failed to return the correct length.\n");
    263     }
    264     if(memcmp(binColData, binResult, len1) != 0){
    265         log_err("Error: ucol_getDefaultRulesArray() failed\n");
    266     }
    267 
    268     free(binColData);
    269     ures_close(binColl);
    270     ures_close(res);
    271     ucol_close(coll);
    272 
    273 }
    274 #endif
    275 
    276 /* Collator Properties
    277  ucol_open, ucol_strcoll,  getStrength/setStrength
    278  getDecomposition/setDecomposition, getDisplayName*/
    279 void TestProperty()
    280 {
    281     UCollator *col, *ruled;
    282     UChar *disName;
    283     int32_t len = 0;
    284     UChar *source, *target;
    285     int32_t tempLength;
    286     UErrorCode status = U_ZERO_ERROR;
    287     /*
    288      * Expected version of the English collator.
    289      * Currently, the major/minor version numbers change when the builder code
    290      * changes,
    291      * number 2 is from the tailoring data version and
    292      * number 3 is the UCA version.
    293      * This changes with every UCA version change, and the expected value
    294      * needs to be adjusted.
    295      * Same in intltest/apicoll.cpp.
    296      */
    297     UVersionInfo currVersionArray = {0x31, 0xC0, 0x05, 0x2A};  /* from ICU 4.4/UCA 5.2 */
    298     UVersionInfo versionArray = {0, 0, 0, 0};
    299     UVersionInfo versionUCAArray = {0, 0, 0, 0};
    300     UVersionInfo versionUCDArray = {0, 0, 0, 0};
    301 
    302     log_verbose("The property tests begin : \n");
    303     log_verbose("Test ucol_strcoll : \n");
    304     col = ucol_open("en_US", &status);
    305     if (U_FAILURE(status)) {
    306         log_err_status(status, "Default Collator creation failed.: %s\n", myErrorName(status));
    307         return;
    308     }
    309 
    310     ucol_getVersion(col, versionArray);
    311     /* Check for a version greater than some value rather than equality
    312      * so that we need not update the expected version each time. */
    313     if (uprv_memcmp(versionArray, currVersionArray, 4)<0) {
    314       log_err("Testing ucol_getVersion() - unexpected result: %02x.%02x.%02x.%02x\n",
    315               versionArray[0], versionArray[1], versionArray[2], versionArray[3]);
    316     } else {
    317       log_verbose("ucol_getVersion() result: %02x.%02x.%02x.%02x\n",
    318                   versionArray[0], versionArray[1], versionArray[2], versionArray[3]);
    319     }
    320 
    321     /* Assume that the UCD and UCA versions are the same,
    322      * rather than hardcoding (and updating each time) a particular UCA version. */
    323     u_getUnicodeVersion(versionUCDArray);
    324     ucol_getUCAVersion(col, versionUCAArray);
    325     if (0!=uprv_memcmp(versionUCAArray, versionUCDArray, 4)) {
    326       log_err("Testing ucol_getUCAVersion() - unexpected result: %hu.%hu.%hu.%hu\n",
    327               versionUCAArray[0], versionUCAArray[1], versionUCAArray[2], versionUCAArray[3]);
    328     }
    329 
    330     source=(UChar*)malloc(sizeof(UChar) * 12);
    331     target=(UChar*)malloc(sizeof(UChar) * 12);
    332 
    333 
    334     u_uastrcpy(source, "ab");
    335     u_uastrcpy(target, "abc");
    336 
    337     doAssert((ucol_strcoll(col, source, u_strlen(source), target, u_strlen(target)) == UCOL_LESS), "ab < abc comparison failed");
    338 
    339     u_uastrcpy(source, "ab");
    340     u_uastrcpy(target, "AB");
    341 
    342     doAssert((ucol_strcoll(col, source, u_strlen(source), target, u_strlen(target)) == UCOL_LESS), "ab < AB comparison failed");
    343 /*    u_uastrcpy(source, "black-bird");
    344     u_uastrcpy(target, "blackbird"); */
    345     u_uastrcpy(target, "black-bird");
    346     u_uastrcpy(source, "blackbird");
    347 
    348     doAssert((ucol_strcoll(col, source, u_strlen(source), target, u_strlen(target)) == UCOL_GREATER),
    349         "black-bird > blackbird comparison failed");
    350     u_uastrcpy(source, "black bird");
    351     u_uastrcpy(target, "black-bird");
    352     doAssert((ucol_strcoll(col, source, u_strlen(source), target, u_strlen(target)) == UCOL_LESS),
    353         "black bird < black-bird comparison failed");
    354     u_uastrcpy(source, "Hello");
    355     u_uastrcpy(target, "hello");
    356 
    357     doAssert((ucol_strcoll(col, source, u_strlen(source), target, u_strlen(target)) == UCOL_GREATER),
    358         "Hello > hello comparison failed");
    359     free(source);
    360     free(target);
    361     log_verbose("Test ucol_strcoll ends.\n");
    362 
    363     log_verbose("testing ucol_getStrength() method ...\n");
    364     doAssert( (ucol_getStrength(col) == UCOL_TERTIARY), "collation object has the wrong strength");
    365     doAssert( (ucol_getStrength(col) != UCOL_PRIMARY), "collation object's strength is primary difference");
    366 
    367     log_verbose("testing ucol_setStrength() method ...\n");
    368     ucol_setStrength(col, UCOL_SECONDARY);
    369     doAssert( (ucol_getStrength(col) != UCOL_TERTIARY), "collation object's strength is secondary difference");
    370     doAssert( (ucol_getStrength(col) != UCOL_PRIMARY), "collation object's strength is primary difference");
    371     doAssert( (ucol_getStrength(col) == UCOL_SECONDARY), "collation object has the wrong strength");
    372 
    373 
    374     log_verbose("Get display name for the default collation in German : \n");
    375 
    376     len=ucol_getDisplayName("en_US", "de_DE", NULL, 0,  &status);
    377     if(status==U_BUFFER_OVERFLOW_ERROR){
    378         status=U_ZERO_ERROR;
    379         disName=(UChar*)malloc(sizeof(UChar) * (len+1));
    380         ucol_getDisplayName("en_US", "de_DE", disName, len+1,  &status);
    381         log_verbose("the display name for default collation in german: %s\n", austrdup(disName) );
    382         free(disName);
    383     }
    384     if(U_FAILURE(status)){
    385         log_err("ERROR: in getDisplayName: %s\n", myErrorName(status));
    386         return;
    387     }
    388     log_verbose("Default collation getDisplayName ended.\n");
    389 
    390     ruled = ucol_open("da_DK", &status);
    391     log_verbose("ucol_getRules() testing ...\n");
    392     ucol_getRules(ruled, &tempLength);
    393     doAssert( tempLength != 0, "getRules() result incorrect" );
    394     log_verbose("getRules tests end.\n");
    395     {
    396         UChar *buffer = (UChar *)malloc(200000*sizeof(UChar));
    397         int32_t bufLen = 200000;
    398         buffer[0] = '\0';
    399         log_verbose("ucol_getRulesEx() testing ...\n");
    400         tempLength = ucol_getRulesEx(col,UCOL_TAILORING_ONLY,buffer,bufLen );
    401         doAssert( tempLength == 0x00, "getRulesEx() result incorrect" );
    402         log_verbose("getRules tests end.\n");
    403 
    404         log_verbose("ucol_getRulesEx() testing ...\n");
    405         tempLength=ucol_getRulesEx(col,UCOL_FULL_RULES,buffer,bufLen );
    406         doAssert( tempLength != 0, "getRulesEx() result incorrect" );
    407         log_verbose("getRules tests end.\n");
    408         free(buffer);
    409     }
    410     ucol_close(ruled);
    411     ucol_close(col);
    412 
    413     log_verbose("open an collator for french locale");
    414     col = ucol_open("fr_FR", &status);
    415     if (U_FAILURE(status)) {
    416        log_err("ERROR: Creating French collation failed.: %s\n", myErrorName(status));
    417         return;
    418     }
    419     ucol_setStrength(col, UCOL_PRIMARY);
    420     log_verbose("testing ucol_getStrength() method again ...\n");
    421     doAssert( (ucol_getStrength(col) != UCOL_TERTIARY), "collation object has the wrong strength");
    422     doAssert( (ucol_getStrength(col) == UCOL_PRIMARY), "collation object's strength is not primary difference");
    423 
    424     log_verbose("testing French ucol_setStrength() method ...\n");
    425     ucol_setStrength(col, UCOL_TERTIARY);
    426     doAssert( (ucol_getStrength(col) == UCOL_TERTIARY), "collation object's strength is not tertiary difference");
    427     doAssert( (ucol_getStrength(col) != UCOL_PRIMARY), "collation object's strength is primary difference");
    428     doAssert( (ucol_getStrength(col) != UCOL_SECONDARY), "collation object's strength is secondary difference");
    429     ucol_close(col);
    430 
    431     log_verbose("Get display name for the french collation in english : \n");
    432     len=ucol_getDisplayName("fr_FR", "en_US", NULL, 0,  &status);
    433     if(status==U_BUFFER_OVERFLOW_ERROR){
    434         status=U_ZERO_ERROR;
    435         disName=(UChar*)malloc(sizeof(UChar) * (len+1));
    436         ucol_getDisplayName("fr_FR", "en_US", disName, len+1,  &status);
    437         log_verbose("the display name for french collation in english: %s\n", austrdup(disName) );
    438         free(disName);
    439     }
    440     if(U_FAILURE(status)){
    441         log_err("ERROR: in getDisplayName: %s\n", myErrorName(status));
    442         return;
    443     }
    444     log_verbose("Default collation getDisplayName ended.\n");
    445 
    446 }
    447 
    448 /* Test RuleBasedCollator and getRules*/
    449 void TestRuleBasedColl()
    450 {
    451     UCollator *col1, *col2, *col3, *col4;
    452     UCollationElements *iter1, *iter2;
    453     UChar ruleset1[60];
    454     UChar ruleset2[50];
    455     UChar teststr[10];
    456     UChar teststr2[10];
    457     const UChar *rule1, *rule2, *rule3, *rule4;
    458     int32_t tempLength;
    459     UErrorCode status = U_ZERO_ERROR;
    460     u_uastrcpy(ruleset1, "&9 < a, A < b, B < c, C; ch, cH, Ch, CH < d, D, e, E");
    461     u_uastrcpy(ruleset2, "&9 < a, A < b, B < c, C < d, D, e, E");
    462 
    463 
    464     col1 = ucol_openRules(ruleset1, u_strlen(ruleset1), UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL,&status);
    465     if (U_FAILURE(status)) {
    466         log_err_status(status, "RuleBased Collator creation failed.: %s\n", myErrorName(status));
    467         return;
    468     }
    469     else
    470         log_verbose("PASS: RuleBased Collator creation passed\n");
    471 
    472     status = U_ZERO_ERROR;
    473     col2 = ucol_openRules(ruleset2, u_strlen(ruleset2),  UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL, &status);
    474     if (U_FAILURE(status)) {
    475         log_err("RuleBased Collator creation failed.: %s\n", myErrorName(status));
    476         return;
    477     }
    478     else
    479         log_verbose("PASS: RuleBased Collator creation passed\n");
    480 
    481 
    482     status = U_ZERO_ERROR;
    483     col3= ucol_open(NULL, &status);
    484     if (U_FAILURE(status)) {
    485         log_err("Default Collator creation failed.: %s\n", myErrorName(status));
    486         return;
    487     }
    488     else
    489         log_verbose("PASS: Default Collator creation passed\n");
    490 
    491     rule1 = ucol_getRules(col1, &tempLength);
    492     rule2 = ucol_getRules(col2, &tempLength);
    493     rule3 = ucol_getRules(col3, &tempLength);
    494 
    495     doAssert((u_strcmp(rule1, rule2) != 0), "Default collator getRules failed");
    496     doAssert((u_strcmp(rule2, rule3) != 0), "Default collator getRules failed");
    497     doAssert((u_strcmp(rule1, rule3) != 0), "Default collator getRules failed");
    498 
    499     col4=ucol_openRules(rule2, u_strlen(rule2), UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL, &status);
    500     if (U_FAILURE(status)) {
    501         log_err("RuleBased Collator creation failed.: %s\n", myErrorName(status));
    502         return;
    503     }
    504     rule4= ucol_getRules(col4, &tempLength);
    505     doAssert((u_strcmp(rule2, rule4) == 0), "Default collator getRules failed");
    506 
    507     ucol_close(col1);
    508     ucol_close(col2);
    509     ucol_close(col3);
    510     ucol_close(col4);
    511 
    512     /* tests that modifier ! is always ignored */
    513     u_uastrcpy(ruleset1, "!&a<b");
    514     teststr[0] = 0x0e40;
    515     teststr[1] = 0x0e01;
    516     teststr[2] = 0x0e2d;
    517     col1 = ucol_openRules(ruleset1, u_strlen(ruleset1), UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL, &status);
    518     if (U_FAILURE(status)) {
    519         log_err("RuleBased Collator creation failed.: %s\n", myErrorName(status));
    520         return;
    521     }
    522     col2 = ucol_open("en_US", &status);
    523     if (U_FAILURE(status)) {
    524         log_err("en_US Collator creation failed.: %s\n", myErrorName(status));
    525         return;
    526     }
    527     iter1 = ucol_openElements(col1, teststr, 3, &status);
    528     iter2 = ucol_openElements(col2, teststr, 3, &status);
    529     if(U_FAILURE(status)) {
    530         log_err("ERROR: CollationElement iterator creation failed.: %s\n", myErrorName(status));
    531         return;
    532     }
    533     while (TRUE) {
    534         /* testing with en since thai has its own tailoring */
    535         uint32_t ce = ucol_next(iter1, &status);
    536         uint32_t ce2 = ucol_next(iter2, &status);
    537         if(U_FAILURE(status)) {
    538             log_err("ERROR: CollationElement iterator creation failed.: %s\n", myErrorName(status));
    539             return;
    540         }
    541         if (ce2 != ce) {
    542              log_err("! modifier test failed");
    543         }
    544         if (ce == UCOL_NULLORDER) {
    545             break;
    546         }
    547     }
    548     ucol_closeElements(iter1);
    549     ucol_closeElements(iter2);
    550     ucol_close(col1);
    551     ucol_close(col2);
    552     /* test that we can start a rule without a & or < */
    553     u_uastrcpy(ruleset1, "< z < a");
    554     col1 = ucol_openRules(ruleset1, u_strlen(ruleset1), UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL, &status);
    555     if (U_FAILURE(status)) {
    556         log_err("RuleBased Collator creation failed.: %s\n", myErrorName(status));
    557         return;
    558     }
    559     u_uastrcpy(teststr, "z");
    560     u_uastrcpy(teststr2, "a");
    561     if (ucol_greaterOrEqual(col1, teststr, 1, teststr2, 1)) {
    562         log_err("Rule \"z < a\" fails");
    563     }
    564     ucol_close(col1);
    565 }
    566 
    567 void TestCompare()
    568 {
    569     UErrorCode status = U_ZERO_ERROR;
    570     UCollator *col;
    571     UChar* test1;
    572     UChar* test2;
    573 
    574     log_verbose("The compare tests begin : \n");
    575     status=U_ZERO_ERROR;
    576     col = ucol_open("en_US", &status);
    577     if(U_FAILURE(status)) {
    578         log_err_status(status, "ucal_open() collation creation failed.: %s\n", myErrorName(status));
    579         return;
    580     }
    581     test1=(UChar*)malloc(sizeof(UChar) * 6);
    582     test2=(UChar*)malloc(sizeof(UChar) * 6);
    583     u_uastrcpy(test1, "Abcda");
    584     u_uastrcpy(test2, "abcda");
    585 
    586     log_verbose("Use tertiary comparison level testing ....\n");
    587 
    588     doAssert( (!ucol_equal(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" != \"abcda\" ");
    589     doAssert( (ucol_greater(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" >>> \"abcda\" ");
    590     doAssert( (ucol_greaterOrEqual(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" >>> \"abcda\"");
    591 
    592     ucol_setStrength(col, UCOL_SECONDARY);
    593     log_verbose("Use secondary comparison level testing ....\n");
    594 
    595     doAssert( (ucol_equal(col, test1, u_strlen(test1), test2, u_strlen(test2) )), "Result should be \"Abcda\" == \"abcda\"");
    596     doAssert( (!ucol_greater(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" == \"abcda\"");
    597     doAssert( (ucol_greaterOrEqual(col, test1, u_strlen(test1), test2, u_strlen(test2) )), "Result should be \"Abcda\" == \"abcda\"");
    598 
    599     ucol_setStrength(col, UCOL_PRIMARY);
    600     log_verbose("Use primary comparison level testing ....\n");
    601 
    602     doAssert( (ucol_equal(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" == \"abcda\"");
    603     doAssert( (!ucol_greater(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" == \"abcda\"");
    604     doAssert( (ucol_greaterOrEqual(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" == \"abcda\"");
    605 
    606 
    607     log_verbose("The compare tests end.\n");
    608     ucol_close(col);
    609     free(test1);
    610     free(test2);
    611 
    612 }
    613 /*
    614 ---------------------------------------------
    615  tests decomposition setting
    616 */
    617 void TestDecomposition() {
    618     UErrorCode status = U_ZERO_ERROR;
    619     UCollator *en_US, *el_GR, *vi_VN;
    620     en_US = ucol_open("en_US", &status);
    621     el_GR = ucol_open("el_GR", &status);
    622     vi_VN = ucol_open("vi_VN", &status);
    623 
    624     if (U_FAILURE(status)) {
    625         log_err_status(status, "ERROR: collation creation failed.: %s\n", myErrorName(status));
    626         return;
    627     }
    628 
    629     if (ucol_getAttribute(vi_VN, UCOL_NORMALIZATION_MODE, &status) != UCOL_ON ||
    630         U_FAILURE(status))
    631     {
    632         log_err("ERROR: vi_VN collation did not have cannonical decomposition for normalization!\n");
    633     }
    634 
    635     status = U_ZERO_ERROR;
    636     if (ucol_getAttribute(el_GR, UCOL_NORMALIZATION_MODE, &status) != UCOL_ON ||
    637         U_FAILURE(status))
    638     {
    639         log_err("ERROR: el_GR collation did not have cannonical decomposition for normalization!\n");
    640     }
    641 
    642     status = U_ZERO_ERROR;
    643     if (ucol_getAttribute(en_US, UCOL_NORMALIZATION_MODE, &status) != UCOL_OFF ||
    644         U_FAILURE(status))
    645     {
    646         log_err("ERROR: en_US collation had cannonical decomposition for normalization!\n");
    647     }
    648 
    649     ucol_close(en_US);
    650     ucol_close(el_GR);
    651     ucol_close(vi_VN);
    652 }
    653 
    654 #define CLONETEST_COLLATOR_COUNT 4
    655 
    656 void TestSafeClone() {
    657     UChar test1[6];
    658     UChar test2[6];
    659     static const UChar umlautUStr[] = {0x00DC, 0};
    660     static const UChar oeStr[] = {0x0055, 0x0045, 0};
    661     UCollator * someCollators [CLONETEST_COLLATOR_COUNT];
    662     UCollator * someClonedCollators [CLONETEST_COLLATOR_COUNT];
    663     UCollator * col;
    664     UErrorCode err = U_ZERO_ERROR;
    665     int8_t index = 6;    /* Leave this here to test buffer alingment in memory*/
    666     uint8_t buffer [CLONETEST_COLLATOR_COUNT] [U_COL_SAFECLONE_BUFFERSIZE];
    667     int32_t bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
    668     const char sampleRuleChars[] = "&Z < CH";
    669     UChar sampleRule[sizeof(sampleRuleChars)];
    670 
    671     if (TestBufferSize()) {
    672         log_err("U_COL_SAFECLONE_BUFFERSIZE should be larger than sizeof(UCollator)\n");
    673         return;
    674     }
    675 
    676     u_uastrcpy(test1, "abCda");
    677     u_uastrcpy(test2, "abcda");
    678     u_uastrcpy(sampleRule, sampleRuleChars);
    679 
    680     /* one default collator & two complex ones */
    681     someCollators[0] = ucol_open("en_US", &err);
    682     someCollators[1] = ucol_open("ko", &err);
    683     someCollators[2] = ucol_open("ja_JP", &err);
    684     someCollators[3] = ucol_openRules(sampleRule, -1, UCOL_ON, UCOL_TERTIARY, NULL, &err);
    685     if(U_FAILURE(err)) {
    686         for (index = 0; index < CLONETEST_COLLATOR_COUNT; index++) {
    687             ucol_close(someCollators[index]);
    688         }
    689         log_data_err("Couldn't open one or more collators\n");
    690         return;
    691     }
    692 
    693     /* Check the various error & informational states: */
    694 
    695     /* Null status - just returns NULL */
    696     if (0 != ucol_safeClone(someCollators[0], buffer[0], &bufferSize, 0))
    697     {
    698         log_err("FAIL: Cloned Collator failed to deal correctly with null status\n");
    699     }
    700     /* error status - should return 0 & keep error the same */
    701     err = U_MEMORY_ALLOCATION_ERROR;
    702     if (0 != ucol_safeClone(someCollators[0], buffer[0], &bufferSize, &err) || err != U_MEMORY_ALLOCATION_ERROR)
    703     {
    704         log_err("FAIL: Cloned Collator failed to deal correctly with incoming error status\n");
    705     }
    706     err = U_ZERO_ERROR;
    707 
    708     /* Null buffer size pointer - just returns NULL & set error to U_ILLEGAL_ARGUMENT_ERROR*/
    709     if (0 != ucol_safeClone(someCollators[0], buffer[0], 0, &err) || err != U_ILLEGAL_ARGUMENT_ERROR)
    710     {
    711         log_err("FAIL: Cloned Collator failed to deal correctly with null bufferSize pointer\n");
    712     }
    713     err = U_ZERO_ERROR;
    714 
    715     /* buffer size pointer is 0 - fill in pbufferSize with a size */
    716     bufferSize = 0;
    717     if (0 != ucol_safeClone(someCollators[0], buffer[0], &bufferSize, &err) || U_FAILURE(err) || bufferSize <= 0)
    718     {
    719         log_err("FAIL: Cloned Collator failed a sizing request ('preflighting')\n");
    720     }
    721     /* Verify our define is large enough  */
    722     if (U_COL_SAFECLONE_BUFFERSIZE < bufferSize)
    723     {
    724         log_err("FAIL: Pre-calculated buffer size is too small\n");
    725     }
    726     /* Verify we can use this run-time calculated size */
    727     if (0 == (col = ucol_safeClone(someCollators[0], buffer[0], &bufferSize, &err)) || U_FAILURE(err))
    728     {
    729         log_err("FAIL: Collator can't be cloned with run-time size\n");
    730     }
    731     if (col) ucol_close(col);
    732     /* size one byte too small - should allocate & let us know */
    733     --bufferSize;
    734     if (0 == (col = ucol_safeClone(someCollators[0], 0, &bufferSize, &err)) || err != U_SAFECLONE_ALLOCATED_WARNING)
    735     {
    736         log_err("FAIL: Cloned Collator failed to deal correctly with too-small buffer size\n");
    737     }
    738     if (col) ucol_close(col);
    739     err = U_ZERO_ERROR;
    740     bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
    741 
    742 
    743     /* Null buffer pointer - return Collator & set error to U_SAFECLONE_ALLOCATED_ERROR */
    744     if (0 == (col = ucol_safeClone(someCollators[0], 0, &bufferSize, &err)) || err != U_SAFECLONE_ALLOCATED_WARNING)
    745     {
    746         log_err("FAIL: Cloned Collator failed to deal correctly with null buffer pointer\n");
    747     }
    748     if (col) ucol_close(col);
    749     err = U_ZERO_ERROR;
    750 
    751     /* Null Collator - return NULL & set U_ILLEGAL_ARGUMENT_ERROR */
    752     if (0 != ucol_safeClone(0, buffer[0], &bufferSize, &err) || err != U_ILLEGAL_ARGUMENT_ERROR)
    753     {
    754         log_err("FAIL: Cloned Collator failed to deal correctly with null Collator pointer\n");
    755     }
    756 
    757     err = U_ZERO_ERROR;
    758 
    759     /* Test that a cloned collator doesn't accidentally use UCA. */
    760     col=ucol_open("de@collation=phonebook", &err);
    761     bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
    762     someClonedCollators[0] = ucol_safeClone(col, buffer[0], &bufferSize, &err);
    763     doAssert( (ucol_greater(col, umlautUStr, u_strlen(umlautUStr), oeStr, u_strlen(oeStr))), "Original German phonebook collation sorts differently than expected");
    764     doAssert( (ucol_greater(someClonedCollators[0], umlautUStr, u_strlen(umlautUStr), oeStr, u_strlen(oeStr))), "Cloned German phonebook collation sorts differently than expected");
    765     if (!ucol_equals(someClonedCollators[0], col)) {
    766         log_err("FAIL: Cloned German phonebook collator is not equal to original.\n");
    767     }
    768     ucol_close(col);
    769     ucol_close(someClonedCollators[0]);
    770 
    771     err = U_ZERO_ERROR;
    772 
    773     /* change orig & clone & make sure they are independent */
    774 
    775     for (index = 0; index < CLONETEST_COLLATOR_COUNT; index++)
    776     {
    777         ucol_setStrength(someCollators[index], UCOL_IDENTICAL);
    778         bufferSize = 1;
    779         err = U_ZERO_ERROR;
    780         ucol_close(ucol_safeClone(someCollators[index], buffer[index], &bufferSize, &err));
    781         if (err != U_SAFECLONE_ALLOCATED_WARNING) {
    782             log_err("FAIL: collator number %d was not allocated.\n", index);
    783             log_err("FAIL: status of Collator[%d] is %d  (hex: %x).\n", index, err, err);
    784         }
    785 
    786         bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
    787         err = U_ZERO_ERROR;
    788         someClonedCollators[index] = ucol_safeClone(someCollators[index], buffer[index], &bufferSize, &err);
    789         if (someClonedCollators[index] == NULL
    790             || someClonedCollators[index] < (UCollator *)buffer[index]
    791             || someClonedCollators[index] > (UCollator *)(buffer[index]+(U_COL_SAFECLONE_BUFFERSIZE-1)))
    792         {
    793             log_err("FAIL: Cloned collator didn't use provided buffer.\n");
    794             return;
    795         }
    796         if (!ucol_equals(someClonedCollators[index], someCollators[index])) {
    797             log_err("FAIL: Cloned collator is not equal to original at index = %d.\n", index);
    798         }
    799 
    800         /* Check the usability */
    801         ucol_setStrength(someCollators[index], UCOL_PRIMARY);
    802         ucol_setAttribute(someCollators[index], UCOL_CASE_LEVEL, UCOL_OFF, &err);
    803 
    804         doAssert( (ucol_equal(someCollators[index], test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"abcda\" == \"abCda\"");
    805 
    806         /* Close the original to make sure that the clone is usable. */
    807         ucol_close(someCollators[index]);
    808 
    809         ucol_setStrength(someClonedCollators[index], UCOL_TERTIARY);
    810         ucol_setAttribute(someClonedCollators[index], UCOL_CASE_LEVEL, UCOL_OFF, &err);
    811         doAssert( (ucol_greater(someClonedCollators[index], test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"abCda\" >>> \"abcda\" ");
    812 
    813         ucol_close(someClonedCollators[index]);
    814     }
    815 }
    816 
    817 void TestCloneBinary(){
    818     UErrorCode err = U_ZERO_ERROR;
    819     UCollator * col = ucol_open("en_US", &err);
    820     UCollator * c;
    821     int32_t size;
    822     uint8_t * buffer;
    823 
    824     if (U_FAILURE(err)) {
    825         log_data_err("Couldn't open collator. Error: %s\n", u_errorName(err));
    826         return;
    827     }
    828 
    829     size = ucol_cloneBinary(col, NULL, 0, &err);
    830     if(size==0 || err!=U_BUFFER_OVERFLOW_ERROR) {
    831         log_err("ucol_cloneBinary - couldn't check size. Error: %s\n", u_errorName(err));
    832         return;
    833     }
    834     err = U_ZERO_ERROR;
    835 
    836     buffer = (uint8_t *) malloc(size);
    837     ucol_cloneBinary(col, buffer, size, &err);
    838     if(U_FAILURE(err)) {
    839         log_err("ucol_cloneBinary - couldn't clone.. Error: %s\n", u_errorName(err));
    840         free(buffer);
    841         return;
    842     }
    843 
    844     /* how to check binary result ? */
    845 
    846     c = ucol_openBinary(buffer, size, col, &err);
    847     if(U_FAILURE(err)) {
    848         log_err("ucol_openBinary failed. Error: %s\n", u_errorName(err));
    849     } else {
    850         UChar t[] = {0x41, 0x42, 0x43, 0};  /* ABC */
    851         uint8_t  *k1, *k2;
    852         int l1, l2;
    853         l1 = ucol_getSortKey(col, t, -1, NULL,0);
    854         l2 = ucol_getSortKey(c, t, -1, NULL,0);
    855         k1 = (uint8_t *) malloc(sizeof(uint8_t) * l1);
    856         k2 = (uint8_t *) malloc(sizeof(uint8_t) * l2);
    857         ucol_getSortKey(col, t, -1, k1, l1);
    858         ucol_getSortKey(col, t, -1, k2, l2);
    859         if (strcmp((char *)k1,(char *)k2) != 0){
    860             log_err("ucol_openBinary - new collator should equal to old one\n");
    861         };
    862         free(k1);
    863         free(k2);
    864     }
    865     free(buffer);
    866     ucol_close(c);
    867     ucol_close(col);
    868 }
    869 /*
    870     TestOpenVsOpenRules ensures that collators from ucol_open and ucol_openRules
    871     will generate identical sort keys
    872 */
    873 void TestOpenVsOpenRules(){
    874 
    875     /* create an array of all the locales */
    876     int32_t numLocales = uloc_countAvailable();
    877     int32_t sizeOfStdSet;
    878     uint32_t adder;
    879     UChar str[41]; /* create an array of UChar of size maximum strSize + 1 */
    880     USet *stdSet;
    881     char* curLoc;
    882     UCollator * c1;
    883     UCollator * c2;
    884     const UChar* rules;
    885     int32_t rulesLength;
    886     int32_t sortKeyLen1, sortKeyLen2;
    887     uint8_t *sortKey1 = NULL, *sortKey2 = NULL;
    888     ULocaleData *uld;
    889     int32_t x, y, z;
    890     USet *eSet;
    891     int32_t eSize;
    892     int strSize;
    893 
    894     UErrorCode err = U_ZERO_ERROR;
    895 
    896     /* create a set of standard characters that aren't very interesting...
    897     and then we can find some interesting ones later */
    898 
    899     stdSet = uset_open(0x61, 0x7A);
    900     uset_addRange(stdSet, 0x41, 0x5A);
    901     uset_addRange(stdSet, 0x30, 0x39);
    902     sizeOfStdSet = uset_size(stdSet);
    903 
    904     adder = 1;
    905     if(getTestOption(QUICK_OPTION))
    906     {
    907         adder = 10;
    908     }
    909 
    910     for(x = 0; x < numLocales; x+=adder){
    911         curLoc = (char *)uloc_getAvailable(x);
    912         log_verbose("Processing %s\n", curLoc);
    913 
    914         /* create a collator the normal API way */
    915         c1 = ucol_open(curLoc, &err);
    916         if (U_FAILURE(err)) {
    917             log_err("ERROR: Normal collation creation failed with locale: %s : %s\n", curLoc, myErrorName(err));
    918             return;
    919         }
    920 
    921         /* grab the rules */
    922         rules = ucol_getRules(c1, &rulesLength);
    923 
    924         /* use those rules to create a collator from rules */
    925         c2 = ucol_openRules(rules, rulesLength, UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL, &err);
    926         if (U_FAILURE(err)) {
    927             log_err("ERROR: Creating collator from rules failed with locale: %s : %s\n", curLoc, myErrorName(err));
    928             return;
    929         }
    930 
    931         uld = ulocdata_open(curLoc, &err);
    932 
    933         /*now that we have some collators, we get several strings */
    934 
    935         for(y = 0; y < 5; y++){
    936 
    937             /* get a set of ALL the characters in this locale */
    938             eSet =  ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &err);
    939             eSize = uset_size(eSet);
    940 
    941             /* make a string with these characters in it */
    942             strSize = (rand()%40) + 1;
    943 
    944             for(z = 0; z < strSize; z++){
    945                 str[z] = uset_charAt(eSet, rand()%eSize);
    946             }
    947 
    948             /* change the set to only include 'abnormal' characters (not A-Z, a-z, 0-9 */
    949             uset_removeAll(eSet, stdSet);
    950             eSize = uset_size(eSet);
    951 
    952             /* if there are some non-normal characters left, put a few into the string, just to make sure we have some */
    953             if(eSize > 0){
    954                 str[2%strSize] = uset_charAt(eSet, rand()%eSize);
    955                 str[3%strSize] = uset_charAt(eSet, rand()%eSize);
    956                 str[5%strSize] = uset_charAt(eSet, rand()%eSize);
    957                 str[10%strSize] = uset_charAt(eSet, rand()%eSize);
    958                 str[13%strSize] = uset_charAt(eSet, rand()%eSize);
    959             }
    960             /* terminate the string */
    961             str[strSize-1] = '\0';
    962             log_verbose("String used: %S\n", str);
    963 
    964             /* get sort keys for both of them, and check that the keys are identicle */
    965             sortKeyLen1 = ucol_getSortKey(c1, str, u_strlen(str),  NULL, 0);
    966             sortKey1 = (uint8_t*)malloc(sizeof(uint8_t) * (sortKeyLen1 + 1));
    967             /*memset(sortKey1, 0xFE, sortKeyLen1);*/
    968             ucol_getSortKey(c1, str, u_strlen(str), sortKey1, sortKeyLen1 + 1);
    969 
    970             sortKeyLen2 = ucol_getSortKey(c2, str, u_strlen(str),  NULL, 0);
    971             sortKey2 = (uint8_t*)malloc(sizeof(uint8_t) * (sortKeyLen2 + 1));
    972             /*memset(sortKey2, 0xFE, sortKeyLen2);*/
    973             ucol_getSortKey(c2, str, u_strlen(str), sortKey2, sortKeyLen2 + 1);
    974 
    975             /* Check that the lengths are the same */
    976             doAssert((sortKeyLen1 == sortKeyLen2), "Sort key lengths do not match.");
    977 
    978             /* check that the keys are the same */
    979             doAssert((memcmp(sortKey1, sortKey2, sortKeyLen1) == 0), "Keys are not equivalent");
    980 
    981             /* clean up after each string */
    982             free(sortKey1);
    983             free(sortKey2);
    984             uset_close(eSet);
    985         }
    986         /* clean up after each locale */
    987         ulocdata_close(uld);
    988         ucol_close(c1);
    989         ucol_close(c2);
    990     }
    991     /* final clean up */
    992     uset_close(stdSet);
    993 }
    994 /*
    995 ----------------------------------------------------------------------------
    996  ctor -- Tests the getSortKey
    997 */
    998 void TestSortKey()
    999 {
   1000     uint8_t *sortk1 = NULL, *sortk2 = NULL, *sortk3 = NULL, *sortkEmpty = NULL;
   1001     int32_t sortklen, osortklen;
   1002     uint32_t toStringLen=0;
   1003     UCollator *col;
   1004     UChar *test1, *test2, *test3;
   1005     UErrorCode status = U_ZERO_ERROR;
   1006     char toStringBuffer[256], *resultP;
   1007 
   1008 
   1009     uint8_t s1[] = { 0x9f, 0x00 };
   1010     uint8_t s2[] = { 0x61, 0x00 };
   1011     int  strcmpResult;
   1012 
   1013     strcmpResult = strcmp((const char *)s1, (const char *)s2);
   1014     log_verbose("strcmp(0x9f..., 0x61...) = %d\n", strcmpResult);
   1015 
   1016     if(strcmpResult <= 0) {
   1017       log_err("ERR: expected strcmp(\"9f 00\", \"61 00\") to be >=0 (GREATER).. got %d. Calling strcmp() for sortkeys may not work! \n",
   1018               strcmpResult);
   1019     }
   1020 
   1021 
   1022     log_verbose("testing SortKey begins...\n");
   1023     /* this is supposed to open default date format, but later on it treats it like it is "en_US"
   1024        - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
   1025     /* col = ucol_open(NULL, &status); */
   1026     col = ucol_open("en_US", &status);
   1027     if (U_FAILURE(status)) {
   1028         log_err_status(status, "ERROR: Default collation creation failed.: %s\n", myErrorName(status));
   1029         return;
   1030     }
   1031 
   1032 
   1033     if(ucol_getStrength(col) != UCOL_DEFAULT_STRENGTH)
   1034     {
   1035         log_err("ERROR: default collation did not have UCOL_DEFAULT_STRENGTH !\n");
   1036     }
   1037     /* Need to use identical strength */
   1038     ucol_setAttribute(col, UCOL_STRENGTH, UCOL_IDENTICAL, &status);
   1039 
   1040     test1=(UChar*)malloc(sizeof(UChar) * 6);
   1041     test2=(UChar*)malloc(sizeof(UChar) * 6);
   1042     test3=(UChar*)malloc(sizeof(UChar) * 6);
   1043 
   1044     memset(test1,0xFE, sizeof(UChar)*6);
   1045     memset(test2,0xFE, sizeof(UChar)*6);
   1046     memset(test3,0xFE, sizeof(UChar)*6);
   1047 
   1048 
   1049     u_uastrcpy(test1, "Abcda");
   1050     u_uastrcpy(test2, "abcda");
   1051     u_uastrcpy(test3, "abcda");
   1052 
   1053     log_verbose("Use tertiary comparison level testing ....\n");
   1054 
   1055     sortklen=ucol_getSortKey(col, test1, u_strlen(test1),  NULL, 0);
   1056     sortk1=(uint8_t*)malloc(sizeof(uint8_t) * (sortklen+1));
   1057     memset(sortk1,0xFE, sortklen);
   1058     ucol_getSortKey(col, test1, u_strlen(test1), sortk1, sortklen+1);
   1059 
   1060     sortklen=ucol_getSortKey(col, test2, u_strlen(test2),  NULL, 0);
   1061     sortk2=(uint8_t*)malloc(sizeof(uint8_t) * (sortklen+1));
   1062     memset(sortk2,0xFE, sortklen);
   1063     ucol_getSortKey(col, test2, u_strlen(test2), sortk2, sortklen+1);
   1064 
   1065     osortklen = sortklen;
   1066     sortklen=ucol_getSortKey(col, test2, u_strlen(test3),  NULL, 0);
   1067     sortk3=(uint8_t*)malloc(sizeof(uint8_t) * (sortklen+1));
   1068     memset(sortk3,0xFE, sortklen);
   1069     ucol_getSortKey(col, test2, u_strlen(test2), sortk3, sortklen+1);
   1070 
   1071     doAssert( (sortklen == osortklen), "Sortkey length should be the same (abcda, abcda)");
   1072 
   1073     doAssert( (memcmp(sortk1, sortk2, sortklen) > 0), "Result should be \"Abcda\" > \"abcda\"");
   1074     doAssert( (memcmp(sortk2, sortk1, sortklen) < 0), "Result should be \"abcda\" < \"Abcda\"");
   1075     doAssert( (memcmp(sortk2, sortk3, sortklen) == 0), "Result should be \"abcda\" ==  \"abcda\"");
   1076 
   1077     resultP = ucol_sortKeyToString(col, sortk3, toStringBuffer, &toStringLen);
   1078     doAssert( (resultP != 0), "sortKeyToString failed!");
   1079 
   1080 #if 1 /* verobse log of sortkeys */
   1081     {
   1082       char junk2[1000];
   1083       char junk3[1000];
   1084       int i;
   1085 
   1086       strcpy(junk2, "abcda[2] ");
   1087       strcpy(junk3, " abcda[3] ");
   1088 
   1089       for(i=0;i<sortklen;i++)
   1090         {
   1091           sprintf(junk2+strlen(junk2), "%02X ",(int)( 0xFF & sortk2[i]));
   1092           sprintf(junk3+strlen(junk3), "%02X ",(int)( 0xFF & sortk3[i]));
   1093         }
   1094 
   1095       log_verbose("%s\n", junk2);
   1096       log_verbose("%s\n", junk3);
   1097     }
   1098 #endif
   1099 
   1100     free(sortk1);
   1101     free(sortk2);
   1102     free(sortk3);
   1103 
   1104     log_verbose("Use secondary comparision level testing ...\n");
   1105     ucol_setStrength(col, UCOL_SECONDARY);
   1106     sortklen=ucol_getSortKey(col, test1, u_strlen(test1),  NULL, 0);
   1107     sortk1=(uint8_t*)malloc(sizeof(uint8_t) * (sortklen+1));
   1108     ucol_getSortKey(col, test1, u_strlen(test1), sortk1, sortklen+1);
   1109     sortklen=ucol_getSortKey(col, test2, u_strlen(test2),  NULL, 0);
   1110     sortk2=(uint8_t*)malloc(sizeof(uint8_t) * (sortklen+1));
   1111     ucol_getSortKey(col, test2, u_strlen(test2), sortk2, sortklen+1);
   1112 
   1113     doAssert( !(memcmp(sortk1, sortk2, sortklen) > 0), "Result should be \"Abcda\" == \"abcda\"");
   1114     doAssert( !(memcmp(sortk2, sortk1, sortklen) < 0), "Result should be \"abcda\" == \"Abcda\"");
   1115     doAssert( (memcmp(sortk1, sortk2, sortklen) == 0), "Result should be \"abcda\" ==  \"abcda\"");
   1116 
   1117     log_verbose("getting sortkey for an empty string\n");
   1118     ucol_setAttribute(col, UCOL_STRENGTH, UCOL_TERTIARY, &status);
   1119     sortklen = ucol_getSortKey(col, test1, 0, NULL, 0);
   1120     sortkEmpty = (uint8_t*)malloc(sizeof(uint8_t) * sortklen+1);
   1121     sortklen = ucol_getSortKey(col, test1, 0, sortkEmpty, sortklen+1);
   1122     if(sortklen != 3 || sortkEmpty[0] != 1 || sortkEmpty[0] != 1 || sortkEmpty[2] != 0) {
   1123       log_err("Empty string generated wrong sortkey!\n");
   1124     }
   1125     free(sortkEmpty);
   1126 
   1127     log_verbose("testing passing invalid string\n");
   1128     sortklen = ucol_getSortKey(col, NULL, 0, NULL, 0);
   1129     if(sortklen != 0) {
   1130       log_err("Invalid string didn't return sortkey size of 0\n");
   1131     }
   1132 
   1133 
   1134     log_verbose("testing sortkey ends...\n");
   1135     ucol_close(col);
   1136     free(test1);
   1137     free(test2);
   1138     free(test3);
   1139     free(sortk1);
   1140     free(sortk2);
   1141 
   1142 }
   1143 void TestHashCode()
   1144 {
   1145     uint8_t *sortk1, *sortk2, *sortk3;
   1146     int32_t sortk1len, sortk2len, sortk3len;
   1147     UCollator *col;
   1148     UChar *test1, *test2, *test3;
   1149     UErrorCode status = U_ZERO_ERROR;
   1150     log_verbose("testing getHashCode begins...\n");
   1151     col = ucol_open("en_US", &status);
   1152     if (U_FAILURE(status)) {
   1153         log_err_status(status, "ERROR: Default collation creation failed.: %s\n", myErrorName(status));
   1154         return;
   1155     }
   1156     test1=(UChar*)malloc(sizeof(UChar) * 6);
   1157     test2=(UChar*)malloc(sizeof(UChar) * 6);
   1158     test3=(UChar*)malloc(sizeof(UChar) * 6);
   1159     u_uastrcpy(test1, "Abcda");
   1160     u_uastrcpy(test2, "abcda");
   1161     u_uastrcpy(test3, "abcda");
   1162 
   1163     log_verbose("Use tertiary comparison level testing ....\n");
   1164     sortk1len=ucol_getSortKey(col, test1, u_strlen(test1),  NULL, 0);
   1165     sortk1=(uint8_t*)malloc(sizeof(uint8_t) * (sortk1len+1));
   1166     ucol_getSortKey(col, test1, u_strlen(test1), sortk1, sortk1len+1);
   1167     sortk2len=ucol_getSortKey(col, test2, u_strlen(test2),  NULL, 0);
   1168     sortk2=(uint8_t*)malloc(sizeof(uint8_t) * (sortk2len+1));
   1169     ucol_getSortKey(col, test2, u_strlen(test2), sortk2, sortk2len+1);
   1170     sortk3len=ucol_getSortKey(col, test2, u_strlen(test3),  NULL, 0);
   1171     sortk3=(uint8_t*)malloc(sizeof(uint8_t) * (sortk3len+1));
   1172     ucol_getSortKey(col, test2, u_strlen(test2), sortk3, sortk3len+1);
   1173 
   1174 
   1175     log_verbose("ucol_hashCode() testing ...\n");
   1176 
   1177     doAssert( ucol_keyHashCode(sortk1, sortk1len) != ucol_keyHashCode(sortk2, sortk2len), "Hash test1 result incorrect" );
   1178     doAssert( !(ucol_keyHashCode(sortk1, sortk1len) == ucol_keyHashCode(sortk2, sortk2len)), "Hash test2 result incorrect" );
   1179     doAssert( ucol_keyHashCode(sortk2, sortk2len) == ucol_keyHashCode(sortk3, sortk3len), "Hash result not equal" );
   1180 
   1181     log_verbose("hashCode tests end.\n");
   1182     ucol_close(col);
   1183     free(sortk1);
   1184     free(sortk2);
   1185     free(sortk3);
   1186     free(test1);
   1187     free(test2);
   1188     free(test3);
   1189 
   1190 
   1191 }
   1192 /*
   1193  *----------------------------------------------------------------------------
   1194  * Tests the UCollatorElements API.
   1195  *
   1196  */
   1197 void TestElemIter()
   1198 {
   1199     int32_t offset;
   1200     int32_t order1, order2, order3;
   1201     UChar *testString1, *testString2;
   1202     UCollator *col;
   1203     UCollationElements *iterator1, *iterator2, *iterator3;
   1204     UErrorCode status = U_ZERO_ERROR;
   1205     log_verbose("testing UCollatorElements begins...\n");
   1206     col = ucol_open("en_US", &status);
   1207     ucol_setAttribute(col, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
   1208     if (U_FAILURE(status)) {
   1209         log_err_status(status, "ERROR: Default collation creation failed.: %s\n", myErrorName(status));
   1210         return;
   1211     }
   1212 
   1213     testString1=(UChar*)malloc(sizeof(UChar) * 150);
   1214     testString2=(UChar*)malloc(sizeof(UChar) * 150);
   1215     u_uastrcpy(testString1, "XFILE What subset of all possible test cases has the highest probability of detecting the most errors?");
   1216     u_uastrcpy(testString2, "Xf_ile What subset of all possible test cases has the lowest probability of detecting the least errors?");
   1217 
   1218     log_verbose("Constructors and comparison testing....\n");
   1219 
   1220     iterator1 = ucol_openElements(col, testString1, u_strlen(testString1), &status);
   1221     if(U_FAILURE(status)) {
   1222         log_err("ERROR: Default collationElement iterator creation failed.: %s\n", myErrorName(status));
   1223         ucol_close(col);
   1224         return;
   1225     }
   1226     else{ log_verbose("PASS: Default collationElement iterator1 creation passed\n");}
   1227 
   1228     iterator2 = ucol_openElements(col, testString1, u_strlen(testString1), &status);
   1229     if(U_FAILURE(status)) {
   1230         log_err("ERROR: Default collationElement iterator creation failed.: %s\n", myErrorName(status));
   1231         ucol_close(col);
   1232         return;
   1233     }
   1234     else{ log_verbose("PASS: Default collationElement iterator2 creation passed\n");}
   1235 
   1236     iterator3 = ucol_openElements(col, testString2, u_strlen(testString2), &status);
   1237     if(U_FAILURE(status)) {
   1238         log_err("ERROR: Default collationElement iterator creation failed.: %s\n", myErrorName(status));
   1239         ucol_close(col);
   1240         return;
   1241     }
   1242     else{ log_verbose("PASS: Default collationElement iterator3 creation passed\n");}
   1243 
   1244     offset=ucol_getOffset(iterator1);
   1245     ucol_setOffset(iterator1, 6, &status);
   1246     if (U_FAILURE(status)) {
   1247         log_err("Error in setOffset for UCollatorElements iterator.: %s\n", myErrorName(status));
   1248         return;
   1249     }
   1250     if(ucol_getOffset(iterator1)==6)
   1251         log_verbose("setOffset and getOffset working fine\n");
   1252     else{
   1253         log_err("error in set and get Offset got %d instead of 6\n", ucol_getOffset(iterator1));
   1254     }
   1255 
   1256     ucol_setOffset(iterator1, 0, &status);
   1257     order1 = ucol_next(iterator1, &status);
   1258     if (U_FAILURE(status)) {
   1259         log_err("Somehow ran out of memory stepping through the iterator1.: %s\n", myErrorName(status));
   1260         return;
   1261     }
   1262     order2=ucol_getOffset(iterator2);
   1263     doAssert((order1 != order2), "The first iterator advance failed");
   1264     order2 = ucol_next(iterator2, &status);
   1265     if (U_FAILURE(status)) {
   1266         log_err("Somehow ran out of memory stepping through the iterator2.: %s\n", myErrorName(status));
   1267         return;
   1268     }
   1269     order3 = ucol_next(iterator3, &status);
   1270     if (U_FAILURE(status)) {
   1271         log_err("Somehow ran out of memory stepping through the iterator3.: %s\n", myErrorName(status));
   1272         return;
   1273     }
   1274 
   1275     doAssert((order1 == order2), "The second iterator advance failed should be the same as first one");
   1276 
   1277 doAssert( (ucol_primaryOrder(order1) == ucol_primaryOrder(order3)), "The primary orders should be identical");
   1278 doAssert( (ucol_secondaryOrder(order1) == ucol_secondaryOrder(order3)), "The secondary orders should be identical");
   1279 doAssert( (ucol_tertiaryOrder(order1) == ucol_tertiaryOrder(order3)), "The tertiary orders should be identical");
   1280 
   1281     order1=ucol_next(iterator1, &status);
   1282     if (U_FAILURE(status)) {
   1283         log_err("Somehow ran out of memory stepping through the iterator2.: %s\n", myErrorName(status));
   1284         return;
   1285     }
   1286     order3=ucol_next(iterator3, &status);
   1287     if (U_FAILURE(status)) {
   1288         log_err("Somehow ran out of memory stepping through the iterator2.: %s\n", myErrorName(status));
   1289         return;
   1290     }
   1291 doAssert( (ucol_primaryOrder(order1) == ucol_primaryOrder(order3)), "The primary orders should be identical");
   1292 doAssert( (ucol_tertiaryOrder(order1) != ucol_tertiaryOrder(order3)), "The tertiary orders should be different");
   1293 
   1294     order1=ucol_next(iterator1, &status);
   1295     if (U_FAILURE(status)) {
   1296         log_err("Somehow ran out of memory stepping through the iterator2.: %s\n", myErrorName(status));
   1297         return;
   1298     }
   1299     order3=ucol_next(iterator3, &status);
   1300     if (U_FAILURE(status)) {
   1301         log_err("Somehow ran out of memory stepping through the iterator2.: %s\n", myErrorName(status));
   1302         return;
   1303     }
   1304     /* this here, my friends, is either pure lunacy or something so obsolete that even it's mother
   1305      * doesn't care about it. Essentialy, this test complains if secondary values for 'I' and '_'
   1306      * are the same. According to the UCA, this is not true. Therefore, remove the test.
   1307      * Besides, if primary strengths for two code points are different, it doesn't matter one bit
   1308      * what is the relation between secondary or any other strengths.
   1309      * killed by weiv 06/11/2002.
   1310      */
   1311     /*
   1312     doAssert( ((order1 & UCOL_SECONDARYMASK) != (order3 & UCOL_SECONDARYMASK)), "The secondary orders should be different");
   1313     */
   1314     doAssert( (order1 != UCOL_NULLORDER), "Unexpected end of iterator reached");
   1315 
   1316     free(testString1);
   1317     free(testString2);
   1318     ucol_closeElements(iterator1);
   1319     ucol_closeElements(iterator2);
   1320     ucol_closeElements(iterator3);
   1321     ucol_close(col);
   1322 
   1323     log_verbose("testing CollationElementIterator ends...\n");
   1324 }
   1325 
   1326 void TestGetLocale() {
   1327   UErrorCode status = U_ZERO_ERROR;
   1328   const char *rules = "&a<x<y<z";
   1329   UChar rlz[256] = {0};
   1330   uint32_t rlzLen = u_unescape(rules, rlz, 256);
   1331 
   1332   UCollator *coll = NULL;
   1333   const char *locale = NULL;
   1334 
   1335   int32_t i = 0;
   1336 
   1337   /* Now that the collation tree is separate, actual==valid at all times. [alan] */
   1338   static const struct {
   1339     const char* requestedLocale;
   1340     const char* validLocale;
   1341     const char* actualLocale;
   1342   } testStruct[] = {
   1343     { "sr_RS", "sr_Cyrl_RS", "sr" },
   1344     { "sh_YU", "sr_Latn_RS", "hr" }, /* this used to be sh, but now sh collation aliases hr */
   1345     { "en_BE_FOO", "en_BE", "root" },
   1346     { "de_DE_NONEXISTANT", "de_DE", "de" }
   1347   };
   1348 
   1349   /* test opening collators for different locales */
   1350   for(i = 0; i<sizeof(testStruct)/sizeof(testStruct[0]); i++) {
   1351     status = U_ZERO_ERROR;
   1352     coll = ucol_open(testStruct[i].requestedLocale, &status);
   1353     if(U_FAILURE(status)) {
   1354       log_err_status(status, "Failed to open collator for %s with %s\n", testStruct[i].requestedLocale, u_errorName(status));
   1355       ucol_close(coll);
   1356       continue;
   1357     }
   1358    locale = ucol_getLocaleByType(coll, ULOC_REQUESTED_LOCALE, &status);
   1359     if(strcmp(locale, testStruct[i].requestedLocale) != 0) {
   1360       log_err("[Coll %s]: Error in requested locale, expected %s, got %s\n", testStruct[i].requestedLocale, testStruct[i].requestedLocale, locale);
   1361     }
   1362     locale = ucol_getLocaleByType(coll, ULOC_VALID_LOCALE, &status);
   1363     if(strcmp(locale, testStruct[i].validLocale) != 0) {
   1364       log_err("[Coll %s]: Error in valid locale, expected %s, got %s\n", testStruct[i].requestedLocale, testStruct[i].validLocale, locale);
   1365     }
   1366     locale = ucol_getLocaleByType(coll, ULOC_ACTUAL_LOCALE, &status);
   1367     if(strcmp(locale, testStruct[i].actualLocale) != 0) {
   1368       log_err("[Coll %s]: Error in actual locale, expected %s, got %s\n", testStruct[i].requestedLocale, testStruct[i].actualLocale, locale);
   1369     }
   1370     ucol_close(coll);
   1371   }
   1372 
   1373   /* completely non-existant locale for collator should get a default collator */
   1374   {
   1375     UCollator *defaultColl = ucol_open(NULL, &status);
   1376     coll = ucol_open("blahaha", &status);
   1377     if(U_SUCCESS(status)) {
   1378       if(strcmp(ucol_getLocaleByType(coll, ULOC_REQUESTED_LOCALE, &status), "blahaha")) {
   1379         log_err("Nonexisting locale didn't preserve the requested locale\n");
   1380       }
   1381       if(strcmp(ucol_getLocaleByType(coll, ULOC_VALID_LOCALE, &status),
   1382         ucol_getLocaleByType(defaultColl, ULOC_VALID_LOCALE, &status))) {
   1383         log_err("Valid locale for nonexisting locale locale collator differs "
   1384           "from valid locale for default collator\n");
   1385       }
   1386       if(strcmp(ucol_getLocaleByType(coll, ULOC_ACTUAL_LOCALE, &status),
   1387         ucol_getLocaleByType(defaultColl, ULOC_ACTUAL_LOCALE, &status))) {
   1388         log_err("Actual locale for nonexisting locale locale collator differs "
   1389           "from actual locale for default collator\n");
   1390       }
   1391       ucol_close(coll);
   1392       ucol_close(defaultColl);
   1393     } else {
   1394       log_data_err("Couldn't open collators\n");
   1395     }
   1396   }
   1397 
   1398 
   1399 
   1400   /* collator instantiated from rules should have all three locales NULL */
   1401   coll = ucol_openRules(rlz, rlzLen, UCOL_DEFAULT, UCOL_DEFAULT, NULL, &status);
   1402   locale = ucol_getLocaleByType(coll, ULOC_REQUESTED_LOCALE, &status);
   1403   if(locale != NULL) {
   1404     log_err("For collator instantiated from rules, requested locale returned %s instead of NULL\n", locale);
   1405   }
   1406   locale = ucol_getLocaleByType(coll, ULOC_VALID_LOCALE, &status);
   1407   if(locale != NULL) {
   1408     log_err("For collator instantiated from rules,  valid locale returned %s instead of NULL\n", locale);
   1409   }
   1410   locale = ucol_getLocaleByType(coll, ULOC_ACTUAL_LOCALE, &status);
   1411   if(locale != NULL) {
   1412     log_err("For collator instantiated from rules, actual locale returned %s instead of NULL\n", locale);
   1413   }
   1414   ucol_close(coll);
   1415 
   1416 }
   1417 
   1418 
   1419 void TestGetAll()
   1420 {
   1421     int32_t i, count;
   1422     count=ucol_countAvailable();
   1423     /* use something sensible w/o hardcoding the count */
   1424     if(count < 0){
   1425         log_err("Error in countAvailable(), it returned %d\n", count);
   1426     }
   1427     else{
   1428         log_verbose("PASS: countAvailable() successful, it returned %d\n", count);
   1429     }
   1430     for(i=0;i<count;i++)
   1431         log_verbose("%s\n", ucol_getAvailable(i));
   1432 
   1433 
   1434 }
   1435 
   1436 
   1437 struct teststruct {
   1438     const char *original;
   1439     uint8_t key[256];
   1440 } ;
   1441 
   1442 static int compare_teststruct(const void *string1, const void *string2) {
   1443     return(strcmp((const char *)((struct teststruct *)string1)->key, (const char *)((struct teststruct *)string2)->key));
   1444 }
   1445 
   1446 void TestBounds() {
   1447     UErrorCode status = U_ZERO_ERROR;
   1448 
   1449     UCollator *coll = ucol_open("sh", &status);
   1450 
   1451     uint8_t sortkey[512], lower[512], upper[512];
   1452     UChar buffer[512];
   1453 
   1454     static const char * const test[] = {
   1455         "John Smith",
   1456         "JOHN SMITH",
   1457         "john SMITH",
   1458         "j\\u00F6hn sm\\u00EFth",
   1459         "J\\u00F6hn Sm\\u00EFth",
   1460         "J\\u00D6HN SM\\u00CFTH",
   1461         "john smithsonian",
   1462         "John Smithsonian",
   1463     };
   1464 
   1465     struct teststruct tests[] = {
   1466         {"\\u010CAKI MIHALJ" } ,
   1467         {"\\u010CAKI MIHALJ" } ,
   1468         {"\\u010CAKI PIRO\\u0160KA" },
   1469         {"\\u010CABAI ANDRIJA" } ,
   1470         {"\\u010CABAI LAJO\\u0160" } ,
   1471         {"\\u010CABAI MARIJA" } ,
   1472         {"\\u010CABAI STEVAN" } ,
   1473         {"\\u010CABAI STEVAN" } ,
   1474         {"\\u010CABARKAPA BRANKO" } ,
   1475         {"\\u010CABARKAPA MILENKO" } ,
   1476         {"\\u010CABARKAPA MIROSLAV" } ,
   1477         {"\\u010CABARKAPA SIMO" } ,
   1478         {"\\u010CABARKAPA STANKO" } ,
   1479         {"\\u010CABARKAPA TAMARA" } ,
   1480         {"\\u010CABARKAPA TOMA\\u0160" } ,
   1481         {"\\u010CABDARI\\u0106 NIKOLA" } ,
   1482         {"\\u010CABDARI\\u0106 ZORICA" } ,
   1483         {"\\u010CABI NANDOR" } ,
   1484         {"\\u010CABOVI\\u0106 MILAN" } ,
   1485         {"\\u010CABRADI AGNEZIJA" } ,
   1486         {"\\u010CABRADI IVAN" } ,
   1487         {"\\u010CABRADI JELENA" } ,
   1488         {"\\u010CABRADI LJUBICA" } ,
   1489         {"\\u010CABRADI STEVAN" } ,
   1490         {"\\u010CABRDA MARTIN" } ,
   1491         {"\\u010CABRILO BOGDAN" } ,
   1492         {"\\u010CABRILO BRANISLAV" } ,
   1493         {"\\u010CABRILO LAZAR" } ,
   1494         {"\\u010CABRILO LJUBICA" } ,
   1495         {"\\u010CABRILO SPASOJA" } ,
   1496         {"\\u010CADE\\u0160 ZDENKA" } ,
   1497         {"\\u010CADESKI BLAGOJE" } ,
   1498         {"\\u010CADOVSKI VLADIMIR" } ,
   1499         {"\\u010CAGLJEVI\\u0106 TOMA" } ,
   1500         {"\\u010CAGOROVI\\u0106 VLADIMIR" } ,
   1501         {"\\u010CAJA VANKA" } ,
   1502         {"\\u010CAJI\\u0106 BOGOLJUB" } ,
   1503         {"\\u010CAJI\\u0106 BORISLAV" } ,
   1504         {"\\u010CAJI\\u0106 RADOSLAV" } ,
   1505         {"\\u010CAK\\u0160IRAN MILADIN" } ,
   1506         {"\\u010CAKAN EUGEN" } ,
   1507         {"\\u010CAKAN EVGENIJE" } ,
   1508         {"\\u010CAKAN IVAN" } ,
   1509         {"\\u010CAKAN JULIJAN" } ,
   1510         {"\\u010CAKAN MIHAJLO" } ,
   1511         {"\\u010CAKAN STEVAN" } ,
   1512         {"\\u010CAKAN VLADIMIR" } ,
   1513         {"\\u010CAKAN VLADIMIR" } ,
   1514         {"\\u010CAKAN VLADIMIR" } ,
   1515         {"\\u010CAKARA ANA" } ,
   1516         {"\\u010CAKAREVI\\u0106 MOMIR" } ,
   1517         {"\\u010CAKAREVI\\u0106 NEDELJKO" } ,
   1518         {"\\u010CAKI \\u0160ANDOR" } ,
   1519         {"\\u010CAKI AMALIJA" } ,
   1520         {"\\u010CAKI ANDRA\\u0160" } ,
   1521         {"\\u010CAKI LADISLAV" } ,
   1522         {"\\u010CAKI LAJO\\u0160" } ,
   1523         {"\\u010CAKI LASLO" } ,
   1524     };
   1525 
   1526 
   1527 
   1528     int32_t i = 0, j = 0, k = 0, buffSize = 0, skSize = 0, lowerSize = 0, upperSize = 0;
   1529     int32_t arraySize = sizeof(tests)/sizeof(tests[0]);
   1530 
   1531     if(U_SUCCESS(status) && coll) {
   1532         for(i = 0; i<arraySize; i++) {
   1533             buffSize = u_unescape(tests[i].original, buffer, 512);
   1534             skSize = ucol_getSortKey(coll, buffer, buffSize, tests[i].key, 512);
   1535         }
   1536 
   1537         qsort(tests, arraySize, sizeof(struct teststruct), compare_teststruct);
   1538 
   1539         for(i = 0; i < arraySize-1; i++) {
   1540             for(j = i+1; j < arraySize; j++) {
   1541                 lowerSize = ucol_getBound(tests[i].key, -1, UCOL_BOUND_LOWER, 1, lower, 512, &status);
   1542                 upperSize = ucol_getBound(tests[j].key, -1, UCOL_BOUND_UPPER, 1, upper, 512, &status);
   1543                 for(k = i; k <= j; k++) {
   1544                     if(strcmp((const char *)lower, (const char *)tests[k].key) > 0) {
   1545                         log_err("Problem with lower! j = %i (%s vs %s)\n", k, tests[k].original, tests[i].original);
   1546                     }
   1547                     if(strcmp((const char *)upper, (const char *)tests[k].key) <= 0) {
   1548                         log_err("Problem with upper! j = %i (%s vs %s)\n", k, tests[k].original, tests[j].original);
   1549                     }
   1550                 }
   1551             }
   1552         }
   1553 
   1554 
   1555 #if 0
   1556         for(i = 0; i < 1000; i++) {
   1557             lowerRND = (rand()/(RAND_MAX/arraySize));
   1558             upperRND = lowerRND + (rand()/(RAND_MAX/(arraySize-lowerRND)));
   1559 
   1560             lowerSize = ucol_getBound(tests[lowerRND].key, -1, UCOL_BOUND_LOWER, 1, lower, 512, &status);
   1561             upperSize = ucol_getBound(tests[upperRND].key, -1, UCOL_BOUND_UPPER_LONG, 1, upper, 512, &status);
   1562 
   1563             for(j = lowerRND; j<=upperRND; j++) {
   1564                 if(strcmp(lower, tests[j].key) > 0) {
   1565                     log_err("Problem with lower! j = %i (%s vs %s)\n", j, tests[j].original, tests[lowerRND].original);
   1566                 }
   1567                 if(strcmp(upper, tests[j].key) <= 0) {
   1568                     log_err("Problem with upper! j = %i (%s vs %s)\n", j, tests[j].original, tests[upperRND].original);
   1569                 }
   1570             }
   1571         }
   1572 #endif
   1573 
   1574 
   1575 
   1576 
   1577 
   1578         for(i = 0; i<sizeof(test)/sizeof(test[0]); i++) {
   1579             buffSize = u_unescape(test[i], buffer, 512);
   1580             skSize = ucol_getSortKey(coll, buffer, buffSize, sortkey, 512);
   1581             lowerSize = ucol_getBound(sortkey, skSize, UCOL_BOUND_LOWER, 1, lower, 512, &status);
   1582             upperSize = ucol_getBound(sortkey, skSize, UCOL_BOUND_UPPER_LONG, 1, upper, 512, &status);
   1583             for(j = i+1; j<sizeof(test)/sizeof(test[0]); j++) {
   1584                 buffSize = u_unescape(test[j], buffer, 512);
   1585                 skSize = ucol_getSortKey(coll, buffer, buffSize, sortkey, 512);
   1586                 if(strcmp((const char *)lower, (const char *)sortkey) > 0) {
   1587                     log_err("Problem with lower! i = %i, j = %i (%s vs %s)\n", i, j, test[i], test[j]);
   1588                 }
   1589                 if(strcmp((const char *)upper, (const char *)sortkey) <= 0) {
   1590                     log_err("Problem with upper! i = %i, j = %i (%s vs %s)\n", i, j, test[i], test[j]);
   1591                 }
   1592             }
   1593         }
   1594         ucol_close(coll);
   1595     } else {
   1596         log_data_err("Couldn't open collator\n");
   1597     }
   1598 
   1599 }
   1600 
   1601 static void doOverrunTest(UCollator *coll, const UChar *uString, int32_t strLen) {
   1602     int32_t skLen = 0, skLen2 = 0;
   1603     uint8_t sortKey[256];
   1604     int32_t i, j;
   1605     uint8_t filler = 0xFF;
   1606 
   1607     skLen = ucol_getSortKey(coll, uString, strLen, NULL, 0);
   1608 
   1609     for(i = 0; i < skLen; i++) {
   1610         memset(sortKey, filler, 256);
   1611         skLen2 = ucol_getSortKey(coll, uString, strLen, sortKey, i);
   1612         if(skLen != skLen2) {
   1613             log_err("For buffer size %i, got different sortkey length. Expected %i got %i\n", i, skLen, skLen2);
   1614         }
   1615         for(j = i; j < 256; j++) {
   1616             if(sortKey[j] != filler) {
   1617                 log_err("Something run over index %i\n", j);
   1618                 break;
   1619             }
   1620         }
   1621     }
   1622 }
   1623 
   1624 /* j1865 reports that if a shorter buffer is passed to
   1625 * to get sort key, a buffer overrun happens in some
   1626 * cases. This test tries to check this.
   1627 */
   1628 void TestSortKeyBufferOverrun(void) {
   1629     UErrorCode status = U_ZERO_ERROR;
   1630     const char* cString = "A very Merry liTTle-lamB..";
   1631     UChar uString[256];
   1632     int32_t strLen = 0;
   1633     UCollator *coll = ucol_open("root", &status);
   1634     strLen = u_unescape(cString, uString, 256);
   1635 
   1636     if(U_SUCCESS(status)) {
   1637         log_verbose("testing non ignorable\n");
   1638         ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status);
   1639         doOverrunTest(coll, uString, strLen);
   1640 
   1641         log_verbose("testing shifted\n");
   1642         ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
   1643         doOverrunTest(coll, uString, strLen);
   1644 
   1645         log_verbose("testing shifted quaternary\n");
   1646         ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_QUATERNARY, &status);
   1647         doOverrunTest(coll, uString, strLen);
   1648 
   1649         log_verbose("testing with french secondaries\n");
   1650         ucol_setAttribute(coll, UCOL_FRENCH_COLLATION, UCOL_ON, &status);
   1651         ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_TERTIARY, &status);
   1652         ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status);
   1653         doOverrunTest(coll, uString, strLen);
   1654 
   1655     }
   1656     ucol_close(coll);
   1657 }
   1658 
   1659 static void TestAttribute()
   1660 {
   1661     UErrorCode error = U_ZERO_ERROR;
   1662     UCollator *coll = ucol_open(NULL, &error);
   1663 
   1664     if (U_FAILURE(error)) {
   1665         log_err_status(error, "Creation of default collator failed\n");
   1666         return;
   1667     }
   1668 
   1669     ucol_setAttribute(coll, UCOL_FRENCH_COLLATION, UCOL_OFF, &error);
   1670     if (ucol_getAttribute(coll, UCOL_FRENCH_COLLATION, &error) != UCOL_OFF ||
   1671         U_FAILURE(error)) {
   1672         log_err_status(error, "Setting and retrieving of the french collation failed\n");
   1673     }
   1674 
   1675     ucol_setAttribute(coll, UCOL_FRENCH_COLLATION, UCOL_ON, &error);
   1676     if (ucol_getAttribute(coll, UCOL_FRENCH_COLLATION, &error) != UCOL_ON ||
   1677         U_FAILURE(error)) {
   1678         log_err_status(error, "Setting and retrieving of the french collation failed\n");
   1679     }
   1680 
   1681     ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &error);
   1682     if (ucol_getAttribute(coll, UCOL_ALTERNATE_HANDLING, &error) != UCOL_SHIFTED ||
   1683         U_FAILURE(error)) {
   1684         log_err_status(error, "Setting and retrieving of the alternate handling failed\n");
   1685     }
   1686 
   1687     ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &error);
   1688     if (ucol_getAttribute(coll, UCOL_ALTERNATE_HANDLING, &error) != UCOL_NON_IGNORABLE ||
   1689         U_FAILURE(error)) {
   1690         log_err_status(error, "Setting and retrieving of the alternate handling failed\n");
   1691     }
   1692 
   1693     ucol_setAttribute(coll, UCOL_CASE_FIRST, UCOL_LOWER_FIRST, &error);
   1694     if (ucol_getAttribute(coll, UCOL_CASE_FIRST, &error) != UCOL_LOWER_FIRST ||
   1695         U_FAILURE(error)) {
   1696         log_err_status(error, "Setting and retrieving of the case first attribute failed\n");
   1697     }
   1698 
   1699     ucol_setAttribute(coll, UCOL_CASE_FIRST, UCOL_UPPER_FIRST, &error);
   1700     if (ucol_getAttribute(coll, UCOL_CASE_FIRST, &error) != UCOL_UPPER_FIRST ||
   1701         U_FAILURE(error)) {
   1702         log_err_status(error, "Setting and retrieving of the case first attribute failed\n");
   1703     }
   1704 
   1705     ucol_setAttribute(coll, UCOL_CASE_LEVEL, UCOL_ON, &error);
   1706     if (ucol_getAttribute(coll, UCOL_CASE_LEVEL, &error) != UCOL_ON ||
   1707         U_FAILURE(error)) {
   1708         log_err_status(error, "Setting and retrieving of the case level attribute failed\n");
   1709     }
   1710 
   1711     ucol_setAttribute(coll, UCOL_CASE_LEVEL, UCOL_OFF, &error);
   1712     if (ucol_getAttribute(coll, UCOL_CASE_LEVEL, &error) != UCOL_OFF ||
   1713         U_FAILURE(error)) {
   1714         log_err_status(error, "Setting and retrieving of the case level attribute failed\n");
   1715     }
   1716 
   1717     ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_ON, &error);
   1718     if (ucol_getAttribute(coll, UCOL_NORMALIZATION_MODE, &error) != UCOL_ON ||
   1719         U_FAILURE(error)) {
   1720         log_err_status(error, "Setting and retrieving of the normalization on/off attribute failed\n");
   1721     }
   1722 
   1723     ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_OFF, &error);
   1724     if (ucol_getAttribute(coll, UCOL_NORMALIZATION_MODE, &error) != UCOL_OFF ||
   1725         U_FAILURE(error)) {
   1726         log_err_status(error, "Setting and retrieving of the normalization on/off attribute failed\n");
   1727     }
   1728 
   1729     ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_PRIMARY, &error);
   1730     if (ucol_getAttribute(coll, UCOL_STRENGTH, &error) != UCOL_PRIMARY ||
   1731         U_FAILURE(error)) {
   1732         log_err_status(error, "Setting and retrieving of the collation strength failed\n");
   1733     }
   1734 
   1735     ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_SECONDARY, &error);
   1736     if (ucol_getAttribute(coll, UCOL_STRENGTH, &error) != UCOL_SECONDARY ||
   1737         U_FAILURE(error)) {
   1738         log_err_status(error, "Setting and retrieving of the collation strength failed\n");
   1739     }
   1740 
   1741     ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_TERTIARY, &error);
   1742     if (ucol_getAttribute(coll, UCOL_STRENGTH, &error) != UCOL_TERTIARY ||
   1743         U_FAILURE(error)) {
   1744         log_err_status(error, "Setting and retrieving of the collation strength failed\n");
   1745     }
   1746 
   1747     ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_QUATERNARY, &error);
   1748     if (ucol_getAttribute(coll, UCOL_STRENGTH, &error) != UCOL_QUATERNARY ||
   1749         U_FAILURE(error)) {
   1750         log_err_status(error, "Setting and retrieving of the collation strength failed\n");
   1751     }
   1752 
   1753     ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_IDENTICAL, &error);
   1754     if (ucol_getAttribute(coll, UCOL_STRENGTH, &error) != UCOL_IDENTICAL ||
   1755         U_FAILURE(error)) {
   1756         log_err_status(error, "Setting and retrieving of the collation strength failed\n");
   1757     }
   1758 
   1759     ucol_close(coll);
   1760 }
   1761 
   1762 void TestGetTailoredSet() {
   1763   struct {
   1764     const char *rules;
   1765     const char *tests[20];
   1766     int32_t testsize;
   1767   } setTest[] = {
   1768     { "&a < \\u212b", { "\\u212b", "A\\u030a", "\\u00c5" }, 3},
   1769     { "& S < \\u0161 <<< \\u0160", { "\\u0161", "s\\u030C", "\\u0160", "S\\u030C" }, 4}
   1770   };
   1771 
   1772   int32_t i = 0, j = 0;
   1773   UErrorCode status = U_ZERO_ERROR;
   1774   UParseError pError;
   1775 
   1776   UCollator *coll = NULL;
   1777   UChar buff[1024];
   1778   int32_t buffLen = 0;
   1779   USet *set = NULL;
   1780 
   1781   for(i = 0; i < sizeof(setTest)/sizeof(setTest[0]); i++) {
   1782     buffLen = u_unescape(setTest[i].rules, buff, 1024);
   1783     coll = ucol_openRules(buff, buffLen, UCOL_DEFAULT, UCOL_DEFAULT, &pError, &status);
   1784     if(U_SUCCESS(status)) {
   1785       set = ucol_getTailoredSet(coll, &status);
   1786       if(uset_size(set) != setTest[i].testsize) {
   1787         log_err("Tailored set size different (%d) than expected (%d)\n", uset_size(set), setTest[i].testsize);
   1788       }
   1789       for(j = 0; j < setTest[i].testsize; j++) {
   1790         buffLen = u_unescape(setTest[i].tests[j], buff, 1024);
   1791         if(!uset_containsString(set, buff, buffLen)) {
   1792           log_err("Tailored set doesn't contain %s... It should\n", setTest[i].tests[j]);
   1793         }
   1794       }
   1795       uset_close(set);
   1796     } else {
   1797       log_err_status(status, "Couldn't open collator with rules %s\n", setTest[i].rules);
   1798     }
   1799     ucol_close(coll);
   1800   }
   1801 }
   1802 
   1803 static int tMemCmp(const uint8_t *first, const uint8_t *second) {
   1804    int32_t firstLen = (int32_t)strlen((const char *)first);
   1805    int32_t secondLen = (int32_t)strlen((const char *)second);
   1806    return memcmp(first, second, uprv_min(firstLen, secondLen));
   1807 }
   1808 static const char * strengthsC[] = {
   1809      "UCOL_PRIMARY",
   1810      "UCOL_SECONDARY",
   1811      "UCOL_TERTIARY",
   1812      "UCOL_QUATERNARY",
   1813      "UCOL_IDENTICAL"
   1814 };
   1815 
   1816 void TestMergeSortKeys(void) {
   1817    UErrorCode status = U_ZERO_ERROR;
   1818    UCollator *coll = ucol_open("en", &status);
   1819    if(U_SUCCESS(status)) {
   1820 
   1821      const char* cases[] = {
   1822        "abc",
   1823          "abcd",
   1824          "abcde"
   1825      };
   1826      uint32_t casesSize = sizeof(cases)/sizeof(cases[0]);
   1827      const char* prefix = "foo";
   1828      const char* suffix = "egg";
   1829      char outBuff1[256], outBuff2[256];
   1830 
   1831      uint8_t **sortkeys = (uint8_t **)malloc(casesSize*sizeof(uint8_t *));
   1832      uint8_t **mergedPrefixkeys = (uint8_t **)malloc(casesSize*sizeof(uint8_t *));
   1833      uint8_t **mergedSuffixkeys = (uint8_t **)malloc(casesSize*sizeof(uint8_t *));
   1834      uint32_t *sortKeysLen = (uint32_t *)malloc(casesSize*sizeof(uint32_t));
   1835      uint8_t prefixKey[256], suffixKey[256];
   1836      uint32_t prefixKeyLen = 0, suffixKeyLen = 0, i = 0;
   1837      UChar buffer[256];
   1838      uint32_t unescapedLen = 0, l1 = 0, l2 = 0;
   1839      UColAttributeValue strength;
   1840 
   1841      log_verbose("ucol_mergeSortkeys test\n");
   1842      log_verbose("Testing order of the test cases\n");
   1843      genericLocaleStarter("en", cases, casesSize);
   1844 
   1845      for(i = 0; i<casesSize; i++) {
   1846        sortkeys[i] = (uint8_t *)malloc(256*sizeof(uint8_t));
   1847        mergedPrefixkeys[i] = (uint8_t *)malloc(256*sizeof(uint8_t));
   1848        mergedSuffixkeys[i] = (uint8_t *)malloc(256*sizeof(uint8_t));
   1849      }
   1850 
   1851      unescapedLen = u_unescape(prefix, buffer, 256);
   1852      prefixKeyLen = ucol_getSortKey(coll, buffer, unescapedLen, prefixKey, 256);
   1853 
   1854      unescapedLen = u_unescape(suffix, buffer, 256);
   1855      suffixKeyLen = ucol_getSortKey(coll, buffer, unescapedLen, suffixKey, 256);
   1856 
   1857      log_verbose("Massaging data with prefixes and different strengths\n");
   1858      strength = UCOL_PRIMARY;
   1859      while(strength <= UCOL_IDENTICAL) {
   1860        log_verbose("Strength %s\n", strengthsC[strength<=UCOL_QUATERNARY?strength:4]);
   1861        ucol_setAttribute(coll, UCOL_STRENGTH, strength, &status);
   1862        for(i = 0; i<casesSize; i++) {
   1863          unescapedLen = u_unescape(cases[i], buffer, 256);
   1864          sortKeysLen[i] = ucol_getSortKey(coll, buffer, unescapedLen, sortkeys[i], 256);
   1865          ucol_mergeSortkeys(prefixKey, prefixKeyLen, sortkeys[i], sortKeysLen[i], mergedPrefixkeys[i], 256);
   1866          ucol_mergeSortkeys(sortkeys[i], sortKeysLen[i], suffixKey, suffixKeyLen, mergedSuffixkeys[i], 256);
   1867          if(i>0) {
   1868            if(tMemCmp(mergedPrefixkeys[i-1], mergedPrefixkeys[i]) >= 0) {
   1869              log_err("Error while comparing prefixed keys @ strength %s:\n", strengthsC[strength<=UCOL_QUATERNARY?strength:4]);
   1870              log_err("%s\n%s\n",
   1871                          ucol_sortKeyToString(coll, mergedPrefixkeys[i-1], outBuff1, &l1),
   1872                          ucol_sortKeyToString(coll, mergedPrefixkeys[i], outBuff2, &l2));
   1873            }
   1874            if(tMemCmp(mergedSuffixkeys[i-1], mergedSuffixkeys[i]) >= 0) {
   1875              log_err("Error while comparing suffixed keys @ strength %s:\n", strengthsC[strength<=UCOL_QUATERNARY?strength:4]);
   1876              log_err("%s\n%s\n",
   1877                          ucol_sortKeyToString(coll, mergedSuffixkeys[i-1], outBuff1, &l1),
   1878                          ucol_sortKeyToString(coll, mergedSuffixkeys[i], outBuff2, &l2));
   1879            }
   1880          }
   1881        }
   1882        if(strength == UCOL_QUATERNARY) {
   1883          strength = UCOL_IDENTICAL;
   1884        } else {
   1885          strength++;
   1886        }
   1887      }
   1888 
   1889      {
   1890        uint8_t smallBuf[3];
   1891        uint32_t reqLen = 0;
   1892        log_verbose("testing buffer overflow\n");
   1893        reqLen = ucol_mergeSortkeys(prefixKey, prefixKeyLen, suffixKey, suffixKeyLen, smallBuf, 3);
   1894        if(reqLen != (prefixKeyLen+suffixKeyLen-1)) {
   1895          log_err("Wrong preflight size for merged sortkey\n");
   1896        }
   1897      }
   1898 
   1899      {
   1900        UChar empty = 0;
   1901        uint8_t emptyKey[20], abcKey[50], mergedKey[100];
   1902        int32_t emptyKeyLen = 0, abcKeyLen = 0, mergedKeyLen = 0;
   1903 
   1904        log_verbose("testing merging with sortkeys generated for empty strings\n");
   1905        emptyKeyLen = ucol_getSortKey(coll, &empty, 0, emptyKey, 20);
   1906        unescapedLen = u_unescape(cases[0], buffer, 256);
   1907        abcKeyLen = ucol_getSortKey(coll, buffer, unescapedLen, abcKey, 50);
   1908        mergedKeyLen = ucol_mergeSortkeys(emptyKey, emptyKeyLen, abcKey, abcKeyLen, mergedKey, 100);
   1909        if(mergedKey[0] != 2) {
   1910          log_err("Empty sortkey didn't produce a level separator\n");
   1911        }
   1912        /* try with zeros */
   1913        mergedKeyLen = ucol_mergeSortkeys(emptyKey, 0, abcKey, abcKeyLen, mergedKey, 100);
   1914        if(mergedKeyLen != 0 || mergedKey[0] != 0) {
   1915          log_err("Empty key didn't produce null mergedKey\n");
   1916        }
   1917        mergedKeyLen = ucol_mergeSortkeys(abcKey, abcKeyLen, emptyKey, 0, mergedKey, 100);
   1918        if(mergedKeyLen != 0 || mergedKey[0] != 0) {
   1919          log_err("Empty key didn't produce null mergedKey\n");
   1920        }
   1921 
   1922      }
   1923 
   1924      for(i = 0; i<casesSize; i++) {
   1925        free(sortkeys[i]);
   1926        free(mergedPrefixkeys[i]);
   1927        free(mergedSuffixkeys[i]);
   1928      }
   1929      free(sortkeys);
   1930      free(mergedPrefixkeys);
   1931      free(mergedSuffixkeys);
   1932      free(sortKeysLen);
   1933      ucol_close(coll);
   1934      /* need to finish this up */
   1935    } else {
   1936      log_data_err("Couldn't open collator");
   1937    }
   1938 }
   1939 static void TestShortString(void)
   1940 {
   1941     struct {
   1942         const char *input;
   1943         const char *expectedOutput;
   1944         const char *locale;
   1945         UErrorCode expectedStatus;
   1946         int32_t    expectedOffset;
   1947         uint32_t   expectedIdentifier;
   1948     } testCases[] = {
   1949         /*
   1950          * The following expectedOutput contains a collation weight (2700 from UCA 6.0)
   1951          * which is the primary weight for the T character (U+0041) in the input.
   1952          * When that character gets a different weight in FractionalUCA.txt,
   1953          * the expectedOutput needs to be adjusted.
   1954          * That is, when we upgrade to a new UCA version or change collation
   1955          * in such a way that the absolute weight for 'A' changes,
   1956          * we will get a test failure here and need to adjust the test case.
   1957          */
   1958         {"LDE_RDE_KPHONEBOOK_T0041_ZLATN","B2700_KPHONEBOOK_LDE", "de@collation=phonebook", U_USING_FALLBACK_WARNING, 0, 0 },
   1959 
   1960         {"LEN_RUS_NO_AS_S4","AS_LROOT_NO_S4", NULL, U_USING_DEFAULT_WARNING, 0, 0 },
   1961         {"LDE_VPHONEBOOK_EO_SI","EO_KPHONEBOOK_LDE_SI", "de@collation=phonebook", U_ZERO_ERROR, 0, 0 },
   1962         {"LDE_Kphonebook","KPHONEBOOK_LDE", "de@collation=phonebook", U_ZERO_ERROR, 0, 0 },
   1963         {"Xqde_DE@collation=phonebookq_S3_EX","KPHONEBOOK_LDE", "de@collation=phonebook", U_USING_FALLBACK_WARNING, 0, 0 },
   1964         {"LFR_FO", "FO_LROOT", NULL, U_USING_DEFAULT_WARNING, 0, 0 },
   1965         {"SO_LX_AS", "", NULL, U_ILLEGAL_ARGUMENT_ERROR, 8, 0 },
   1966         {"S3_ASS_MMM", "", NULL, U_ILLEGAL_ARGUMENT_ERROR, 5, 0 }
   1967     };
   1968 
   1969     int32_t i = 0;
   1970     UCollator *coll = NULL, *fromNormalized = NULL;
   1971     UParseError parseError;
   1972     UErrorCode status = U_ZERO_ERROR;
   1973     char fromShortBuffer[256], normalizedBuffer[256], fromNormalizedBuffer[256];
   1974     const char* locale = NULL;
   1975 
   1976 
   1977     for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
   1978         status = U_ZERO_ERROR;
   1979         if(testCases[i].locale) {
   1980             locale = testCases[i].locale;
   1981         } else {
   1982             locale = NULL;
   1983         }
   1984 
   1985         coll = ucol_openFromShortString(testCases[i].input, FALSE, &parseError, &status);
   1986         if(status != testCases[i].expectedStatus) {
   1987             log_err_status(status, "Got status '%s' that is different from expected '%s' for '%s'\n",
   1988                 u_errorName(status), u_errorName(testCases[i].expectedStatus), testCases[i].input);
   1989             continue;
   1990         }
   1991 
   1992         if(U_SUCCESS(status)) {
   1993             ucol_getShortDefinitionString(coll, locale, fromShortBuffer, 256, &status);
   1994 
   1995             if(strcmp(fromShortBuffer, testCases[i].expectedOutput)) {
   1996                 log_err("Got short string '%s' from the collator. Expected '%s' for input '%s'\n",
   1997                     fromShortBuffer, testCases[i].expectedOutput, testCases[i].input);
   1998             }
   1999 
   2000             ucol_normalizeShortDefinitionString(testCases[i].input, normalizedBuffer, 256, &parseError, &status);
   2001             fromNormalized = ucol_openFromShortString(normalizedBuffer, FALSE, &parseError, &status);
   2002             ucol_getShortDefinitionString(fromNormalized, locale, fromNormalizedBuffer, 256, &status);
   2003 
   2004             if(strcmp(fromShortBuffer, fromNormalizedBuffer)) {
   2005                 log_err("Strings obtained from collators instantiated by short string ('%s') and from normalized string ('%s') differ\n",
   2006                     fromShortBuffer, fromNormalizedBuffer);
   2007             }
   2008 
   2009 
   2010             if(!ucol_equals(coll, fromNormalized)) {
   2011                 log_err("Collator from short string ('%s') differs from one obtained through a normalized version ('%s')\n",
   2012                     testCases[i].input, normalizedBuffer);
   2013             }
   2014 
   2015             ucol_close(fromNormalized);
   2016             ucol_close(coll);
   2017 
   2018         } else {
   2019             if(parseError.offset != testCases[i].expectedOffset) {
   2020                 log_err("Got parse error offset %i, but expected %i instead for '%s'\n",
   2021                     parseError.offset, testCases[i].expectedOffset, testCases[i].input);
   2022             }
   2023         }
   2024     }
   2025 
   2026 }
   2027 
   2028 static void
   2029 doSetsTest(const char *locale, const USet *ref, USet *set, const char* inSet, const char* outSet, UErrorCode *status) {
   2030     UChar buffer[512];
   2031     int32_t bufLen;
   2032 
   2033     uset_clear(set);
   2034     bufLen = u_unescape(inSet, buffer, 512);
   2035     uset_applyPattern(set, buffer, bufLen, 0, status);
   2036     if(U_FAILURE(*status)) {
   2037         log_err("%s: Failure setting pattern %s\n", locale, u_errorName(*status));
   2038     }
   2039 
   2040     if(!uset_containsAll(ref, set)) {
   2041         log_err("%s: Some stuff from %s is not present in the set\n", locale, inSet);
   2042     }
   2043 
   2044     uset_clear(set);
   2045     bufLen = u_unescape(outSet, buffer, 512);
   2046     uset_applyPattern(set, buffer, bufLen, 0, status);
   2047     if(U_FAILURE(*status)) {
   2048         log_err("%s: Failure setting pattern %s\n", locale, u_errorName(*status));
   2049     }
   2050 
   2051     if(!uset_containsNone(ref, set)) {
   2052         log_err("%s: Some stuff from %s is present in the set\n", locale, outSet);
   2053     }
   2054 }
   2055 
   2056 
   2057 
   2058 
   2059 static void
   2060 TestGetContractionsAndUnsafes(void)
   2061 {
   2062     static struct {
   2063         const char* locale;
   2064         const char* inConts;
   2065         const char* outConts;
   2066         const char* inExp;
   2067         const char* outExp;
   2068         const char* unsafeCodeUnits;
   2069         const char* safeCodeUnits;
   2070     } tests[] = {
   2071         { "ru",
   2072             "[{\\u0418\\u0306}{\\u0438\\u0306}]",
   2073             "[\\u0439\\u0457]",
   2074             "[\\u00e6]",
   2075             "[ae]",
   2076             "[\\u0418\\u0438]",
   2077             "[aAbB\\u0430\\u0410\\u0433\\u0413]"
   2078         },
   2079         { "uk",
   2080             "[{\\u0406\\u0308}{\\u0456\\u0308}{\\u0418\\u0306}{\\u0438\\u0306}]",
   2081             "[\\u0407\\u0419\\u0439\\u0457]",
   2082             "[\\u00e6]",
   2083             "[ae]",
   2084             "[\\u0406\\u0456\\u0418\\u0438]",
   2085             "[aAbBxv]",
   2086         },
   2087         { "sh",
   2088             "[{C\\u0301}{C\\u030C}{C\\u0341}{DZ\\u030C}{Dz\\u030C}{D\\u017D}{D\\u017E}{lj}{nj}]",
   2089             "[{\\u309d\\u3099}{\\u30fd\\u3099}]",
   2090             "[\\u00e6]",
   2091             "[a]",
   2092             "[nlcdzNLCDZ]",
   2093             "[jabv]"
   2094         },
   2095         { "ja",
   2096           "[{\\u3053\\u3099\\u309D}{\\u3053\\u3099\\u309D\\u3099}{\\u3053\\u3099\\u309E}{\\u3053\\u3099\\u30FC}{\\u3053\\u309D}{\\u3053\\u309D\\u3099}{\\u3053\\u309E}{\\u3053\\u30FC}{\\u30B3\\u3099\\u30FC}{\\u30B3\\u3099\\u30FD}{\\u30B3\\u3099\\u30FD\\u3099}{\\u30B3\\u3099\\u30FE}{\\u30B3\\u30FC}{\\u30B3\\u30FD}{\\u30B3\\u30FD\\u3099}{\\u30B3\\u30FE}]",
   2097           "[{\\u30FD\\u3099}{\\u309D\\u3099}{\\u3053\\u3099}{\\u30B3\\u3099}{lj}{nj}]",
   2098             "[\\u30FE\\u00e6]",
   2099             "[a]",
   2100             "[\\u3099]",
   2101             "[]"
   2102         }
   2103     };
   2104 
   2105 
   2106 
   2107 
   2108     UErrorCode status = U_ZERO_ERROR;
   2109     UCollator *coll = NULL;
   2110     int32_t i = 0;
   2111     int32_t noConts = 0;
   2112     USet *conts = uset_open(0,0);
   2113     USet *exp = uset_open(0, 0);
   2114     USet *set  = uset_open(0,0);
   2115     int32_t setBufferLen = 65536;
   2116     UChar buffer[65536];
   2117     int32_t setLen = 0;
   2118 
   2119     for(i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
   2120         log_verbose("Testing locale: %s\n", tests[i].locale);
   2121         coll = ucol_open(tests[i].locale, &status);
   2122         if (coll == NULL || U_FAILURE(status)) {
   2123             log_err_status(status, "Unable to open collator for locale %s ==> %s\n", tests[i].locale, u_errorName(status));
   2124             continue;
   2125         }
   2126         ucol_getContractionsAndExpansions(coll, conts, exp, TRUE, &status);
   2127         doSetsTest(tests[i].locale, conts, set, tests[i].inConts, tests[i].outConts, &status);
   2128         setLen = uset_toPattern(conts, buffer, setBufferLen, TRUE, &status);
   2129         if(U_SUCCESS(status)) {
   2130             /*log_verbose("Contractions %i: %s\n", uset_getItemCount(conts), aescstrdup(buffer, setLen));*/
   2131         } else {
   2132             log_err("error %s. %i\n", u_errorName(status), setLen);
   2133             status = U_ZERO_ERROR;
   2134         }
   2135         doSetsTest(tests[i].locale, exp, set, tests[i].inExp, tests[i].outExp, &status);
   2136         setLen = uset_toPattern(exp, buffer, setBufferLen, TRUE, &status);
   2137         if(U_SUCCESS(status)) {
   2138             /*log_verbose("Expansions %i: %s\n", uset_getItemCount(exp), aescstrdup(buffer, setLen));*/
   2139         } else {
   2140             log_err("error %s. %i\n", u_errorName(status), setLen);
   2141             status = U_ZERO_ERROR;
   2142         }
   2143 
   2144         noConts = ucol_getUnsafeSet(coll, conts, &status);
   2145         doSetsTest(tests[i].locale, conts, set, tests[i].unsafeCodeUnits, tests[i].safeCodeUnits, &status);
   2146         setLen = uset_toPattern(conts, buffer, setBufferLen, TRUE, &status);
   2147         if(U_SUCCESS(status)) {
   2148             log_verbose("Unsafe %i: %s\n", uset_getItemCount(exp), aescstrdup(buffer, setLen));
   2149         } else {
   2150             log_err("error %s. %i\n", u_errorName(status), setLen);
   2151             status = U_ZERO_ERROR;
   2152         }
   2153 
   2154         ucol_close(coll);
   2155     }
   2156 
   2157 
   2158     uset_close(conts);
   2159     uset_close(exp);
   2160     uset_close(set);
   2161 }
   2162 
   2163 static void
   2164 TestOpenBinary(void)
   2165 {
   2166     UErrorCode status = U_ZERO_ERROR;
   2167     /*
   2168     char rule[] = "&h < d < c < b";
   2169     char *wUCA[] = { "a", "h", "d", "c", "b", "i" };
   2170     char *noUCA[] = {"d", "c", "b", "a", "h", "i" };
   2171     */
   2172     /* we have to use Cyrillic letters because latin-1 always gets copied */
   2173     const char rule[] = "&\\u0452 < \\u0434 < \\u0433 < \\u0432"; /* &dje < d < g < v */
   2174     const char *wUCA[] = { "\\u0430", "\\u0452", "\\u0434", "\\u0433", "\\u0432", "\\u0435" }; /* a, dje, d, g, v, e */
   2175     const char *noUCA[] = {"\\u0434", "\\u0433", "\\u0432", "\\u0430", "\\u0435", "\\u0452" }; /* d, g, v, a, e, dje */
   2176 
   2177     UChar uRules[256];
   2178     int32_t uRulesLen = u_unescape(rule, uRules, 256);
   2179 
   2180     UCollator *coll = ucol_openRules(uRules, uRulesLen, UCOL_DEFAULT, UCOL_DEFAULT, NULL, &status);
   2181     UCollator *UCA = NULL;
   2182     UCollator *cloneNOUCA = NULL, *cloneWUCA = NULL;
   2183 
   2184     uint8_t imageBuffer[32768];
   2185     uint8_t *image = imageBuffer;
   2186     int32_t imageBufferCapacity = 32768;
   2187 
   2188     int32_t imageSize;
   2189 
   2190     if((coll==NULL)||(U_FAILURE(status))) {
   2191         log_data_err("could not load collators or error occured: %s\n",
   2192             u_errorName(status));
   2193         return;
   2194     }
   2195     UCA = ucol_open("root", &status);
   2196     if((UCA==NULL)||(U_FAILURE(status))) {
   2197         log_data_err("could not load UCA collator or error occured: %s\n",
   2198             u_errorName(status));
   2199         return;
   2200     }
   2201     imageSize = ucol_cloneBinary(coll, image, imageBufferCapacity, &status);
   2202     if(U_FAILURE(status)) {
   2203         image = (uint8_t *)malloc(imageSize*sizeof(uint8_t));
   2204         status = U_ZERO_ERROR;
   2205         imageSize = ucol_cloneBinary(coll, imageBuffer, imageSize, &status);
   2206     }
   2207 
   2208 
   2209     cloneWUCA = ucol_openBinary(image, imageSize, UCA, &status);
   2210     cloneNOUCA = ucol_openBinary(image, imageSize, NULL, &status);
   2211 
   2212     genericOrderingTest(coll, wUCA, sizeof(wUCA)/sizeof(wUCA[0]));
   2213 
   2214     genericOrderingTest(cloneWUCA, wUCA, sizeof(wUCA)/sizeof(wUCA[0]));
   2215     genericOrderingTest(cloneNOUCA, noUCA, sizeof(noUCA)/sizeof(noUCA[0]));
   2216 
   2217     if(image != imageBuffer) {
   2218         free(image);
   2219     }
   2220     ucol_close(coll);
   2221     ucol_close(cloneNOUCA);
   2222     ucol_close(cloneWUCA);
   2223     ucol_close(UCA);
   2224 }
   2225 
   2226 static void TestDefault(void) {
   2227     /* Tests for code coverage. */
   2228     UErrorCode status = U_ZERO_ERROR;
   2229     UCollator *coll = ucol_open("es@collation=pinyin", &status);
   2230     if (coll == NULL || status == U_FILE_ACCESS_ERROR) {
   2231         log_data_err("Unable to open collator es@collation=pinyin\n");
   2232         return;
   2233     }
   2234     if (status != U_USING_DEFAULT_WARNING) {
   2235         /* What do you mean that you know about using pinyin collation in Spanish!? This should be in the zh locale. */
   2236         log_err("es@collation=pinyin should return U_USING_DEFAULT_WARNING, but returned %s\n", u_errorName(status));
   2237     }
   2238     ucol_close(coll);
   2239     if (ucol_getKeywordValues("funky", &status) != NULL) {
   2240         log_err("Collators should not know about the funky keyword.\n");
   2241     }
   2242     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
   2243         log_err("funky keyword didn't fail as expected %s\n", u_errorName(status));
   2244     }
   2245     if (ucol_getKeywordValues("collation", &status) != NULL) {
   2246         log_err("ucol_getKeywordValues should not work when given a bad status.\n");
   2247     }
   2248 }
   2249 
   2250 static void TestDefaultKeyword(void) {
   2251     /* Tests for code coverage. */
   2252     UErrorCode status = U_ZERO_ERROR;
   2253     const char *loc = "zh_TW@collation=default";
   2254     UCollator *coll = ucol_open(loc, &status);
   2255     if(U_FAILURE(status)) {
   2256         log_info("Warning: ucol_open(%s, ...) returned %s, at least it didn't crash.\n", loc, u_errorName(status));
   2257     } else if (status != U_USING_FALLBACK_WARNING) {
   2258         /* Hmm, skip the following test for CLDR 1.9 data and/or ICU 4.6, no longer seems to apply */
   2259         #if 0
   2260         log_err("ucol_open(%s, ...) should return an error or some sort of U_USING_FALLBACK_WARNING, but returned %s\n", loc, u_errorName(status));
   2261         #endif
   2262     }
   2263     ucol_close(coll);
   2264 }
   2265 
   2266 static void TestGetKeywordValuesForLocale(void) {
   2267 #define INCLUDE_UNIHAN_COLLATION 0
   2268 #define PREFERRED_SIZE 16
   2269 #define MAX_NUMBER_OF_KEYWORDS 8
   2270     const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS+1] = {
   2271             { "und",            "standard", "ducet", "search", NULL, NULL, NULL, NULL, NULL },
   2272             { "en_US",          "standard", "ducet", "search", NULL, NULL, NULL, NULL, NULL },
   2273             { "en_029",         "standard", "ducet", "search", NULL, NULL, NULL, NULL, NULL },
   2274             { "de_DE",          "standard", "phonebook", "search", "ducet", NULL, NULL, NULL, NULL },
   2275             { "de_Latn_DE",     "standard", "phonebook", "search", "ducet", NULL, NULL, NULL, NULL },
   2276 #if INCLUDE_UNIHAN_COLLATION
   2277             { "zh",             "pinyin", "big5han", "gb2312han", "standard", "stroke", "unihan", "ducet", "search" },
   2278             { "zh_Hans",        "pinyin", "big5han", "gb2312han", "standard", "stroke", "unihan", "ducet", "search" },
   2279             { "zh_CN",          "pinyin", "big5han", "gb2312han", "standard", "stroke", "unihan", "ducet", "search" },
   2280             { "zh_Hant",        "stroke", "big5han", "gb2312han", "pinyin", "standard", "unihan", "ducet", "search" },
   2281             { "zh_TW",          "stroke", "big5han", "gb2312han", "pinyin", "standard", "unihan", "ducet", "search" },
   2282             { "zh__PINYIN",     "pinyin", "big5han", "gb2312han", "standard", "stroke", "unihan", "ducet", "search" },
   2283 #else
   2284             { "zh",             "pinyin", "big5han", "gb2312han", "standard", "stroke", "ducet", "search", NULL },
   2285             { "zh_Hans",        "pinyin", "big5han", "gb2312han", "standard", "stroke", "ducet", "search", NULL },
   2286             { "zh_CN",          "pinyin", "big5han", "gb2312han", "standard", "stroke", "ducet", "search", NULL },
   2287             { "zh_Hant",        "stroke", "big5han", "gb2312han", "pinyin", "standard", "ducet", "search", NULL },
   2288             { "zh_TW",          "stroke", "big5han", "gb2312han", "pinyin", "standard", "ducet", "search", NULL },
   2289             { "zh__PINYIN",     "pinyin", "big5han", "gb2312han", "standard", "stroke", "ducet", "search", NULL },
   2290 #endif
   2291             { "es_ES",          "standard", "search", "traditional", "ducet", NULL, NULL, NULL, NULL },
   2292             { "es__TRADITIONAL","traditional", "search", "standard", "ducet", NULL, NULL, NULL, NULL },
   2293             { "und@collation=phonebook",    "standard", "ducet", "search", NULL, NULL, NULL, NULL, NULL },
   2294             { "de_DE@collation=big5han",    "standard", "phonebook", "search", "ducet", NULL, NULL, NULL, NULL },
   2295             { "zzz@collation=xxx",          "standard", "ducet", "search", NULL, NULL, NULL, NULL, NULL }
   2296     };
   2297 #if INCLUDE_UNIHAN_COLLATION
   2298     const int32_t expectedLength[PREFERRED_SIZE] = { 3, 3, 3, 4, 4, 8, 8, 8, 8, 8, 8, 4, 4, 3, 4, 3 };
   2299 #else
   2300     const int32_t expectedLength[PREFERRED_SIZE] = { 3, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 4, 4, 3, 4, 3 };
   2301 #endif
   2302 
   2303     UErrorCode status = U_ZERO_ERROR;
   2304     UEnumeration *keywordValues = NULL;
   2305     int32_t i, n, size, valueLength;
   2306     const char *locale = NULL, *value = NULL;
   2307     UBool errorOccurred = FALSE;
   2308 
   2309     for (i = 0; i < PREFERRED_SIZE; i++) {
   2310         locale = PREFERRED[i][0];
   2311         value = NULL;
   2312         valueLength = 0;
   2313         size = 0;
   2314 
   2315         keywordValues = ucol_getKeywordValuesForLocale("collation", locale, TRUE, &status);
   2316         if (keywordValues == NULL || U_FAILURE(status)) {
   2317             log_err_status(status, "Error getting keyword values: %s\n", u_errorName(status));
   2318             break;
   2319         }
   2320         size = uenum_count(keywordValues, &status);
   2321 
   2322         if (size == expectedLength[i]) {
   2323             for (n = 0; n < expectedLength[i]; n++) {
   2324                 if ((value = uenum_next(keywordValues, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
   2325                     if (uprv_strcmp(value, PREFERRED[i][n+1]) != 0) {
   2326                         log_err("Keyword values differ: Got [%s] Expected [%s] for locale: %s\n", value, PREFERRED[i][n+1], locale);
   2327                         errorOccurred = TRUE;
   2328                         break;
   2329                     }
   2330 
   2331                 } else {
   2332                     log_err("While getting keyword value from locale: %s got this error: %s\n", locale, u_errorName(status));
   2333                     errorOccurred = TRUE;
   2334                     break;
   2335                 }
   2336             }
   2337             if (errorOccurred) {
   2338                 break;
   2339             }
   2340         } else {
   2341             log_err("Number of keywords (%d) does not match expected size (%d) for locale: %s\n", size, expectedLength[i], locale);
   2342             break;
   2343         }
   2344         uenum_close(keywordValues);
   2345         keywordValues = NULL;
   2346     }
   2347     if (keywordValues != NULL) {
   2348         uenum_close(keywordValues);
   2349     }
   2350 }
   2351 
   2352 
   2353 #endif /* #if !UCONFIG_NO_COLLATION */
   2354