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 35static void 36TestCaseLower(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 && 63buffer[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 133static void 134TestCaseUpper(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 229static void 230TestCaseTitle(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 333static void 334TestCaseDutchTitle(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 399static void 400TestCaseFolding(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 625static void 626TestCaseCompare(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 */ 723static void 724TestUCaseMap(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. */ 862static void 863TestUCaseMapToTitle(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 */ 998static void 999TestUCaseInsensitivePrefixMatch(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 1040void addCaseTest(TestNode** root); 1041 1042void 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