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