Home | History | Annotate | Download | only in cintltst
      1 /********************************************************************
      2  * Copyright (c) 2001-2009 International Business Machines
      3  * Corporation and others. All Rights Reserved.
      4  ********************************************************************
      5  * File usrchtst.c
      6  * Modification History:
      7  * Name           Date             Description
      8  * synwee         July 19 2001     creation
      9  ********************************************************************/
     10 
     11 #include "unicode/utypes.h"
     12 
     13 #if !UCONFIG_NO_COLLATION && !UCONFIG_NO_BREAK_ITERATION
     14 
     15 #include "unicode/usearch.h"
     16 #include "unicode/ustring.h"
     17 #include "ccolltst.h"
     18 #include "cmemory.h"
     19 #include <stdio.h>
     20 #include "usrchdat.c"
     21 #include "unicode/ubrk.h"
     22 #include <assert.h>
     23 
     24 static UBool      TOCLOSE_ = TRUE;
     25 static UCollator *EN_US_;
     26 static UCollator *FR_FR_;
     27 static UCollator *DE_;
     28 static UCollator *ES_;
     29 
     30 /**
     31  * CHECK_BREAK(char *brk)
     32  *     Test if a break iterator is passed in AND break iteration is disabled.
     33  *     Skip the test if so.
     34  * CHECK_BREAK_BOOL(char *brk)
     35  *     Same as above, but returns 'TRUE' as a passing result
     36  */
     37 
     38 #if !UCONFIG_NO_BREAK_ITERATION
     39 static UBreakIterator *EN_WORDBREAKER_;
     40 static UBreakIterator *EN_CHARACTERBREAKER_;
     41 #define CHECK_BREAK(x)
     42 #define CHECK_BREAK_BOOL(x)
     43 #else
     44 #define CHECK_BREAK(x)  if(x) { log_info("Skipping test on %s:%d because UCONFIG_NO_BREAK_ITERATION is on\n", __FILE__, __LINE__); return; }
     45 #define CHECK_BREAK_BOOL(x)  if(x) { log_info("Skipping test on %s:%d because UCONFIG_NO_BREAK_ITERATION is on\n", __FILE__, __LINE__); return TRUE; }
     46 #endif
     47 
     48 /**
     49 * Opening all static collators and break iterators
     50 */
     51 static void open(UErrorCode* status)
     52 {
     53     if (TOCLOSE_) {
     54         UChar      rules[1024];
     55         int32_t    rulelength = 0;
     56         *status = U_ZERO_ERROR;
     57 
     58         EN_US_ = ucol_open("en_US", status);
     59         if(U_FAILURE(*status)) {
     60           log_err_status(*status, "Error opening collator\n");
     61           return;
     62         }
     63         FR_FR_ = ucol_open("fr_FR", status);
     64         DE_ = ucol_open("de_DE", status);
     65         ES_ = ucol_open("es_ES", status);
     66 
     67         u_strcpy(rules, ucol_getRules(DE_, &rulelength));
     68         u_unescape(EXTRACOLLATIONRULE, rules + rulelength, 1024 - rulelength);
     69 
     70         ucol_close(DE_);
     71 
     72         DE_ = ucol_openRules(rules, u_strlen(rules), UCOL_ON, UCOL_TERTIARY,
     73                              (UParseError *)NULL, status);
     74         u_strcpy(rules, ucol_getRules(ES_, &rulelength));
     75         u_unescape(EXTRACOLLATIONRULE, rules + rulelength, 1024 - rulelength);
     76 
     77         ucol_close(ES_);
     78         ES_ = ucol_openRules(rules, u_strlen(rules), UCOL_ON, UCOL_TERTIARY,
     79                              NULL, status);
     80 #if !UCONFIG_NO_BREAK_ITERATION
     81         EN_WORDBREAKER_     = ubrk_open(UBRK_WORD, "en_US", NULL, 0, status);
     82         EN_CHARACTERBREAKER_ = ubrk_open(UBRK_CHARACTER, "en_US", NULL, 0,
     83                                         status);
     84 #endif
     85         TOCLOSE_ = TRUE;
     86     }
     87 }
     88 
     89 /**
     90 * Start opening all static collators and break iterators
     91 */
     92 static void TestStart(void)
     93 {
     94     UErrorCode status = U_ZERO_ERROR;
     95     open(&status);
     96     if (U_FAILURE(status)) {
     97         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
     98         return;
     99     }
    100     TOCLOSE_ = FALSE;
    101 }
    102 
    103 /**
    104 * Closing all static collators and break iterators
    105 */
    106 static void close(void)
    107 {
    108     if (TOCLOSE_) {
    109         ucol_close(EN_US_);
    110         ucol_close(FR_FR_);
    111         ucol_close(DE_);
    112         ucol_close(ES_);
    113 #if !UCONFIG_NO_BREAK_ITERATION
    114         ubrk_close(EN_WORDBREAKER_);
    115         ubrk_close(EN_CHARACTERBREAKER_);
    116 #endif
    117     }
    118     TOCLOSE_ = FALSE;
    119 }
    120 
    121 /**
    122 * End closing all static collators and break iterators
    123 */
    124 static void TestEnd(void)
    125 {
    126     TOCLOSE_ = TRUE;
    127     close();
    128     TOCLOSE_ = TRUE;
    129 }
    130 
    131 /**
    132 * output UChar strings for printing.
    133 */
    134 static char *toCharString(const UChar* unichars)
    135 {
    136     static char result[1024];
    137     char *temp   = result;
    138     int   count  = 0;
    139     int   length = u_strlen(unichars);
    140 
    141     for (; count < length; count ++) {
    142         UChar ch = unichars[count];
    143         if (ch >= 0x20 && ch <= 0x7e) {
    144             *temp ++ = (char)ch;
    145         }
    146         else {
    147             sprintf(temp, "\\u%04x", ch);
    148             temp += 6; /* \uxxxx */
    149         }
    150     }
    151     *temp = 0;
    152 
    153     return result;
    154 }
    155 
    156 /**
    157 * Getting the collator
    158 */
    159 static UCollator *getCollator(const char *collator)
    160 {
    161     if (collator == NULL) {
    162         return EN_US_;
    163     }
    164     if (strcmp(collator, "fr") == 0) {
    165         return FR_FR_;
    166     }
    167     else if (strcmp(collator, "de") == 0) {
    168         return DE_;
    169     }
    170     else if (strcmp(collator, "es") == 0) {
    171         return ES_;
    172     }
    173     else {
    174         return EN_US_;
    175     }
    176 }
    177 
    178 /**
    179 * Getting the breakiterator
    180 */
    181 static UBreakIterator *getBreakIterator(const char *breaker)
    182 {
    183     if (breaker == NULL) {
    184         return NULL;
    185     }
    186 #if !UCONFIG_NO_BREAK_ITERATION
    187     if (strcmp(breaker, "wordbreaker") == 0) {
    188         return EN_WORDBREAKER_;
    189     }
    190     else {
    191         return EN_CHARACTERBREAKER_;
    192     }
    193 #else
    194     return NULL;
    195 #endif
    196 }
    197 
    198 static void TestOpenClose(void)
    199 {
    200           UErrorCode      status    = U_ZERO_ERROR;
    201           UStringSearch  *result;
    202     const UChar           pattern[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
    203     const UChar           text[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67};
    204 #if !UCONFIG_NO_BREAK_ITERATION
    205           UBreakIterator *breakiter = ubrk_open(UBRK_WORD, "en_US",
    206                                                 text, 6, &status);
    207 #endif
    208     /* testing null arguments */
    209     result = usearch_open(NULL, 0, NULL, 0, NULL, NULL, &status);
    210     if (U_SUCCESS(status) || result != NULL) {
    211         log_err("Error: NULL arguments should produce an error and a NULL result\n");
    212     }
    213     status = U_ZERO_ERROR;
    214     result = usearch_openFromCollator(NULL, 0, NULL, 0, NULL, NULL, &status);
    215     if (U_SUCCESS(status) || result != NULL) {
    216         log_err("Error: NULL arguments should produce an error and a NULL result\n");
    217     }
    218 
    219     status = U_ZERO_ERROR;
    220     result = usearch_open(pattern, 3, NULL, 0, NULL, NULL, &status);
    221     if (U_SUCCESS(status) || result != NULL) {
    222         log_err("Error: NULL arguments should produce an error and a NULL result\n");
    223     }
    224     status = U_ZERO_ERROR;
    225     result = usearch_openFromCollator(pattern, 3, NULL, 0, NULL, NULL,
    226                                       &status);
    227     if (U_SUCCESS(status) || result != NULL) {
    228         log_err("Error: NULL arguments should produce an error and a NULL result\n");
    229     }
    230 
    231     status = U_ZERO_ERROR;
    232     result = usearch_open(pattern, 3, text, 6, NULL, NULL, &status);
    233     if (U_SUCCESS(status) || result != NULL) {
    234         log_err("Error: NULL arguments should produce an error and a NULL result\n");
    235     }
    236     status = U_ZERO_ERROR;
    237     result = usearch_openFromCollator(pattern, 3, text, 6, NULL, NULL,
    238                                       &status);
    239     if (U_SUCCESS(status) || result != NULL) {
    240         log_err("Error: NULL arguments should produce an error and a NULL result\n");
    241     }
    242 
    243     status = U_ZERO_ERROR;
    244     result = usearch_open(pattern, 3, text, 6, "en_US", NULL, &status);
    245     if (U_FAILURE(status) || result == NULL) {
    246         log_err_status(status, "Error: NULL break iterator is valid for opening search\n");
    247     }
    248     else {
    249         usearch_close(result);
    250     }
    251     open(&status);
    252     if (U_FAILURE(status)) {
    253         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
    254         return;
    255     }
    256     status = U_ZERO_ERROR;
    257     result = usearch_openFromCollator(pattern, 3, text, 6, EN_US_, NULL,
    258                                       &status);
    259     if (U_FAILURE(status) || result == NULL) {
    260         if (EN_US_ == NULL) {
    261             log_data_err("Opening collator failed.\n");
    262         } else {
    263             log_err("Error: NULL break iterator is valid for opening search\n");
    264         }
    265     }
    266     else {
    267         usearch_close(result);
    268     }
    269 
    270 
    271     status = U_ZERO_ERROR;
    272 #if !UCONFIG_NO_BREAK_ITERATION
    273 
    274     result = usearch_open(pattern, 3, text, 6, "en_US", breakiter, &status);
    275     if (U_FAILURE(status) || result == NULL) {
    276         log_err_status(status, "Error: Break iterator is valid for opening search\n");
    277     }
    278     else {
    279         usearch_close(result);
    280     }
    281     status = U_ZERO_ERROR;
    282     result = usearch_openFromCollator(pattern, 3, text, 6, EN_US_, breakiter,
    283                                       &status);
    284     if (U_FAILURE(status) || result == NULL) {
    285         if (EN_US_ == NULL) {
    286             log_data_err("Opening collator failed.\n");
    287         } else {
    288             log_err("Error: Break iterator is valid for opening search\n");
    289         }
    290     }
    291     else {
    292         usearch_close(result);
    293     }
    294     ubrk_close(breakiter);
    295 #endif
    296     close();
    297 }
    298 
    299 static void TestInitialization(void)
    300 {
    301           UErrorCode      status = U_ZERO_ERROR;
    302           UChar           pattern[512];
    303     const UChar           text[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
    304     int32_t i = 0;
    305     UStringSearch  *result;
    306 
    307     /* simple test on the pattern ce construction */
    308     pattern[0] = 0x41;
    309     pattern[1] = 0x42;
    310     open(&status);
    311     if (U_FAILURE(status)) {
    312         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
    313         return;
    314     }
    315     result = usearch_openFromCollator(pattern, 2, text, 3, EN_US_, NULL,
    316                                       &status);
    317     if (U_FAILURE(status)) {
    318         log_err("Error opening search %s\n", u_errorName(status));
    319     }
    320     usearch_close(result);
    321 
    322     /* testing if an extremely large pattern will fail the initialization */
    323     for(i = 0; i < 512; i++) {
    324       pattern[i] = 0x41;
    325     }
    326     /*uprv_memset(pattern, 0x41, 512);*/
    327     result = usearch_openFromCollator(pattern, 512, text, 3, EN_US_, NULL,
    328                                       &status);
    329     if (U_FAILURE(status)) {
    330         log_err("Error opening search %s\n", u_errorName(status));
    331     }
    332     usearch_close(result);
    333     close();
    334 }
    335 
    336 static UBool assertEqualWithUStringSearch(      UStringSearch *strsrch,
    337                                           const SearchData     search)
    338 {
    339     int         count       = 0;
    340     int         matchlimit  = 0;
    341     UErrorCode  status      = U_ZERO_ERROR;
    342     int32_t matchindex  = search.offset[count];
    343     int32_t     textlength;
    344     UChar       matchtext[128];
    345 
    346     if (usearch_getMatchedStart(strsrch) != USEARCH_DONE ||
    347         usearch_getMatchedLength(strsrch) != 0) {
    348         log_err("Error with the initialization of match start and length\n");
    349     }
    350     /* start of following matches */
    351     while (U_SUCCESS(status) && matchindex >= 0) {
    352         uint32_t matchlength = search.size[count];
    353         usearch_next(strsrch, &status);
    354         if (matchindex != usearch_getMatchedStart(strsrch) ||
    355             matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
    356             char *str = toCharString(usearch_getText(strsrch, &textlength));
    357             log_err("Text: %s\n", str);
    358             str = toCharString(usearch_getPattern(strsrch, &textlength));
    359             log_err("Pattern: %s\n", str);
    360             log_err("Error following match found at %d %d\n",
    361                     usearch_getMatchedStart(strsrch),
    362                     usearch_getMatchedLength(strsrch));
    363             return FALSE;
    364         }
    365         count ++;
    366 
    367         if (usearch_getMatchedText(strsrch, matchtext, 128, &status) !=
    368             (int32_t) matchlength || U_FAILURE(status) ||
    369             memcmp(matchtext,
    370                    usearch_getText(strsrch, &textlength) + matchindex,
    371                    matchlength * sizeof(UChar)) != 0) {
    372             log_err("Error getting following matched text\n");
    373         }
    374 
    375         matchindex = search.offset[count];
    376     }
    377     usearch_next(strsrch, &status);
    378     if (usearch_getMatchedStart(strsrch) != USEARCH_DONE ||
    379         usearch_getMatchedLength(strsrch) != 0) {
    380         char *str = toCharString(usearch_getText(strsrch, &textlength));
    381         log_err("Text: %s\n", str);
    382         str = toCharString(usearch_getPattern(strsrch, &textlength));
    383         log_err("Pattern: %s\n", str);
    384         log_err("Error following match found at %d %d\n",
    385                     usearch_getMatchedStart(strsrch),
    386                     usearch_getMatchedLength(strsrch));
    387         return FALSE;
    388     }
    389     /* start of preceding matches */
    390     count = count == 0 ? 0 : count - 1;
    391     matchlimit = count;
    392     matchindex = search.offset[count];
    393 
    394     while (U_SUCCESS(status) && matchindex >= 0) {
    395         uint32_t matchlength = search.size[count];
    396         usearch_previous(strsrch, &status);
    397         if (matchindex != usearch_getMatchedStart(strsrch) ||
    398             matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
    399             char *str = toCharString(usearch_getText(strsrch, &textlength));
    400             log_err("Text: %s\n", str);
    401             str = toCharString(usearch_getPattern(strsrch, &textlength));
    402             log_err("Pattern: %s\n", str);
    403             log_err("Error preceding match found at %d %d\n",
    404                     usearch_getMatchedStart(strsrch),
    405                     usearch_getMatchedLength(strsrch));
    406             return FALSE;
    407         }
    408 
    409         if (usearch_getMatchedText(strsrch, matchtext, 128, &status) !=
    410             (int32_t) matchlength || U_FAILURE(status) ||
    411             memcmp(matchtext,
    412                    usearch_getText(strsrch, &textlength) + matchindex,
    413                    matchlength * sizeof(UChar)) != 0) {
    414             log_err("Error getting preceding matched text\n");
    415         }
    416 
    417         matchindex = count > 0 ? search.offset[count - 1] : -1;
    418         count --;
    419     }
    420     usearch_previous(strsrch, &status);
    421     if (usearch_getMatchedStart(strsrch) != USEARCH_DONE ||
    422         usearch_getMatchedLength(strsrch) != 0) {
    423         char *str = toCharString(usearch_getText(strsrch, &textlength));
    424         log_err("Text: %s\n", str);
    425         str = toCharString(usearch_getPattern(strsrch, &textlength));
    426         log_err("Pattern: %s\n", str);
    427         log_err("Error preceding match found at %d %d\n",
    428                     usearch_getMatchedStart(strsrch),
    429                     usearch_getMatchedLength(strsrch));
    430         return FALSE;
    431     }
    432 
    433     return TRUE;
    434 }
    435 
    436 static UBool assertEqual(const SearchData search)
    437 {
    438     UErrorCode      status      = U_ZERO_ERROR;
    439     UChar           pattern[32];
    440     UChar           text[128];
    441     UCollator      *collator = getCollator(search.collator);
    442     UBreakIterator *breaker  = getBreakIterator(search.breaker);
    443     UStringSearch  *strsrch;
    444 
    445     CHECK_BREAK_BOOL(search.breaker);
    446 
    447     u_unescape(search.text, text, 128);
    448     u_unescape(search.pattern, pattern, 32);
    449     ucol_setStrength(collator, search.strength);
    450     strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
    451                                        breaker, &status);
    452     if (U_FAILURE(status)) {
    453         log_err("Error opening string search %s\n", u_errorName(status));
    454         return FALSE;
    455     }
    456 
    457     if (!assertEqualWithUStringSearch(strsrch, search)) {
    458         ucol_setStrength(collator, UCOL_TERTIARY);
    459         usearch_close(strsrch);
    460         return FALSE;
    461     }
    462     ucol_setStrength(collator, UCOL_TERTIARY);
    463     usearch_close(strsrch);
    464     return TRUE;
    465 }
    466 
    467 static UBool assertCanonicalEqual(const SearchData search)
    468 {
    469     UErrorCode      status      = U_ZERO_ERROR;
    470     UChar           pattern[32];
    471     UChar           text[128];
    472     UCollator      *collator = getCollator(search.collator);
    473     UBreakIterator *breaker  = getBreakIterator(search.breaker);
    474     UStringSearch  *strsrch;
    475     UBool           result = TRUE;
    476 
    477     CHECK_BREAK_BOOL(search.breaker);
    478     u_unescape(search.text, text, 128);
    479     u_unescape(search.pattern, pattern, 32);
    480     ucol_setStrength(collator, search.strength);
    481     ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
    482     strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
    483                                        breaker, &status);
    484     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
    485                          &status);
    486     if (U_FAILURE(status)) {
    487         log_err("Error opening string search %s\n", u_errorName(status));
    488         result = FALSE;
    489         goto bail;
    490     }
    491 
    492     if (!assertEqualWithUStringSearch(strsrch, search)) {
    493         ucol_setStrength(collator, UCOL_TERTIARY);
    494         usearch_close(strsrch);
    495         result = FALSE;
    496         goto bail;
    497     }
    498 
    499 bail:
    500     ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
    501     ucol_setStrength(collator, UCOL_TERTIARY);
    502     usearch_close(strsrch);
    503     return result;
    504 }
    505 
    506 static UBool assertEqualWithAttribute(const SearchData            search,
    507                                             USearchAttributeValue canonical,
    508                                             USearchAttributeValue overlap)
    509 {
    510     UErrorCode      status      = U_ZERO_ERROR;
    511     UChar           pattern[32];
    512     UChar           text[128];
    513     UCollator      *collator = getCollator(search.collator);
    514     UBreakIterator *breaker  = getBreakIterator(search.breaker);
    515     UStringSearch  *strsrch;
    516 
    517     CHECK_BREAK_BOOL(search.breaker);
    518     u_unescape(search.text, text, 128);
    519     u_unescape(search.pattern, pattern, 32);
    520     ucol_setStrength(collator, search.strength);
    521     strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
    522                                        breaker, &status);
    523     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, canonical,
    524                          &status);
    525     usearch_setAttribute(strsrch, USEARCH_OVERLAP, overlap, &status);
    526 
    527     if (U_FAILURE(status)) {
    528         log_err("Error opening string search %s\n", u_errorName(status));
    529         return FALSE;
    530     }
    531 
    532     if (!assertEqualWithUStringSearch(strsrch, search)) {
    533             ucol_setStrength(collator, UCOL_TERTIARY);
    534             usearch_close(strsrch);
    535             return FALSE;
    536     }
    537     ucol_setStrength(collator, UCOL_TERTIARY);
    538     usearch_close(strsrch);
    539     return TRUE;
    540 }
    541 
    542 static void TestBasic(void)
    543 {
    544     int count = 0;
    545     UErrorCode status = U_ZERO_ERROR;
    546     open(&status);
    547     if (U_FAILURE(status)) {
    548         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
    549         return;
    550     }
    551     while (BASIC[count].text != NULL) {
    552         if (!assertEqual(BASIC[count])) {
    553             log_err("Error at test number %d\n", count);
    554         }
    555         count ++;
    556     }
    557     close();
    558 }
    559 
    560 static void TestNormExact(void)
    561 {
    562     int count = 0;
    563     UErrorCode status = U_ZERO_ERROR;
    564     open(&status);
    565     if (U_FAILURE(status)) {
    566         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
    567         return;
    568     }
    569     ucol_setAttribute(EN_US_, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
    570     if (U_FAILURE(status)) {
    571         log_err("Error setting collation normalization %s\n",
    572             u_errorName(status));
    573     }
    574     while (BASIC[count].text != NULL) {
    575         if (!assertEqual(BASIC[count])) {
    576             log_err("Error at test number %d\n", count);
    577         }
    578         count ++;
    579     }
    580     count = 0;
    581     while (NORMEXACT[count].text != NULL) {
    582         if (!assertEqual(NORMEXACT[count])) {
    583             log_err("Error at test number %d\n", count);
    584         }
    585         count ++;
    586     }
    587     ucol_setAttribute(EN_US_, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
    588     count = 0;
    589     while (NONNORMEXACT[count].text != NULL) {
    590         if (!assertEqual(NONNORMEXACT[count])) {
    591             log_err("Error at test number %d\n", count);
    592         }
    593         count ++;
    594     }
    595     close();
    596 }
    597 
    598 static void TestStrength(void)
    599 {
    600     int count = 0;
    601     UErrorCode status = U_ZERO_ERROR;
    602     open(&status);
    603     if (U_FAILURE(status)) {
    604         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
    605         return;
    606     }
    607     while (STRENGTH[count].text != NULL) {
    608         if (!assertEqual(STRENGTH[count])) {
    609             log_err("Error at test number %d\n", count);
    610         }
    611         count ++;
    612     }
    613     close();
    614 }
    615 
    616 static void TestBreakIterator(void) {
    617     UErrorCode      status      = U_ZERO_ERROR;
    618     UStringSearch  *strsrch;
    619     UChar           text[128];
    620     UChar           pattern[32];
    621     int             count = 0;
    622 
    623     CHECK_BREAK("x");
    624 
    625 #if !UCONFIG_NO_BREAK_ITERATION
    626     open(&status);
    627     if (U_FAILURE(status)) {
    628         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
    629         return;
    630     }
    631     if (usearch_getBreakIterator(NULL) != NULL) {
    632         log_err("Expected NULL breakiterator from NULL string search\n");
    633     }
    634     u_unescape(BREAKITERATOREXACT[0].text, text, 128);
    635     u_unescape(BREAKITERATOREXACT[0].pattern, pattern, 32);
    636     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_, NULL,
    637                                        &status);
    638     if (U_FAILURE(status)) {
    639         log_err("Error opening string search %s\n", u_errorName(status));
    640         goto ENDTESTBREAKITERATOR;
    641     }
    642 
    643     usearch_setBreakIterator(strsrch, NULL, &status);
    644     if (U_FAILURE(status) || usearch_getBreakIterator(strsrch) != NULL) {
    645         log_err("Error usearch_getBreakIterator returned wrong object");
    646         goto ENDTESTBREAKITERATOR;
    647     }
    648 
    649     usearch_setBreakIterator(strsrch, EN_CHARACTERBREAKER_, &status);
    650     if (U_FAILURE(status) ||
    651         usearch_getBreakIterator(strsrch) != EN_CHARACTERBREAKER_) {
    652         log_err("Error usearch_getBreakIterator returned wrong object");
    653         goto ENDTESTBREAKITERATOR;
    654     }
    655 
    656     usearch_setBreakIterator(strsrch, EN_WORDBREAKER_, &status);
    657     if (U_FAILURE(status) ||
    658         usearch_getBreakIterator(strsrch) != EN_WORDBREAKER_) {
    659         log_err("Error usearch_getBreakIterator returned wrong object");
    660         goto ENDTESTBREAKITERATOR;
    661     }
    662 
    663     usearch_close(strsrch);
    664 
    665     count = 0;
    666     while (count < 4) {
    667         /* 0-3 test are fixed */
    668         const SearchData     *search   = &(BREAKITERATOREXACT[count]);
    669               UCollator      *collator = getCollator(search->collator);
    670               UBreakIterator *breaker  = getBreakIterator(search->breaker);
    671 
    672         u_unescape(search->text, text, 128);
    673         u_unescape(search->pattern, pattern, 32);
    674         ucol_setStrength(collator, search->strength);
    675 
    676         strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
    677                                            breaker, &status);
    678         if (U_FAILURE(status) ||
    679             usearch_getBreakIterator(strsrch) != breaker) {
    680             log_err("Error setting break iterator\n");
    681             if (strsrch != NULL) {
    682                 usearch_close(strsrch);
    683             }
    684         }
    685         if (!assertEqualWithUStringSearch(strsrch, *search)) {
    686             ucol_setStrength(collator, UCOL_TERTIARY);
    687             usearch_close(strsrch);
    688             goto ENDTESTBREAKITERATOR;
    689         }
    690         search   = &(BREAKITERATOREXACT[count + 1]);
    691         breaker  = getBreakIterator(search->breaker);
    692         usearch_setBreakIterator(strsrch, breaker, &status);
    693         if (U_FAILURE(status) || usearch_getBreakIterator(strsrch) != breaker) {
    694             log_err("Error setting break iterator\n");
    695             usearch_close(strsrch);
    696             goto ENDTESTBREAKITERATOR;
    697         }
    698         usearch_reset(strsrch);
    699         if (!assertEqualWithUStringSearch(strsrch, *search)) {
    700             log_err("Error at test number %d\n", count);
    701             usearch_close(strsrch);
    702             goto ENDTESTBREAKITERATOR;
    703         }
    704         usearch_close(strsrch);
    705         count += 2;
    706     }
    707     count = 0;
    708     while (BREAKITERATOREXACT[count].text != NULL) {
    709          if (!assertEqual(BREAKITERATOREXACT[count])) {
    710              log_err("Error at test number %d\n", count);
    711              goto ENDTESTBREAKITERATOR;
    712          }
    713          count ++;
    714     }
    715 
    716 ENDTESTBREAKITERATOR:
    717     close();
    718 #endif
    719 }
    720 
    721 static void TestVariable(void)
    722 {
    723     int count = 0;
    724     UErrorCode status = U_ZERO_ERROR;
    725     open(&status);
    726     if (U_FAILURE(status)) {
    727         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
    728         return;
    729     }
    730     ucol_setAttribute(EN_US_, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
    731     if (U_FAILURE(status)) {
    732         log_err("Error setting collation alternate attribute %s\n",
    733             u_errorName(status));
    734     }
    735     while (VARIABLE[count].text != NULL) {
    736         log_verbose("variable %d\n", count);
    737         if (!assertEqual(VARIABLE[count])) {
    738             log_err("Error at test number %d\n", count);
    739         }
    740         count ++;
    741     }
    742     ucol_setAttribute(EN_US_, UCOL_ALTERNATE_HANDLING,
    743                       UCOL_NON_IGNORABLE, &status);
    744     close();
    745 }
    746 
    747 static void TestOverlap(void)
    748 {
    749     int count = 0;
    750     UErrorCode status = U_ZERO_ERROR;
    751     open(&status);
    752     if (U_FAILURE(status)) {
    753         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
    754         return;
    755     }
    756     while (OVERLAP[count].text != NULL) {
    757         if (!assertEqualWithAttribute(OVERLAP[count], USEARCH_OFF,
    758                                       USEARCH_ON)) {
    759             log_err("Error at overlap test number %d\n", count);
    760         }
    761         count ++;
    762     }
    763     count = 0;
    764     while (NONOVERLAP[count].text != NULL) {
    765         if (!assertEqual(NONOVERLAP[count])) {
    766             log_err("Error at non overlap test number %d\n", count);
    767         }
    768         count ++;
    769     }
    770 
    771     count = 0;
    772     while (count < 1) {
    773               UChar           pattern[32];
    774               UChar           text[128];
    775         const SearchData     *search   = &(OVERLAP[count]);
    776               UCollator      *collator = getCollator(search->collator);
    777               UStringSearch  *strsrch;
    778               status   = U_ZERO_ERROR;
    779 
    780         u_unescape(search->text, text, 128);
    781         u_unescape(search->pattern, pattern, 32);
    782         strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
    783                                            NULL, &status);
    784         if(status == U_FILE_ACCESS_ERROR) {
    785           log_data_err("Is your data around?\n");
    786           return;
    787         } else if(U_FAILURE(status)) {
    788           log_err("Error opening searcher\n");
    789           return;
    790         }
    791         usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_ON, &status);
    792         if (U_FAILURE(status) ||
    793             usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_ON) {
    794             log_err("Error setting overlap option\n");
    795         }
    796         if (!assertEqualWithUStringSearch(strsrch, *search)) {
    797             usearch_close(strsrch);
    798             return;
    799         }
    800         search   = &(NONOVERLAP[count]);
    801         usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_OFF, &status);
    802         if (U_FAILURE(status) ||
    803             usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF) {
    804             log_err("Error setting overlap option\n");
    805         }
    806         usearch_reset(strsrch);
    807         if (!assertEqualWithUStringSearch(strsrch, *search)) {
    808             usearch_close(strsrch);
    809             log_err("Error at test number %d\n", count);
    810          }
    811 
    812         count ++;
    813         usearch_close(strsrch);
    814     }
    815     close();
    816 }
    817 
    818 static void TestCollator(void)
    819 {
    820     /* test collator that thinks "o" and "p" are the same thing */
    821           UChar          rules[32];
    822           UCollator     *tailored = NULL;
    823           UErrorCode     status   = U_ZERO_ERROR;
    824           UChar          pattern[32];
    825           UChar          text[128];
    826           UStringSearch *strsrch;
    827 
    828     text[0] = 0x41;
    829     text[1] = 0x42;
    830     text[2] = 0x43;
    831     text[3] = 0x44;
    832     text[4] = 0x45;
    833     pattern[0] = 0x62;
    834     pattern[1] = 0x63;
    835     strsrch  = usearch_open(pattern, 2, text, 5, "en_US",  NULL,  &status);
    836     if(status == U_FILE_ACCESS_ERROR) {
    837       log_data_err("Is your data around?\n");
    838       return;
    839     } else if(U_FAILURE(status)) {
    840       log_err("Error opening searcher\n");
    841       return;
    842     }
    843     tailored = usearch_getCollator(strsrch);
    844     if (usearch_next(strsrch, &status) != -1) {
    845         log_err("Error: Found case insensitive match, when we shouldn't\n");
    846     }
    847     ucol_setStrength(tailored, UCOL_PRIMARY);
    848     usearch_reset(strsrch);
    849     if (usearch_next(strsrch, &status) != 1) {
    850         log_err("Error: Found case insensitive match not found\n");
    851     }
    852     usearch_close(strsrch);
    853 
    854     open(&status);
    855 
    856     if (usearch_getCollator(NULL) != NULL) {
    857         log_err("Expected NULL collator from NULL string search\n");
    858     }
    859     u_unescape(COLLATOR[0].text, text, 128);
    860     u_unescape(COLLATOR[0].pattern, pattern, 32);
    861 
    862     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
    863                                        NULL, &status);
    864     if (U_FAILURE(status)) {
    865         log_err("Error opening string search %s\n", u_errorName(status));
    866     }
    867     if (!assertEqualWithUStringSearch(strsrch, COLLATOR[0])) {
    868         goto ENDTESTCOLLATOR;
    869     }
    870 
    871     u_unescape(TESTCOLLATORRULE, rules, 32);
    872     tailored = ucol_openRules(rules, -1, UCOL_ON, COLLATOR[1].strength,
    873                               NULL, &status);
    874     if (U_FAILURE(status)) {
    875         log_err("Error opening rule based collator %s\n", u_errorName(status));
    876     }
    877 
    878     usearch_setCollator(strsrch, tailored, &status);
    879     if (U_FAILURE(status) || usearch_getCollator(strsrch) != tailored) {
    880         log_err("Error setting rule based collator\n");
    881     }
    882     usearch_reset(strsrch);
    883     if (!assertEqualWithUStringSearch(strsrch, COLLATOR[1])) {
    884         goto ENDTESTCOLLATOR;
    885     }
    886 
    887     usearch_setCollator(strsrch, EN_US_, &status);
    888     usearch_reset(strsrch);
    889     if (U_FAILURE(status) || usearch_getCollator(strsrch) != EN_US_) {
    890         log_err("Error setting rule based collator\n");
    891     }
    892     if (!assertEqualWithUStringSearch(strsrch, COLLATOR[0])) {
    893         goto ENDTESTCOLLATOR;
    894     }
    895 
    896 ENDTESTCOLLATOR:
    897     usearch_close(strsrch);
    898     if (tailored != NULL) {
    899         ucol_close(tailored);
    900     }
    901     close();
    902 }
    903 
    904 static void TestPattern(void)
    905 {
    906           UStringSearch *strsrch;
    907           UChar          pattern[32];
    908           UChar          bigpattern[512];
    909           UChar          text[128];
    910     const UChar         *temp;
    911           int32_t        templength;
    912           UErrorCode     status = U_ZERO_ERROR;
    913 
    914     open(&status);
    915     if (U_FAILURE(status)) {
    916         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
    917         return;
    918     }
    919     if (usearch_getPattern(NULL, &templength) != NULL) {
    920         log_err("Error NULL string search expected returning NULL pattern\n");
    921     }
    922     usearch_setPattern(NULL, pattern, 3, &status);
    923     if (U_SUCCESS(status)) {
    924         log_err("Error expected setting pattern in NULL strings search\n");
    925     }
    926     status = U_ZERO_ERROR;
    927     u_unescape(PATTERN[0].text, text, 128);
    928     u_unescape(PATTERN[0].pattern, pattern, 32);
    929 
    930     ucol_setStrength(EN_US_, PATTERN[0].strength);
    931     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
    932                                        NULL, &status);
    933     if(status == U_FILE_ACCESS_ERROR) {
    934       log_data_err("Is your data around?\n");
    935       return;
    936     } else if(U_FAILURE(status)) {
    937       log_err("Error opening searcher\n");
    938       return;
    939     }
    940 
    941     status = U_ZERO_ERROR;
    942     usearch_setPattern(strsrch, NULL, 3, &status);
    943     if (U_SUCCESS(status)) {
    944         log_err("Error expected setting NULL pattern in strings search\n");
    945     }
    946     status = U_ZERO_ERROR;
    947     usearch_setPattern(strsrch, pattern, 0, &status);
    948     if (U_SUCCESS(status)) {
    949         log_err("Error expected setting pattern with length 0 in strings search\n");
    950     }
    951     status = U_ZERO_ERROR;
    952     if (U_FAILURE(status)) {
    953         log_err("Error opening string search %s\n", u_errorName(status));
    954         goto ENDTESTPATTERN;
    955     }
    956     temp = usearch_getPattern(strsrch, &templength);
    957     if (u_strcmp(pattern, temp) != 0) {
    958         log_err("Error setting pattern\n");
    959     }
    960     if (!assertEqualWithUStringSearch(strsrch, PATTERN[0])) {
    961         goto ENDTESTPATTERN;
    962     }
    963 
    964     u_unescape(PATTERN[1].pattern, pattern, 32);
    965     usearch_setPattern(strsrch, pattern, -1, &status);
    966     temp = usearch_getPattern(strsrch, &templength);
    967     if (u_strcmp(pattern, temp) != 0) {
    968         log_err("Error setting pattern\n");
    969         goto ENDTESTPATTERN;
    970     }
    971     usearch_reset(strsrch);
    972     if (U_FAILURE(status)) {
    973         log_err("Error setting pattern %s\n", u_errorName(status));
    974     }
    975     if (!assertEqualWithUStringSearch(strsrch, PATTERN[1])) {
    976         goto ENDTESTPATTERN;
    977     }
    978 
    979     u_unescape(PATTERN[0].pattern, pattern, 32);
    980     usearch_setPattern(strsrch, pattern, -1, &status);
    981     temp = usearch_getPattern(strsrch, &templength);
    982     if (u_strcmp(pattern, temp) != 0) {
    983         log_err("Error setting pattern\n");
    984         goto ENDTESTPATTERN;
    985     }
    986     usearch_reset(strsrch);
    987     if (U_FAILURE(status)) {
    988         log_err("Error setting pattern %s\n", u_errorName(status));
    989     }
    990     if (!assertEqualWithUStringSearch(strsrch, PATTERN[0])) {
    991         goto ENDTESTPATTERN;
    992     }
    993     /* enormous pattern size to see if this crashes */
    994     for (templength = 0; templength != 512; templength ++) {
    995         bigpattern[templength] = 0x61;
    996     }
    997     bigpattern[511] = 0;
    998     usearch_setPattern(strsrch, bigpattern, -1, &status);
    999     if (U_FAILURE(status)) {
   1000         log_err("Error setting pattern with size 512, %s \n",
   1001             u_errorName(status));
   1002     }
   1003 ENDTESTPATTERN:
   1004     ucol_setStrength(EN_US_, UCOL_TERTIARY);
   1005     if (strsrch != NULL) {
   1006         usearch_close(strsrch);
   1007     }
   1008     close();
   1009 }
   1010 
   1011 static void TestText(void)
   1012 {
   1013           UStringSearch *strsrch;
   1014           UChar          pattern[32];
   1015           UChar          text[128];
   1016     const UChar         *temp;
   1017           int32_t        templength;
   1018           UErrorCode     status = U_ZERO_ERROR;
   1019 
   1020     u_unescape(TEXT[0].text, text, 128);
   1021     u_unescape(TEXT[0].pattern, pattern, 32);
   1022 
   1023     open(&status);
   1024     if (U_FAILURE(status)) {
   1025         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1026         return;
   1027     }
   1028 
   1029     if (usearch_getText(NULL, &templength) != NULL) {
   1030         log_err("Error NULL string search should return NULL text\n");
   1031     }
   1032 
   1033     usearch_setText(NULL, text, 10, &status);
   1034     if (U_SUCCESS(status)) {
   1035         log_err("Error NULL string search should have an error when setting text\n");
   1036     }
   1037 
   1038     status = U_ZERO_ERROR;
   1039     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
   1040                                        NULL, &status);
   1041 
   1042     if (U_FAILURE(status)) {
   1043         log_err("Error opening string search %s\n", u_errorName(status));
   1044         goto ENDTESTPATTERN;
   1045     }
   1046     temp = usearch_getText(strsrch, &templength);
   1047     if (u_strcmp(text, temp) != 0) {
   1048         log_err("Error setting text\n");
   1049     }
   1050     if (!assertEqualWithUStringSearch(strsrch, TEXT[0])) {
   1051         goto ENDTESTPATTERN;
   1052     }
   1053 
   1054     u_unescape(TEXT[1].text, text, 32);
   1055     usearch_setText(strsrch, text, -1, &status);
   1056     temp = usearch_getText(strsrch, &templength);
   1057     if (u_strcmp(text, temp) != 0) {
   1058         log_err("Error setting text\n");
   1059         goto ENDTESTPATTERN;
   1060     }
   1061     if (U_FAILURE(status)) {
   1062         log_err("Error setting text %s\n", u_errorName(status));
   1063     }
   1064     if (!assertEqualWithUStringSearch(strsrch, TEXT[1])) {
   1065         goto ENDTESTPATTERN;
   1066     }
   1067 
   1068     u_unescape(TEXT[0].text, text, 32);
   1069     usearch_setText(strsrch, text, -1, &status);
   1070     temp = usearch_getText(strsrch, &templength);
   1071     if (u_strcmp(text, temp) != 0) {
   1072         log_err("Error setting text\n");
   1073         goto ENDTESTPATTERN;
   1074     }
   1075     if (U_FAILURE(status)) {
   1076         log_err("Error setting pattern %s\n", u_errorName(status));
   1077     }
   1078     if (!assertEqualWithUStringSearch(strsrch, TEXT[0])) {
   1079         goto ENDTESTPATTERN;
   1080     }
   1081 ENDTESTPATTERN:
   1082     if (strsrch != NULL) {
   1083         usearch_close(strsrch);
   1084     }
   1085     close();
   1086 }
   1087 
   1088 static void TestCompositeBoundaries(void)
   1089 {
   1090     int count = 0;
   1091     UErrorCode status = U_ZERO_ERROR;
   1092     open(&status);
   1093     if (U_FAILURE(status)) {
   1094         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1095         return;
   1096     }
   1097     while (COMPOSITEBOUNDARIES[count].text != NULL) {
   1098         log_verbose("composite %d\n", count);
   1099         if (!assertEqual(COMPOSITEBOUNDARIES[count])) {
   1100             log_err("Error at test number %d\n", count);
   1101         }
   1102         count ++;
   1103     }
   1104     close();
   1105 }
   1106 
   1107 static void TestGetSetOffset(void)
   1108 {
   1109     int            index   = 0;
   1110     UChar          pattern[32];
   1111     UChar          text[128];
   1112     UErrorCode     status  = U_ZERO_ERROR;
   1113     UStringSearch *strsrch;
   1114     memset(pattern, 0, 32*sizeof(UChar));
   1115     memset(text, 0, 128*sizeof(UChar));
   1116 
   1117     open(&status);
   1118     if (U_FAILURE(status)) {
   1119         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1120         return;
   1121     }
   1122     if (usearch_getOffset(NULL) != USEARCH_DONE) {
   1123         log_err("usearch_getOffset(NULL) expected USEARCH_DONE\n");
   1124     }
   1125     strsrch = usearch_openFromCollator(pattern, 16, text, 32, EN_US_, NULL,
   1126                                        &status);
   1127     /* testing out of bounds error */
   1128     usearch_setOffset(strsrch, -1, &status);
   1129     if (U_SUCCESS(status)) {
   1130         log_err("Error expecting set offset error\n");
   1131     }
   1132     usearch_setOffset(strsrch, 128, &status);
   1133     if (U_SUCCESS(status)) {
   1134         log_err("Error expecting set offset error\n");
   1135     }
   1136     while (BASIC[index].text != NULL) {
   1137         int         count       = 0;
   1138         SearchData  search      = BASIC[index ++];
   1139         int32_t matchindex  = search.offset[count];
   1140         int32_t     textlength;
   1141 
   1142         u_unescape(search.text, text, 128);
   1143         u_unescape(search.pattern, pattern, 32);
   1144         status = U_ZERO_ERROR;
   1145         usearch_setText(strsrch, text, -1, &status);
   1146         usearch_setPattern(strsrch, pattern, -1, &status);
   1147         ucol_setStrength(usearch_getCollator(strsrch), search.strength);
   1148         usearch_reset(strsrch);
   1149         while (U_SUCCESS(status) && matchindex >= 0) {
   1150             uint32_t matchlength = search.size[count];
   1151             usearch_next(strsrch, &status);
   1152             if (matchindex != usearch_getMatchedStart(strsrch) ||
   1153                 matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
   1154                 char *str = toCharString(usearch_getText(strsrch,
   1155                                                          &textlength));
   1156                 log_err("Text: %s\n", str);
   1157                 str = toCharString(usearch_getPattern(strsrch, &textlength));
   1158                 log_err("Pattern: %s\n", str);
   1159                 log_err("Error match found at %d %d\n",
   1160                         usearch_getMatchedStart(strsrch),
   1161                         usearch_getMatchedLength(strsrch));
   1162                 return;
   1163             }
   1164             usearch_setOffset(strsrch, matchindex + matchlength, &status);
   1165             usearch_previous(strsrch, &status);
   1166             if (matchindex != usearch_getMatchedStart(strsrch) ||
   1167                 matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
   1168                 char *str = toCharString(usearch_getText(strsrch,
   1169                                                          &textlength));
   1170                 log_err("Text: %s\n", str);
   1171                 str = toCharString(usearch_getPattern(strsrch, &textlength));
   1172                 log_err("Pattern: %s\n", str);
   1173                 log_err("Error match found at %d %d\n",
   1174                         usearch_getMatchedStart(strsrch),
   1175                         usearch_getMatchedLength(strsrch));
   1176                 return;
   1177             }
   1178             usearch_setOffset(strsrch, matchindex + matchlength, &status);
   1179             matchindex = search.offset[count + 1] == -1 ? -1 :
   1180                          search.offset[count + 2];
   1181             if (search.offset[count + 1] != -1) {
   1182                 usearch_setOffset(strsrch, search.offset[count + 1] + 1,
   1183                                   &status);
   1184                 if (usearch_getOffset(strsrch) != search.offset[count + 1] + 1) {
   1185                     log_err("Error setting offset\n");
   1186                     return;
   1187                 }
   1188             }
   1189 
   1190             count += 2;
   1191         }
   1192         usearch_next(strsrch, &status);
   1193         if (usearch_getMatchedStart(strsrch) != USEARCH_DONE) {
   1194             char *str = toCharString(usearch_getText(strsrch, &textlength));
   1195             log_err("Text: %s\n", str);
   1196             str = toCharString(usearch_getPattern(strsrch, &textlength));
   1197             log_err("Pattern: %s\n", str);
   1198             log_err("Error match found at %d %d\n",
   1199                         usearch_getMatchedStart(strsrch),
   1200                         usearch_getMatchedLength(strsrch));
   1201             return;
   1202         }
   1203     }
   1204     ucol_setStrength(usearch_getCollator(strsrch), UCOL_TERTIARY);
   1205     usearch_close(strsrch);
   1206     close();
   1207 }
   1208 
   1209 static void TestGetSetAttribute(void)
   1210 {
   1211     UErrorCode      status    = U_ZERO_ERROR;
   1212     UChar           pattern[32];
   1213     UChar           text[128];
   1214     UStringSearch  *strsrch;
   1215 
   1216     memset(pattern, 0, 32*sizeof(UChar));
   1217     memset(text, 0, 128*sizeof(UChar));
   1218 
   1219     open(&status);
   1220     if (U_FAILURE(status)) {
   1221         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1222         return;
   1223     }
   1224     if (usearch_getAttribute(NULL, USEARCH_OVERLAP) != USEARCH_DEFAULT ||
   1225         usearch_getAttribute(NULL, USEARCH_CANONICAL_MATCH) !=
   1226                                                          USEARCH_DEFAULT) {
   1227         log_err(
   1228             "Attributes for NULL string search should be USEARCH_DEFAULT\n");
   1229     }
   1230     strsrch = usearch_openFromCollator(pattern, 16, text, 32, EN_US_, NULL,
   1231                                        &status);
   1232     if (U_FAILURE(status)) {
   1233         log_err("Error opening search %s\n", u_errorName(status));
   1234         return;
   1235     }
   1236 
   1237     usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_DEFAULT, &status);
   1238     if (U_FAILURE(status) ||
   1239         usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF) {
   1240         log_err("Error setting overlap to the default\n");
   1241     }
   1242     usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_ON, &status);
   1243     if (U_FAILURE(status) ||
   1244         usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_ON) {
   1245         log_err("Error setting overlap true\n");
   1246     }
   1247     usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_OFF, &status);
   1248     if (U_FAILURE(status) ||
   1249         usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF) {
   1250         log_err("Error setting overlap false\n");
   1251     }
   1252     usearch_setAttribute(strsrch, USEARCH_OVERLAP,
   1253                          USEARCH_ATTRIBUTE_VALUE_COUNT, &status);
   1254     if (U_SUCCESS(status)) {
   1255         log_err("Error setting overlap to illegal value\n");
   1256     }
   1257     status = U_ZERO_ERROR;
   1258     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_DEFAULT,
   1259                          &status);
   1260     if (U_FAILURE(status) ||
   1261         usearch_getAttribute(strsrch, USEARCH_CANONICAL_MATCH) !=
   1262                                                         USEARCH_OFF) {
   1263         log_err("Error setting canonical match to the default\n");
   1264     }
   1265     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   1266                          &status);
   1267     if (U_FAILURE(status) ||
   1268         usearch_getAttribute(strsrch, USEARCH_CANONICAL_MATCH) !=
   1269                                                          USEARCH_ON) {
   1270         log_err("Error setting canonical match true\n");
   1271     }
   1272     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_OFF,
   1273                          &status);
   1274     if (U_FAILURE(status) ||
   1275         usearch_getAttribute(strsrch, USEARCH_CANONICAL_MATCH) !=
   1276                                                         USEARCH_OFF) {
   1277         log_err("Error setting canonical match false\n");
   1278     }
   1279     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH,
   1280                          USEARCH_ATTRIBUTE_VALUE_COUNT, &status);
   1281     if (U_SUCCESS(status)) {
   1282         log_err("Error setting canonical match to illegal value\n");
   1283     }
   1284     status = U_ZERO_ERROR;
   1285     usearch_setAttribute(strsrch, USEARCH_ATTRIBUTE_COUNT, USEARCH_DEFAULT,
   1286                          &status);
   1287     if (U_SUCCESS(status)) {
   1288         log_err("Error setting illegal attribute success\n");
   1289     }
   1290 
   1291     usearch_close(strsrch);
   1292     close();
   1293 }
   1294 
   1295 static void TestGetMatch(void)
   1296 {
   1297     int            count       = 0;
   1298     UErrorCode     status      = U_ZERO_ERROR;
   1299     UChar          text[128];
   1300     UChar          pattern[32];
   1301     SearchData     search      = MATCH[0];
   1302     int32_t    matchindex  = search.offset[count];
   1303     UStringSearch *strsrch;
   1304     int32_t        textlength;
   1305     UChar          matchtext[128];
   1306 
   1307     open(&status);
   1308     if (U_FAILURE(status)) {
   1309         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1310         return;
   1311     }
   1312 
   1313     if (usearch_getMatchedStart(NULL) != USEARCH_DONE ||
   1314         usearch_getMatchedLength(NULL) != USEARCH_DONE) {
   1315         log_err(
   1316    "Expected start and length of NULL string search should be USEARCH_DONE\n");
   1317     }
   1318 
   1319     u_unescape(search.text, text, 128);
   1320     u_unescape(search.pattern, pattern, 32);
   1321     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
   1322                                        NULL, &status);
   1323     if (U_FAILURE(status)) {
   1324         log_err("Error opening string search %s\n", u_errorName(status));
   1325         if (strsrch != NULL) {
   1326             usearch_close(strsrch);
   1327         }
   1328         return;
   1329     }
   1330 
   1331     while (U_SUCCESS(status) && matchindex >= 0) {
   1332         int32_t matchlength = search.size[count];
   1333         usearch_next(strsrch, &status);
   1334         if (matchindex != usearch_getMatchedStart(strsrch) ||
   1335             matchlength != usearch_getMatchedLength(strsrch)) {
   1336             char *str = toCharString(usearch_getText(strsrch, &textlength));
   1337             log_err("Text: %s\n", str);
   1338             str = toCharString(usearch_getPattern(strsrch, &textlength));
   1339             log_err("Pattern: %s\n", str);
   1340             log_err("Error match found at %d %d\n",
   1341                     usearch_getMatchedStart(strsrch),
   1342                     usearch_getMatchedLength(strsrch));
   1343             return;
   1344         }
   1345         count ++;
   1346 
   1347         status = U_ZERO_ERROR;
   1348         if (usearch_getMatchedText(NULL, matchtext, 128, &status) !=
   1349             USEARCH_DONE || U_SUCCESS(status)){
   1350             log_err("Error expecting errors with NULL string search\n");
   1351         }
   1352         status = U_ZERO_ERROR;
   1353         if (usearch_getMatchedText(strsrch, NULL, 0, &status) !=
   1354             (int32_t)matchlength || U_SUCCESS(status)){
   1355             log_err("Error pre-flighting match length\n");
   1356         }
   1357         status = U_ZERO_ERROR;
   1358         if (usearch_getMatchedText(strsrch, matchtext, 0, &status) !=
   1359             (int32_t)matchlength || U_SUCCESS(status)){
   1360             log_err("Error getting match text with buffer size 0\n");
   1361         }
   1362         status = U_ZERO_ERROR;
   1363         if (usearch_getMatchedText(strsrch, matchtext, matchlength, &status)
   1364             != (int32_t)matchlength || matchtext[matchlength - 1] == 0 ||
   1365             U_FAILURE(status)){
   1366             log_err("Error getting match text with exact size\n");
   1367         }
   1368         status = U_ZERO_ERROR;
   1369         if (usearch_getMatchedText(strsrch, matchtext, 128, &status) !=
   1370             (int32_t) matchlength || U_FAILURE(status) ||
   1371             memcmp(matchtext,
   1372                    usearch_getText(strsrch, &textlength) + matchindex,
   1373                    matchlength * sizeof(UChar)) != 0 ||
   1374             matchtext[matchlength] != 0) {
   1375             log_err("Error getting matched text\n");
   1376         }
   1377 
   1378         matchindex = search.offset[count];
   1379     }
   1380     status = U_ZERO_ERROR;
   1381     usearch_next(strsrch, &status);
   1382     if (usearch_getMatchedStart(strsrch)  != USEARCH_DONE ||
   1383         usearch_getMatchedLength(strsrch) != 0) {
   1384         log_err("Error end of match not found\n");
   1385     }
   1386     status = U_ZERO_ERROR;
   1387     if (usearch_getMatchedText(strsrch, matchtext, 128, &status) !=
   1388         USEARCH_DONE) {
   1389         log_err("Error getting null matches\n");
   1390     }
   1391     usearch_close(strsrch);
   1392     close();
   1393 }
   1394 
   1395 static void TestSetMatch(void)
   1396 {
   1397     int            count       = 0;
   1398     UErrorCode status = U_ZERO_ERROR;
   1399     open(&status);
   1400     if (U_FAILURE(status)) {
   1401         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1402         return;
   1403     }
   1404     while (MATCH[count].text != NULL) {
   1405         SearchData     search = MATCH[count];
   1406         int            size   = 0;
   1407         int            index = 0;
   1408         UChar          text[128];
   1409         UChar          pattern[32];
   1410         UStringSearch *strsrch;
   1411         status = U_ZERO_ERROR;
   1412 
   1413         if (usearch_first(NULL, &status) != USEARCH_DONE ||
   1414             usearch_last(NULL, &status) != USEARCH_DONE) {
   1415             log_err("Error getting the first and last match of a NULL string search\n");
   1416         }
   1417         u_unescape(search.text, text, 128);
   1418         u_unescape(search.pattern, pattern, 32);
   1419         strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
   1420                                            NULL, &status);
   1421         if (U_FAILURE(status)) {
   1422             log_err("Error opening string search %s\n", u_errorName(status));
   1423             if (strsrch != NULL) {
   1424                 usearch_close(strsrch);
   1425             }
   1426             return;
   1427         }
   1428 
   1429         size = 0;
   1430         while (search.offset[size] != -1) {
   1431             size ++;
   1432         }
   1433 
   1434         if (usearch_first(strsrch, &status) != search.offset[0] ||
   1435             U_FAILURE(status)) {
   1436             log_err("Error getting first match\n");
   1437         }
   1438         if (usearch_last(strsrch, &status) != search.offset[size -1] ||
   1439             U_FAILURE(status)) {
   1440             log_err("Error getting last match\n");
   1441         }
   1442 
   1443         while (index < size) {
   1444             if (index + 2 < size) {
   1445                 if (usearch_following(strsrch, search.offset[index + 2] - 1,
   1446                                       &status) != search.offset[index + 2] ||
   1447                     U_FAILURE(status)) {
   1448                     log_err("Error getting following match at index %d\n",
   1449                             search.offset[index + 2] - 1);
   1450                 }
   1451             }
   1452             if (index + 1 < size) {
   1453                 if (usearch_preceding(strsrch, search.offset[index + 1] +
   1454                                                search.size[index + 1] + 1,
   1455                                       &status) != search.offset[index + 1] ||
   1456                     U_FAILURE(status)) {
   1457                     log_err("Error getting preceeding match at index %d\n",
   1458                             search.offset[index + 1] + 1);
   1459                 }
   1460             }
   1461             index += 2;
   1462         }
   1463         status = U_ZERO_ERROR;
   1464         if (usearch_following(strsrch, u_strlen(text), &status) !=
   1465             USEARCH_DONE) {
   1466             log_err("Error expecting out of bounds match\n");
   1467         }
   1468         if (usearch_preceding(strsrch, 0, &status) != USEARCH_DONE) {
   1469             log_err("Error expecting out of bounds match\n");
   1470         }
   1471         count ++;
   1472         usearch_close(strsrch);
   1473     }
   1474     close();
   1475 }
   1476 
   1477 static void TestReset(void)
   1478 {
   1479     UErrorCode     status    = U_ZERO_ERROR;
   1480     UChar          text[]    = {0x66, 0x69, 0x73, 0x68, 0x20,
   1481                                 0x66, 0x69, 0x73, 0x68};
   1482     UChar          pattern[] = {0x73};
   1483     UStringSearch *strsrch;
   1484 
   1485     open(&status);
   1486     if (U_FAILURE(status)) {
   1487         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1488         return;
   1489     }
   1490     strsrch = usearch_openFromCollator(pattern, 1, text, 9,
   1491                                                       EN_US_, NULL, &status);
   1492     if (U_FAILURE(status)) {
   1493         log_err("Error opening string search %s\n", u_errorName(status));
   1494         if (strsrch != NULL) {
   1495             usearch_close(strsrch);
   1496         }
   1497         return;
   1498     }
   1499     usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_ON, &status);
   1500     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   1501                          &status);
   1502     usearch_setOffset(strsrch, 9, &status);
   1503     if (U_FAILURE(status)) {
   1504         log_err("Error setting attributes and offsets\n");
   1505     }
   1506     else {
   1507         usearch_reset(strsrch);
   1508         if (usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF ||
   1509             usearch_getAttribute(strsrch, USEARCH_CANONICAL_MATCH) !=
   1510                                  USEARCH_OFF ||
   1511             usearch_getOffset(strsrch) != 0 ||
   1512             usearch_getMatchedLength(strsrch) != 0 ||
   1513             usearch_getMatchedStart(strsrch) != USEARCH_DONE) {
   1514             log_err("Error resetting string search\n");
   1515         }
   1516         usearch_previous(strsrch, &status);
   1517         if (usearch_getMatchedStart(strsrch) != 7 ||
   1518             usearch_getMatchedLength(strsrch) != 1) {
   1519             log_err("Error resetting string search\n");
   1520         }
   1521     }
   1522     usearch_close(strsrch);
   1523     close();
   1524 }
   1525 
   1526 static void TestSupplementary(void)
   1527 {
   1528     int count = 0;
   1529     UErrorCode status = U_ZERO_ERROR;
   1530     open(&status);
   1531     if (U_FAILURE(status)) {
   1532         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1533         return;
   1534     }
   1535     while (SUPPLEMENTARY[count].text != NULL) {
   1536         if (!assertEqual(SUPPLEMENTARY[count])) {
   1537             log_err("Error at test number %d\n", count);
   1538         }
   1539         count ++;
   1540     }
   1541     close();
   1542 }
   1543 
   1544 static void TestContraction(void)
   1545 {
   1546     UChar          rules[128];
   1547     UChar          pattern[128];
   1548     UChar          text[128];
   1549     UCollator     *collator;
   1550     UErrorCode     status = U_ZERO_ERROR;
   1551     int            count = 0;
   1552     UStringSearch *strsrch;
   1553     memset(rules, 0, 128*sizeof(UChar));
   1554     memset(pattern, 0, 128*sizeof(UChar));
   1555     memset(text, 0, 128*sizeof(UChar));
   1556 
   1557     u_unescape(CONTRACTIONRULE, rules, 128);
   1558     collator = ucol_openRules(rules, u_strlen(rules), UCOL_ON,
   1559                               UCOL_TERTIARY, NULL, &status);
   1560     if(status == U_FILE_ACCESS_ERROR) {
   1561       log_data_err("Is your data around?\n");
   1562       return;
   1563     } else if(U_FAILURE(status)) {
   1564       log_err("Error opening collator %s\n", u_errorName(status));
   1565       return;
   1566     }
   1567     strsrch = usearch_openFromCollator(pattern, 1, text, 1, collator, NULL,
   1568                                        &status);
   1569     if (U_FAILURE(status)) {
   1570         log_err("Error opening string search %s\n", u_errorName(status));
   1571     }
   1572 
   1573     while (CONTRACTION[count].text != NULL) {
   1574         u_unescape(CONTRACTION[count].text, text, 128);
   1575         u_unescape(CONTRACTION[count].pattern, pattern, 128);
   1576         usearch_setText(strsrch, text, -1, &status);
   1577         usearch_setPattern(strsrch, pattern, -1, &status);
   1578         if (!assertEqualWithUStringSearch(strsrch, CONTRACTION[count])) {
   1579             log_err("Error at test number %d\n", count);
   1580         }
   1581         count ++;
   1582     }
   1583     usearch_close(strsrch);
   1584     ucol_close(collator);
   1585 }
   1586 
   1587 static void TestIgnorable(void)
   1588 {
   1589     UChar          rules[128];
   1590     UChar          pattern[128];
   1591     UChar          text[128];
   1592     UCollator     *collator;
   1593     UErrorCode     status = U_ZERO_ERROR;
   1594     UStringSearch *strsrch;
   1595     uint32_t       count = 0;
   1596 
   1597     memset(rules, 0, 128*sizeof(UChar));
   1598     memset(pattern, 0, 128*sizeof(UChar));
   1599     memset(text, 0, 128*sizeof(UChar));
   1600 
   1601     u_unescape(IGNORABLERULE, rules, 128);
   1602     collator = ucol_openRules(rules, u_strlen(rules), UCOL_ON,
   1603                               IGNORABLE[count].strength, NULL, &status);
   1604     if(status == U_FILE_ACCESS_ERROR) {
   1605       log_data_err("Is your data around?\n");
   1606       return;
   1607     } else if(U_FAILURE(status)) {
   1608         log_err("Error opening collator %s\n", u_errorName(status));
   1609         return;
   1610     }
   1611     strsrch = usearch_openFromCollator(pattern, 1, text, 1, collator, NULL,
   1612                                        &status);
   1613     if (U_FAILURE(status)) {
   1614         log_err("Error opening string search %s\n", u_errorName(status));
   1615     }
   1616 
   1617     while (IGNORABLE[count].text != NULL) {
   1618         u_unescape(IGNORABLE[count].text, text, 128);
   1619         u_unescape(IGNORABLE[count].pattern, pattern, 128);
   1620         usearch_setText(strsrch, text, -1, &status);
   1621         usearch_setPattern(strsrch, pattern, -1, &status);
   1622         if (!assertEqualWithUStringSearch(strsrch, IGNORABLE[count])) {
   1623             log_err("Error at test number %d\n", count);
   1624         }
   1625         count ++;
   1626     }
   1627     usearch_close(strsrch);
   1628     ucol_close(collator);
   1629 }
   1630 
   1631 static void TestDiacriticMatch(void)
   1632 {
   1633     UChar          pattern[128];
   1634     UChar          text[128];
   1635     UErrorCode     status = U_ZERO_ERROR;
   1636     UStringSearch *strsrch = NULL;
   1637     UCollator *coll = NULL;
   1638     uint32_t       count = 0;
   1639     SearchData search;
   1640 
   1641     memset(pattern, 0, 128*sizeof(UChar));
   1642     memset(text, 0, 128*sizeof(UChar));
   1643 
   1644     strsrch = usearch_open(pattern, 1, text, 1, uloc_getDefault(), NULL, &status);
   1645 	if (U_FAILURE(status)) {
   1646         log_err_status(status, "Error opening string search %s\n", u_errorName(status));
   1647         return;
   1648     }
   1649 
   1650     search = DIACRITICMATCH[count];
   1651     while (search.text != NULL) {
   1652     	if (search.collator != NULL) {
   1653     		coll = ucol_openFromShortString(search.collator, FALSE, NULL, &status);
   1654     	} else {
   1655             /* Always use "en_US" because some of these tests fail in Danish locales. */
   1656     		coll = ucol_open("en_US"/*uloc_getDefault()*/, &status);
   1657     		ucol_setStrength(coll, search.strength);
   1658     	}
   1659     	if (U_FAILURE(status)) {
   1660 	        log_err("Error opening string search collator(\"%s\") %s\n", search.collator, u_errorName(status));
   1661 	        return;
   1662 	    }
   1663 
   1664     	usearch_setCollator(strsrch, coll, &status);
   1665     	if (U_FAILURE(status)) {
   1666 	        log_err("Error setting string search collator %s\n", u_errorName(status));
   1667 	        return;
   1668 	    }
   1669 
   1670         u_unescape(search.text, text, 128);
   1671         u_unescape(search.pattern, pattern, 128);
   1672         usearch_setText(strsrch, text, -1, &status);
   1673         usearch_setPattern(strsrch, pattern, -1, &status);
   1674         if (!assertEqualWithUStringSearch(strsrch, search)) {
   1675             log_err("Error at test number %d\n", count);
   1676         }
   1677         ucol_close(coll);
   1678 
   1679         search = DIACRITICMATCH[++count];
   1680     }
   1681     usearch_close(strsrch);
   1682 }
   1683 
   1684 static void TestCanonical(void)
   1685 {
   1686     int count = 0;
   1687     UErrorCode status = U_ZERO_ERROR;
   1688     open(&status);
   1689     if (U_FAILURE(status)) {
   1690         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1691         return;
   1692     }
   1693     while (BASICCANONICAL[count].text != NULL) {
   1694         if (!assertCanonicalEqual(BASICCANONICAL[count])) {
   1695             log_err("Error at test number %d\n", count);
   1696         }
   1697         count ++;
   1698     }
   1699     close();
   1700 }
   1701 
   1702 static void TestNormCanonical(void)
   1703 {
   1704     int count = 0;
   1705     UErrorCode status = U_ZERO_ERROR;
   1706     open(&status);
   1707     if (U_FAILURE(status)) {
   1708         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1709         return;
   1710     }
   1711     ucol_setAttribute(EN_US_, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
   1712     count = 0;
   1713     while (NORMCANONICAL[count].text != NULL) {
   1714         if (!assertCanonicalEqual(NORMCANONICAL[count])) {
   1715             log_err("Error at test number %d\n", count);
   1716         }
   1717         count ++;
   1718     }
   1719     ucol_setAttribute(EN_US_, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
   1720     close();
   1721 }
   1722 
   1723 static void TestStrengthCanonical(void)
   1724 {
   1725     int count = 0;
   1726     UErrorCode status = U_ZERO_ERROR;
   1727     open(&status);
   1728     if (U_FAILURE(status)) {
   1729         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1730         return;
   1731     }
   1732     while (STRENGTHCANONICAL[count].text != NULL) {
   1733         if (!assertCanonicalEqual(STRENGTHCANONICAL[count])) {
   1734             log_err("Error at test number %d\n", count);
   1735         }
   1736         count ++;
   1737     }
   1738     close();
   1739 }
   1740 
   1741 static void TestBreakIteratorCanonical(void) {
   1742     UErrorCode      status      = U_ZERO_ERROR;
   1743     int             count = 0;
   1744 
   1745     CHECK_BREAK("x");
   1746 
   1747 #if !UCONFIG_NO_BREAK_ITERATION
   1748 
   1749     open(&status);
   1750     if (U_FAILURE(status)) {
   1751         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1752         return;
   1753     }
   1754     while (count < 4) {
   1755         /* 0-3 test are fixed */
   1756               UChar           pattern[32];
   1757               UChar           text[128];
   1758         const SearchData     *search   = &(BREAKITERATORCANONICAL[count]);
   1759               UCollator      *collator = getCollator(search->collator);
   1760               UBreakIterator *breaker  = getBreakIterator(search->breaker);
   1761               UStringSearch  *strsrch;
   1762 
   1763         u_unescape(search->text, text, 128);
   1764         u_unescape(search->pattern, pattern, 32);
   1765         ucol_setStrength(collator, search->strength);
   1766 
   1767         strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
   1768                                            breaker, &status);
   1769         if(status == U_FILE_ACCESS_ERROR) {
   1770             log_data_err("Is your data around?\n");
   1771             goto ENDTESTBREAKITERATOR;
   1772         } else if(U_FAILURE(status)) {
   1773             log_err("Error opening searcher\n");
   1774             goto ENDTESTBREAKITERATOR;
   1775         }
   1776         usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   1777                              &status);
   1778         if (U_FAILURE(status) ||
   1779             usearch_getBreakIterator(strsrch) != breaker) {
   1780             log_err("Error setting break iterator\n");
   1781             usearch_close(strsrch);
   1782             goto ENDTESTBREAKITERATOR;
   1783         }
   1784         if (!assertEqualWithUStringSearch(strsrch, *search)) {
   1785             ucol_setStrength(collator, UCOL_TERTIARY);
   1786             usearch_close(strsrch);
   1787             goto ENDTESTBREAKITERATOR;
   1788         }
   1789         search   = &(BREAKITERATOREXACT[count + 1]);
   1790         breaker  = getBreakIterator(search->breaker);
   1791         usearch_setBreakIterator(strsrch, breaker, &status);
   1792         if (U_FAILURE(status) || usearch_getBreakIterator(strsrch) != breaker) {
   1793             log_err("Error setting break iterator\n");
   1794             usearch_close(strsrch);
   1795             goto ENDTESTBREAKITERATOR;
   1796         }
   1797         usearch_reset(strsrch);
   1798         usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   1799                              &status);
   1800         if (!assertEqualWithUStringSearch(strsrch, *search)) {
   1801             log_err("Error at test number %d\n", count);
   1802             usearch_close(strsrch);
   1803             goto ENDTESTBREAKITERATOR;
   1804         }
   1805         usearch_close(strsrch);
   1806         count += 2;
   1807     }
   1808     count = 0;
   1809     while (BREAKITERATORCANONICAL[count].text != NULL) {
   1810          if (!assertEqual(BREAKITERATORCANONICAL[count])) {
   1811              log_err("Error at test number %d\n", count);
   1812              goto ENDTESTBREAKITERATOR;
   1813          }
   1814          count ++;
   1815     }
   1816 
   1817 ENDTESTBREAKITERATOR:
   1818     close();
   1819 #endif
   1820 }
   1821 
   1822 static void TestVariableCanonical(void)
   1823 {
   1824     int count = 0;
   1825     UErrorCode status = U_ZERO_ERROR;
   1826     open(&status);
   1827     if (U_FAILURE(status)) {
   1828         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1829         return;
   1830     }
   1831     ucol_setAttribute(EN_US_, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
   1832     if (U_FAILURE(status)) {
   1833         log_err("Error setting collation alternate attribute %s\n",
   1834             u_errorName(status));
   1835     }
   1836     while (VARIABLE[count].text != NULL) {
   1837         log_verbose("variable %d\n", count);
   1838         if (!assertCanonicalEqual(VARIABLE[count])) {
   1839             log_err("Error at test number %d\n", count);
   1840         }
   1841         count ++;
   1842     }
   1843     ucol_setAttribute(EN_US_, UCOL_ALTERNATE_HANDLING,
   1844                       UCOL_NON_IGNORABLE, &status);
   1845     close();
   1846 }
   1847 
   1848 static void TestOverlapCanonical(void)
   1849 {
   1850     int count = 0;
   1851     UErrorCode status = U_ZERO_ERROR;
   1852     open(&status);
   1853     if (U_FAILURE(status)) {
   1854         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1855         return;
   1856     }
   1857     while (OVERLAPCANONICAL[count].text != NULL) {
   1858         if (!assertEqualWithAttribute(OVERLAPCANONICAL[count], USEARCH_ON,
   1859                                       USEARCH_ON)) {
   1860             log_err("Error at overlap test number %d\n", count);
   1861         }
   1862         count ++;
   1863     }
   1864     count = 0;
   1865     while (NONOVERLAP[count].text != NULL) {
   1866         if (!assertCanonicalEqual(NONOVERLAPCANONICAL[count])) {
   1867             log_err("Error at non overlap test number %d\n", count);
   1868         }
   1869         count ++;
   1870     }
   1871 
   1872     count = 0;
   1873     while (count < 1) {
   1874               UChar           pattern[32];
   1875               UChar           text[128];
   1876         const SearchData     *search   = &(OVERLAPCANONICAL[count]);
   1877               UCollator      *collator = getCollator(search->collator);
   1878               UStringSearch  *strsrch;
   1879               status   = U_ZERO_ERROR;
   1880 
   1881         u_unescape(search->text, text, 128);
   1882         u_unescape(search->pattern, pattern, 32);
   1883         strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
   1884                                            NULL, &status);
   1885         if(status == U_FILE_ACCESS_ERROR) {
   1886           log_data_err("Is your data around?\n");
   1887           return;
   1888         } else if(U_FAILURE(status)) {
   1889           log_err("Error opening searcher\n");
   1890           return;
   1891         }
   1892         usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   1893                              &status);
   1894         usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_ON, &status);
   1895         if (U_FAILURE(status) ||
   1896             usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_ON) {
   1897             log_err("Error setting overlap option\n");
   1898         }
   1899         if (!assertEqualWithUStringSearch(strsrch, *search)) {
   1900             usearch_close(strsrch);
   1901             return;
   1902         }
   1903         search   = &(NONOVERLAPCANONICAL[count]);
   1904         usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_OFF, &status);
   1905         if (U_FAILURE(status) ||
   1906             usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF) {
   1907             log_err("Error setting overlap option\n");
   1908         }
   1909         usearch_reset(strsrch);
   1910         if (!assertEqualWithUStringSearch(strsrch, *search)) {
   1911             usearch_close(strsrch);
   1912             log_err("Error at test number %d\n", count);
   1913          }
   1914 
   1915         count ++;
   1916         usearch_close(strsrch);
   1917     }
   1918     close();
   1919 }
   1920 
   1921 static void TestCollatorCanonical(void)
   1922 {
   1923     /* test collator that thinks "o" and "p" are the same thing */
   1924           UChar          rules[32];
   1925           UCollator     *tailored = NULL;
   1926           UErrorCode     status = U_ZERO_ERROR;
   1927           UChar          pattern[32];
   1928           UChar          text[128];
   1929           UStringSearch *strsrch;
   1930 
   1931     open(&status);
   1932     if (U_FAILURE(status)) {
   1933         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   1934         return;
   1935     }
   1936     u_unescape(COLLATORCANONICAL[0].text, text, 128);
   1937     u_unescape(COLLATORCANONICAL[0].pattern, pattern, 32);
   1938 
   1939     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
   1940                                        NULL, &status);
   1941     if(status == U_FILE_ACCESS_ERROR) {
   1942       log_data_err("Is your data around?\n");
   1943       return;
   1944     } else if(U_FAILURE(status)) {
   1945       log_err("Error opening searcher\n");
   1946       return;
   1947     }
   1948     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   1949                          &status);
   1950     if (U_FAILURE(status)) {
   1951         log_err("Error opening string search %s\n", u_errorName(status));
   1952     }
   1953     if (!assertEqualWithUStringSearch(strsrch, COLLATORCANONICAL[0])) {
   1954         goto ENDTESTCOLLATOR;
   1955     }
   1956 
   1957     u_unescape(TESTCOLLATORRULE, rules, 32);
   1958     tailored = ucol_openRules(rules, -1, UCOL_ON,
   1959                               COLLATORCANONICAL[1].strength, NULL, &status);
   1960     if (U_FAILURE(status)) {
   1961         log_err("Error opening rule based collator %s\n", u_errorName(status));
   1962     }
   1963 
   1964     usearch_setCollator(strsrch, tailored, &status);
   1965     if (U_FAILURE(status) || usearch_getCollator(strsrch) != tailored) {
   1966         log_err("Error setting rule based collator\n");
   1967     }
   1968     usearch_reset(strsrch);
   1969     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   1970                          &status);
   1971     if (!assertEqualWithUStringSearch(strsrch, COLLATORCANONICAL[1])) {
   1972         goto ENDTESTCOLLATOR;
   1973     }
   1974 
   1975     usearch_setCollator(strsrch, EN_US_, &status);
   1976     usearch_reset(strsrch);
   1977     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   1978                          &status);
   1979     if (U_FAILURE(status) || usearch_getCollator(strsrch) != EN_US_) {
   1980         log_err("Error setting rule based collator\n");
   1981     }
   1982     if (!assertEqualWithUStringSearch(strsrch, COLLATORCANONICAL[0])) {
   1983         goto ENDTESTCOLLATOR;
   1984     }
   1985 
   1986 ENDTESTCOLLATOR:
   1987     usearch_close(strsrch);
   1988     if (tailored != NULL) {
   1989         ucol_close(tailored);
   1990     }
   1991     close();
   1992 }
   1993 
   1994 static void TestPatternCanonical(void)
   1995 {
   1996           UStringSearch *strsrch;
   1997           UChar          pattern[32];
   1998           UChar          text[128];
   1999     const UChar         *temp;
   2000           int32_t        templength;
   2001           UErrorCode     status = U_ZERO_ERROR;
   2002 
   2003     open(&status);
   2004     if (U_FAILURE(status)) {
   2005         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   2006         return;
   2007     }
   2008     u_unescape(PATTERNCANONICAL[0].text, text, 128);
   2009     u_unescape(PATTERNCANONICAL[0].pattern, pattern, 32);
   2010 
   2011     ucol_setStrength(EN_US_, PATTERNCANONICAL[0].strength);
   2012     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
   2013                                        NULL, &status);
   2014     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   2015                          &status);
   2016     if (U_FAILURE(status)) {
   2017         log_err("Error opening string search %s\n", u_errorName(status));
   2018         goto ENDTESTPATTERN;
   2019     }
   2020     temp = usearch_getPattern(strsrch, &templength);
   2021     if (u_strcmp(pattern, temp) != 0) {
   2022         log_err("Error setting pattern\n");
   2023     }
   2024     if (!assertEqualWithUStringSearch(strsrch, PATTERNCANONICAL[0])) {
   2025         goto ENDTESTPATTERN;
   2026     }
   2027 
   2028     u_unescape(PATTERNCANONICAL[1].pattern, pattern, 32);
   2029     usearch_setPattern(strsrch, pattern, -1, &status);
   2030     temp = usearch_getPattern(strsrch, &templength);
   2031     if (u_strcmp(pattern, temp) != 0) {
   2032         log_err("Error setting pattern\n");
   2033         goto ENDTESTPATTERN;
   2034     }
   2035     usearch_reset(strsrch);
   2036     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   2037                          &status);
   2038     if (U_FAILURE(status)) {
   2039         log_err("Error setting pattern %s\n", u_errorName(status));
   2040     }
   2041     if (!assertEqualWithUStringSearch(strsrch, PATTERNCANONICAL[1])) {
   2042         goto ENDTESTPATTERN;
   2043     }
   2044 
   2045     u_unescape(PATTERNCANONICAL[0].pattern, pattern, 32);
   2046     usearch_setPattern(strsrch, pattern, -1, &status);
   2047     temp = usearch_getPattern(strsrch, &templength);
   2048     if (u_strcmp(pattern, temp) != 0) {
   2049         log_err("Error setting pattern\n");
   2050         goto ENDTESTPATTERN;
   2051     }
   2052     usearch_reset(strsrch);
   2053     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   2054                          &status);
   2055     if (U_FAILURE(status)) {
   2056         log_err("Error setting pattern %s\n", u_errorName(status));
   2057     }
   2058     if (!assertEqualWithUStringSearch(strsrch, PATTERNCANONICAL[0])) {
   2059         goto ENDTESTPATTERN;
   2060     }
   2061 ENDTESTPATTERN:
   2062     ucol_setStrength(EN_US_, UCOL_TERTIARY);
   2063     if (strsrch != NULL) {
   2064         usearch_close(strsrch);
   2065     }
   2066     close();
   2067 }
   2068 
   2069 static void TestTextCanonical(void)
   2070 {
   2071           UStringSearch *strsrch;
   2072           UChar          pattern[32];
   2073           UChar          text[128];
   2074     const UChar         *temp;
   2075           int32_t        templength;
   2076           UErrorCode     status = U_ZERO_ERROR;
   2077 
   2078     u_unescape(TEXTCANONICAL[0].text, text, 128);
   2079     u_unescape(TEXTCANONICAL[0].pattern, pattern, 32);
   2080 
   2081     open(&status);
   2082     if (U_FAILURE(status)) {
   2083         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   2084         return;
   2085     }
   2086     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
   2087                                        NULL, &status);
   2088     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   2089                          &status);
   2090 
   2091     if (U_FAILURE(status)) {
   2092         log_err("Error opening string search %s\n", u_errorName(status));
   2093         goto ENDTESTPATTERN;
   2094     }
   2095     temp = usearch_getText(strsrch, &templength);
   2096     if (u_strcmp(text, temp) != 0) {
   2097         log_err("Error setting text\n");
   2098     }
   2099     if (!assertEqualWithUStringSearch(strsrch, TEXTCANONICAL[0])) {
   2100         goto ENDTESTPATTERN;
   2101     }
   2102 
   2103     u_unescape(TEXTCANONICAL[1].text, text, 32);
   2104     usearch_setText(strsrch, text, -1, &status);
   2105     temp = usearch_getText(strsrch, &templength);
   2106     if (u_strcmp(text, temp) != 0) {
   2107         log_err("Error setting text\n");
   2108         goto ENDTESTPATTERN;
   2109     }
   2110     if (U_FAILURE(status)) {
   2111         log_err("Error setting text %s\n", u_errorName(status));
   2112     }
   2113     if (!assertEqualWithUStringSearch(strsrch, TEXTCANONICAL[1])) {
   2114         goto ENDTESTPATTERN;
   2115     }
   2116 
   2117     u_unescape(TEXTCANONICAL[0].text, text, 32);
   2118     usearch_setText(strsrch, text, -1, &status);
   2119     temp = usearch_getText(strsrch, &templength);
   2120     if (u_strcmp(text, temp) != 0) {
   2121         log_err("Error setting text\n");
   2122         goto ENDTESTPATTERN;
   2123     }
   2124     if (U_FAILURE(status)) {
   2125         log_err("Error setting pattern %s\n", u_errorName(status));
   2126     }
   2127     if (!assertEqualWithUStringSearch(strsrch, TEXTCANONICAL[0])) {
   2128         goto ENDTESTPATTERN;
   2129     }
   2130 ENDTESTPATTERN:
   2131     if (strsrch != NULL) {
   2132         usearch_close(strsrch);
   2133     }
   2134     close();
   2135 }
   2136 
   2137 static void TestCompositeBoundariesCanonical(void)
   2138 {
   2139     int count = 0;
   2140     UErrorCode status = U_ZERO_ERROR;
   2141     open(&status);
   2142     if (U_FAILURE(status)) {
   2143         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   2144         return;
   2145     }
   2146     while (COMPOSITEBOUNDARIESCANONICAL[count].text != NULL) {
   2147         log_verbose("composite %d\n", count);
   2148         if (!assertCanonicalEqual(COMPOSITEBOUNDARIESCANONICAL[count])) {
   2149             log_err("Error at test number %d\n", count);
   2150         }
   2151         count ++;
   2152     }
   2153     close();
   2154 }
   2155 
   2156 static void TestGetSetOffsetCanonical(void)
   2157 {
   2158     int            index   = 0;
   2159     UChar          pattern[32];
   2160     UChar          text[128];
   2161     UErrorCode     status  = U_ZERO_ERROR;
   2162     UStringSearch *strsrch;
   2163     UCollator     *collator;
   2164 
   2165     memset(pattern, 0, 32*sizeof(UChar));
   2166     memset(text, 0, 128*sizeof(UChar));
   2167 
   2168     open(&status);
   2169     if (U_FAILURE(status)) {
   2170         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   2171         return;
   2172     }
   2173     strsrch = usearch_openFromCollator(pattern, 16, text, 32, EN_US_, NULL,
   2174                                        &status);
   2175 
   2176     collator = usearch_getCollator(strsrch);
   2177     ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
   2178 
   2179     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   2180                          &status);
   2181 
   2182     /* testing out of bounds error */
   2183     usearch_setOffset(strsrch, -1, &status);
   2184     if (U_SUCCESS(status)) {
   2185         log_err("Error expecting set offset error\n");
   2186     }
   2187     usearch_setOffset(strsrch, 128, &status);
   2188     if (U_SUCCESS(status)) {
   2189         log_err("Error expecting set offset error\n");
   2190     }
   2191     while (BASICCANONICAL[index].text != NULL) {
   2192         int         count       = 0;
   2193         SearchData  search      = BASICCANONICAL[index ++];
   2194         int32_t matchindex  = search.offset[count];
   2195         int32_t     textlength;
   2196 
   2197         if (BASICCANONICAL[index].text == NULL) {
   2198             /* skip the last one */
   2199             break;
   2200         }
   2201 
   2202         u_unescape(search.text, text, 128);
   2203         u_unescape(search.pattern, pattern, 32);
   2204         status = U_ZERO_ERROR;
   2205         usearch_setText(strsrch, text, -1, &status);
   2206         usearch_setPattern(strsrch, pattern, -1, &status);
   2207         while (U_SUCCESS(status) && matchindex >= 0) {
   2208             uint32_t matchlength = search.size[count];
   2209             usearch_next(strsrch, &status);
   2210             if (matchindex != usearch_getMatchedStart(strsrch) ||
   2211                 matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
   2212                 char *str = toCharString(usearch_getText(strsrch,
   2213                                                          &textlength));
   2214                 log_err("Text: %s\n", str);
   2215                 str = toCharString(usearch_getPattern(strsrch, &textlength));
   2216                 log_err("Pattern: %s\n", str);
   2217                 log_err("Error match found at %d %d\n",
   2218                         usearch_getMatchedStart(strsrch),
   2219                         usearch_getMatchedLength(strsrch));
   2220                 goto bail;
   2221             }
   2222             matchindex = search.offset[count + 1] == -1 ? -1 :
   2223                          search.offset[count + 2];
   2224             if (search.offset[count + 1] != -1) {
   2225                 usearch_setOffset(strsrch, search.offset[count + 1] + 1,
   2226                                   &status);
   2227                 if (usearch_getOffset(strsrch) != search.offset[count + 1] + 1) {
   2228                     log_err("Error setting offset\n");
   2229                     goto bail;
   2230                 }
   2231             }
   2232 
   2233             count += 2;
   2234         }
   2235         usearch_next(strsrch, &status);
   2236         if (usearch_getMatchedStart(strsrch) != USEARCH_DONE) {
   2237             char *str = toCharString(usearch_getText(strsrch, &textlength));
   2238             log_err("Text: %s\n", str);
   2239             str = toCharString(usearch_getPattern(strsrch, &textlength));
   2240             log_err("Pattern: %s\n", str);
   2241             log_err("Error match found at %d %d\n",
   2242                         usearch_getMatchedStart(strsrch),
   2243                         usearch_getMatchedLength(strsrch));
   2244             goto bail;
   2245         }
   2246     }
   2247 
   2248 bail:
   2249     ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
   2250     usearch_close(strsrch);
   2251     close();
   2252 }
   2253 
   2254 static void TestSupplementaryCanonical(void)
   2255 {
   2256     int count = 0;
   2257     UErrorCode status = U_ZERO_ERROR;
   2258     open(&status);
   2259     if (U_FAILURE(status)) {
   2260         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
   2261         return;
   2262     }
   2263     while (SUPPLEMENTARYCANONICAL[count].text != NULL) {
   2264         if (!assertCanonicalEqual(SUPPLEMENTARYCANONICAL[count])) {
   2265             log_err("Error at test number %d\n", count);
   2266         }
   2267         count ++;
   2268     }
   2269     close();
   2270 }
   2271 
   2272 static void TestContractionCanonical(void)
   2273 {
   2274     UChar          rules[128];
   2275     UChar          pattern[128];
   2276     UChar          text[128];
   2277     UCollator     *collator = NULL;
   2278     UErrorCode     status = U_ZERO_ERROR;
   2279     int            count = 0;
   2280     UStringSearch *strsrch = NULL;
   2281     memset(rules, 0, 128*sizeof(UChar));
   2282     memset(pattern, 0, 128*sizeof(UChar));
   2283     memset(text, 0, 128*sizeof(UChar));
   2284 
   2285     u_unescape(CONTRACTIONRULE, rules, 128);
   2286     collator = ucol_openRules(rules, u_strlen(rules), UCOL_ON,
   2287                               UCOL_TERTIARY, NULL, &status);
   2288     if(status == U_FILE_ACCESS_ERROR) {
   2289       log_data_err("Is your data around?\n");
   2290       return;
   2291     } else if(U_FAILURE(status)) {
   2292       log_err("Error opening collator %s\n", u_errorName(status));
   2293       return;
   2294     }
   2295     strsrch = usearch_openFromCollator(pattern, 1, text, 1, collator, NULL,
   2296                                        &status);
   2297     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
   2298                          &status);
   2299     if (U_FAILURE(status)) {
   2300         log_err("Error opening string search %s\n", u_errorName(status));
   2301     }
   2302 
   2303     while (CONTRACTIONCANONICAL[count].text != NULL) {
   2304         u_unescape(CONTRACTIONCANONICAL[count].text, text, 128);
   2305         u_unescape(CONTRACTIONCANONICAL[count].pattern, pattern, 128);
   2306         usearch_setText(strsrch, text, -1, &status);
   2307         usearch_setPattern(strsrch, pattern, -1, &status);
   2308         if (!assertEqualWithUStringSearch(strsrch,
   2309                                               CONTRACTIONCANONICAL[count])) {
   2310             log_err("Error at test number %d\n", count);
   2311         }
   2312         count ++;
   2313     }
   2314     usearch_close(strsrch);
   2315     ucol_close(collator);
   2316 }
   2317 
   2318 static void TestNumeric(void) {
   2319     UCollator     *coll = NULL;
   2320     UStringSearch *strsrch = NULL;
   2321     UErrorCode     status = U_ZERO_ERROR;
   2322 
   2323     UChar          pattern[128];
   2324     UChar          text[128];
   2325     memset(pattern, 0, 128*sizeof(UChar));
   2326     memset(text, 0, 128*sizeof(UChar));
   2327 
   2328     coll = ucol_open("", &status);
   2329     if(U_FAILURE(status)) {
   2330         log_data_err("Could not open UCA. Is your data around?\n");
   2331         return;
   2332     }
   2333 
   2334     ucol_setAttribute(coll, UCOL_NUMERIC_COLLATION, UCOL_ON, &status);
   2335 
   2336     strsrch = usearch_openFromCollator(pattern, 1, text, 1, coll, NULL, &status);
   2337 
   2338     if(status != U_UNSUPPORTED_ERROR || U_SUCCESS(status)) {
   2339         log_err("Expected U_UNSUPPORTED_ERROR when trying to instantiate a search object from a CODAN collator, got %s instead\n", u_errorName(status));
   2340         if(strsrch) {
   2341             usearch_close(strsrch);
   2342         }
   2343     }
   2344 
   2345     ucol_close(coll);
   2346 
   2347 }
   2348 
   2349 /* This test is for ticket 4038 due to incorrect backward searching when certain patterns have a length > 1 */
   2350 static void TestForwardBackward(void) {
   2351     UErrorCode status = U_ZERO_ERROR;
   2352     UCollator *coll = NULL;
   2353     UStringSearch *search = NULL;
   2354     UChar usrcstr[32], value[4];
   2355     int32_t pos= -1;
   2356     int32_t expectedPos = 9;
   2357 
   2358     coll = ucol_open("en_GB", &status);
   2359     if (U_FAILURE(status)) {
   2360         log_err_status(status, "ucol_open failed: %s\n", u_errorName(status));
   2361         goto exitTestForwardBackward;
   2362     }
   2363     ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_PRIMARY, &status);
   2364     ucol_setAttribute(coll, UCOL_CASE_LEVEL, UCOL_ON, &status);
   2365     ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status);
   2366 
   2367     u_uastrcpy(usrcstr, "QBitArray::bitarr_data"); /* text */
   2368     u_uastrcpy(value, "::");                       /* pattern */
   2369 
   2370     search = usearch_openFromCollator(value, 2, usrcstr, 22, coll, NULL, &status);
   2371     if (U_FAILURE(status)) {
   2372         log_err("usearch_openFromCollator failed: %s\n", u_errorName(status));
   2373         goto exitTestForwardBackward;
   2374     }
   2375 
   2376     usearch_reset(search);
   2377     /* forward search */
   2378     pos = usearch_first(search, &status);
   2379     if (pos != expectedPos) {
   2380         log_err("Expected search result: %d; Got instead: %d\n", expectedPos, pos);
   2381         goto exitTestForwardBackward;
   2382     }
   2383 
   2384     pos = -1;
   2385     usearch_reset(search);
   2386     /* backward search */
   2387     pos = usearch_last(search, &status);
   2388     if (pos != expectedPos) {
   2389         log_err("Expected search result: %d; Got instead: %d\n", expectedPos, pos);
   2390     }
   2391 
   2392 exitTestForwardBackward :
   2393     if (coll != NULL) {
   2394         ucol_close(coll);
   2395     }
   2396     if (search != NULL) {
   2397         usearch_close(search);
   2398     }
   2399 }
   2400 
   2401 #define TEST_ASSERT(x) \
   2402    {if (U_FAILURE(x)) {log_err_status(x, "%s:%d: FAIL: test assertion failure \n", __FILE__, __LINE__);\
   2403    }}
   2404 
   2405 static void TestSearchForNull(void) {
   2406     UCollator *coll;
   2407     UErrorCode ec;
   2408     UStringSearch *search;
   2409     int pos;
   2410     int len;
   2411     int expectedPos;
   2412     int expectedLen;
   2413     int expectedNum;
   2414     int count = 0;
   2415     const UChar zerodigit = 0x0030; /* 0 */
   2416     const UChar nulldigit = 0x0000; /* null */
   2417 
   2418     /* static const UChar var[(length)+1]=U_DECLARE_UTF16(cs) */
   2419 #define PATTERN_LEN 4
   2420 #define TEXT_LEN 10
   2421 
   2422     U_STRING_DECL(_pattern, "IS 0", PATTERN_LEN);
   2423     U_STRING_DECL(_text, "_0IS 0 OK?", TEXT_LEN);
   2424     UChar pattern[PATTERN_LEN + 1], text[TEXT_LEN + 1];
   2425 
   2426     U_STRING_INIT(_pattern, "IS 0", PATTERN_LEN);
   2427     U_STRING_INIT(_text, "_0IS 0 OK?", TEXT_LEN);
   2428     expectedPos = 2;
   2429     expectedLen = 4;
   2430     expectedNum = 1;
   2431 
   2432     for (pos = 0; pos < PATTERN_LEN; pos++) {
   2433         if (_pattern[pos] == zerodigit) {
   2434             pattern[pos] = nulldigit;
   2435         } else {
   2436             pattern[pos] = _pattern[pos];
   2437         }
   2438     }
   2439     pattern[PATTERN_LEN] = 0x0000;
   2440 
   2441     for (pos = 0; pos < TEXT_LEN; pos++) {
   2442         if (_text[pos] == zerodigit) {
   2443             text[pos] = nulldigit;
   2444         } else {
   2445             text[pos] = _text[pos];
   2446         }
   2447     }
   2448     text[TEXT_LEN] = 0x0000;
   2449 
   2450     ec = U_ZERO_ERROR;
   2451 
   2452     /* create a US-English collator */
   2453     coll = ucol_open("en_US", &ec);
   2454 
   2455     /* make sure we didn't fail. */
   2456      TEST_ASSERT (ec);
   2457 
   2458     ucol_setStrength(coll, UCOL_IDENTICAL);
   2459 
   2460     /* open a search looking for 0 */
   2461     search = usearch_openFromCollator(pattern, PATTERN_LEN, text,
   2462             TEXT_LEN, coll, NULL, &ec);
   2463      TEST_ASSERT (ec);
   2464 
   2465     if (coll != NULL && search != NULL) {
   2466         pos = usearch_first(search, &ec);
   2467         len = usearch_getMatchedLength(search);
   2468         if (pos != expectedPos) {
   2469             log_err("Expected search result: %d; Got instead: %d\n", expectedPos,
   2470                     pos);
   2471         }
   2472 
   2473         if (len != expectedLen) {
   2474             log_err("Expected search result length: %d; Got instead: %d\n",
   2475                     expectedLen, len);
   2476         }
   2477 
   2478         for (pos = usearch_first(search, &ec); pos != USEARCH_DONE; pos
   2479                 = usearch_next(search, &ec)) {
   2480             log_verbose("Match at %d\n", pos);
   2481             count += 1;
   2482         }
   2483 
   2484         if (count != expectedNum) {
   2485             log_err("Expected %d search hits, found %d\n", expectedNum, count);
   2486         }
   2487     }
   2488 
   2489     ucol_close(coll);
   2490     usearch_close(search);
   2491 }
   2492 
   2493 static void TestStrengthIdentical(void)
   2494 {
   2495 	UCollator *coll;
   2496 	UErrorCode ec = U_ZERO_ERROR;
   2497 	UStringSearch *search;
   2498 
   2499     UChar pattern[] = {0x05E9, 0x0591, 0x05E9};
   2500     UChar text[]    = {0x05E9, 0x0592, 0x05E9};
   2501     int32_t pLen = sizeof (pattern) / sizeof(pattern[0]);
   2502     int32_t tLen = sizeof(text) / sizeof (text[0]);
   2503 	int32_t expectedPos = 0;
   2504 	int32_t expectedLen = 3;
   2505 
   2506 	int32_t pos;
   2507 	int32_t len;
   2508 
   2509     /* create a US-English collator */
   2510 	coll = ucol_open ("en_US", &ec);
   2511 
   2512 	/* make sure we didn't fail. */
   2513 	TEST_ASSERT (ec);
   2514 
   2515     ucol_setStrength( coll, UCOL_TERTIARY);
   2516 
   2517 	/* open a search looking for 0 */
   2518 	search = usearch_openFromCollator (pattern, pLen, text, tLen, coll, NULL, &ec);
   2519 	TEST_ASSERT (ec);
   2520 
   2521     if (coll != NULL && search != NULL) {
   2522 	    pos = usearch_first(search, &ec);
   2523 	    len = usearch_getMatchedLength(search);
   2524 
   2525 	    if(pos != expectedPos) {
   2526 		    log_err("Expected search result: %d; Got instead: %d\n", expectedPos, pos);
   2527 	    }
   2528 
   2529 	    if(len != expectedLen) {
   2530 		    log_err("Expected search result length: %d; Got instead: %d\n", expectedLen, len);
   2531 	    }
   2532 
   2533         /* Now try it at strength == UCOL_IDENTICAL */
   2534         ucol_setStrength(coll, UCOL_IDENTICAL);
   2535 	    usearch_reset(search);
   2536 
   2537 	    pos = usearch_first(search, &ec);
   2538 	    len = usearch_getMatchedLength(search);
   2539 
   2540 	    if(pos != -1) {
   2541 		    log_err("Expected failure for strentgh = UCOL_IDENTICAL: got %d instead.\n", pos);
   2542 	    }
   2543     }
   2544 
   2545     usearch_close(search);
   2546     ucol_close(coll);
   2547 }
   2548 
   2549 
   2550 void addSearchTest(TestNode** root)
   2551 {
   2552     addTest(root, &TestStart, "tscoll/usrchtst/TestStart");
   2553     addTest(root, &TestOpenClose, "tscoll/usrchtst/TestOpenClose");
   2554     addTest(root, &TestInitialization, "tscoll/usrchtst/TestInitialization");
   2555     addTest(root, &TestBasic, "tscoll/usrchtst/TestBasic");
   2556     addTest(root, &TestNormExact, "tscoll/usrchtst/TestNormExact");
   2557     addTest(root, &TestStrength, "tscoll/usrchtst/TestStrength");
   2558     addTest(root, &TestBreakIterator, "tscoll/usrchtst/TestBreakIterator");
   2559     addTest(root, &TestVariable, "tscoll/usrchtst/TestVariable");
   2560     addTest(root, &TestOverlap, "tscoll/usrchtst/TestOverlap");
   2561     addTest(root, &TestCollator, "tscoll/usrchtst/TestCollator");
   2562     addTest(root, &TestPattern, "tscoll/usrchtst/TestPattern");
   2563     addTest(root, &TestText, "tscoll/usrchtst/TestText");
   2564     addTest(root, &TestCompositeBoundaries,
   2565                                   "tscoll/usrchtst/TestCompositeBoundaries");
   2566     addTest(root, &TestGetSetOffset, "tscoll/usrchtst/TestGetSetOffset");
   2567     addTest(root, &TestGetSetAttribute,
   2568                                       "tscoll/usrchtst/TestGetSetAttribute");
   2569     addTest(root, &TestGetMatch, "tscoll/usrchtst/TestGetMatch");
   2570     addTest(root, &TestSetMatch, "tscoll/usrchtst/TestSetMatch");
   2571     addTest(root, &TestReset, "tscoll/usrchtst/TestReset");
   2572     addTest(root, &TestSupplementary, "tscoll/usrchtst/TestSupplementary");
   2573     addTest(root, &TestContraction, "tscoll/usrchtst/TestContraction");
   2574     addTest(root, &TestIgnorable, "tscoll/usrchtst/TestIgnorable");
   2575     addTest(root, &TestCanonical, "tscoll/usrchtst/TestCanonical");
   2576     addTest(root, &TestNormCanonical, "tscoll/usrchtst/TestNormCanonical");
   2577     addTest(root, &TestStrengthCanonical,
   2578                                     "tscoll/usrchtst/TestStrengthCanonical");
   2579     addTest(root, &TestBreakIteratorCanonical,
   2580                                "tscoll/usrchtst/TestBreakIteratorCanonical");
   2581     addTest(root, &TestVariableCanonical,
   2582                                     "tscoll/usrchtst/TestVariableCanonical");
   2583     addTest(root, &TestOverlapCanonical,
   2584                                      "tscoll/usrchtst/TestOverlapCanonical");
   2585     addTest(root, &TestCollatorCanonical,
   2586                                     "tscoll/usrchtst/TestCollatorCanonical");
   2587     addTest(root, &TestPatternCanonical,
   2588                                      "tscoll/usrchtst/TestPatternCanonical");
   2589     addTest(root, &TestTextCanonical, "tscoll/usrchtst/TestTextCanonical");
   2590     addTest(root, &TestCompositeBoundariesCanonical,
   2591                          "tscoll/usrchtst/TestCompositeBoundariesCanonical");
   2592     addTest(root, &TestGetSetOffsetCanonical,
   2593                                 "tscoll/usrchtst/TestGetSetOffsetCanonical");
   2594     addTest(root, &TestSupplementaryCanonical,
   2595                                "tscoll/usrchtst/TestSupplementaryCanonical");
   2596     addTest(root, &TestContractionCanonical,
   2597                                  "tscoll/usrchtst/TestContractionCanonical");
   2598     addTest(root, &TestEnd, "tscoll/usrchtst/TestEnd");
   2599     addTest(root, &TestNumeric, "tscoll/usrchtst/TestNumeric");
   2600     addTest(root, &TestDiacriticMatch, "tscoll/usrchtst/TestDiacriticMatch");
   2601     addTest(root, &TestForwardBackward, "tscoll/usrchtst/TestForwardBackward");
   2602 	addTest(root, &TestSearchForNull, "tscoll/usrchtst/TestSearchForNull");
   2603     addTest(root, &TestStrengthIdentical, "tscoll/usrchtst/TestStrengthIdentical");
   2604 }
   2605 
   2606 #endif /* #if !UCONFIG_NO_COLLATION */
   2607