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