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