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