Home | History | Annotate | Download | only in cintltst
      1 /*
      2 *******************************************************************************
      3 *
      4 *   Copyright (C) 2002-2015, International Business Machines
      5 *   Corporation and others.  All Rights Reserved.
      6 *
      7 *******************************************************************************
      8 *   file name:  cstrcase.c
      9 *   encoding:   US-ASCII
     10 *   tab size:   8 (not used)
     11 *   indentation:4
     12 *
     13 *   created on: 2002feb21
     14 *   created by: Markus W. Scherer
     15 *
     16 *   Test file for string casing C API functions.
     17 */
     18 
     19 #include <string.h>
     20 #include "unicode/utypes.h"
     21 #include "unicode/uchar.h"
     22 #include "unicode/ustring.h"
     23 #include "unicode/uloc.h"
     24 #include "unicode/ubrk.h"
     25 #include "unicode/ucasemap.h"
     26 #include "cmemory.h"
     27 #include "cintltst.h"
     28 #include "ustr_imp.h"
     29 
     30 /* test string case mapping functions --------------------------------------- */
     31 
     32 static void
     33 TestCaseLower(void) {
     34     static const UChar
     35 
     36     beforeLower[]= { 0x61, 0x42, 0x49,  0x3a3, 0xdf, 0x3a3, 0x2f, 0xd93f, 0xdfff },
     37     lowerRoot[]=   { 0x61, 0x62, 0x69,  0x3c3, 0xdf, 0x3c2, 0x2f, 0xd93f, 0xdfff },
     38     lowerTurkish[]={ 0x61, 0x62, 0x131, 0x3c3, 0xdf, 0x3c2, 0x2f, 0xd93f, 0xdfff };
     39 
     40     UChar buffer[32];
     41     int32_t length;
     42     UErrorCode errorCode;
     43 
     44     /* lowercase with root locale and separate buffers */
     45     buffer[0]=0xabcd;
     46     errorCode=U_ZERO_ERROR;
     47     length=u_strToLower(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
     48                         beforeLower, sizeof(beforeLower)/U_SIZEOF_UCHAR,
     49                         "",
     50                         &errorCode);
     51     if( U_FAILURE(errorCode) ||
     52         length!=(sizeof(lowerRoot)/U_SIZEOF_UCHAR) ||
     53         uprv_memcmp(lowerRoot, buffer, length*U_SIZEOF_UCHAR)!=0 ||
     54         buffer[length]!=0
     55     ) {
     56         log_err("error in u_strToLower(root locale)=%ld error=%s string matches: %s\t\nlowerRoot=%s\t\nbuffer=%s\n",
     57             length,
     58             u_errorName(errorCode),
     59             uprv_memcmp(lowerRoot, buffer, length*U_SIZEOF_UCHAR)==0 &&
     60 buffer[length]==0 ? "yes" : "no",
     61             aescstrdup(lowerRoot,-1),
     62             aescstrdup(buffer,-1));
     63     }
     64 
     65     /* lowercase with turkish locale and in the same buffer */
     66     uprv_memcpy(buffer, beforeLower, sizeof(beforeLower));
     67     buffer[sizeof(beforeLower)/U_SIZEOF_UCHAR]=0;
     68     errorCode=U_ZERO_ERROR;
     69     length=u_strToLower(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
     70                         buffer, -1, /* implicit srcLength */
     71                         "tr",
     72                         &errorCode);
     73     if( U_FAILURE(errorCode) ||
     74         length!=(sizeof(lowerTurkish)/U_SIZEOF_UCHAR) ||
     75         uprv_memcmp(lowerTurkish, buffer, length*U_SIZEOF_UCHAR)!=0 ||
     76         buffer[length]!=0
     77     ) {
     78         log_err("error in u_strToLower(turkish locale)=%ld error=%s string matches: %s\n",
     79             length,
     80             u_errorName(errorCode),
     81             uprv_memcmp(lowerTurkish, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no");
     82     }
     83 
     84     /* test preflighting */
     85     buffer[0]=buffer[2]=0xabcd;
     86     errorCode=U_ZERO_ERROR;
     87     length=u_strToLower(buffer, 2, /* set destCapacity=2 */
     88                         beforeLower, sizeof(beforeLower)/U_SIZEOF_UCHAR,
     89                         "",
     90                         &errorCode);
     91     if( errorCode!=U_BUFFER_OVERFLOW_ERROR ||
     92         length!=(sizeof(lowerRoot)/U_SIZEOF_UCHAR) ||
     93         uprv_memcmp(lowerRoot, buffer, 2*U_SIZEOF_UCHAR)!=0 ||
     94         buffer[2]!=0xabcd
     95     ) {
     96         log_err("error in u_strToLower(root locale preflighting)=%ld error=%s string matches: %s\n",
     97             length,
     98             u_errorName(errorCode),
     99             uprv_memcmp(lowerRoot, buffer, 2*U_SIZEOF_UCHAR)==0 && buffer[2]==0xabcd ? "yes" : "no");
    100     }
    101 
    102     /* test error handling */
    103     errorCode=U_ZERO_ERROR;
    104     length=u_strToLower(NULL, sizeof(buffer)/U_SIZEOF_UCHAR,
    105                         beforeLower, sizeof(beforeLower)/U_SIZEOF_UCHAR,
    106                         "",
    107                         &errorCode);
    108     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
    109         log_err("error in u_strToLower(root locale dest=NULL)=%ld error=%s\n",
    110             length,
    111             u_errorName(errorCode));
    112     }
    113 
    114     buffer[0]=0xabcd;
    115     errorCode=U_ZERO_ERROR;
    116     length=u_strToLower(buffer, -1,
    117                         beforeLower, sizeof(beforeLower)/U_SIZEOF_UCHAR,
    118                         "",
    119                         &errorCode);
    120     if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR ||
    121         buffer[0]!=0xabcd
    122     ) {
    123         log_err("error in u_strToLower(root locale destCapacity=-1)=%ld error=%s buffer[0]==0x%lx\n",
    124             length,
    125             u_errorName(errorCode),
    126             buffer[0]);
    127     }
    128 }
    129 
    130 static void
    131 TestCaseUpper(void) {
    132     static const UChar
    133 
    134     beforeUpper[]= { 0x61, 0x42, 0x69,  0x3c2, 0xdf,       0x3c3, 0x2f, 0xfb03,           0xd93f, 0xdfff },
    135     upperRoot[]=   { 0x41, 0x42, 0x49,  0x3a3, 0x53, 0x53, 0x3a3, 0x2f, 0x46, 0x46, 0x49, 0xd93f, 0xdfff },
    136     upperTurkish[]={ 0x41, 0x42, 0x130, 0x3a3, 0x53, 0x53, 0x3a3, 0x2f, 0x46, 0x46, 0x49, 0xd93f, 0xdfff };
    137 
    138     UChar buffer[32];
    139     int32_t length;
    140     UErrorCode errorCode;
    141 
    142     /* uppercase with root locale and in the same buffer */
    143     uprv_memcpy(buffer, beforeUpper, sizeof(beforeUpper));
    144     errorCode=U_ZERO_ERROR;
    145     length=u_strToUpper(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    146                         buffer, sizeof(beforeUpper)/U_SIZEOF_UCHAR,
    147                         "",
    148                         &errorCode);
    149     if( U_FAILURE(errorCode) ||
    150         length!=(sizeof(upperRoot)/U_SIZEOF_UCHAR) ||
    151         uprv_memcmp(upperRoot, buffer, length*U_SIZEOF_UCHAR)!=0 ||
    152         buffer[length]!=0
    153     ) {
    154         log_err("error in u_strToUpper(root locale)=%ld error=%s string matches: %s\n",
    155             length,
    156             u_errorName(errorCode),
    157             uprv_memcmp(upperRoot, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no");
    158     }
    159 
    160     /* uppercase with turkish locale and separate buffers */
    161     buffer[0]=0xabcd;
    162     errorCode=U_ZERO_ERROR;
    163     length=u_strToUpper(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    164                         beforeUpper, sizeof(beforeUpper)/U_SIZEOF_UCHAR,
    165                         "tr",
    166                         &errorCode);
    167     if( U_FAILURE(errorCode) ||
    168         length!=(sizeof(upperTurkish)/U_SIZEOF_UCHAR) ||
    169         uprv_memcmp(upperTurkish, buffer, length*U_SIZEOF_UCHAR)!=0 ||
    170         buffer[length]!=0
    171     ) {
    172         log_err("error in u_strToUpper(turkish locale)=%ld error=%s string matches: %s\n",
    173             length,
    174             u_errorName(errorCode),
    175             uprv_memcmp(upperTurkish, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no");
    176     }
    177 
    178     /* test preflighting */
    179     errorCode=U_ZERO_ERROR;
    180     length=u_strToUpper(NULL, 0,
    181                         beforeUpper, sizeof(beforeUpper)/U_SIZEOF_UCHAR,
    182                         "tr",
    183                         &errorCode);
    184     if( errorCode!=U_BUFFER_OVERFLOW_ERROR ||
    185         length!=(sizeof(upperTurkish)/U_SIZEOF_UCHAR)
    186     ) {
    187         log_err("error in u_strToUpper(turkish locale pure preflighting)=%ld error=%s\n",
    188             length,
    189             u_errorName(errorCode));
    190     }
    191 
    192     /* test error handling */
    193     buffer[0]=0xabcd;
    194     errorCode=U_ZERO_ERROR;
    195     length=u_strToUpper(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    196                         NULL, sizeof(beforeUpper)/U_SIZEOF_UCHAR,
    197                         "tr",
    198                         &errorCode);
    199     if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR ||
    200         buffer[0]!=0xabcd
    201     ) {
    202         log_err("error in u_strToUpper(turkish locale src=NULL)=%ld error=%s buffer[0]==0x%lx\n",
    203             length,
    204             u_errorName(errorCode),
    205             buffer[0]);
    206     }
    207 
    208     buffer[0]=0xabcd;
    209     errorCode=U_ZERO_ERROR;
    210     length=u_strToUpper(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    211                         beforeUpper, -2,
    212                         "tr",
    213                         &errorCode);
    214     if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR ||
    215         buffer[0]!=0xabcd
    216     ) {
    217         log_err("error in u_strToUpper(turkish locale srcLength=-2)=%ld error=%s buffer[0]==0x%lx\n",
    218             length,
    219             u_errorName(errorCode),
    220             buffer[0]);
    221     }
    222 }
    223 
    224 #if !UCONFIG_NO_BREAK_ITERATION
    225 
    226 static void
    227 TestCaseTitle(void) {
    228     static const UChar
    229 
    230     beforeTitle[]= { 0x61, 0x42, 0x20, 0x69,  0x3c2, 0x20, 0xdf,       0x3c3, 0x2f, 0xfb03,           0xd93f, 0xdfff },
    231     titleWord[]=   { 0x41, 0x62, 0x20, 0x49,  0x3c2, 0x20, 0x53, 0x73, 0x3c3, 0x2f, 0x46, 0x66, 0x69, 0xd93f, 0xdfff },
    232     titleChar[]=   { 0x41, 0x42, 0x20, 0x49,  0x3a3, 0x20, 0x53, 0x73, 0x3a3, 0x2f, 0x46, 0x66, 0x69, 0xd93f, 0xdfff };
    233 
    234     UChar buffer[32];
    235     UBreakIterator *titleIterChars;
    236     int32_t length;
    237     UErrorCode errorCode;
    238 
    239     errorCode=U_ZERO_ERROR;
    240     titleIterChars=ubrk_open(UBRK_CHARACTER, "", beforeTitle, sizeof(beforeTitle)/U_SIZEOF_UCHAR, &errorCode);
    241     if(U_FAILURE(errorCode)) {
    242         log_err_status(errorCode, "error: ubrk_open(UBRK_CHARACTER)->%s\n", u_errorName(errorCode));
    243         return;
    244     }
    245 
    246     /* titlecase with standard break iterator and in the same buffer */
    247     uprv_memcpy(buffer, beforeTitle, sizeof(beforeTitle));
    248     errorCode=U_ZERO_ERROR;
    249     length=u_strToTitle(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    250                         buffer, sizeof(beforeTitle)/U_SIZEOF_UCHAR,
    251                         NULL, "",
    252                         &errorCode);
    253     if( U_FAILURE(errorCode) ||
    254         length!=(sizeof(titleWord)/U_SIZEOF_UCHAR) ||
    255         uprv_memcmp(titleWord, buffer, length*U_SIZEOF_UCHAR)!=0 ||
    256         buffer[length]!=0
    257     ) {
    258         log_err("error in u_strToTitle(standard iterator)=%ld error=%s string matches: %s\n",
    259             length,
    260             u_errorName(errorCode),
    261             uprv_memcmp(titleWord, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no");
    262     }
    263 
    264     /* titlecase with UBRK_CHARACTERS and separate buffers */
    265     buffer[0]=0xabcd;
    266     errorCode=U_ZERO_ERROR;
    267     length=u_strToTitle(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    268                         beforeTitle, sizeof(beforeTitle)/U_SIZEOF_UCHAR,
    269                         titleIterChars, "",
    270                         &errorCode);
    271     if( U_FAILURE(errorCode) ||
    272         length!=(sizeof(titleChar)/U_SIZEOF_UCHAR) ||
    273         uprv_memcmp(titleChar, buffer, length*U_SIZEOF_UCHAR)!=0 ||
    274         buffer[length]!=0
    275     ) {
    276         log_err("error in u_strToTitle(UBRK_CHARACTERS)=%ld error=%s string matches: %s\n",
    277             length,
    278             u_errorName(errorCode),
    279             uprv_memcmp(titleChar, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no");
    280     }
    281 
    282     /* test preflighting */
    283     errorCode=U_ZERO_ERROR;
    284     length=u_strToTitle(NULL, 0,
    285                         beforeTitle, sizeof(beforeTitle)/U_SIZEOF_UCHAR,
    286                         titleIterChars, "",
    287                         &errorCode);
    288     if( errorCode!=U_BUFFER_OVERFLOW_ERROR ||
    289         length!=(sizeof(titleChar)/U_SIZEOF_UCHAR)
    290     ) {
    291         log_err("error in u_strToTitle(UBRK_CHARACTERS pure preflighting)=%ld error=%s\n",
    292             length,
    293             u_errorName(errorCode));
    294     }
    295 
    296     /* test error handling */
    297     buffer[0]=0xabcd;
    298     errorCode=U_ZERO_ERROR;
    299     length=u_strToTitle(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    300                         NULL, sizeof(beforeTitle)/U_SIZEOF_UCHAR,
    301                         titleIterChars, "",
    302                         &errorCode);
    303     if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR ||
    304         buffer[0]!=0xabcd
    305     ) {
    306         log_err("error in u_strToTitle(UBRK_CHARACTERS src=NULL)=%ld error=%s buffer[0]==0x%lx\n",
    307             length,
    308             u_errorName(errorCode),
    309             buffer[0]);
    310     }
    311 
    312     buffer[0]=0xabcd;
    313     errorCode=U_ZERO_ERROR;
    314     length=u_strToTitle(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    315                         beforeTitle, -2,
    316                         titleIterChars, "",
    317                         &errorCode);
    318     if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR ||
    319         buffer[0]!=0xabcd
    320     ) {
    321         log_err("error in u_strToTitle(UBRK_CHARACTERS srcLength=-2)=%ld error=%s buffer[0]==0x%lx\n",
    322             length,
    323             u_errorName(errorCode),
    324             buffer[0]);
    325     }
    326 
    327     ubrk_close(titleIterChars);
    328 }
    329 
    330 static void
    331 TestCaseDutchTitle(void) {
    332     static const UChar
    333 
    334     beforeTitle[]= { 0x69, 0x6A, 0x73, 0x73,  0x45, 0x6c, 0x20, 0x69, 0x67, 0x6c, 0x4f, 0x6f , 0x20 , 0x49, 0x4A, 0x53, 0x53, 0x45, 0x4C },
    335     titleRoot[]=   { 0x49, 0x6A, 0x73, 0x73,  0x65, 0x6c, 0x20, 0x49, 0x67, 0x6c, 0x6f, 0x6f , 0x20 , 0x49, 0x6A, 0x73, 0x73, 0x65, 0x6C },
    336     titleDutch[]=  { 0x49, 0x4A, 0x73, 0x73,  0x65, 0x6c, 0x20, 0x49, 0x67, 0x6c, 0x6f, 0x6f , 0x20 , 0x49, 0x4A, 0x73, 0x73, 0x65, 0x6C };
    337 
    338     UChar buffer[32];
    339     UBreakIterator *titleIterWord;
    340     int32_t length;
    341     UErrorCode errorCode;
    342 
    343     errorCode=U_ZERO_ERROR;
    344     titleIterWord=ubrk_open(UBRK_WORD, "", beforeTitle, sizeof(beforeTitle)/U_SIZEOF_UCHAR, &errorCode);
    345     if(U_FAILURE(errorCode)) {
    346         log_err_status(errorCode, "error: ubrk_open(UBRK_WORD)->%s\n", u_errorName(errorCode));
    347         return;
    348     }
    349 
    350     /* titlecase with default locale */
    351     buffer[0]=0xabcd;
    352     errorCode=U_ZERO_ERROR;
    353     length=u_strToTitle(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    354                         beforeTitle, sizeof(beforeTitle)/U_SIZEOF_UCHAR,
    355                         titleIterWord, "",
    356                         &errorCode);
    357     if( U_FAILURE(errorCode) ||
    358         length!=(sizeof(titleRoot)/U_SIZEOF_UCHAR) ||
    359         uprv_memcmp(titleRoot, buffer, length*U_SIZEOF_UCHAR)!=0 ||
    360         buffer[length]!=0
    361     ) {
    362         char charsOut[21];
    363         u_UCharsToChars(buffer,charsOut,sizeof(charsOut));
    364         log_err("error in u_strToTitle(UBRK_CHARACTERS)=%ld error=%s root locale string matches: %s\noutput buffer is {%s}\n",
    365             length,
    366             u_errorName(errorCode),
    367             uprv_memcmp(titleRoot, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no", charsOut);
    368     }
    369     /* titlecase with Dutch locale */
    370     buffer[0]=0xabcd;
    371     errorCode=U_ZERO_ERROR;
    372     length=u_strToTitle(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    373                         beforeTitle, sizeof(beforeTitle)/U_SIZEOF_UCHAR,
    374                         titleIterWord, "nl",
    375                         &errorCode);
    376     if( U_FAILURE(errorCode) ||
    377         length!=(sizeof(titleDutch)/U_SIZEOF_UCHAR) ||
    378         uprv_memcmp(titleDutch, buffer, length*U_SIZEOF_UCHAR)!=0 ||
    379         buffer[length]!=0
    380     ) {
    381         char charsOut[21];
    382         u_UCharsToChars(buffer,charsOut,sizeof(charsOut));
    383         log_err("error in u_strToTitle(UBRK_CHARACTERS)=%ld error=%s dutch locale string matches: %s\noutput buffer is {%s}\n",
    384             length,
    385             u_errorName(errorCode),
    386             uprv_memcmp(titleDutch, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no", charsOut);
    387     }
    388 
    389     ubrk_close(titleIterWord);
    390 }
    391 
    392 #endif
    393 
    394 /* test case folding and case-insensitive string compare -------------------- */
    395 
    396 static void
    397 TestCaseFolding(void) {
    398     /*
    399      * CaseFolding.txt says about i and its cousins:
    400      *   0049; C; 0069; # LATIN CAPITAL LETTER I
    401      *   0049; T; 0131; # LATIN CAPITAL LETTER I
    402      *
    403      *   0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE
    404      *   0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE
    405      * That's all.
    406      * See CaseFolding.txt and the Unicode Standard for how to apply the case foldings.
    407      */
    408     static const UChar32
    409     simple[]={
    410         /* input, default, exclude special i */
    411         0x61,   0x61,  0x61,
    412         0x49,   0x69,  0x131,
    413         0x130,  0x130, 0x69,
    414         0x131,  0x131, 0x131,
    415         0xdf,   0xdf,  0xdf,
    416         0xfb03, 0xfb03, 0xfb03,
    417         0x1040e,0x10436,0x10436,
    418         0x5ffff,0x5ffff,0x5ffff
    419     };
    420 
    421     static const UChar
    422     mixed[]=                { 0x61, 0x42, 0x130,       0x49,  0x131, 0x3d0, 0xdf,       0xfb03,           0xd93f, 0xdfff },
    423     foldedDefault[]=        { 0x61, 0x62, 0x69, 0x307, 0x69,  0x131, 0x3b2, 0x73, 0x73, 0x66, 0x66, 0x69, 0xd93f, 0xdfff },
    424     foldedExcludeSpecialI[]={ 0x61, 0x62, 0x69,        0x131, 0x131, 0x3b2, 0x73, 0x73, 0x66, 0x66, 0x69, 0xd93f, 0xdfff };
    425 
    426     UVersionInfo unicodeVersion={ 0, 0, 17, 89 }, unicode_3_1={ 3, 1, 0, 0 };
    427 
    428     const UChar32 *p;
    429     int32_t i;
    430 
    431     UChar buffer[32];
    432     int32_t length;
    433     UErrorCode errorCode;
    434     UBool isUnicode_3_1;
    435 
    436     /* if unicodeVersion()>=3.1 then test exclude-special-i cases as well */
    437     u_getUnicodeVersion(unicodeVersion);
    438     isUnicode_3_1= uprv_memcmp(unicodeVersion, unicode_3_1, 4)>=0;
    439 
    440     /* test simple case folding */
    441     p=simple;
    442     for(i=0; i<sizeof(simple)/12; p+=3, ++i) {
    443         if(u_foldCase(p[0], U_FOLD_CASE_DEFAULT)!=p[1]) {
    444             log_err("error: u_foldCase(0x%04lx, default)=0x%04lx instead of 0x%04lx\n",
    445                     p[0], u_foldCase(p[0], U_FOLD_CASE_DEFAULT), p[1]);
    446             return;
    447         }
    448 
    449         if(isUnicode_3_1 && u_foldCase(p[0], U_FOLD_CASE_EXCLUDE_SPECIAL_I)!=p[2]) {
    450             log_err("error: u_foldCase(0x%04lx, exclude special i)=0x%04lx instead of 0x%04lx\n",
    451                     p[0], u_foldCase(p[0], U_FOLD_CASE_EXCLUDE_SPECIAL_I), p[2]);
    452             return;
    453         }
    454     }
    455 
    456     /* test full string case folding with default option and separate buffers */
    457     buffer[0]=0xabcd;
    458     errorCode=U_ZERO_ERROR;
    459     length=u_strFoldCase(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    460                         mixed, sizeof(mixed)/U_SIZEOF_UCHAR,
    461                         U_FOLD_CASE_DEFAULT,
    462                         &errorCode);
    463     if( U_FAILURE(errorCode) ||
    464         length!=(sizeof(foldedDefault)/U_SIZEOF_UCHAR) ||
    465         uprv_memcmp(foldedDefault, buffer, length*U_SIZEOF_UCHAR)!=0 ||
    466         buffer[length]!=0
    467     ) {
    468         log_err("error in u_strFoldCase(default)=%ld error=%s string matches: %s\n",
    469             length,
    470             u_errorName(errorCode),
    471             uprv_memcmp(foldedDefault, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no");
    472     }
    473 
    474     /* exclude special i */
    475     if(isUnicode_3_1) {
    476         buffer[0]=0xabcd;
    477         errorCode=U_ZERO_ERROR;
    478         length=u_strFoldCase(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    479                             mixed, sizeof(mixed)/U_SIZEOF_UCHAR,
    480                             U_FOLD_CASE_EXCLUDE_SPECIAL_I,
    481                             &errorCode);
    482         if( U_FAILURE(errorCode) ||
    483             length!=(sizeof(foldedExcludeSpecialI)/U_SIZEOF_UCHAR) ||
    484             uprv_memcmp(foldedExcludeSpecialI, buffer, length*U_SIZEOF_UCHAR)!=0 ||
    485             buffer[length]!=0
    486         ) {
    487             log_err("error in u_strFoldCase(exclude special i)=%ld error=%s string matches: %s\n",
    488                 length,
    489                 u_errorName(errorCode),
    490                 uprv_memcmp(foldedExcludeSpecialI, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no");
    491         }
    492     }
    493 
    494     /* test full string case folding with default option and in the same buffer */
    495     uprv_memcpy(buffer, mixed, sizeof(mixed));
    496     buffer[sizeof(mixed)/U_SIZEOF_UCHAR]=0;
    497     errorCode=U_ZERO_ERROR;
    498     length=u_strFoldCase(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    499                         buffer, -1, /* implicit srcLength */
    500                         U_FOLD_CASE_DEFAULT,
    501                         &errorCode);
    502     if( U_FAILURE(errorCode) ||
    503         length!=(sizeof(foldedDefault)/U_SIZEOF_UCHAR) ||
    504         uprv_memcmp(foldedDefault, buffer, length*U_SIZEOF_UCHAR)!=0 ||
    505         buffer[length]!=0
    506     ) {
    507         log_err("error in u_strFoldCase(default same buffer)=%ld error=%s string matches: %s\n",
    508             length,
    509             u_errorName(errorCode),
    510             uprv_memcmp(foldedDefault, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no");
    511     }
    512 
    513     /* test full string case folding, exclude special i, in the same buffer */
    514     if(isUnicode_3_1) {
    515         uprv_memcpy(buffer, mixed, sizeof(mixed));
    516         errorCode=U_ZERO_ERROR;
    517         length=u_strFoldCase(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    518                             buffer, sizeof(mixed)/U_SIZEOF_UCHAR,
    519                             U_FOLD_CASE_EXCLUDE_SPECIAL_I,
    520                             &errorCode);
    521         if( U_FAILURE(errorCode) ||
    522             length!=(sizeof(foldedExcludeSpecialI)/U_SIZEOF_UCHAR) ||
    523             uprv_memcmp(foldedExcludeSpecialI, buffer, length*U_SIZEOF_UCHAR)!=0 ||
    524             buffer[length]!=0
    525         ) {
    526             log_err("error in u_strFoldCase(exclude special i same buffer)=%ld error=%s string matches: %s\n",
    527                 length,
    528                 u_errorName(errorCode),
    529                 uprv_memcmp(foldedExcludeSpecialI, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no");
    530         }
    531     }
    532 
    533     /* test preflighting */
    534     buffer[0]=buffer[2]=0xabcd;
    535     errorCode=U_ZERO_ERROR;
    536     length=u_strFoldCase(buffer, 2, /* set destCapacity=2 */
    537                         mixed, sizeof(mixed)/U_SIZEOF_UCHAR,
    538                         U_FOLD_CASE_DEFAULT,
    539                         &errorCode);
    540     if( errorCode!=U_BUFFER_OVERFLOW_ERROR ||
    541         length!=(sizeof(foldedDefault)/U_SIZEOF_UCHAR) ||
    542         uprv_memcmp(foldedDefault, buffer, 2*U_SIZEOF_UCHAR)!=0 ||
    543         buffer[2]!=0xabcd
    544     ) {
    545         log_err("error in u_strFoldCase(default preflighting)=%ld error=%s string matches: %s\n",
    546             length,
    547             u_errorName(errorCode),
    548             uprv_memcmp(foldedDefault, buffer, 2*U_SIZEOF_UCHAR)==0 && buffer[2]==0xabcd ? "yes" : "no");
    549     }
    550 
    551     errorCode=U_ZERO_ERROR;
    552     length=u_strFoldCase(NULL, 0,
    553                         mixed, sizeof(mixed)/U_SIZEOF_UCHAR,
    554                         U_FOLD_CASE_DEFAULT,
    555                         &errorCode);
    556     if( errorCode!=U_BUFFER_OVERFLOW_ERROR ||
    557         length!=(sizeof(foldedDefault)/U_SIZEOF_UCHAR)
    558     ) {
    559         log_err("error in u_strFoldCase(default pure preflighting)=%ld error=%s\n",
    560             length,
    561             u_errorName(errorCode));
    562     }
    563 
    564     /* test error handling */
    565     errorCode=U_ZERO_ERROR;
    566     length=u_strFoldCase(NULL, sizeof(buffer)/U_SIZEOF_UCHAR,
    567                         mixed, sizeof(mixed)/U_SIZEOF_UCHAR,
    568                         U_FOLD_CASE_DEFAULT,
    569                         &errorCode);
    570     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
    571         log_err("error in u_strFoldCase(default dest=NULL)=%ld error=%s\n",
    572             length,
    573             u_errorName(errorCode));
    574     }
    575 
    576     buffer[0]=0xabcd;
    577     errorCode=U_ZERO_ERROR;
    578     length=u_strFoldCase(buffer, -1,
    579                         mixed, sizeof(mixed)/U_SIZEOF_UCHAR,
    580                         U_FOLD_CASE_DEFAULT,
    581                         &errorCode);
    582     if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR ||
    583         buffer[0]!=0xabcd
    584     ) {
    585         log_err("error in u_strFoldCase(default destCapacity=-1)=%ld error=%s buffer[0]==0x%lx\n",
    586             length,
    587             u_errorName(errorCode),
    588             buffer[0]);
    589     }
    590 
    591     buffer[0]=0xabcd;
    592     errorCode=U_ZERO_ERROR;
    593     length=u_strFoldCase(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    594                         NULL, sizeof(mixed)/U_SIZEOF_UCHAR,
    595                         U_FOLD_CASE_EXCLUDE_SPECIAL_I,
    596                         &errorCode);
    597     if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR ||
    598         buffer[0]!=0xabcd
    599     ) {
    600         log_err("error in u_strFoldCase(exclude special i src=NULL)=%ld error=%s buffer[0]==0x%lx\n",
    601             length,
    602             u_errorName(errorCode),
    603             buffer[0]);
    604     }
    605 
    606     buffer[0]=0xabcd;
    607     errorCode=U_ZERO_ERROR;
    608     length=u_strFoldCase(buffer, sizeof(buffer)/U_SIZEOF_UCHAR,
    609                         mixed, -2,
    610                         U_FOLD_CASE_EXCLUDE_SPECIAL_I,
    611                         &errorCode);
    612     if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR ||
    613         buffer[0]!=0xabcd
    614     ) {
    615         log_err("error in u_strFoldCase(exclude special i srcLength=-2)=%ld error=%s buffer[0]==0x%lx\n",
    616             length,
    617             u_errorName(errorCode),
    618             buffer[0]);
    619     }
    620 }
    621 
    622 static void
    623 TestCaseCompare(void) {
    624     static const UChar
    625 
    626     mixed[]=               { 0x61, 0x42, 0x131, 0x3a3, 0xdf,       0xfb03,           0xd93f, 0xdfff, 0 },
    627     otherDefault[]=        { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x46, 0x66, 0x49, 0xd93f, 0xdfff, 0 },
    628     otherExcludeSpecialI[]={ 0x41, 0x62, 0x131, 0x3c3, 0x53, 0x73, 0x66, 0x46, 0x69, 0xd93f, 0xdfff, 0 },
    629     different[]=           { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x46, 0x66, 0x49, 0xd93f, 0xdffd, 0 };
    630 
    631     UVersionInfo unicodeVersion={ 0, 0, 17, 89 }, unicode_3_1={ 3, 1, 0, 0 };
    632 
    633     int32_t result, lenMixed, lenOtherDefault, lenOtherExcludeSpecialI, lenDifferent;
    634     UErrorCode errorCode;
    635     UBool isUnicode_3_1;
    636 
    637     errorCode=U_ZERO_ERROR;
    638 
    639     lenMixed=u_strlen(mixed);
    640     lenOtherDefault=u_strlen(otherDefault);
    641     (void)lenOtherDefault;    /* Suppress set but not used warning. */
    642     lenOtherExcludeSpecialI=u_strlen(otherExcludeSpecialI);
    643     lenDifferent=u_strlen(different);
    644 
    645     /* if unicodeVersion()>=3.1 then test exclude-special-i cases as well */
    646     u_getUnicodeVersion(unicodeVersion);
    647     isUnicode_3_1= uprv_memcmp(unicodeVersion, unicode_3_1, 4)>=0;
    648     (void)isUnicode_3_1;    /* Suppress set but not used warning. */
    649 
    650     /* test u_strcasecmp() */
    651     result=u_strcasecmp(mixed, otherDefault, U_FOLD_CASE_DEFAULT);
    652     if(result!=0) {
    653         log_err("error: u_strcasecmp(mixed, other, default)=%ld instead of 0\n", result);
    654     }
    655     result=u_strCaseCompare(mixed, -1, otherDefault, -1, U_FOLD_CASE_DEFAULT, &errorCode);
    656     if(result!=0) {
    657         log_err("error: u_strCaseCompare(mixed, other, default)=%ld instead of 0\n", result);
    658     }
    659 
    660     /* test u_strcasecmp() - exclude special i */
    661     result=u_strcasecmp(mixed, otherExcludeSpecialI, U_FOLD_CASE_EXCLUDE_SPECIAL_I);
    662     if(result!=0) {
    663         log_err("error: u_strcasecmp(mixed, other, exclude special i)=%ld instead of 0\n", result);
    664     }
    665     result=u_strCaseCompare(mixed, lenMixed, otherExcludeSpecialI, lenOtherExcludeSpecialI, U_FOLD_CASE_EXCLUDE_SPECIAL_I, &errorCode);
    666     if(result!=0) {
    667         log_err("error: u_strCaseCompare(mixed, other, exclude special i)=%ld instead of 0\n", result);
    668     }
    669 
    670     /* test u_strcasecmp() */
    671     result=u_strcasecmp(mixed, different, U_FOLD_CASE_DEFAULT);
    672     if(result<=0) {
    673         log_err("error: u_strcasecmp(mixed, different, default)=%ld instead of positive\n", result);
    674     }
    675     result=u_strCaseCompare(mixed, -1, different, lenDifferent, U_FOLD_CASE_DEFAULT, &errorCode);
    676     if(result<=0) {
    677         log_err("error: u_strCaseCompare(mixed, different, default)=%ld instead of positive\n", result);
    678     }
    679 
    680     /* test u_strncasecmp() - stop before the sharp s (U+00df) */
    681     result=u_strncasecmp(mixed, different, 4, U_FOLD_CASE_DEFAULT);
    682     if(result!=0) {
    683         log_err("error: u_strncasecmp(mixed, different, 4, default)=%ld instead of 0\n", result);
    684     }
    685     result=u_strCaseCompare(mixed, 4, different, 4, U_FOLD_CASE_DEFAULT, &errorCode);
    686     if(result!=0) {
    687         log_err("error: u_strCaseCompare(mixed, 4, different, 4, default)=%ld instead of 0\n", result);
    688     }
    689 
    690     /* test u_strncasecmp() - stop in the middle of the sharp s (U+00df) */
    691     result=u_strncasecmp(mixed, different, 5, U_FOLD_CASE_DEFAULT);
    692     if(result<=0) {
    693         log_err("error: u_strncasecmp(mixed, different, 5, default)=%ld instead of positive\n", result);
    694     }
    695     result=u_strCaseCompare(mixed, 5, different, 5, U_FOLD_CASE_DEFAULT, &errorCode);
    696     if(result<=0) {
    697         log_err("error: u_strCaseCompare(mixed, 5, different, 5, default)=%ld instead of positive\n", result);
    698     }
    699 
    700     /* test u_memcasecmp() - stop before the sharp s (U+00df) */
    701     result=u_memcasecmp(mixed, different, 4, U_FOLD_CASE_DEFAULT);
    702     if(result!=0) {
    703         log_err("error: u_memcasecmp(mixed, different, 4, default)=%ld instead of 0\n", result);
    704     }
    705 
    706     /* test u_memcasecmp() - stop in the middle of the sharp s (U+00df) */
    707     result=u_memcasecmp(mixed, different, 5, U_FOLD_CASE_DEFAULT);
    708     if(result<=0) {
    709         log_err("error: u_memcasecmp(mixed, different, 5, default)=%ld instead of positive\n", result);
    710     }
    711 }
    712 
    713 /* test UCaseMap ------------------------------------------------------------ */
    714 
    715 /*
    716  * API test for UCaseMap;
    717  * test cases for actual case mappings using UCaseMap see
    718  * intltest utility/UnicodeStringTest/StringCaseTest/TestCasing
    719  */
    720 static void
    721 TestUCaseMap(void) {
    722     static const char
    723         aBc[] ={ 0x61, 0x42, 0x63, 0 },
    724         abc[] ={ 0x61, 0x62, 0x63, 0 },
    725         ABCg[]={ 0x41, 0x42, 0x43, 0x67, 0 },
    726         defg[]={ 0x64, 0x65, 0x66, 0x67, 0 };
    727     char utf8Out[8];
    728 
    729     UCaseMap *csm;
    730     const char *locale;
    731     uint32_t options;
    732     int32_t length;
    733     UErrorCode errorCode;
    734 
    735     errorCode=U_ZERO_ERROR;
    736     csm=ucasemap_open("tur", 0xa5, &errorCode);
    737     if(U_FAILURE(errorCode)) {
    738         log_err("ucasemap_open(\"tur\") failed - %s\n", u_errorName(errorCode));
    739         return;
    740     }
    741     locale=ucasemap_getLocale(csm);
    742     if(0!=strcmp(locale, "tr")) {
    743         log_err("ucasemap_getLocale(ucasemap_open(\"tur\"))==%s!=\"tr\"\n", locale);
    744     }
    745     /* overly long locale IDs get truncated to their language code to avoid unnecessary allocation */
    746     ucasemap_setLocale(csm, "I-kLInGOn-the-quick-brown-fox-jumps-over-the-lazy-dog", &errorCode);
    747     locale=ucasemap_getLocale(csm);
    748     if(0!=strcmp(locale, "i-klingon")) {
    749         log_err("ucasemap_getLocale(ucasemap_setLocale(\"I-kLInGOn-the-quick-br...\"))==%s!=\"i-klingon\"\n", locale);
    750     }
    751 
    752     errorCode=U_ZERO_ERROR;
    753     options=ucasemap_getOptions(csm);
    754     if(options!=0xa5) {
    755         log_err("ucasemap_getOptions(ucasemap_open(0xa5))==0x%lx!=0xa5\n", (long)options);
    756     }
    757     ucasemap_setOptions(csm, 0x333333, &errorCode);
    758     options=ucasemap_getOptions(csm);
    759     if(options!=0x333333) {
    760         log_err("ucasemap_getOptions(ucasemap_setOptions(0x333333))==0x%lx!=0x333333\n", (long)options);
    761     }
    762 
    763     /* test case mapping API; not all permutations necessary due to shared implementation code */
    764 
    765     /* NUL terminated source */
    766     errorCode=U_ZERO_ERROR;
    767     length=ucasemap_utf8ToLower(csm, utf8Out, (int32_t)sizeof(utf8Out), aBc, -1, &errorCode);
    768     if(U_FAILURE(errorCode) || length!=3 || 0!=strcmp(abc, utf8Out)) {
    769         log_err("ucasemap_utf8ToLower(aBc\\0) failed\n");
    770     }
    771 
    772     /* incoming failure code */
    773     errorCode=U_PARSE_ERROR;
    774     strcpy(utf8Out, defg);
    775     length=ucasemap_utf8ToLower(csm, utf8Out, (int32_t)sizeof(utf8Out), aBc, -1, &errorCode);
    776     if(errorCode!=U_PARSE_ERROR || 0!=strcmp(defg, utf8Out)) {
    777         log_err("ucasemap_utf8ToLower(failure) failed\n");
    778     }
    779 
    780     /* overlapping input & output */
    781     errorCode=U_ZERO_ERROR;
    782     strcpy(utf8Out, aBc);
    783     length=ucasemap_utf8ToUpper(csm, utf8Out, 2, utf8Out+1, 2, &errorCode);
    784     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || 0!=strcmp(aBc, utf8Out)) {
    785         log_err("ucasemap_utf8ToUpper(overlap 1) failed\n");
    786     }
    787 
    788     /* overlap in the other direction */
    789     errorCode=U_ZERO_ERROR;
    790     strcpy(utf8Out, aBc);
    791     length=ucasemap_utf8ToUpper(csm, utf8Out+1, 2, utf8Out, 2, &errorCode);
    792     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || 0!=strcmp(aBc, utf8Out)) {
    793         log_err("ucasemap_utf8ToUpper(overlap 2) failed\n");
    794     }
    795 
    796     /* NULL destination */
    797     errorCode=U_ZERO_ERROR;
    798     strcpy(utf8Out, defg);
    799     length=ucasemap_utf8ToLower(csm, NULL, (int32_t)sizeof(utf8Out), aBc, -1, &errorCode);
    800     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || 0!=strcmp(defg, utf8Out)) {
    801         log_err("ucasemap_utf8ToLower(dest=NULL) failed\n");
    802     }
    803 
    804     /* destCapacity<0 */
    805     errorCode=U_ZERO_ERROR;
    806     strcpy(utf8Out, defg);
    807     length=ucasemap_utf8ToLower(csm, utf8Out, -2, aBc, -1, &errorCode);
    808     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || 0!=strcmp(defg, utf8Out)) {
    809         log_err("ucasemap_utf8ToLower(destCapacity<0) failed\n");
    810     }
    811 
    812     /* NULL source */
    813     errorCode=U_ZERO_ERROR;
    814     strcpy(utf8Out, defg);
    815     length=ucasemap_utf8ToLower(csm, utf8Out, (int32_t)sizeof(utf8Out), NULL, -1, &errorCode);
    816     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || 0!=strcmp(defg, utf8Out)) {
    817         log_err("ucasemap_utf8ToLower(src=NULL) failed\n");
    818     }
    819 
    820     /* srcLength<-1 */
    821     errorCode=U_ZERO_ERROR;
    822     strcpy(utf8Out, defg);
    823     length=ucasemap_utf8ToLower(csm, utf8Out, (int32_t)sizeof(utf8Out), aBc, -2, &errorCode);
    824     if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || 0!=strcmp(defg, utf8Out)) {
    825         log_err("ucasemap_utf8ToLower(srcLength<-1) failed\n");
    826     }
    827 
    828     /* buffer overflow */
    829     errorCode=U_ZERO_ERROR;
    830     strcpy(utf8Out, defg);
    831     length=ucasemap_utf8ToUpper(csm, utf8Out, 2, aBc, 3, &errorCode);
    832     if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=3 || 0!=strcmp(defg+2, utf8Out+2)) {
    833         log_err("ucasemap_utf8ToUpper(overflow) failed\n");
    834     }
    835 
    836     /* dest not terminated (leaves g from defg alone) */
    837     errorCode=U_ZERO_ERROR;
    838     strcpy(utf8Out, defg);
    839     length=ucasemap_utf8ToUpper(csm, utf8Out, 3, aBc, 3, &errorCode);
    840     if(errorCode!=U_STRING_NOT_TERMINATED_WARNING || length!=3 || 0!=strcmp(ABCg, utf8Out)) {
    841         log_err("ucasemap_utf8ToUpper(overflow) failed\n");
    842     }
    843 
    844     /* C API coverage for case folding. More thorough test via C++ intltest's StringCaseTest::TestCasing(). */
    845     errorCode=U_ZERO_ERROR;
    846     utf8Out[0]=0;
    847     length=ucasemap_utf8FoldCase(csm, utf8Out, (int32_t)sizeof(utf8Out), aBc, 3, &errorCode);
    848     if(U_FAILURE(errorCode) || length!=3 || 0!=strcmp(abc, utf8Out)) {
    849         log_err("ucasemap_utf8FoldCase(aBc) failed\n");
    850     }
    851 
    852     ucasemap_close(csm);
    853 }
    854 
    855 #if !UCONFIG_NO_BREAK_ITERATION
    856 
    857 /* Try titlecasing with options. */
    858 static void
    859 TestUCaseMapToTitle(void) {
    860     /* "a 'CaT. A 'dOg! 'eTc." where '=U+02BB */
    861     /*
    862      * Note: The sentence BreakIterator does not recognize a '.'
    863      * as a sentence terminator if it is followed by lowercase.
    864      * That is why the example has the '!'.
    865      */
    866     static const UChar
    867 
    868     beforeTitle[]=      { 0x61, 0x20, 0x2bb, 0x43, 0x61, 0x54, 0x2e, 0x20, 0x41, 0x20, 0x2bb, 0x64, 0x4f, 0x67, 0x21, 0x20, 0x2bb, 0x65, 0x54, 0x63, 0x2e },
    869     titleWord[]=        { 0x41, 0x20, 0x2bb, 0x43, 0x61, 0x74, 0x2e, 0x20, 0x41, 0x20, 0x2bb, 0x44, 0x6f, 0x67, 0x21, 0x20, 0x2bb, 0x45, 0x74, 0x63, 0x2e },
    870     titleWordNoAdjust[]={ 0x41, 0x20, 0x2bb, 0x63, 0x61, 0x74, 0x2e, 0x20, 0x41, 0x20, 0x2bb, 0x64, 0x6f, 0x67, 0x21, 0x20, 0x2bb, 0x65, 0x74, 0x63, 0x2e },
    871     titleSentNoLower[]= { 0x41, 0x20, 0x2bb, 0x43, 0x61, 0x54, 0x2e, 0x20, 0x41, 0x20, 0x2bb, 0x64, 0x4f, 0x67, 0x21, 0x20, 0x2bb, 0x45, 0x54, 0x63, 0x2e };
    872 
    873     UChar buffer[32];
    874     UCaseMap *csm;
    875     UBreakIterator *sentenceIter;
    876     const UBreakIterator *iter;
    877     int32_t length;
    878     UErrorCode errorCode;
    879 
    880     errorCode=U_ZERO_ERROR;
    881     csm=ucasemap_open("", 0, &errorCode);
    882     if(U_FAILURE(errorCode)) {
    883         log_err("ucasemap_open(\"\") failed - %s\n", u_errorName(errorCode));
    884         return;
    885     }
    886 
    887     iter=ucasemap_getBreakIterator(csm);
    888     if(iter!=NULL) {
    889         log_err("ucasemap_getBreakIterator() returns %p!=NULL before setting any iterator or titlecasing\n", iter);
    890     }
    891 
    892     /* Use default UBreakIterator: Word breaks. */
    893     length=ucasemap_toTitle(csm, buffer, UPRV_LENGTHOF(buffer), beforeTitle, UPRV_LENGTHOF(beforeTitle), &errorCode);
    894     if( U_FAILURE(errorCode) ||
    895         length!=UPRV_LENGTHOF(titleWord) ||
    896         0!=u_memcmp(buffer, titleWord, length) ||
    897         buffer[length]!=0
    898     ) {
    899         log_err_status(errorCode, "ucasemap_toTitle(default iterator)=%ld failed - %s\n", (long)length, u_errorName(errorCode));
    900     }
    901     if (U_SUCCESS(errorCode)) {
    902         iter=ucasemap_getBreakIterator(csm);
    903         if(iter==NULL) {
    904             log_err("ucasemap_getBreakIterator() returns NULL after titlecasing\n");
    905         }
    906     }
    907 
    908     /* Try U_TITLECASE_NO_BREAK_ADJUSTMENT. */
    909     ucasemap_setOptions(csm, U_TITLECASE_NO_BREAK_ADJUSTMENT, &errorCode);
    910     if(U_FAILURE(errorCode)) {
    911         log_err_status(errorCode, "error: ucasemap_setOptions(U_TITLECASE_NO_BREAK_ADJUSTMENT) failed - %s\n", u_errorName(errorCode));
    912         return;
    913     }
    914 
    915     length=ucasemap_toTitle(csm, buffer, UPRV_LENGTHOF(buffer), beforeTitle, UPRV_LENGTHOF(beforeTitle), &errorCode);
    916     if( U_FAILURE(errorCode) ||
    917         length!=UPRV_LENGTHOF(titleWordNoAdjust) ||
    918         0!=u_memcmp(buffer, titleWordNoAdjust, length) ||
    919         buffer[length]!=0
    920     ) {
    921         log_err("ucasemap_toTitle(default iterator, no break adjustment)=%ld failed - %s\n", (long)length, u_errorName(errorCode));
    922     }
    923 
    924     /* Set a sentence break iterator. */
    925     errorCode=U_ZERO_ERROR;
    926     sentenceIter=ubrk_open(UBRK_SENTENCE, "", NULL, 0, &errorCode);
    927     if(U_FAILURE(errorCode)) {
    928         log_err("error: ubrk_open(UBRK_SENTENCE) failed - %s\n", u_errorName(errorCode));
    929         ucasemap_close(csm);
    930         return;
    931     }
    932     ucasemap_setBreakIterator(csm, sentenceIter, &errorCode);
    933     if(U_FAILURE(errorCode)) {
    934         log_err("error: ucasemap_setBreakIterator(sentence iterator) failed - %s\n", u_errorName(errorCode));
    935         ubrk_close(sentenceIter);
    936         ucasemap_close(csm);
    937         return;
    938     }
    939     iter=ucasemap_getBreakIterator(csm);
    940     if(iter!=sentenceIter) {
    941         log_err("ucasemap_getBreakIterator() returns %p!=%p after setting the iterator\n", iter, sentenceIter);
    942     }
    943 
    944     ucasemap_setOptions(csm, U_TITLECASE_NO_LOWERCASE, &errorCode);
    945     if(U_FAILURE(errorCode)) {
    946         log_err("error: ucasemap_setOptions(U_TITLECASE_NO_LOWERCASE) failed - %s\n", u_errorName(errorCode));
    947         return;
    948     }
    949 
    950     /* Use the sentence break iterator with the option. Preflight first. */
    951     length=ucasemap_toTitle(csm, NULL, 0, beforeTitle, UPRV_LENGTHOF(beforeTitle), &errorCode);
    952     if( errorCode!=U_BUFFER_OVERFLOW_ERROR ||
    953         length!=UPRV_LENGTHOF(titleSentNoLower)
    954     ) {
    955         log_err("ucasemap_toTitle(preflight sentence break iterator, no lowercasing)=%ld failed - %s\n", (long)length, u_errorName(errorCode));
    956     }
    957 
    958     errorCode=U_ZERO_ERROR;
    959     buffer[0]=0;
    960     length=ucasemap_toTitle(csm, buffer, UPRV_LENGTHOF(buffer), beforeTitle, UPRV_LENGTHOF(beforeTitle), &errorCode);
    961     if( U_FAILURE(errorCode) ||
    962         length!=UPRV_LENGTHOF(titleSentNoLower) ||
    963         0!=u_memcmp(buffer, titleSentNoLower, length) ||
    964         buffer[length]!=0
    965     ) {
    966         log_err("ucasemap_toTitle(sentence break iterator, no lowercasing)=%ld failed - %s\n", (long)length, u_errorName(errorCode));
    967     }
    968 
    969     /* UTF-8 C API coverage. More thorough test via C++ intltest's StringCaseTest::TestCasing(). */
    970     {
    971         char utf8BeforeTitle[64], utf8TitleSentNoLower[64], utf8[64];
    972         int32_t utf8BeforeTitleLength, utf8TitleSentNoLowerLength;
    973 
    974         errorCode=U_ZERO_ERROR;
    975         u_strToUTF8(utf8BeforeTitle, (int32_t)sizeof(utf8BeforeTitle), &utf8BeforeTitleLength, beforeTitle, UPRV_LENGTHOF(beforeTitle), &errorCode);
    976         u_strToUTF8(utf8TitleSentNoLower, (int32_t)sizeof(utf8TitleSentNoLower), &utf8TitleSentNoLowerLength, titleSentNoLower, UPRV_LENGTHOF(titleSentNoLower), &errorCode);
    977 
    978         length=ucasemap_utf8ToTitle(csm, utf8, (int32_t)sizeof(utf8), utf8BeforeTitle, utf8BeforeTitleLength, &errorCode);
    979         if( U_FAILURE(errorCode) ||
    980             length!=utf8TitleSentNoLowerLength ||
    981             0!=uprv_memcmp(utf8, utf8TitleSentNoLower, length) ||
    982             utf8[length]!=0
    983         ) {
    984             log_err("ucasemap_utf8ToTitle(sentence break iterator, no lowercasing)=%ld failed - %s\n", (long)length, u_errorName(errorCode));
    985         }
    986     }
    987 
    988     ucasemap_close(csm);
    989 }
    990 
    991 #endif
    992 
    993 /* Test case for internal API u_caseInsensitivePrefixMatch */
    994 static void
    995 TestUCaseInsensitivePrefixMatch(void) {
    996     struct {
    997         const char     *s1;
    998         const char     *s2;
    999         int32_t         r1;
   1000         int32_t         r2;
   1001     } testCases[] = {
   1002         {"ABC", "ab", 2, 2},
   1003         {"ABCD", "abcx", 3, 3},
   1004         {"ABC", "xyz", 0, 0},
   1005         /* U+00DF LATIN SMALL LETTER SHARP S */
   1006         {"A\\u00dfBC", "Ass", 2, 3},
   1007         {"Fust", "Fu\\u00dfball", 2, 2},
   1008         {"\\u00dfsA", "s\\u00dfB", 2, 2},
   1009         {"\\u00dfs", "s\\u00df", 2, 2},
   1010         /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */
   1011         {"XYZ\\u0130i\\u0307xxx", "xyzi\\u0307\\u0130yyy", 6, 6},
   1012         {0, 0, 0, 0}
   1013     };
   1014     int32_t i;
   1015 
   1016     for (i = 0; testCases[i].s1 != 0; i++) {
   1017         UErrorCode sts = U_ZERO_ERROR;
   1018         UChar u1[64], u2[64];
   1019         int32_t matchLen1, matchLen2;
   1020 
   1021         u_unescape(testCases[i].s1, u1, 64);
   1022         u_unescape(testCases[i].s2, u2, 64);
   1023 
   1024         u_caseInsensitivePrefixMatch(u1, -1, u2, -1, 0, &matchLen1, &matchLen2, &sts);
   1025         if (U_FAILURE(sts)) {
   1026             log_err("error: %s, s1=%s, s2=%s", u_errorName(sts), testCases[i].s1, testCases[i].s2);
   1027         } else if (matchLen1 != testCases[i].r1 || matchLen2 != testCases[i].r2) {
   1028             log_err("s1=%s, s2=%2 / match len1=%d, len2=%d / expected len1=%d, len2=%d",
   1029                 testCases[i].s1, testCases[i].s2,
   1030                 matchLen1, matchLen2,
   1031                 testCases[i].r1, testCases[i].r2);
   1032         }
   1033     }
   1034 }
   1035 
   1036 void addCaseTest(TestNode** root);
   1037 
   1038 void addCaseTest(TestNode** root) {
   1039     /* cstrcase.c functions, declared in cucdtst.h */
   1040     addTest(root, &TestCaseLower, "tsutil/cstrcase/TestCaseLower");
   1041     addTest(root, &TestCaseUpper, "tsutil/cstrcase/TestCaseUpper");
   1042 #if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILE_IO
   1043     addTest(root, &TestCaseTitle, "tsutil/cstrcase/TestCaseTitle");
   1044     addTest(root, &TestCaseDutchTitle, "tsutil/cstrcase/TestCaseDutchTitle");
   1045 #endif
   1046     addTest(root, &TestCaseFolding, "tsutil/cstrcase/TestCaseFolding");
   1047     addTest(root, &TestCaseCompare, "tsutil/cstrcase/TestCaseCompare");
   1048     addTest(root, &TestUCaseMap, "tsutil/cstrcase/TestUCaseMap");
   1049 #if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILE_IO
   1050     addTest(root, &TestUCaseMapToTitle, "tsutil/cstrcase/TestUCaseMapToTitle");
   1051 #endif
   1052     addTest(root, &TestUCaseInsensitivePrefixMatch, "tsutil/cstrcase/TestUCaseInsensitivePrefixMatch");
   1053 }
   1054