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