Home | History | Annotate | Download | only in cintltst
      1 /********************************************************************
      2  * COPYRIGHT:
      3  * Copyright (c) 1997-2009, International Business Machines Corporation and
      4  * others. All Rights Reserved.
      5  ********************************************************************/
      6 /********************************************************************************
      7 *
      8 * File CBIAPTS.C
      9 *
     10 * Modification History:
     11 *        Name                     Description
     12 *     Madhu Katragadda              Creation
     13 *********************************************************************************/
     14 /*C API TEST FOR BREAKITERATOR */
     15 /**
     16 * This is an API test.  It doesn't test very many cases, and doesn't
     17 * try to test the full functionality.  It just calls each function in the class and
     18 * verifies that it works on a basic level.
     19 **/
     20 
     21 #include "unicode/utypes.h"
     22 
     23 #if !UCONFIG_NO_BREAK_ITERATION
     24 
     25 #include <stdlib.h>
     26 #include <string.h>
     27 #include "unicode/uloc.h"
     28 #include "unicode/ubrk.h"
     29 #include "unicode/ustring.h"
     30 #include "unicode/ucnv.h"
     31 #include "unicode/utext.h"
     32 #include "cintltst.h"
     33 #include "cbiapts.h"
     34 
     35 #define TEST_ASSERT_SUCCESS(status) {if (U_FAILURE(status)) { \
     36 log_data_err("Failure at file %s, line %d, error = %s (Are you missing data?)\n", __FILE__, __LINE__, u_errorName(status));}}
     37 
     38 #define TEST_ASSERT(expr) {if ((expr)==FALSE) { \
     39 log_data_err("Test Failure at file %s, line %d (Are you missing data?)\n", __FILE__, __LINE__);}}
     40 
     41 static void TestBreakIteratorSafeClone(void);
     42 static void TestBreakIteratorRules(void);
     43 static void TestBreakIteratorRuleError(void);
     44 static void TestBreakIteratorStatusVec(void);
     45 static void TestBreakIteratorUText(void);
     46 
     47 void addBrkIterAPITest(TestNode** root);
     48 
     49 void addBrkIterAPITest(TestNode** root)
     50 {
     51     addTest(root, &TestBreakIteratorCAPI, "tstxtbd/cbiapts/TestBreakIteratorCAPI");
     52     addTest(root, &TestBreakIteratorSafeClone, "tstxtbd/cbiapts/TestBreakIteratorSafeClone");
     53     addTest(root, &TestBreakIteratorRules, "tstxtbd/cbiapts/TestBreakIteratorRules");
     54     addTest(root, &TestBreakIteratorRuleError, "tstxtbd/cbiapts/TestBreakIteratorRuleError");
     55     addTest(root, &TestBreakIteratorStatusVec, "tstxtbd/cbiapts/TestBreakIteratorStatusVec");
     56     addTest(root, &TestBreakIteratorUText, "tstxtbd/cbiapts/TestBreakIteratorUText");
     57 }
     58 
     59 #define CLONETEST_ITERATOR_COUNT 2
     60 
     61 /*
     62  *   Utility function for converting char * to UChar * strings, to
     63  *     simplify the test code.   Converted strings are put in heap allocated
     64  *     storage.   A hook (probably a local in the caller's code) allows all
     65  *     strings converted with that hook to be freed with a single call.
     66  */
     67 typedef struct StringStruct {
     68         struct StringStruct   *link;
     69         UChar                 str[1];
     70     } StringStruct;
     71 
     72 
     73 static UChar* toUChar(const char *src, void **freeHook) {
     74     /* Structure of the memory that we allocate on the heap */
     75 
     76     int32_t    numUChars;
     77     int32_t    destSize;
     78     UChar      stackBuf[2000 + sizeof(void *)/sizeof(UChar)];
     79     StringStruct  *dest;
     80     UConverter *cnv;
     81 
     82     UErrorCode status = U_ZERO_ERROR;
     83     if (src == NULL) {
     84         return NULL;
     85     };
     86 
     87     cnv = ucnv_open(NULL, &status);
     88     if(U_FAILURE(status) || cnv == NULL) {
     89         return NULL;
     90     }
     91     ucnv_reset(cnv);
     92     numUChars = ucnv_toUChars(cnv,
     93                   stackBuf,
     94                   2000,
     95                   src, -1,
     96                   &status);
     97 
     98     destSize = (numUChars+1) * sizeof(UChar) + sizeof(struct StringStruct);
     99     dest = (StringStruct *)malloc(destSize);
    100     if (dest != NULL) {
    101         if (status == U_BUFFER_OVERFLOW_ERROR || status == U_STRING_NOT_TERMINATED_WARNING) {
    102             ucnv_toUChars(cnv, dest->str, numUChars+1, src, -1, &status);
    103         } else if (status == U_ZERO_ERROR) {
    104             u_strcpy(dest->str, stackBuf);
    105         } else {
    106             free(dest);
    107             dest = NULL;
    108         }
    109     }
    110 
    111     ucnv_reset(cnv); /* be good citizens */
    112     ucnv_close(cnv);
    113     if (dest == NULL) {
    114         return NULL;
    115     }
    116 
    117     dest->link = (StringStruct*)(*freeHook);
    118     *freeHook = dest;
    119     return dest->str;
    120 }
    121 
    122 static void freeToUCharStrings(void **hook) {
    123     StringStruct  *s = *(StringStruct **)hook;
    124     while (s != NULL) {
    125         StringStruct *next = s->link;
    126         free(s);
    127         s = next;
    128     }
    129 }
    130 
    131 
    132 static void TestBreakIteratorCAPI()
    133 {
    134     UErrorCode status = U_ZERO_ERROR;
    135     UBreakIterator *word, *sentence, *line, *character, *b, *bogus;
    136     int32_t start,pos,end,to;
    137     int32_t i;
    138     int32_t count = 0;
    139 
    140     UChar text[50];
    141 
    142     /* Note:  the adjacent "" are concatenating strings, not adding a \" to the
    143        string, which is probably what whoever wrote this intended.  Don't fix,
    144        because it would throw off the hard coded break positions in the following
    145        tests. */
    146     u_uastrcpy(text, "He's from Africa. ""Mr. Livingston, I presume?"" Yeah");
    147 
    148 
    149 /*test ubrk_open()*/
    150     log_verbose("\nTesting BreakIterator open functions\n");
    151 
    152     /* Use french for fun */
    153     word         = ubrk_open(UBRK_WORD, "en_US", text, u_strlen(text), &status);
    154     if(status == U_FILE_ACCESS_ERROR) {
    155         log_data_err("Check your data - it doesn't seem to be around\n");
    156         return;
    157     } else if(U_FAILURE(status)){
    158         log_err_status(status, "FAIL: Error in ubrk_open() for word breakiterator: %s\n", myErrorName(status));
    159     }
    160     else{
    161         log_verbose("PASS: Successfully opened  word breakiterator\n");
    162     }
    163 
    164     sentence     = ubrk_open(UBRK_SENTENCE, "en_US", text, u_strlen(text), &status);
    165     if(U_FAILURE(status)){
    166         log_err_status(status, "FAIL: Error in ubrk_open() for sentence breakiterator: %s\n", myErrorName(status));
    167         return;
    168     }
    169     else{
    170         log_verbose("PASS: Successfully opened  sentence breakiterator\n");
    171     }
    172 
    173     line         = ubrk_open(UBRK_LINE, "en_US", text, u_strlen(text), &status);
    174     if(U_FAILURE(status)){
    175         log_err("FAIL: Error in ubrk_open() for line breakiterator: %s\n", myErrorName(status));
    176         return;
    177     }
    178     else{
    179         log_verbose("PASS: Successfully opened  line breakiterator\n");
    180     }
    181 
    182     character     = ubrk_open(UBRK_CHARACTER, "en_US", text, u_strlen(text), &status);
    183     if(U_FAILURE(status)){
    184         log_err("FAIL: Error in ubrk_open() for character breakiterator: %s\n", myErrorName(status));
    185         return;
    186     }
    187     else{
    188         log_verbose("PASS: Successfully opened  character breakiterator\n");
    189     }
    190     /*trying to open an illegal iterator*/
    191     bogus     = ubrk_open((UBreakIteratorType)5, "en_US", text, u_strlen(text), &status);
    192     if(U_SUCCESS(status)){
    193         log_err("FAIL: Error in ubrk_open() for BOGUS breakiterator. Expected U_ILLEGAL_ARGUMENT_ERROR\n");
    194     }
    195     if(U_FAILURE(status)){
    196         if(status != U_ILLEGAL_ARGUMENT_ERROR){
    197             log_err("FAIL: Error in ubrk_open() for BOGUS breakiterator. Expected U_ILLEGAL_ARGUMENT_ERROR\n Got %s\n", myErrorName(status));
    198         }
    199     }
    200     status=U_ZERO_ERROR;
    201 
    202 
    203 /* ======= Test ubrk_countAvialable() and ubrk_getAvialable() */
    204 
    205     log_verbose("\nTesting ubrk_countAvailable() and ubrk_getAvailable()\n");
    206     count=ubrk_countAvailable();
    207     /* use something sensible w/o hardcoding the count */
    208     if(count < 0){
    209         log_err("FAIL: Error in ubrk_countAvialable() returned %d\n", count);
    210     }
    211     else{
    212         log_verbose("PASS: ubrk_countAvialable() successful returned %d\n", count);
    213     }
    214     for(i=0;i<count;i++)
    215     {
    216         log_verbose("%s\n", ubrk_getAvailable(i));
    217         if (ubrk_getAvailable(i) == 0)
    218             log_err("No locale for which breakiterator is applicable\n");
    219         else
    220             log_verbose("A locale %s for which breakiterator is applicable\n",ubrk_getAvailable(i));
    221     }
    222 
    223 /*========Test ubrk_first(), ubrk_last()...... and other functions*/
    224 
    225     log_verbose("\nTesting the functions for word\n");
    226     start = ubrk_first(word);
    227     if(start!=0)
    228         log_err("error ubrk_start(word) did not return 0\n");
    229     log_verbose("first (word = %d\n", (int32_t)start);
    230        pos=ubrk_next(word);
    231     if(pos!=4)
    232         log_err("error ubrk_next(word) did not return 4\n");
    233     log_verbose("next (word = %d\n", (int32_t)pos);
    234     pos=ubrk_following(word, 4);
    235     if(pos!=5)
    236         log_err("error ubrl_following(word,4) did not return 6\n");
    237     log_verbose("next (word = %d\n", (int32_t)pos);
    238     end=ubrk_last(word);
    239     if(end!=49)
    240         log_err("error ubrk_last(word) did not return 49\n");
    241     log_verbose("last (word = %d\n", (int32_t)end);
    242 
    243     pos=ubrk_previous(word);
    244     log_verbose("%d   %d\n", end, pos);
    245 
    246     pos=ubrk_previous(word);
    247     log_verbose("%d \n", pos);
    248 
    249     if (ubrk_isBoundary(word, 2) != FALSE) {
    250         log_err("error ubrk_isBoundary(word, 2) did not return FALSE\n");
    251     }
    252     pos=ubrk_current(word);
    253     if (pos != 4) {
    254         log_err("error ubrk_current() != 4 after ubrk_isBoundary(word, 2)\n");
    255     }
    256     if (ubrk_isBoundary(word, 4) != TRUE) {
    257         log_err("error ubrk_isBoundary(word, 4) did not return TRUE\n");
    258     }
    259 
    260 
    261 
    262     log_verbose("\nTesting the functions for character\n");
    263     ubrk_first(character);
    264     pos = ubrk_following(character, 5);
    265     if(pos!=6)
    266        log_err("error ubrk_following(character,5) did not return 6\n");
    267     log_verbose("Following (character,5) = %d\n", (int32_t)pos);
    268     pos=ubrk_following(character, 18);
    269     if(pos!=19)
    270        log_err("error ubrk_following(character,18) did not return 19\n");
    271     log_verbose("Followingcharacter,18) = %d\n", (int32_t)pos);
    272     pos=ubrk_preceding(character, 22);
    273     if(pos!=21)
    274        log_err("error ubrk_preceding(character,22) did not return 21\n");
    275     log_verbose("preceding(character,22) = %d\n", (int32_t)pos);
    276 
    277 
    278     log_verbose("\nTesting the functions for line\n");
    279     pos=ubrk_first(line);
    280     if(pos != 0)
    281         log_err("error ubrk_first(line) returned %d, expected 0\n", (int32_t)pos);
    282     pos = ubrk_next(line);
    283     pos=ubrk_following(line, 18);
    284     if(pos!=22)
    285         log_err("error ubrk_following(line) did not return 22\n");
    286     log_verbose("following (line) = %d\n", (int32_t)pos);
    287 
    288 
    289     log_verbose("\nTesting the functions for sentence\n");
    290     ubrk_first(sentence);
    291     pos = ubrk_current(sentence);
    292     log_verbose("Current(sentence) = %d\n", (int32_t)pos);
    293        pos = ubrk_last(sentence);
    294     if(pos!=49)
    295         log_err("error ubrk_last for sentence did not return 49\n");
    296     log_verbose("Last (sentence) = %d\n", (int32_t)pos);
    297     ubrk_first(sentence);
    298     to = ubrk_following( sentence, 0 );
    299     if (to == 0) log_err("ubrk_following returned 0\n");
    300     to = ubrk_preceding( sentence, to );
    301     if (to != 0) log_err("ubrk_preceding didn't return 0\n");
    302     if (ubrk_first(sentence)!=ubrk_current(sentence)) {
    303         log_err("error in ubrk_first() or ubrk_current()\n");
    304     }
    305 
    306 
    307     /*---- */
    308     /*Testing ubrk_open and ubrk_close()*/
    309    log_verbose("\nTesting open and close for us locale\n");
    310     b = ubrk_open(UBRK_WORD, "fr_FR", text, u_strlen(text), &status);
    311     if (U_FAILURE(status)) {
    312         log_err("ubrk_open for word returned NULL: %s\n", myErrorName(status));
    313     }
    314     ubrk_close(b);
    315 
    316     /* Test setText and setUText */
    317     {
    318         UChar s1[] = {0x41, 0x42, 0x20, 0};
    319         UChar s2[] = {0x41, 0x42, 0x43, 0x44, 0x45, 0};
    320         UText *ut = NULL;
    321         UBreakIterator *bb;
    322         int j;
    323 
    324         log_verbose("\nTesting ubrk_setText() and ubrk_setUText()\n");
    325         status = U_ZERO_ERROR;
    326         bb = ubrk_open(UBRK_WORD, "en_US", NULL, 0, &status);
    327         TEST_ASSERT_SUCCESS(status);
    328         ubrk_setText(bb, s1, -1, &status);
    329         TEST_ASSERT_SUCCESS(status);
    330         ubrk_first(bb);
    331         j = ubrk_next(bb);
    332         TEST_ASSERT(j == 2);
    333         ut = utext_openUChars(ut, s2, -1, &status);
    334         ubrk_setUText(bb, ut, &status);
    335         TEST_ASSERT_SUCCESS(status);
    336         j = ubrk_next(bb);
    337         TEST_ASSERT(j == 5);
    338 
    339         ubrk_close(bb);
    340         utext_close(ut);
    341     }
    342 
    343     ubrk_close(word);
    344     ubrk_close(sentence);
    345     ubrk_close(line);
    346     ubrk_close(character);
    347 }
    348 
    349 static void TestBreakIteratorSafeClone(void)
    350 {
    351     UChar text[51];     /* Keep this odd to test for 64-bit memory alignment */
    352                         /*  NOTE:  This doesn't reliably force mis-alignment of following items. */
    353     uint8_t buffer [CLONETEST_ITERATOR_COUNT] [U_BRK_SAFECLONE_BUFFERSIZE];
    354     int32_t bufferSize = U_BRK_SAFECLONE_BUFFERSIZE;
    355 
    356     UBreakIterator * someIterators [CLONETEST_ITERATOR_COUNT];
    357     UBreakIterator * someClonedIterators [CLONETEST_ITERATOR_COUNT];
    358 
    359     UBreakIterator * brk;
    360     UErrorCode status = U_ZERO_ERROR;
    361     int32_t start,pos;
    362     int32_t i;
    363 
    364     /*Testing ubrk_safeClone */
    365 
    366     /* Note:  the adjacent "" are concatenating strings, not adding a \" to the
    367        string, which is probably what whoever wrote this intended.  Don't fix,
    368        because it would throw off the hard coded break positions in the following
    369        tests. */
    370     u_uastrcpy(text, "He's from Africa. ""Mr. Livingston, I presume?"" Yeah");
    371 
    372     /* US & Thai - rule-based & dictionary based */
    373     someIterators[0] = ubrk_open(UBRK_WORD, "en_US", text, u_strlen(text), &status);
    374     if(!someIterators[0] || U_FAILURE(status)) {
    375       log_data_err("Couldn't open en_US word break iterator - %s\n", u_errorName(status));
    376       return;
    377     }
    378 
    379     someIterators[1] = ubrk_open(UBRK_WORD, "th_TH", text, u_strlen(text), &status);
    380     if(!someIterators[1] || U_FAILURE(status)) {
    381       log_data_err("Couldn't open th_TH word break iterator - %s\n", u_errorName(status));
    382       return;
    383     }
    384 
    385     /* test each type of iterator */
    386     for (i = 0; i < CLONETEST_ITERATOR_COUNT; i++)
    387     {
    388 
    389         /* Check the various error & informational states */
    390 
    391         /* Null status - just returns NULL */
    392         if (0 != ubrk_safeClone(someIterators[i], buffer[i], &bufferSize, 0))
    393         {
    394             log_err("FAIL: Cloned Iterator failed to deal correctly with null status\n");
    395         }
    396         /* error status - should return 0 & keep error the same */
    397         status = U_MEMORY_ALLOCATION_ERROR;
    398         if (0 != ubrk_safeClone(someIterators[i], buffer[i], &bufferSize, &status) || status != U_MEMORY_ALLOCATION_ERROR)
    399         {
    400             log_err("FAIL: Cloned Iterator failed to deal correctly with incoming error status\n");
    401         }
    402         status = U_ZERO_ERROR;
    403 
    404         /* Null buffer size pointer - just returns NULL & set error to U_ILLEGAL_ARGUMENT_ERROR*/
    405         if (0 != ubrk_safeClone(someIterators[i], buffer[i], 0, &status) || status != U_ILLEGAL_ARGUMENT_ERROR)
    406         {
    407             log_err("FAIL: Cloned Iterator failed to deal correctly with null bufferSize pointer\n");
    408         }
    409         status = U_ZERO_ERROR;
    410 
    411         /* buffer size pointer is 0 - fill in pbufferSize with a size */
    412         bufferSize = 0;
    413         if (0 != ubrk_safeClone(someIterators[i], buffer[i], &bufferSize, &status) || U_FAILURE(status) || bufferSize <= 0)
    414         {
    415             log_err("FAIL: Cloned Iterator failed a sizing request ('preflighting')\n");
    416         }
    417         /* Verify our define is large enough  */
    418         if (U_BRK_SAFECLONE_BUFFERSIZE < bufferSize)
    419         {
    420             log_err("FAIL: Pre-calculated buffer size is too small\n");
    421         }
    422         /* Verify we can use this run-time calculated size */
    423         if (0 == (brk = ubrk_safeClone(someIterators[i], buffer[i], &bufferSize, &status)) || U_FAILURE(status))
    424         {
    425             log_err("FAIL: Iterator can't be cloned with run-time size\n");
    426         }
    427         if (brk)
    428             ubrk_close(brk);
    429         /* size one byte too small - should allocate & let us know */
    430         --bufferSize;
    431         if (0 == (brk = ubrk_safeClone(someIterators[i], 0, &bufferSize, &status)) || status != U_SAFECLONE_ALLOCATED_WARNING)
    432         {
    433             log_err("FAIL: Cloned Iterator failed to deal correctly with too-small buffer size\n");
    434         }
    435         if (brk)
    436             ubrk_close(brk);
    437         status = U_ZERO_ERROR;
    438         bufferSize = U_BRK_SAFECLONE_BUFFERSIZE;
    439 
    440         /* Null buffer pointer - return Iterator & set error to U_SAFECLONE_ALLOCATED_ERROR */
    441         if (0 == (brk = ubrk_safeClone(someIterators[i], 0, &bufferSize, &status)) || status != U_SAFECLONE_ALLOCATED_WARNING)
    442         {
    443             log_err("FAIL: Cloned Iterator failed to deal correctly with null buffer pointer\n");
    444         }
    445         if (brk)
    446             ubrk_close(brk);
    447         status = U_ZERO_ERROR;
    448 
    449         /* Mis-aligned buffer pointer. */
    450         {
    451             char  stackBuf[U_BRK_SAFECLONE_BUFFERSIZE+sizeof(void *)];
    452             void  *p;
    453             int32_t offset;
    454 
    455             brk = ubrk_safeClone(someIterators[i], &stackBuf[1], &bufferSize, &status);
    456             if (U_FAILURE(status) || brk == 0) {
    457                 log_err("FAIL: Cloned Iterator failed with misaligned buffer pointer\n");
    458             }
    459             if (status == U_SAFECLONE_ALLOCATED_WARNING) {
    460                 log_err("FAIL: Cloned Iterator allocated when using a mis-aligned buffer.\n");
    461             }
    462             offset = (int32_t)((char *)&p-(char*)brk);
    463             if (offset < 0) {
    464                 offset = -offset;
    465             }
    466             if (offset % sizeof(void *) != 0) {
    467                 log_err("FAIL: Cloned Iterator failed to align correctly with misaligned buffer pointer\n");
    468             }
    469             if (brk)
    470                 ubrk_close(brk);
    471         }
    472 
    473 
    474         /* Null Iterator - return NULL & set U_ILLEGAL_ARGUMENT_ERROR */
    475         if (0 != ubrk_safeClone(0, buffer[i], &bufferSize, &status) || status != U_ILLEGAL_ARGUMENT_ERROR)
    476         {
    477             log_err("FAIL: Cloned Iterator failed to deal correctly with null Iterator pointer\n");
    478         }
    479         status = U_ZERO_ERROR;
    480 
    481         /* Do these cloned Iterators work at all - make a first & next call */
    482         bufferSize = U_BRK_SAFECLONE_BUFFERSIZE;
    483         someClonedIterators[i] = ubrk_safeClone(someIterators[i], buffer[i], &bufferSize, &status);
    484 
    485         start = ubrk_first(someClonedIterators[i]);
    486         if(start!=0)
    487             log_err("error ubrk_start(clone) did not return 0\n");
    488         pos=ubrk_next(someClonedIterators[i]);
    489         if(pos!=4)
    490             log_err("error ubrk_next(clone) did not return 4\n");
    491 
    492         ubrk_close(someClonedIterators[i]);
    493         ubrk_close(someIterators[i]);
    494     }
    495 }
    496 
    497 
    498 /*
    499 //  Open a break iterator from char * rules.  Take care of conversion
    500 //     of the rules and error checking.
    501 */
    502 static UBreakIterator * testOpenRules(char *rules) {
    503     UErrorCode      status       = U_ZERO_ERROR;
    504     UChar          *ruleSourceU  = NULL;
    505     void           *strCleanUp   = NULL;
    506     UParseError     parseErr;
    507     UBreakIterator *bi;
    508 
    509     ruleSourceU = toUChar(rules, &strCleanUp);
    510 
    511     bi = ubrk_openRules(ruleSourceU,  -1,     /*  The rules  */
    512                         NULL,  -1,            /*  The text to be iterated over. */
    513                         &parseErr, &status);
    514 
    515     if (U_FAILURE(status)) {
    516         log_data_err("FAIL: ubrk_openRules: ICU Error \"%s\" (Are you missing data?)\n", u_errorName(status));
    517         bi = 0;
    518     };
    519     freeToUCharStrings(&strCleanUp);
    520     return bi;
    521 
    522 }
    523 
    524 /*
    525  *  TestBreakIteratorRules - Verify that a break iterator can be created from
    526  *                           a set of source rules.
    527  */
    528 static void TestBreakIteratorRules() {
    529     /*  Rules will keep together any run of letters not including 'a', OR
    530      *             keep together 'abc', but only when followed by 'def', OTHERWISE
    531      *             just return one char at a time.
    532      */
    533     char         rules[]  = "abc{666}/def;\n   [\\p{L} - [a]]* {2};  . {1};";
    534     /*                        0123456789012345678 */
    535     char         data[]   =  "abcdex abcdefgh-def";     /* the test data string                     */
    536     char         breaks[] =  "**    **  *    **  *";    /*  * the expected break positions          */
    537     char         tags[]   =  "01    21  6    21  2";    /*  expected tag values at break positions  */
    538     int32_t      tagMap[] = {0, 1, 2, 3, 4, 5, 666};
    539 
    540     UChar       *uData;
    541     void        *freeHook = NULL;
    542     UErrorCode   status   = U_ZERO_ERROR;
    543     int32_t      pos;
    544     int          i;
    545 
    546     UBreakIterator *bi = testOpenRules(rules);
    547     if (bi == NULL) {return;}
    548     uData = toUChar(data, &freeHook);
    549     ubrk_setText(bi,  uData, -1, &status);
    550 
    551     pos = ubrk_first(bi);
    552     for (i=0; i<sizeof(breaks); i++) {
    553         if (pos == i && breaks[i] != '*') {
    554             log_err("FAIL: unexpected break at position %d found\n", pos);
    555             break;
    556         }
    557         if (pos != i && breaks[i] == '*') {
    558             log_err("FAIL: expected break at position %d not found.\n", i);
    559             break;
    560         }
    561         if (pos == i) {
    562             int32_t tag, expectedTag;
    563             tag = ubrk_getRuleStatus(bi);
    564             expectedTag = tagMap[tags[i]&0xf];
    565             if (tag != expectedTag) {
    566                 log_err("FAIL: incorrect tag value.  Position = %d;  expected tag %d, got %d",
    567                     pos, expectedTag, tag);
    568                 break;
    569             }
    570             pos = ubrk_next(bi);
    571         }
    572     }
    573 
    574     freeToUCharStrings(&freeHook);
    575     ubrk_close(bi);
    576 }
    577 
    578 static void TestBreakIteratorRuleError() {
    579 /*
    580  *  TestBreakIteratorRuleError -   Try to create a BI from rules with syntax errors,
    581  *                                 check that the error is reported correctly.
    582  */
    583     char            rules[]  = "           #  This is a rule comment on line 1\n"
    584                                "[:L:];     # this rule is OK.\n"
    585                                "abcdefg);  # Error, mismatched parens\n";
    586     UChar          *uRules;
    587     void           *freeHook = NULL;
    588     UErrorCode      status   = U_ZERO_ERROR;
    589     UParseError     parseErr;
    590     UBreakIterator *bi;
    591 
    592     uRules = toUChar(rules, &freeHook);
    593     bi = ubrk_openRules(uRules,  -1,          /*  The rules  */
    594                         NULL,  -1,            /*  The text to be iterated over. */
    595                         &parseErr, &status);
    596     if (U_SUCCESS(status)) {
    597         log_err("FAIL: construction of break iterator succeeded when it should have failed.\n");
    598         ubrk_close(bi);
    599     } else {
    600         if (parseErr.line != 3 || parseErr.offset != 8) {
    601             log_data_err("FAIL: incorrect error position reported. Got line %d, char %d, expected line 3, char 7 (Are you missing data?)\n",
    602                 parseErr.line, parseErr.offset);
    603         }
    604     }
    605     freeToUCharStrings(&freeHook);
    606 }
    607 
    608 
    609 /*
    610 *   TestsBreakIteratorStatusVals()   Test the ubrk_getRuleStatusVec() funciton
    611 */
    612 static void TestBreakIteratorStatusVec() {
    613     #define RULE_STRING_LENGTH 200
    614     UChar          rules[RULE_STRING_LENGTH];
    615 
    616     #define TEST_STRING_LENGTH 25
    617     UChar           testString[TEST_STRING_LENGTH];
    618     UBreakIterator *bi        = NULL;
    619     int32_t         pos       = 0;
    620     int32_t         vals[10];
    621     int32_t         numVals;
    622     UErrorCode      status    = U_ZERO_ERROR;
    623 
    624     u_uastrncpy(rules,  "[A-N]{100}; \n"
    625                              "[a-w]{200}; \n"
    626                              "[\\p{L}]{300}; \n"
    627                              "[\\p{N}]{400}; \n"
    628                              "[0-5]{500}; \n"
    629                               "!.*;\n", RULE_STRING_LENGTH);
    630     u_uastrncpy(testString, "ABC", TEST_STRING_LENGTH);
    631 
    632 
    633     bi = ubrk_openRules(rules, -1, testString, -1, NULL, &status);
    634     TEST_ASSERT_SUCCESS(status);
    635     TEST_ASSERT(bi != NULL);
    636 
    637     /* The TEST_ASSERT above should change too... */
    638     if (bi != NULL) {
    639         pos = ubrk_next(bi);
    640         TEST_ASSERT(pos == 1);
    641 
    642         memset(vals, -1, sizeof(vals));
    643         numVals = ubrk_getRuleStatusVec(bi, vals, 10, &status);
    644         TEST_ASSERT_SUCCESS(status);
    645         TEST_ASSERT(numVals == 2);
    646         TEST_ASSERT(vals[0] == 100);
    647         TEST_ASSERT(vals[1] == 300);
    648         TEST_ASSERT(vals[2] == -1);
    649 
    650         numVals = ubrk_getRuleStatusVec(bi, vals, 0, &status);
    651         TEST_ASSERT(status == U_BUFFER_OVERFLOW_ERROR);
    652         TEST_ASSERT(numVals == 2);
    653     }
    654 
    655     ubrk_close(bi);
    656 }
    657 
    658 
    659 /*
    660  *  static void TestBreakIteratorUText(void);
    661  *
    662  *         Test that ubrk_setUText() is present and works for a simple case.
    663  */
    664 static void TestBreakIteratorUText(void) {
    665     const char *UTF8Str = "\x41\xc3\x85\x5A\x20\x41\x52\x69\x6E\x67";  /* c3 85 is utf-8 for A with a ring on top */
    666                       /*   0  1   2 34567890  */
    667 
    668     UErrorCode      status = U_ZERO_ERROR;
    669     UBreakIterator *bi     = NULL;
    670     int32_t         pos    = 0;
    671 
    672 
    673     UText *ut = utext_openUTF8(NULL, UTF8Str, -1, &status);
    674     TEST_ASSERT_SUCCESS(status);
    675 
    676     bi = ubrk_open(UBRK_WORD, "en_US", NULL, 0, &status);
    677     if (U_FAILURE(status)) {
    678         log_err_status(status, "Failure at file %s, line %d, error = %s\n", __FILE__, __LINE__, u_errorName(status));
    679         return;
    680     }
    681 
    682     ubrk_setUText(bi, ut, &status);
    683     if (U_FAILURE(status)) {
    684         log_err("Failure at file %s, line %d, error = %s\n", __FILE__, __LINE__, u_errorName(status));
    685         return;
    686     }
    687 
    688     pos = ubrk_first(bi);
    689     TEST_ASSERT(pos == 0);
    690 
    691     pos = ubrk_next(bi);
    692     TEST_ASSERT(pos == 4);
    693 
    694     pos = ubrk_next(bi);
    695     TEST_ASSERT(pos == 5);
    696 
    697     pos = ubrk_next(bi);
    698     TEST_ASSERT(pos == 10);
    699 
    700     pos = ubrk_next(bi);
    701     TEST_ASSERT(pos == UBRK_DONE);
    702     ubrk_close(bi);
    703     utext_close(ut);
    704 }
    705 
    706 
    707 
    708 #endif /* #if !UCONFIG_NO_BREAK_ITERATION */
    709