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