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