2 *******************************************************************************
4 * Copyright (C) 2002-2009, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * file name: cstrcase.c
10 * tab size: 8 (not used)
13 * created on: 2002feb21
14 * created by: Markus W. Scherer
16 * Test file for string casing C API functions.
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"
29 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
31 /* test string case mapping functions --------------------------------------- */
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 };
45 /* lowercase with root locale and separate buffers */
47 errorCode
=U_ZERO_ERROR
;
48 length
=u_strToLower(buffer
, sizeof(buffer
)/U_SIZEOF_UCHAR
,
49 beforeLower
, sizeof(beforeLower
)/U_SIZEOF_UCHAR
,
52 if( U_FAILURE(errorCode
) ||
53 length
!=(sizeof(lowerRoot
)/U_SIZEOF_UCHAR
) ||
54 uprv_memcmp(lowerRoot
, buffer
, length
*U_SIZEOF_UCHAR
)!=0 ||
57 log_err("error in u_strToLower(root locale)=%ld error=%s string matches: %s\t\nlowerRoot=%s\t\nbuffer=%s\n",
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));
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 */
74 if( U_FAILURE(errorCode
) ||
75 length
!=(sizeof(lowerTurkish
)/U_SIZEOF_UCHAR
) ||
76 uprv_memcmp(lowerTurkish
, buffer
, length
*U_SIZEOF_UCHAR
)!=0 ||
79 log_err("error in u_strToLower(turkish locale)=%ld error=%s string matches: %s\n",
81 u_errorName(errorCode
),
82 uprv_memcmp(lowerTurkish
, buffer
, length
*U_SIZEOF_UCHAR
)==0 && buffer
[length
]==0 ? "yes" : "no");
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
,
92 if( errorCode
!=U_BUFFER_OVERFLOW_ERROR
||
93 length
!=(sizeof(lowerRoot
)/U_SIZEOF_UCHAR
) ||
94 uprv_memcmp(lowerRoot
, buffer
, 2*U_SIZEOF_UCHAR
)!=0 ||
97 log_err("error in u_strToLower(root locale preflighting)=%ld error=%s string matches: %s\n",
99 u_errorName(errorCode
),
100 uprv_memcmp(lowerRoot
, buffer
, 2*U_SIZEOF_UCHAR
)==0 && buffer
[2]==0xabcd ? "yes" : "no");
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
,
109 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
110 log_err("error in u_strToLower(root locale dest=NULL)=%ld error=%s\n",
112 u_errorName(errorCode
));
116 errorCode
=U_ZERO_ERROR
;
117 length
=u_strToLower(buffer
, -1,
118 beforeLower
, sizeof(beforeLower
)/U_SIZEOF_UCHAR
,
121 if( errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
||
124 log_err("error in u_strToLower(root locale destCapacity=-1)=%ld error=%s buffer[0]==0x%lx\n",
126 u_errorName(errorCode
),
132 TestCaseUpper(void) {
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 };
141 UErrorCode errorCode
;
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
,
150 if( U_FAILURE(errorCode
) ||
151 length
!=(sizeof(upperRoot
)/U_SIZEOF_UCHAR
) ||
152 uprv_memcmp(upperRoot
, buffer
, length
*U_SIZEOF_UCHAR
)!=0 ||
155 log_err("error in u_strToUpper(root locale)=%ld error=%s string matches: %s\n",
157 u_errorName(errorCode
),
158 uprv_memcmp(upperRoot
, buffer
, length
*U_SIZEOF_UCHAR
)==0 && buffer
[length
]==0 ? "yes" : "no");
161 /* uppercase with turkish locale and separate buffers */
163 errorCode
=U_ZERO_ERROR
;
164 length
=u_strToUpper(buffer
, sizeof(buffer
)/U_SIZEOF_UCHAR
,
165 beforeUpper
, sizeof(beforeUpper
)/U_SIZEOF_UCHAR
,
168 if( U_FAILURE(errorCode
) ||
169 length
!=(sizeof(upperTurkish
)/U_SIZEOF_UCHAR
) ||
170 uprv_memcmp(upperTurkish
, buffer
, length
*U_SIZEOF_UCHAR
)!=0 ||
173 log_err("error in u_strToUpper(turkish locale)=%ld error=%s string matches: %s\n",
175 u_errorName(errorCode
),
176 uprv_memcmp(upperTurkish
, buffer
, length
*U_SIZEOF_UCHAR
)==0 && buffer
[length
]==0 ? "yes" : "no");
179 /* test preflighting */
180 errorCode
=U_ZERO_ERROR
;
181 length
=u_strToUpper(NULL
, 0,
182 beforeUpper
, sizeof(beforeUpper
)/U_SIZEOF_UCHAR
,
185 if( errorCode
!=U_BUFFER_OVERFLOW_ERROR
||
186 length
!=(sizeof(upperTurkish
)/U_SIZEOF_UCHAR
)
188 log_err("error in u_strToUpper(turkish locale pure preflighting)=%ld error=%s\n",
190 u_errorName(errorCode
));
193 /* test error handling */
195 errorCode
=U_ZERO_ERROR
;
196 length
=u_strToUpper(buffer
, sizeof(buffer
)/U_SIZEOF_UCHAR
,
197 NULL
, sizeof(beforeUpper
)/U_SIZEOF_UCHAR
,
200 if( errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
||
203 log_err("error in u_strToUpper(turkish locale src=NULL)=%ld error=%s buffer[0]==0x%lx\n",
205 u_errorName(errorCode
),
210 errorCode
=U_ZERO_ERROR
;
211 length
=u_strToUpper(buffer
, sizeof(buffer
)/U_SIZEOF_UCHAR
,
215 if( errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
||
218 log_err("error in u_strToUpper(turkish locale srcLength=-2)=%ld error=%s buffer[0]==0x%lx\n",
220 u_errorName(errorCode
),
225 #if !UCONFIG_NO_BREAK_ITERATION
228 TestCaseTitle(void) {
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 };
236 UBreakIterator
*titleIterChars
;
238 UErrorCode errorCode
;
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
));
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
,
254 if( U_FAILURE(errorCode
) ||
255 length
!=(sizeof(titleWord
)/U_SIZEOF_UCHAR
) ||
256 uprv_memcmp(titleWord
, buffer
, length
*U_SIZEOF_UCHAR
)!=0 ||
259 log_err("error in u_strToTitle(standard iterator)=%ld error=%s string matches: %s\n",
261 u_errorName(errorCode
),
262 uprv_memcmp(titleWord
, buffer
, length
*U_SIZEOF_UCHAR
)==0 && buffer
[length
]==0 ? "yes" : "no");
265 /* titlecase with UBRK_CHARACTERS and separate buffers */
267 errorCode
=U_ZERO_ERROR
;
268 length
=u_strToTitle(buffer
, sizeof(buffer
)/U_SIZEOF_UCHAR
,
269 beforeTitle
, sizeof(beforeTitle
)/U_SIZEOF_UCHAR
,
272 if( U_FAILURE(errorCode
) ||
273 length
!=(sizeof(titleChar
)/U_SIZEOF_UCHAR
) ||
274 uprv_memcmp(titleChar
, buffer
, length
*U_SIZEOF_UCHAR
)!=0 ||
277 log_err("error in u_strToTitle(UBRK_CHARACTERS)=%ld error=%s string matches: %s\n",
279 u_errorName(errorCode
),
280 uprv_memcmp(titleChar
, buffer
, length
*U_SIZEOF_UCHAR
)==0 && buffer
[length
]==0 ? "yes" : "no");
283 /* test preflighting */
284 errorCode
=U_ZERO_ERROR
;
285 length
=u_strToTitle(NULL
, 0,
286 beforeTitle
, sizeof(beforeTitle
)/U_SIZEOF_UCHAR
,
289 if( errorCode
!=U_BUFFER_OVERFLOW_ERROR
||
290 length
!=(sizeof(titleChar
)/U_SIZEOF_UCHAR
)
292 log_err("error in u_strToTitle(UBRK_CHARACTERS pure preflighting)=%ld error=%s\n",
294 u_errorName(errorCode
));
297 /* test error handling */
299 errorCode
=U_ZERO_ERROR
;
300 length
=u_strToTitle(buffer
, sizeof(buffer
)/U_SIZEOF_UCHAR
,
301 NULL
, sizeof(beforeTitle
)/U_SIZEOF_UCHAR
,
304 if( errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
||
307 log_err("error in u_strToTitle(UBRK_CHARACTERS src=NULL)=%ld error=%s buffer[0]==0x%lx\n",
309 u_errorName(errorCode
),
314 errorCode
=U_ZERO_ERROR
;
315 length
=u_strToTitle(buffer
, sizeof(buffer
)/U_SIZEOF_UCHAR
,
319 if( errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
||
322 log_err("error in u_strToTitle(UBRK_CHARACTERS srcLength=-2)=%ld error=%s buffer[0]==0x%lx\n",
324 u_errorName(errorCode
),
328 ubrk_close(titleIterChars
);
332 TestCaseDutchTitle(void) {
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 };
340 UBreakIterator
*titleIterWord
;
342 UErrorCode errorCode
;
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
));
351 /* titlecase with default locale */
353 errorCode
=U_ZERO_ERROR
;
354 length
=u_strToTitle(buffer
, sizeof(buffer
)/U_SIZEOF_UCHAR
,
355 beforeTitle
, sizeof(beforeTitle
)/U_SIZEOF_UCHAR
,
358 if( U_FAILURE(errorCode
) ||
359 length
!=(sizeof(titleRoot
)/U_SIZEOF_UCHAR
) ||
360 uprv_memcmp(titleRoot
, buffer
, length
*U_SIZEOF_UCHAR
)!=0 ||
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",
367 u_errorName(errorCode
),
368 uprv_memcmp(titleRoot
, buffer
, length
*U_SIZEOF_UCHAR
)==0 && buffer
[length
]==0 ? "yes" : "no", charsOut
);
370 /* titlecase with Dutch locale */
372 errorCode
=U_ZERO_ERROR
;
373 length
=u_strToTitle(buffer
, sizeof(buffer
)/U_SIZEOF_UCHAR
,
374 beforeTitle
, sizeof(beforeTitle
)/U_SIZEOF_UCHAR
,
377 if( U_FAILURE(errorCode
) ||
378 length
!=(sizeof(titleDutch
)/U_SIZEOF_UCHAR
) ||
379 uprv_memcmp(titleDutch
, buffer
, length
*U_SIZEOF_UCHAR
)!=0 ||
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",
386 u_errorName(errorCode
),
387 uprv_memcmp(titleDutch
, buffer
, length
*U_SIZEOF_UCHAR
)==0 && buffer
[length
]==0 ? "yes" : "no", charsOut
);
390 ubrk_close(titleIterWord
);
395 /* test case folding and case-insensitive string compare -------------------- */
398 TestCaseFolding(void) {
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
404 * 0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE
405 * 0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE
407 * See CaseFolding.txt and the Unicode Standard for how to apply the case foldings.
411 /* input, default, exclude special i */
417 0xfb03, 0xfb03, 0xfb03,
418 0x1040e,0x10436,0x10436,
419 0x5ffff,0x5ffff,0x5ffff
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 };
427 UVersionInfo unicodeVersion
={ 0, 0, 17, 89 }, unicode_3_1
={ 3, 1, 0, 0 };
434 UErrorCode errorCode
;
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;
441 /* test simple case folding */
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]);
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]);
457 /* test full string case folding with default option and separate buffers */
459 errorCode
=U_ZERO_ERROR
;
460 length
=u_strFoldCase(buffer
, sizeof(buffer
)/U_SIZEOF_UCHAR
,
461 mixed
, sizeof(mixed
)/U_SIZEOF_UCHAR
,
464 if( U_FAILURE(errorCode
) ||
465 length
!=(sizeof(foldedDefault
)/U_SIZEOF_UCHAR
) ||
466 uprv_memcmp(foldedDefault
, buffer
, length
*U_SIZEOF_UCHAR
)!=0 ||
469 log_err("error in u_strFoldCase(default)=%ld error=%s string matches: %s\n",
471 u_errorName(errorCode
),
472 uprv_memcmp(foldedDefault
, buffer
, length
*U_SIZEOF_UCHAR
)==0 && buffer
[length
]==0 ? "yes" : "no");
475 /* exclude special i */
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
,
483 if( U_FAILURE(errorCode
) ||
484 length
!=(sizeof(foldedExcludeSpecialI
)/U_SIZEOF_UCHAR
) ||
485 uprv_memcmp(foldedExcludeSpecialI
, buffer
, length
*U_SIZEOF_UCHAR
)!=0 ||
488 log_err("error in u_strFoldCase(exclude special i)=%ld error=%s string matches: %s\n",
490 u_errorName(errorCode
),
491 uprv_memcmp(foldedExcludeSpecialI
, buffer
, length
*U_SIZEOF_UCHAR
)==0 && buffer
[length
]==0 ? "yes" : "no");
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 */
503 if( U_FAILURE(errorCode
) ||
504 length
!=(sizeof(foldedDefault
)/U_SIZEOF_UCHAR
) ||
505 uprv_memcmp(foldedDefault
, buffer
, length
*U_SIZEOF_UCHAR
)!=0 ||
508 log_err("error in u_strFoldCase(default same buffer)=%ld error=%s string matches: %s\n",
510 u_errorName(errorCode
),
511 uprv_memcmp(foldedDefault
, buffer
, length
*U_SIZEOF_UCHAR
)==0 && buffer
[length
]==0 ? "yes" : "no");
514 /* test full string case folding, exclude special i, in the same buffer */
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
,
522 if( U_FAILURE(errorCode
) ||
523 length
!=(sizeof(foldedExcludeSpecialI
)/U_SIZEOF_UCHAR
) ||
524 uprv_memcmp(foldedExcludeSpecialI
, buffer
, length
*U_SIZEOF_UCHAR
)!=0 ||
527 log_err("error in u_strFoldCase(exclude special i same buffer)=%ld error=%s string matches: %s\n",
529 u_errorName(errorCode
),
530 uprv_memcmp(foldedExcludeSpecialI
, buffer
, length
*U_SIZEOF_UCHAR
)==0 && buffer
[length
]==0 ? "yes" : "no");
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
,
541 if( errorCode
!=U_BUFFER_OVERFLOW_ERROR
||
542 length
!=(sizeof(foldedDefault
)/U_SIZEOF_UCHAR
) ||
543 uprv_memcmp(foldedDefault
, buffer
, 2*U_SIZEOF_UCHAR
)!=0 ||
546 log_err("error in u_strFoldCase(default preflighting)=%ld error=%s string matches: %s\n",
548 u_errorName(errorCode
),
549 uprv_memcmp(foldedDefault
, buffer
, 2*U_SIZEOF_UCHAR
)==0 && buffer
[2]==0xabcd ? "yes" : "no");
552 errorCode
=U_ZERO_ERROR
;
553 length
=u_strFoldCase(NULL
, 0,
554 mixed
, sizeof(mixed
)/U_SIZEOF_UCHAR
,
557 if( errorCode
!=U_BUFFER_OVERFLOW_ERROR
||
558 length
!=(sizeof(foldedDefault
)/U_SIZEOF_UCHAR
)
560 log_err("error in u_strFoldCase(default pure preflighting)=%ld error=%s\n",
562 u_errorName(errorCode
));
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
,
571 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
) {
572 log_err("error in u_strFoldCase(default dest=NULL)=%ld error=%s\n",
574 u_errorName(errorCode
));
578 errorCode
=U_ZERO_ERROR
;
579 length
=u_strFoldCase(buffer
, -1,
580 mixed
, sizeof(mixed
)/U_SIZEOF_UCHAR
,
583 if( errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
||
586 log_err("error in u_strFoldCase(default destCapacity=-1)=%ld error=%s buffer[0]==0x%lx\n",
588 u_errorName(errorCode
),
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
,
598 if( errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
||
601 log_err("error in u_strFoldCase(exclude special i src=NULL)=%ld error=%s buffer[0]==0x%lx\n",
603 u_errorName(errorCode
),
608 errorCode
=U_ZERO_ERROR
;
609 length
=u_strFoldCase(buffer
, sizeof(buffer
)/U_SIZEOF_UCHAR
,
611 U_FOLD_CASE_EXCLUDE_SPECIAL_I
,
613 if( errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
||
616 log_err("error in u_strFoldCase(exclude special i srcLength=-2)=%ld error=%s buffer[0]==0x%lx\n",
618 u_errorName(errorCode
),
624 TestCaseCompare(void) {
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 };
632 UVersionInfo unicodeVersion
={ 0, 0, 17, 89 }, unicode_3_1
={ 3, 1, 0, 0 };
634 int32_t result
, lenMixed
, lenOtherDefault
, lenOtherExcludeSpecialI
, lenDifferent
;
635 UErrorCode errorCode
;
638 errorCode
=U_ZERO_ERROR
;
640 lenMixed
=u_strlen(mixed
);
641 lenOtherDefault
=u_strlen(otherDefault
);
642 lenOtherExcludeSpecialI
=u_strlen(otherExcludeSpecialI
);
643 lenDifferent
=u_strlen(different
);
645 /* if unicodeVersion()>=3.1 then test exclude-special-i cases as well */
646 u_getUnicodeVersion(unicodeVersion
);
647 isUnicode_3_1
= uprv_memcmp(unicodeVersion
, unicode_3_1
, 4)>=0;
649 /* test u_strcasecmp() */
650 result
=u_strcasecmp(mixed
, otherDefault
, U_FOLD_CASE_DEFAULT
);
652 log_err("error: u_strcasecmp(mixed, other, default)=%ld instead of 0\n", result
);
654 result
=u_strCaseCompare(mixed
, -1, otherDefault
, -1, U_FOLD_CASE_DEFAULT
, &errorCode
);
656 log_err("error: u_strCaseCompare(mixed, other, default)=%ld instead of 0\n", result
);
659 /* test u_strcasecmp() - exclude special i */
660 result
=u_strcasecmp(mixed
, otherExcludeSpecialI
, U_FOLD_CASE_EXCLUDE_SPECIAL_I
);
662 log_err("error: u_strcasecmp(mixed, other, exclude special i)=%ld instead of 0\n", result
);
664 result
=u_strCaseCompare(mixed
, lenMixed
, otherExcludeSpecialI
, lenOtherExcludeSpecialI
, U_FOLD_CASE_EXCLUDE_SPECIAL_I
, &errorCode
);
666 log_err("error: u_strCaseCompare(mixed, other, exclude special i)=%ld instead of 0\n", result
);
669 /* test u_strcasecmp() */
670 result
=u_strcasecmp(mixed
, different
, U_FOLD_CASE_DEFAULT
);
672 log_err("error: u_strcasecmp(mixed, different, default)=%ld instead of positive\n", result
);
674 result
=u_strCaseCompare(mixed
, -1, different
, lenDifferent
, U_FOLD_CASE_DEFAULT
, &errorCode
);
676 log_err("error: u_strCaseCompare(mixed, different, default)=%ld instead of positive\n", result
);
679 /* test u_strncasecmp() - stop before the sharp s (U+00df) */
680 result
=u_strncasecmp(mixed
, different
, 4, U_FOLD_CASE_DEFAULT
);
682 log_err("error: u_strncasecmp(mixed, different, 4, default)=%ld instead of 0\n", result
);
684 result
=u_strCaseCompare(mixed
, 4, different
, 4, U_FOLD_CASE_DEFAULT
, &errorCode
);
686 log_err("error: u_strCaseCompare(mixed, 4, different, 4, default)=%ld instead of 0\n", result
);
689 /* test u_strncasecmp() - stop in the middle of the sharp s (U+00df) */
690 result
=u_strncasecmp(mixed
, different
, 5, U_FOLD_CASE_DEFAULT
);
692 log_err("error: u_strncasecmp(mixed, different, 5, default)=%ld instead of positive\n", result
);
694 result
=u_strCaseCompare(mixed
, 5, different
, 5, U_FOLD_CASE_DEFAULT
, &errorCode
);
696 log_err("error: u_strCaseCompare(mixed, 5, different, 5, default)=%ld instead of positive\n", result
);
699 /* test u_memcasecmp() - stop before the sharp s (U+00df) */
700 result
=u_memcasecmp(mixed
, different
, 4, U_FOLD_CASE_DEFAULT
);
702 log_err("error: u_memcasecmp(mixed, different, 4, default)=%ld instead of 0\n", result
);
705 /* test u_memcasecmp() - stop in the middle of the sharp s (U+00df) */
706 result
=u_memcasecmp(mixed
, different
, 5, U_FOLD_CASE_DEFAULT
);
708 log_err("error: u_memcasecmp(mixed, different, 5, default)=%ld instead of positive\n", result
);
712 /* test UCaseMap ------------------------------------------------------------ */
715 * API test for UCaseMap;
716 * test cases for actual case mappings using UCaseMap see
717 * intltest utility/UnicodeStringTest/StringCaseTest/TestCasing
722 aBc
[] ={ 0x61, 0x42, 0x63, 0 },
723 abc
[] ={ 0x61, 0x62, 0x63, 0 },
724 ABCg
[]={ 0x41, 0x42, 0x43, 0x67, 0 },
725 defg
[]={ 0x64, 0x65, 0x66, 0x67, 0 };
732 UErrorCode errorCode
;
734 errorCode
=U_ZERO_ERROR
;
735 csm
=ucasemap_open("tur", 0xa5, &errorCode
);
736 if(U_FAILURE(errorCode
)) {
737 log_err("ucasemap_open(\"tur\") failed - %s\n", u_errorName(errorCode
));
740 locale
=ucasemap_getLocale(csm
);
741 if(0!=strcmp(locale
, "tr")) {
742 log_err("ucasemap_getLocale(ucasemap_open(\"tur\"))==%s!=\"tr\"\n", locale
);
744 /* overly long locale IDs get truncated to their language code to avoid unnecessary allocation */
745 ucasemap_setLocale(csm
, "I-kLInGOn-the-quick-brown-fox-jumps-over-the-lazy-dog", &errorCode
);
746 locale
=ucasemap_getLocale(csm
);
747 if(0!=strcmp(locale
, "i-klingon")) {
748 log_err("ucasemap_getLocale(ucasemap_setLocale(\"I-kLInGOn-the-quick-br...\"))==%s!=\"i-klingon\"\n", locale
);
751 errorCode
=U_ZERO_ERROR
;
752 options
=ucasemap_getOptions(csm
);
754 log_err("ucasemap_getOptions(ucasemap_open(0xa5))==0x%lx!=0xa5\n", (long)options
);
756 ucasemap_setOptions(csm
, 0x333333, &errorCode
);
757 options
=ucasemap_getOptions(csm
);
758 if(options
!=0x333333) {
759 log_err("ucasemap_getOptions(ucasemap_setOptions(0x333333))==0x%lx!=0x333333\n", (long)options
);
762 /* test case mapping API; not all permutations necessary due to shared implementation code */
764 /* NUL terminated source */
765 errorCode
=U_ZERO_ERROR
;
766 length
=ucasemap_utf8ToLower(csm
, utf8Out
, (int32_t)sizeof(utf8Out
), aBc
, -1, &errorCode
);
767 if(U_FAILURE(errorCode
) || length
!=3 || 0!=strcmp(abc
, utf8Out
)) {
768 log_err("ucasemap_utf8ToLower(aBc\\0) failed\n");
771 /* incoming failure code */
772 errorCode
=U_PARSE_ERROR
;
773 strcpy(utf8Out
, defg
);
774 length
=ucasemap_utf8ToLower(csm
, utf8Out
, (int32_t)sizeof(utf8Out
), aBc
, -1, &errorCode
);
775 if(errorCode
!=U_PARSE_ERROR
|| 0!=strcmp(defg
, utf8Out
)) {
776 log_err("ucasemap_utf8ToLower(failure) failed\n");
779 /* overlapping input & output */
780 errorCode
=U_ZERO_ERROR
;
781 strcpy(utf8Out
, aBc
);
782 length
=ucasemap_utf8ToUpper(csm
, utf8Out
, 2, utf8Out
+1, 2, &errorCode
);
783 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
|| 0!=strcmp(aBc
, utf8Out
)) {
784 log_err("ucasemap_utf8ToUpper(overlap 1) failed\n");
787 /* overlap in the other direction */
788 errorCode
=U_ZERO_ERROR
;
789 strcpy(utf8Out
, aBc
);
790 length
=ucasemap_utf8ToUpper(csm
, utf8Out
+1, 2, utf8Out
, 2, &errorCode
);
791 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
|| 0!=strcmp(aBc
, utf8Out
)) {
792 log_err("ucasemap_utf8ToUpper(overlap 2) failed\n");
795 /* NULL destination */
796 errorCode
=U_ZERO_ERROR
;
797 strcpy(utf8Out
, defg
);
798 length
=ucasemap_utf8ToLower(csm
, NULL
, (int32_t)sizeof(utf8Out
), aBc
, -1, &errorCode
);
799 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
|| 0!=strcmp(defg
, utf8Out
)) {
800 log_err("ucasemap_utf8ToLower(dest=NULL) failed\n");
804 errorCode
=U_ZERO_ERROR
;
805 strcpy(utf8Out
, defg
);
806 length
=ucasemap_utf8ToLower(csm
, utf8Out
, -2, aBc
, -1, &errorCode
);
807 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
|| 0!=strcmp(defg
, utf8Out
)) {
808 log_err("ucasemap_utf8ToLower(destCapacity<0) failed\n");
812 errorCode
=U_ZERO_ERROR
;
813 strcpy(utf8Out
, defg
);
814 length
=ucasemap_utf8ToLower(csm
, utf8Out
, (int32_t)sizeof(utf8Out
), NULL
, -1, &errorCode
);
815 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
|| 0!=strcmp(defg
, utf8Out
)) {
816 log_err("ucasemap_utf8ToLower(src=NULL) failed\n");
820 errorCode
=U_ZERO_ERROR
;
821 strcpy(utf8Out
, defg
);
822 length
=ucasemap_utf8ToLower(csm
, utf8Out
, (int32_t)sizeof(utf8Out
), aBc
, -2, &errorCode
);
823 if(errorCode
!=U_ILLEGAL_ARGUMENT_ERROR
|| 0!=strcmp(defg
, utf8Out
)) {
824 log_err("ucasemap_utf8ToLower(srcLength<-1) failed\n");
827 /* buffer overflow */
828 errorCode
=U_ZERO_ERROR
;
829 strcpy(utf8Out
, defg
);
830 length
=ucasemap_utf8ToUpper(csm
, utf8Out
, 2, aBc
, 3, &errorCode
);
831 if(errorCode
!=U_BUFFER_OVERFLOW_ERROR
|| length
!=3 || 0!=strcmp(defg
+2, utf8Out
+2)) {
832 log_err("ucasemap_utf8ToUpper(overflow) failed\n");
835 /* dest not terminated (leaves g from defg alone) */
836 errorCode
=U_ZERO_ERROR
;
837 strcpy(utf8Out
, defg
);
838 length
=ucasemap_utf8ToUpper(csm
, utf8Out
, 3, aBc
, 3, &errorCode
);
839 if(errorCode
!=U_STRING_NOT_TERMINATED_WARNING
|| length
!=3 || 0!=strcmp(ABCg
, utf8Out
)) {
840 log_err("ucasemap_utf8ToUpper(overflow) failed\n");
843 /* C API coverage for case folding. More thorough test via C++ intltest's StringCaseTest::TestCasing(). */
844 errorCode
=U_ZERO_ERROR
;
846 length
=ucasemap_utf8FoldCase(csm
, utf8Out
, (int32_t)sizeof(utf8Out
), aBc
, 3, &errorCode
);
847 if(U_FAILURE(errorCode
) || length
!=3 || 0!=strcmp(abc
, utf8Out
)) {
848 log_err("ucasemap_utf8FoldCase(aBc) failed\n");
854 #if !UCONFIG_NO_BREAK_ITERATION
856 /* Try titlecasing with options. */
858 TestUCaseMapToTitle(void) {
859 /* "a 'CaT. A 'dOg! 'eTc." where '=U+02BB */
861 * Note: The sentence BreakIterator does not recognize a '.'
862 * as a sentence terminator if it is followed by lowercase.
863 * That is why the example has the '!'.
867 beforeTitle
[]= { 0x61, 0x20, 0x2bb, 0x43, 0x61, 0x54, 0x2e, 0x20, 0x41, 0x20, 0x2bb, 0x64, 0x4f, 0x67, 0x21, 0x20, 0x2bb, 0x65, 0x54, 0x63, 0x2e },
868 titleWord
[]= { 0x41, 0x20, 0x2bb, 0x43, 0x61, 0x74, 0x2e, 0x20, 0x41, 0x20, 0x2bb, 0x44, 0x6f, 0x67, 0x21, 0x20, 0x2bb, 0x45, 0x74, 0x63, 0x2e },
869 titleWordNoAdjust
[]={ 0x41, 0x20, 0x2bb, 0x63, 0x61, 0x74, 0x2e, 0x20, 0x41, 0x20, 0x2bb, 0x64, 0x6f, 0x67, 0x21, 0x20, 0x2bb, 0x65, 0x74, 0x63, 0x2e },
870 titleSentNoLower
[]= { 0x41, 0x20, 0x2bb, 0x43, 0x61, 0x54, 0x2e, 0x20, 0x41, 0x20, 0x2bb, 0x64, 0x4f, 0x67, 0x21, 0x20, 0x2bb, 0x45, 0x54, 0x63, 0x2e };
874 UBreakIterator
*sentenceIter
;
875 const UBreakIterator
*iter
;
877 UErrorCode errorCode
;
879 errorCode
=U_ZERO_ERROR
;
880 csm
=ucasemap_open("", 0, &errorCode
);
881 if(U_FAILURE(errorCode
)) {
882 log_err("ucasemap_open(\"\") failed - %s\n", u_errorName(errorCode
));
886 iter
=ucasemap_getBreakIterator(csm
);
888 log_err("ucasemap_getBreakIterator() returns %p!=NULL before setting any iterator or titlecasing\n", iter
);
891 /* Use default UBreakIterator: Word breaks. */
892 length
=ucasemap_toTitle(csm
, buffer
, LENGTHOF(buffer
), beforeTitle
, LENGTHOF(beforeTitle
), &errorCode
);
893 if( U_FAILURE(errorCode
) ||
894 length
!=LENGTHOF(titleWord
) ||
895 0!=u_memcmp(buffer
, titleWord
, length
) ||
898 log_err_status(errorCode
, "ucasemap_toTitle(default iterator)=%ld failed - %s\n", (long)length
, u_errorName(errorCode
));
900 if (U_SUCCESS(errorCode
)) {
901 iter
=ucasemap_getBreakIterator(csm
);
903 log_err("ucasemap_getBreakIterator() returns NULL after titlecasing\n");
907 /* Try U_TITLECASE_NO_BREAK_ADJUSTMENT. */
908 ucasemap_setOptions(csm
, U_TITLECASE_NO_BREAK_ADJUSTMENT
, &errorCode
);
909 if(U_FAILURE(errorCode
)) {
910 log_err_status(errorCode
, "error: ucasemap_setOptions(U_TITLECASE_NO_BREAK_ADJUSTMENT) failed - %s\n", u_errorName(errorCode
));
914 length
=ucasemap_toTitle(csm
, buffer
, LENGTHOF(buffer
), beforeTitle
, LENGTHOF(beforeTitle
), &errorCode
);
915 if( U_FAILURE(errorCode
) ||
916 length
!=LENGTHOF(titleWordNoAdjust
) ||
917 0!=u_memcmp(buffer
, titleWordNoAdjust
, length
) ||
920 log_err("ucasemap_toTitle(default iterator, no break adjustment)=%ld failed - %s\n", (long)length
, u_errorName(errorCode
));
923 /* Set a sentence break iterator. */
924 errorCode
=U_ZERO_ERROR
;
925 sentenceIter
=ubrk_open(UBRK_SENTENCE
, "", NULL
, 0, &errorCode
);
926 if(U_FAILURE(errorCode
)) {
927 log_err("error: ubrk_open(UBRK_SENTENCE) failed - %s\n", u_errorName(errorCode
));
931 ucasemap_setBreakIterator(csm
, sentenceIter
, &errorCode
);
932 if(U_FAILURE(errorCode
)) {
933 log_err("error: ucasemap_setBreakIterator(sentence iterator) failed - %s\n", u_errorName(errorCode
));
934 ubrk_close(sentenceIter
);
938 iter
=ucasemap_getBreakIterator(csm
);
939 if(iter
!=sentenceIter
) {
940 log_err("ucasemap_getBreakIterator() returns %p!=%p after setting the iterator\n", iter
, sentenceIter
);
943 ucasemap_setOptions(csm
, U_TITLECASE_NO_LOWERCASE
, &errorCode
);
944 if(U_FAILURE(errorCode
)) {
945 log_err("error: ucasemap_setOptions(U_TITLECASE_NO_LOWERCASE) failed - %s\n", u_errorName(errorCode
));
949 /* Use the sentence break iterator with the option. Preflight first. */
950 length
=ucasemap_toTitle(csm
, NULL
, 0, beforeTitle
, LENGTHOF(beforeTitle
), &errorCode
);
951 if( errorCode
!=U_BUFFER_OVERFLOW_ERROR
||
952 length
!=LENGTHOF(titleSentNoLower
)
954 log_err("ucasemap_toTitle(preflight sentence break iterator, no lowercasing)=%ld failed - %s\n", (long)length
, u_errorName(errorCode
));
957 errorCode
=U_ZERO_ERROR
;
959 length
=ucasemap_toTitle(csm
, buffer
, LENGTHOF(buffer
), beforeTitle
, LENGTHOF(beforeTitle
), &errorCode
);
960 if( U_FAILURE(errorCode
) ||
961 length
!=LENGTHOF(titleSentNoLower
) ||
962 0!=u_memcmp(buffer
, titleSentNoLower
, length
) ||
965 log_err("ucasemap_toTitle(sentence break iterator, no lowercasing)=%ld failed - %s\n", (long)length
, u_errorName(errorCode
));
968 /* UTF-8 C API coverage. More thorough test via C++ intltest's StringCaseTest::TestCasing(). */
970 char utf8BeforeTitle
[64], utf8TitleSentNoLower
[64], utf8
[64];
971 int32_t utf8BeforeTitleLength
, utf8TitleSentNoLowerLength
;
973 errorCode
=U_ZERO_ERROR
;
974 u_strToUTF8(utf8BeforeTitle
, (int32_t)sizeof(utf8BeforeTitle
), &utf8BeforeTitleLength
, beforeTitle
, LENGTHOF(beforeTitle
), &errorCode
);
975 u_strToUTF8(utf8TitleSentNoLower
, (int32_t)sizeof(utf8TitleSentNoLower
), &utf8TitleSentNoLowerLength
, titleSentNoLower
, LENGTHOF(titleSentNoLower
), &errorCode
);
977 length
=ucasemap_utf8ToTitle(csm
, utf8
, (int32_t)sizeof(utf8
), utf8BeforeTitle
, utf8BeforeTitleLength
, &errorCode
);
978 if( U_FAILURE(errorCode
) ||
979 length
!=utf8TitleSentNoLowerLength
||
980 0!=uprv_memcmp(utf8
, utf8TitleSentNoLower
, length
) ||
983 log_err("ucasemap_utf8ToTitle(sentence break iterator, no lowercasing)=%ld failed - %s\n", (long)length
, u_errorName(errorCode
));
992 void addCaseTest(TestNode
** root
);
994 void addCaseTest(TestNode
** root
) {
995 /* cstrcase.c functions, declared in cucdtst.h */
996 addTest(root
, &TestCaseLower
, "tsutil/cstrcase/TestCaseLower");
997 addTest(root
, &TestCaseUpper
, "tsutil/cstrcase/TestCaseUpper");
998 #if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILE_IO
999 addTest(root
, &TestCaseTitle
, "tsutil/cstrcase/TestCaseTitle");
1000 addTest(root
, &TestCaseDutchTitle
, "tsutil/cstrcase/TestCaseDutchTitle");
1002 addTest(root
, &TestCaseFolding
, "tsutil/cstrcase/TestCaseFolding");
1003 addTest(root
, &TestCaseCompare
, "tsutil/cstrcase/TestCaseCompare");
1004 addTest(root
, &TestUCaseMap
, "tsutil/cstrcase/TestUCaseMap");
1005 #if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILE_IO
1006 addTest(root
, &TestUCaseMapToTitle
, "tsutil/cstrcase/TestUCaseMapToTitle");