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