]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | ******************************************************************************* | |
3 | * | |
4 | * Copyright (C) 2002-2006, International Business Machines | |
5 | * Corporation and others. All Rights Reserved. | |
6 | * | |
7 | ******************************************************************************* | |
8 | * file name: cstrcase.c | |
9 | * encoding: US-ASCII | |
10 | * tab size: 8 (not used) | |
11 | * indentation:4 | |
12 | * | |
13 | * created on: 2002feb21 | |
14 | * created by: Markus W. Scherer | |
15 | * | |
16 | * Test file for string casing C API functions. | |
17 | */ | |
18 | ||
19 | #include <string.h> | |
20 | #include "unicode/utypes.h" | |
21 | #include "unicode/uchar.h" | |
22 | #include "unicode/ustring.h" | |
23 | #include "unicode/uloc.h" | |
24 | #include "unicode/ubrk.h" | |
25 | #include "unicode/ucasemap.h" | |
26 | #include "cmemory.h" | |
27 | #include "cintltst.h" | |
28 | ||
29 | /* test string case mapping functions --------------------------------------- */ | |
30 | ||
31 | static void | |
32 | TestCaseLower(void) { | |
33 | static const UChar | |
34 | ||
35 | beforeLower[]= { 0x61, 0x42, 0x49, 0x3a3, 0xdf, 0x3a3, 0x2f, 0xd93f, 0xdfff }, | |
36 | lowerRoot[]= { 0x61, 0x62, 0x69, 0x3c3, 0xdf, 0x3c2, 0x2f, 0xd93f, 0xdfff }, | |
37 | lowerTurkish[]={ 0x61, 0x62, 0x131, 0x3c3, 0xdf, 0x3c2, 0x2f, 0xd93f, 0xdfff }; | |
38 | ||
39 | UChar buffer[32]; | |
40 | int32_t length; | |
41 | UErrorCode errorCode; | |
42 | ||
43 | /* lowercase with root locale and separate buffers */ | |
44 | buffer[0]=0xabcd; | |
45 | errorCode=U_ZERO_ERROR; | |
46 | length=u_strToLower(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
47 | beforeLower, sizeof(beforeLower)/U_SIZEOF_UCHAR, | |
48 | "", | |
49 | &errorCode); | |
50 | if( U_FAILURE(errorCode) || | |
51 | length!=(sizeof(lowerRoot)/U_SIZEOF_UCHAR) || | |
52 | uprv_memcmp(lowerRoot, buffer, length*U_SIZEOF_UCHAR)!=0 || | |
53 | buffer[length]!=0 | |
54 | ) { | |
55 | log_err("error in u_strToLower(root locale)=%ld error=%s string matches: %s\t\nlowerRoot=%s\t\nbuffer=%s\n", | |
56 | length, | |
57 | u_errorName(errorCode), | |
58 | uprv_memcmp(lowerRoot, buffer, length*U_SIZEOF_UCHAR)==0 && | |
59 | buffer[length]==0 ? "yes" : "no", | |
60 | aescstrdup(lowerRoot,-1), | |
61 | aescstrdup(buffer,-1)); | |
62 | } | |
63 | ||
64 | /* lowercase with turkish locale and in the same buffer */ | |
65 | uprv_memcpy(buffer, beforeLower, sizeof(beforeLower)); | |
66 | buffer[sizeof(beforeLower)/U_SIZEOF_UCHAR]=0; | |
67 | errorCode=U_ZERO_ERROR; | |
68 | length=u_strToLower(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
69 | buffer, -1, /* implicit srcLength */ | |
70 | "tr", | |
71 | &errorCode); | |
72 | if( U_FAILURE(errorCode) || | |
73 | length!=(sizeof(lowerTurkish)/U_SIZEOF_UCHAR) || | |
74 | uprv_memcmp(lowerTurkish, buffer, length*U_SIZEOF_UCHAR)!=0 || | |
75 | buffer[length]!=0 | |
76 | ) { | |
77 | log_err("error in u_strToLower(turkish locale)=%ld error=%s string matches: %s\n", | |
78 | length, | |
79 | u_errorName(errorCode), | |
80 | uprv_memcmp(lowerTurkish, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no"); | |
81 | } | |
82 | ||
83 | /* test preflighting */ | |
84 | buffer[0]=buffer[2]=0xabcd; | |
85 | errorCode=U_ZERO_ERROR; | |
86 | length=u_strToLower(buffer, 2, /* set destCapacity=2 */ | |
87 | beforeLower, sizeof(beforeLower)/U_SIZEOF_UCHAR, | |
88 | "", | |
89 | &errorCode); | |
90 | if( errorCode!=U_BUFFER_OVERFLOW_ERROR || | |
91 | length!=(sizeof(lowerRoot)/U_SIZEOF_UCHAR) || | |
92 | uprv_memcmp(lowerRoot, buffer, 2*U_SIZEOF_UCHAR)!=0 || | |
93 | buffer[2]!=0xabcd | |
94 | ) { | |
95 | log_err("error in u_strToLower(root locale preflighting)=%ld error=%s string matches: %s\n", | |
96 | length, | |
97 | u_errorName(errorCode), | |
98 | uprv_memcmp(lowerRoot, buffer, 2*U_SIZEOF_UCHAR)==0 && buffer[2]==0xabcd ? "yes" : "no"); | |
99 | } | |
100 | ||
101 | /* test error handling */ | |
102 | errorCode=U_ZERO_ERROR; | |
103 | length=u_strToLower(NULL, sizeof(buffer)/U_SIZEOF_UCHAR, | |
104 | beforeLower, sizeof(beforeLower)/U_SIZEOF_UCHAR, | |
105 | "", | |
106 | &errorCode); | |
107 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { | |
108 | log_err("error in u_strToLower(root locale dest=NULL)=%ld error=%s\n", | |
109 | length, | |
110 | u_errorName(errorCode)); | |
111 | } | |
112 | ||
113 | buffer[0]=0xabcd; | |
114 | errorCode=U_ZERO_ERROR; | |
115 | length=u_strToLower(buffer, -1, | |
116 | beforeLower, sizeof(beforeLower)/U_SIZEOF_UCHAR, | |
117 | "", | |
118 | &errorCode); | |
119 | if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR || | |
120 | buffer[0]!=0xabcd | |
121 | ) { | |
122 | log_err("error in u_strToLower(root locale destCapacity=-1)=%ld error=%s buffer[0]==0x%lx\n", | |
123 | length, | |
124 | u_errorName(errorCode), | |
125 | buffer[0]); | |
126 | } | |
127 | } | |
128 | ||
129 | static void | |
130 | TestCaseUpper(void) { | |
131 | static const UChar | |
132 | ||
133 | beforeUpper[]= { 0x61, 0x42, 0x69, 0x3c2, 0xdf, 0x3c3, 0x2f, 0xfb03, 0xd93f, 0xdfff }, | |
134 | upperRoot[]= { 0x41, 0x42, 0x49, 0x3a3, 0x53, 0x53, 0x3a3, 0x2f, 0x46, 0x46, 0x49, 0xd93f, 0xdfff }, | |
135 | upperTurkish[]={ 0x41, 0x42, 0x130, 0x3a3, 0x53, 0x53, 0x3a3, 0x2f, 0x46, 0x46, 0x49, 0xd93f, 0xdfff }; | |
136 | ||
137 | UChar buffer[32]; | |
138 | int32_t length; | |
139 | UErrorCode errorCode; | |
140 | ||
141 | /* uppercase with root locale and in the same buffer */ | |
142 | uprv_memcpy(buffer, beforeUpper, sizeof(beforeUpper)); | |
143 | errorCode=U_ZERO_ERROR; | |
144 | length=u_strToUpper(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
145 | buffer, sizeof(beforeUpper)/U_SIZEOF_UCHAR, | |
146 | "", | |
147 | &errorCode); | |
148 | if( U_FAILURE(errorCode) || | |
149 | length!=(sizeof(upperRoot)/U_SIZEOF_UCHAR) || | |
150 | uprv_memcmp(upperRoot, buffer, length*U_SIZEOF_UCHAR)!=0 || | |
151 | buffer[length]!=0 | |
152 | ) { | |
153 | log_err("error in u_strToUpper(root locale)=%ld error=%s string matches: %s\n", | |
154 | length, | |
155 | u_errorName(errorCode), | |
156 | uprv_memcmp(upperRoot, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no"); | |
157 | } | |
158 | ||
159 | /* uppercase with turkish locale and separate buffers */ | |
160 | buffer[0]=0xabcd; | |
161 | errorCode=U_ZERO_ERROR; | |
162 | length=u_strToUpper(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
163 | beforeUpper, sizeof(beforeUpper)/U_SIZEOF_UCHAR, | |
164 | "tr", | |
165 | &errorCode); | |
166 | if( U_FAILURE(errorCode) || | |
167 | length!=(sizeof(upperTurkish)/U_SIZEOF_UCHAR) || | |
168 | uprv_memcmp(upperTurkish, buffer, length*U_SIZEOF_UCHAR)!=0 || | |
169 | buffer[length]!=0 | |
170 | ) { | |
171 | log_err("error in u_strToUpper(turkish locale)=%ld error=%s string matches: %s\n", | |
172 | length, | |
173 | u_errorName(errorCode), | |
174 | uprv_memcmp(upperTurkish, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no"); | |
175 | } | |
176 | ||
177 | /* test preflighting */ | |
178 | errorCode=U_ZERO_ERROR; | |
179 | length=u_strToUpper(NULL, 0, | |
180 | beforeUpper, sizeof(beforeUpper)/U_SIZEOF_UCHAR, | |
181 | "tr", | |
182 | &errorCode); | |
183 | if( errorCode!=U_BUFFER_OVERFLOW_ERROR || | |
184 | length!=(sizeof(upperTurkish)/U_SIZEOF_UCHAR) | |
185 | ) { | |
186 | log_err("error in u_strToUpper(turkish locale pure preflighting)=%ld error=%s\n", | |
187 | length, | |
188 | u_errorName(errorCode)); | |
189 | } | |
190 | ||
191 | /* test error handling */ | |
192 | buffer[0]=0xabcd; | |
193 | errorCode=U_ZERO_ERROR; | |
194 | length=u_strToUpper(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
195 | NULL, sizeof(beforeUpper)/U_SIZEOF_UCHAR, | |
196 | "tr", | |
197 | &errorCode); | |
198 | if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR || | |
199 | buffer[0]!=0xabcd | |
200 | ) { | |
201 | log_err("error in u_strToUpper(turkish locale src=NULL)=%ld error=%s buffer[0]==0x%lx\n", | |
202 | length, | |
203 | u_errorName(errorCode), | |
204 | buffer[0]); | |
205 | } | |
206 | ||
207 | buffer[0]=0xabcd; | |
208 | errorCode=U_ZERO_ERROR; | |
209 | length=u_strToUpper(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
210 | beforeUpper, -2, | |
211 | "tr", | |
212 | &errorCode); | |
213 | if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR || | |
214 | buffer[0]!=0xabcd | |
215 | ) { | |
216 | log_err("error in u_strToUpper(turkish locale srcLength=-2)=%ld error=%s buffer[0]==0x%lx\n", | |
217 | length, | |
218 | u_errorName(errorCode), | |
219 | buffer[0]); | |
220 | } | |
221 | } | |
222 | ||
223 | #if !UCONFIG_NO_BREAK_ITERATION | |
224 | ||
225 | static void | |
226 | TestCaseTitle(void) { | |
227 | static const UChar | |
228 | ||
229 | beforeTitle[]= { 0x61, 0x42, 0x20, 0x69, 0x3c2, 0x20, 0xdf, 0x3c3, 0x2f, 0xfb03, 0xd93f, 0xdfff }, | |
230 | titleWord[]= { 0x41, 0x62, 0x20, 0x49, 0x3c2, 0x20, 0x53, 0x73, 0x3c3, 0x2f, 0x46, 0x66, 0x69, 0xd93f, 0xdfff }, | |
231 | titleChar[]= { 0x41, 0x42, 0x20, 0x49, 0x3a3, 0x20, 0x53, 0x73, 0x3a3, 0x2f, 0x46, 0x66, 0x69, 0xd93f, 0xdfff }; | |
232 | ||
233 | UChar buffer[32]; | |
234 | UBreakIterator *titleIterChars; | |
235 | int32_t length; | |
236 | UErrorCode errorCode; | |
237 | ||
238 | errorCode=U_ZERO_ERROR; | |
239 | titleIterChars=ubrk_open(UBRK_CHARACTER, "", beforeTitle, sizeof(beforeTitle)/U_SIZEOF_UCHAR, &errorCode); | |
240 | if(U_FAILURE(errorCode)) { | |
241 | log_err("error: ubrk_open(UBRK_CHARACTER)->%s\n", u_errorName(errorCode)); | |
242 | return; | |
243 | } | |
244 | ||
245 | /* titlecase with standard break iterator and in the same buffer */ | |
246 | uprv_memcpy(buffer, beforeTitle, sizeof(beforeTitle)); | |
247 | errorCode=U_ZERO_ERROR; | |
248 | length=u_strToTitle(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
249 | buffer, sizeof(beforeTitle)/U_SIZEOF_UCHAR, | |
250 | NULL, "", | |
251 | &errorCode); | |
252 | if( U_FAILURE(errorCode) || | |
253 | length!=(sizeof(titleWord)/U_SIZEOF_UCHAR) || | |
254 | uprv_memcmp(titleWord, buffer, length*U_SIZEOF_UCHAR)!=0 || | |
255 | buffer[length]!=0 | |
256 | ) { | |
257 | log_err("error in u_strToTitle(standard iterator)=%ld error=%s string matches: %s\n", | |
258 | length, | |
259 | u_errorName(errorCode), | |
260 | uprv_memcmp(titleWord, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no"); | |
261 | } | |
262 | ||
263 | /* titlecase with UBRK_CHARACTERS and separate buffers */ | |
264 | buffer[0]=0xabcd; | |
265 | errorCode=U_ZERO_ERROR; | |
266 | length=u_strToTitle(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
267 | beforeTitle, sizeof(beforeTitle)/U_SIZEOF_UCHAR, | |
268 | titleIterChars, "", | |
269 | &errorCode); | |
270 | if( U_FAILURE(errorCode) || | |
271 | length!=(sizeof(titleChar)/U_SIZEOF_UCHAR) || | |
272 | uprv_memcmp(titleChar, buffer, length*U_SIZEOF_UCHAR)!=0 || | |
273 | buffer[length]!=0 | |
274 | ) { | |
275 | log_err("error in u_strToTitle(UBRK_CHARACTERS)=%ld error=%s string matches: %s\n", | |
276 | length, | |
277 | u_errorName(errorCode), | |
278 | uprv_memcmp(titleChar, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no"); | |
279 | } | |
280 | ||
281 | /* test preflighting */ | |
282 | errorCode=U_ZERO_ERROR; | |
283 | length=u_strToTitle(NULL, 0, | |
284 | beforeTitle, sizeof(beforeTitle)/U_SIZEOF_UCHAR, | |
285 | titleIterChars, "", | |
286 | &errorCode); | |
287 | if( errorCode!=U_BUFFER_OVERFLOW_ERROR || | |
288 | length!=(sizeof(titleChar)/U_SIZEOF_UCHAR) | |
289 | ) { | |
290 | log_err("error in u_strToTitle(UBRK_CHARACTERS pure preflighting)=%ld error=%s\n", | |
291 | length, | |
292 | u_errorName(errorCode)); | |
293 | } | |
294 | ||
295 | /* test error handling */ | |
296 | buffer[0]=0xabcd; | |
297 | errorCode=U_ZERO_ERROR; | |
298 | length=u_strToTitle(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
299 | NULL, sizeof(beforeTitle)/U_SIZEOF_UCHAR, | |
300 | titleIterChars, "", | |
301 | &errorCode); | |
302 | if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR || | |
303 | buffer[0]!=0xabcd | |
304 | ) { | |
305 | log_err("error in u_strToTitle(UBRK_CHARACTERS src=NULL)=%ld error=%s buffer[0]==0x%lx\n", | |
306 | length, | |
307 | u_errorName(errorCode), | |
308 | buffer[0]); | |
309 | } | |
310 | ||
311 | buffer[0]=0xabcd; | |
312 | errorCode=U_ZERO_ERROR; | |
313 | length=u_strToTitle(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
314 | beforeTitle, -2, | |
315 | titleIterChars, "", | |
316 | &errorCode); | |
317 | if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR || | |
318 | buffer[0]!=0xabcd | |
319 | ) { | |
320 | log_err("error in u_strToTitle(UBRK_CHARACTERS srcLength=-2)=%ld error=%s buffer[0]==0x%lx\n", | |
321 | length, | |
322 | u_errorName(errorCode), | |
323 | buffer[0]); | |
324 | } | |
325 | ||
326 | ubrk_close(titleIterChars); | |
327 | } | |
328 | ||
329 | #endif | |
330 | ||
331 | /* test case folding and case-insensitive string compare -------------------- */ | |
332 | ||
333 | static void | |
334 | TestCaseFolding(void) { | |
335 | /* | |
336 | * CaseFolding.txt says about i and its cousins: | |
337 | * 0049; C; 0069; # LATIN CAPITAL LETTER I | |
338 | * 0049; T; 0131; # LATIN CAPITAL LETTER I | |
339 | * | |
340 | * 0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE | |
341 | * 0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE | |
342 | * That's all. | |
343 | * See CaseFolding.txt and the Unicode Standard for how to apply the case foldings. | |
344 | */ | |
345 | static const UChar32 | |
346 | simple[]={ | |
347 | /* input, default, exclude special i */ | |
348 | 0x61, 0x61, 0x61, | |
349 | 0x49, 0x69, 0x131, | |
350 | 0x130, 0x130, 0x69, | |
351 | 0x131, 0x131, 0x131, | |
352 | 0xdf, 0xdf, 0xdf, | |
353 | 0xfb03, 0xfb03, 0xfb03, | |
354 | 0x1040e,0x10436,0x10436, | |
355 | 0x5ffff,0x5ffff,0x5ffff | |
356 | }; | |
357 | ||
358 | static const UChar | |
359 | mixed[]= { 0x61, 0x42, 0x130, 0x49, 0x131, 0x3d0, 0xdf, 0xfb03, 0xd93f, 0xdfff }, | |
360 | foldedDefault[]= { 0x61, 0x62, 0x69, 0x307, 0x69, 0x131, 0x3b2, 0x73, 0x73, 0x66, 0x66, 0x69, 0xd93f, 0xdfff }, | |
361 | foldedExcludeSpecialI[]={ 0x61, 0x62, 0x69, 0x131, 0x131, 0x3b2, 0x73, 0x73, 0x66, 0x66, 0x69, 0xd93f, 0xdfff }; | |
362 | ||
363 | UVersionInfo unicodeVersion={ 0, 0, 17, 89 }, unicode_3_1={ 3, 1, 0, 0 }; | |
364 | ||
365 | const UChar32 *p; | |
366 | int32_t i; | |
367 | ||
368 | UChar buffer[32]; | |
369 | int32_t length; | |
370 | UErrorCode errorCode; | |
371 | UBool isUnicode_3_1; | |
372 | ||
373 | /* if unicodeVersion()>=3.1 then test exclude-special-i cases as well */ | |
374 | u_getUnicodeVersion(unicodeVersion); | |
375 | isUnicode_3_1= uprv_memcmp(unicodeVersion, unicode_3_1, 4)>=0; | |
376 | ||
377 | /* test simple case folding */ | |
378 | p=simple; | |
379 | for(i=0; i<sizeof(simple)/12; p+=3, ++i) { | |
380 | if(u_foldCase(p[0], U_FOLD_CASE_DEFAULT)!=p[1]) { | |
381 | log_err("error: u_foldCase(0x%04lx, default)=0x%04lx instead of 0x%04lx\n", | |
382 | p[0], u_foldCase(p[0], U_FOLD_CASE_DEFAULT), p[1]); | |
383 | return; | |
384 | } | |
385 | ||
386 | if(isUnicode_3_1 && u_foldCase(p[0], U_FOLD_CASE_EXCLUDE_SPECIAL_I)!=p[2]) { | |
387 | log_err("error: u_foldCase(0x%04lx, exclude special i)=0x%04lx instead of 0x%04lx\n", | |
388 | p[0], u_foldCase(p[0], U_FOLD_CASE_EXCLUDE_SPECIAL_I), p[2]); | |
389 | return; | |
390 | } | |
391 | } | |
392 | ||
393 | /* test full string case folding with default option and separate buffers */ | |
394 | buffer[0]=0xabcd; | |
395 | errorCode=U_ZERO_ERROR; | |
396 | length=u_strFoldCase(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
397 | mixed, sizeof(mixed)/U_SIZEOF_UCHAR, | |
398 | U_FOLD_CASE_DEFAULT, | |
399 | &errorCode); | |
400 | if( U_FAILURE(errorCode) || | |
401 | length!=(sizeof(foldedDefault)/U_SIZEOF_UCHAR) || | |
402 | uprv_memcmp(foldedDefault, buffer, length*U_SIZEOF_UCHAR)!=0 || | |
403 | buffer[length]!=0 | |
404 | ) { | |
405 | log_err("error in u_strFoldCase(default)=%ld error=%s string matches: %s\n", | |
406 | length, | |
407 | u_errorName(errorCode), | |
408 | uprv_memcmp(foldedDefault, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no"); | |
409 | } | |
410 | ||
411 | /* exclude special i */ | |
412 | if(isUnicode_3_1) { | |
413 | buffer[0]=0xabcd; | |
414 | errorCode=U_ZERO_ERROR; | |
415 | length=u_strFoldCase(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
416 | mixed, sizeof(mixed)/U_SIZEOF_UCHAR, | |
417 | U_FOLD_CASE_EXCLUDE_SPECIAL_I, | |
418 | &errorCode); | |
419 | if( U_FAILURE(errorCode) || | |
420 | length!=(sizeof(foldedExcludeSpecialI)/U_SIZEOF_UCHAR) || | |
421 | uprv_memcmp(foldedExcludeSpecialI, buffer, length*U_SIZEOF_UCHAR)!=0 || | |
422 | buffer[length]!=0 | |
423 | ) { | |
424 | log_err("error in u_strFoldCase(exclude special i)=%ld error=%s string matches: %s\n", | |
425 | length, | |
426 | u_errorName(errorCode), | |
427 | uprv_memcmp(foldedExcludeSpecialI, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no"); | |
428 | } | |
429 | } | |
430 | ||
431 | /* test full string case folding with default option and in the same buffer */ | |
432 | uprv_memcpy(buffer, mixed, sizeof(mixed)); | |
433 | buffer[sizeof(mixed)/U_SIZEOF_UCHAR]=0; | |
434 | errorCode=U_ZERO_ERROR; | |
435 | length=u_strFoldCase(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
436 | buffer, -1, /* implicit srcLength */ | |
437 | U_FOLD_CASE_DEFAULT, | |
438 | &errorCode); | |
439 | if( U_FAILURE(errorCode) || | |
440 | length!=(sizeof(foldedDefault)/U_SIZEOF_UCHAR) || | |
441 | uprv_memcmp(foldedDefault, buffer, length*U_SIZEOF_UCHAR)!=0 || | |
442 | buffer[length]!=0 | |
443 | ) { | |
444 | log_err("error in u_strFoldCase(default same buffer)=%ld error=%s string matches: %s\n", | |
445 | length, | |
446 | u_errorName(errorCode), | |
447 | uprv_memcmp(foldedDefault, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no"); | |
448 | } | |
449 | ||
450 | /* test full string case folding, exclude special i, in the same buffer */ | |
451 | if(isUnicode_3_1) { | |
452 | uprv_memcpy(buffer, mixed, sizeof(mixed)); | |
453 | errorCode=U_ZERO_ERROR; | |
454 | length=u_strFoldCase(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
455 | buffer, sizeof(mixed)/U_SIZEOF_UCHAR, | |
456 | U_FOLD_CASE_EXCLUDE_SPECIAL_I, | |
457 | &errorCode); | |
458 | if( U_FAILURE(errorCode) || | |
459 | length!=(sizeof(foldedExcludeSpecialI)/U_SIZEOF_UCHAR) || | |
460 | uprv_memcmp(foldedExcludeSpecialI, buffer, length*U_SIZEOF_UCHAR)!=0 || | |
461 | buffer[length]!=0 | |
462 | ) { | |
463 | log_err("error in u_strFoldCase(exclude special i same buffer)=%ld error=%s string matches: %s\n", | |
464 | length, | |
465 | u_errorName(errorCode), | |
466 | uprv_memcmp(foldedExcludeSpecialI, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no"); | |
467 | } | |
468 | } | |
469 | ||
470 | /* test preflighting */ | |
471 | buffer[0]=buffer[2]=0xabcd; | |
472 | errorCode=U_ZERO_ERROR; | |
473 | length=u_strFoldCase(buffer, 2, /* set destCapacity=2 */ | |
474 | mixed, sizeof(mixed)/U_SIZEOF_UCHAR, | |
475 | U_FOLD_CASE_DEFAULT, | |
476 | &errorCode); | |
477 | if( errorCode!=U_BUFFER_OVERFLOW_ERROR || | |
478 | length!=(sizeof(foldedDefault)/U_SIZEOF_UCHAR) || | |
479 | uprv_memcmp(foldedDefault, buffer, 2*U_SIZEOF_UCHAR)!=0 || | |
480 | buffer[2]!=0xabcd | |
481 | ) { | |
482 | log_err("error in u_strFoldCase(default preflighting)=%ld error=%s string matches: %s\n", | |
483 | length, | |
484 | u_errorName(errorCode), | |
485 | uprv_memcmp(foldedDefault, buffer, 2*U_SIZEOF_UCHAR)==0 && buffer[2]==0xabcd ? "yes" : "no"); | |
486 | } | |
487 | ||
488 | errorCode=U_ZERO_ERROR; | |
489 | length=u_strFoldCase(NULL, 0, | |
490 | mixed, sizeof(mixed)/U_SIZEOF_UCHAR, | |
491 | U_FOLD_CASE_DEFAULT, | |
492 | &errorCode); | |
493 | if( errorCode!=U_BUFFER_OVERFLOW_ERROR || | |
494 | length!=(sizeof(foldedDefault)/U_SIZEOF_UCHAR) | |
495 | ) { | |
496 | log_err("error in u_strFoldCase(default pure preflighting)=%ld error=%s\n", | |
497 | length, | |
498 | u_errorName(errorCode)); | |
499 | } | |
500 | ||
501 | /* test error handling */ | |
502 | errorCode=U_ZERO_ERROR; | |
503 | length=u_strFoldCase(NULL, sizeof(buffer)/U_SIZEOF_UCHAR, | |
504 | mixed, sizeof(mixed)/U_SIZEOF_UCHAR, | |
505 | U_FOLD_CASE_DEFAULT, | |
506 | &errorCode); | |
507 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { | |
508 | log_err("error in u_strFoldCase(default dest=NULL)=%ld error=%s\n", | |
509 | length, | |
510 | u_errorName(errorCode)); | |
511 | } | |
512 | ||
513 | buffer[0]=0xabcd; | |
514 | errorCode=U_ZERO_ERROR; | |
515 | length=u_strFoldCase(buffer, -1, | |
516 | mixed, sizeof(mixed)/U_SIZEOF_UCHAR, | |
517 | U_FOLD_CASE_DEFAULT, | |
518 | &errorCode); | |
519 | if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR || | |
520 | buffer[0]!=0xabcd | |
521 | ) { | |
522 | log_err("error in u_strFoldCase(default destCapacity=-1)=%ld error=%s buffer[0]==0x%lx\n", | |
523 | length, | |
524 | u_errorName(errorCode), | |
525 | buffer[0]); | |
526 | } | |
527 | ||
528 | buffer[0]=0xabcd; | |
529 | errorCode=U_ZERO_ERROR; | |
530 | length=u_strFoldCase(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
531 | NULL, sizeof(mixed)/U_SIZEOF_UCHAR, | |
532 | U_FOLD_CASE_EXCLUDE_SPECIAL_I, | |
533 | &errorCode); | |
534 | if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR || | |
535 | buffer[0]!=0xabcd | |
536 | ) { | |
537 | log_err("error in u_strFoldCase(exclude special i src=NULL)=%ld error=%s buffer[0]==0x%lx\n", | |
538 | length, | |
539 | u_errorName(errorCode), | |
540 | buffer[0]); | |
541 | } | |
542 | ||
543 | buffer[0]=0xabcd; | |
544 | errorCode=U_ZERO_ERROR; | |
545 | length=u_strFoldCase(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, | |
546 | mixed, -2, | |
547 | U_FOLD_CASE_EXCLUDE_SPECIAL_I, | |
548 | &errorCode); | |
549 | if( errorCode!=U_ILLEGAL_ARGUMENT_ERROR || | |
550 | buffer[0]!=0xabcd | |
551 | ) { | |
552 | log_err("error in u_strFoldCase(exclude special i srcLength=-2)=%ld error=%s buffer[0]==0x%lx\n", | |
553 | length, | |
554 | u_errorName(errorCode), | |
555 | buffer[0]); | |
556 | } | |
557 | } | |
558 | ||
559 | static void | |
560 | TestCaseCompare(void) { | |
561 | static const UChar | |
562 | ||
563 | mixed[]= { 0x61, 0x42, 0x131, 0x3a3, 0xdf, 0xfb03, 0xd93f, 0xdfff, 0 }, | |
564 | otherDefault[]= { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x46, 0x66, 0x49, 0xd93f, 0xdfff, 0 }, | |
565 | otherExcludeSpecialI[]={ 0x41, 0x62, 0x131, 0x3c3, 0x53, 0x73, 0x66, 0x46, 0x69, 0xd93f, 0xdfff, 0 }, | |
566 | different[]= { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x46, 0x66, 0x49, 0xd93f, 0xdffd, 0 }; | |
567 | ||
568 | UVersionInfo unicodeVersion={ 0, 0, 17, 89 }, unicode_3_1={ 3, 1, 0, 0 }; | |
569 | ||
570 | int32_t result, lenMixed, lenOtherDefault, lenOtherExcludeSpecialI, lenDifferent; | |
571 | UErrorCode errorCode; | |
572 | UBool isUnicode_3_1; | |
573 | ||
574 | errorCode=U_ZERO_ERROR; | |
575 | ||
576 | lenMixed=u_strlen(mixed); | |
577 | lenOtherDefault=u_strlen(otherDefault); | |
578 | lenOtherExcludeSpecialI=u_strlen(otherExcludeSpecialI); | |
579 | lenDifferent=u_strlen(different); | |
580 | ||
581 | /* if unicodeVersion()>=3.1 then test exclude-special-i cases as well */ | |
582 | u_getUnicodeVersion(unicodeVersion); | |
583 | isUnicode_3_1= uprv_memcmp(unicodeVersion, unicode_3_1, 4)>=0; | |
584 | ||
585 | /* test u_strcasecmp() */ | |
586 | result=u_strcasecmp(mixed, otherDefault, U_FOLD_CASE_DEFAULT); | |
587 | if(result!=0) { | |
588 | log_err("error: u_strcasecmp(mixed, other, default)=%ld instead of 0\n", result); | |
589 | } | |
590 | result=u_strCaseCompare(mixed, -1, otherDefault, -1, U_FOLD_CASE_DEFAULT, &errorCode); | |
591 | if(result!=0) { | |
592 | log_err("error: u_strCaseCompare(mixed, other, default)=%ld instead of 0\n", result); | |
593 | } | |
594 | ||
595 | /* test u_strcasecmp() - exclude special i */ | |
596 | result=u_strcasecmp(mixed, otherExcludeSpecialI, U_FOLD_CASE_EXCLUDE_SPECIAL_I); | |
597 | if(result!=0) { | |
598 | log_err("error: u_strcasecmp(mixed, other, exclude special i)=%ld instead of 0\n", result); | |
599 | } | |
600 | result=u_strCaseCompare(mixed, lenMixed, otherExcludeSpecialI, lenOtherExcludeSpecialI, U_FOLD_CASE_EXCLUDE_SPECIAL_I, &errorCode); | |
601 | if(result!=0) { | |
602 | log_err("error: u_strCaseCompare(mixed, other, exclude special i)=%ld instead of 0\n", result); | |
603 | } | |
604 | ||
605 | /* test u_strcasecmp() */ | |
606 | result=u_strcasecmp(mixed, different, U_FOLD_CASE_DEFAULT); | |
607 | if(result<=0) { | |
608 | log_err("error: u_strcasecmp(mixed, different, default)=%ld instead of positive\n", result); | |
609 | } | |
610 | result=u_strCaseCompare(mixed, -1, different, lenDifferent, U_FOLD_CASE_DEFAULT, &errorCode); | |
611 | if(result<=0) { | |
612 | log_err("error: u_strCaseCompare(mixed, different, default)=%ld instead of positive\n", result); | |
613 | } | |
614 | ||
615 | /* test u_strncasecmp() - stop before the sharp s (U+00df) */ | |
616 | result=u_strncasecmp(mixed, different, 4, U_FOLD_CASE_DEFAULT); | |
617 | if(result!=0) { | |
618 | log_err("error: u_strncasecmp(mixed, different, 4, default)=%ld instead of 0\n", result); | |
619 | } | |
620 | result=u_strCaseCompare(mixed, 4, different, 4, U_FOLD_CASE_DEFAULT, &errorCode); | |
621 | if(result!=0) { | |
622 | log_err("error: u_strCaseCompare(mixed, 4, different, 4, default)=%ld instead of 0\n", result); | |
623 | } | |
624 | ||
625 | /* test u_strncasecmp() - stop in the middle of the sharp s (U+00df) */ | |
626 | result=u_strncasecmp(mixed, different, 5, U_FOLD_CASE_DEFAULT); | |
627 | if(result<=0) { | |
628 | log_err("error: u_strncasecmp(mixed, different, 5, default)=%ld instead of positive\n", result); | |
629 | } | |
630 | result=u_strCaseCompare(mixed, 5, different, 5, U_FOLD_CASE_DEFAULT, &errorCode); | |
631 | if(result<=0) { | |
632 | log_err("error: u_strCaseCompare(mixed, 5, different, 5, default)=%ld instead of positive\n", result); | |
633 | } | |
634 | ||
635 | /* test u_memcasecmp() - stop before the sharp s (U+00df) */ | |
636 | result=u_memcasecmp(mixed, different, 4, U_FOLD_CASE_DEFAULT); | |
637 | if(result!=0) { | |
638 | log_err("error: u_memcasecmp(mixed, different, 4, default)=%ld instead of 0\n", result); | |
639 | } | |
640 | ||
641 | /* test u_memcasecmp() - stop in the middle of the sharp s (U+00df) */ | |
642 | result=u_memcasecmp(mixed, different, 5, U_FOLD_CASE_DEFAULT); | |
643 | if(result<=0) { | |
644 | log_err("error: u_memcasecmp(mixed, different, 5, default)=%ld instead of positive\n", result); | |
645 | } | |
646 | } | |
647 | ||
648 | /* test UCaseMap ------------------------------------------------------------ */ | |
649 | ||
650 | /* | |
651 | * API test for UCaseMap; | |
652 | * test cases for actual case mappings using UCaseMap see | |
653 | * intltest utility/UnicodeStringTest/StringCaseTest/TestCasing | |
654 | */ | |
655 | static void | |
656 | TestUCaseMap(void) { | |
657 | static const char | |
658 | aBc[] ={ 0x61, 0x42, 0x63, 0 }, | |
659 | abc[] ={ 0x61, 0x62, 0x63, 0 }, | |
660 | ABCg[]={ 0x41, 0x42, 0x43, 0x67, 0 }, | |
661 | defg[]={ 0x64, 0x65, 0x66, 0x67, 0 }; | |
662 | char utf8Out[8]; | |
663 | ||
664 | UCaseMap *csm; | |
665 | const char *locale; | |
666 | uint32_t options; | |
667 | int32_t length; | |
668 | UErrorCode errorCode; | |
669 | ||
670 | errorCode=U_ZERO_ERROR; | |
671 | csm=ucasemap_open("tur", 0xa5, &errorCode); | |
672 | if(U_FAILURE(errorCode)) { | |
673 | log_err("ucasemap_open(\"tur\") failed - %s\n", u_errorName(errorCode)); | |
674 | return; | |
675 | } | |
676 | locale=ucasemap_getLocale(csm); | |
677 | if(0!=strcmp(locale, "tr")) { | |
678 | log_err("ucasemap_getLocale(ucasemap_open(\"tur\"))==%s!=\"tr\"\n", locale); | |
679 | } | |
680 | /* overly long locale IDs get truncated to their language code to avoid unnecessary allocation */ | |
681 | ucasemap_setLocale(csm, "I-kLInGOn-the-quick-brown-fox-jumps-over-the-lazy-dog", &errorCode); | |
682 | locale=ucasemap_getLocale(csm); | |
683 | if(0!=strcmp(locale, "i-klingon")) { | |
684 | log_err("ucasemap_getLocale(ucasemap_setLocale(\"I-kLInGOn-the-quick-br...\"))==%s!=\"i-klingon\"\n", locale); | |
685 | } | |
686 | ||
687 | errorCode=U_ZERO_ERROR; | |
688 | options=ucasemap_getOptions(csm); | |
689 | if(options!=0xa5) { | |
690 | log_err("ucasemap_getOptions(ucasemap_open(0xa5))==0x%lx!=0xa5\n", (long)options); | |
691 | } | |
692 | ucasemap_setOptions(csm, 0x333333, &errorCode); | |
693 | options=ucasemap_getOptions(csm); | |
694 | if(options!=0x333333) { | |
695 | log_err("ucasemap_getOptions(ucasemap_setOptions(0x333333))==0x%lx!=0x333333\n", (long)options); | |
696 | } | |
697 | ||
698 | /* test case mapping API; not all permutations necessary due to shared implementation code */ | |
699 | ||
700 | /* NUL terminated source */ | |
701 | errorCode=U_ZERO_ERROR; | |
702 | length=ucasemap_utf8ToLower(csm, utf8Out, (int32_t)sizeof(utf8Out), aBc, -1, &errorCode); | |
703 | if(U_FAILURE(errorCode) || length!=3 || 0!=strcmp(abc, utf8Out)) { | |
704 | log_err("ucasemap_utf8ToLower(aBc\\0) failed\n"); | |
705 | } | |
706 | ||
707 | /* incoming failure code */ | |
708 | errorCode=U_PARSE_ERROR; | |
709 | strcpy(utf8Out, defg); | |
710 | length=ucasemap_utf8ToLower(csm, utf8Out, (int32_t)sizeof(utf8Out), aBc, -1, &errorCode); | |
711 | if(errorCode!=U_PARSE_ERROR || 0!=strcmp(defg, utf8Out)) { | |
712 | log_err("ucasemap_utf8ToLower(failure) failed\n"); | |
713 | } | |
714 | ||
715 | /* overlapping input & output */ | |
716 | errorCode=U_ZERO_ERROR; | |
717 | strcpy(utf8Out, aBc); | |
718 | length=ucasemap_utf8ToUpper(csm, utf8Out, 2, utf8Out+1, 2, &errorCode); | |
719 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || 0!=strcmp(aBc, utf8Out)) { | |
720 | log_err("ucasemap_utf8ToUpper(overlap 1) failed\n"); | |
721 | } | |
722 | ||
723 | /* overlap in the other direction */ | |
724 | errorCode=U_ZERO_ERROR; | |
725 | strcpy(utf8Out, aBc); | |
726 | length=ucasemap_utf8ToUpper(csm, utf8Out+1, 2, utf8Out, 2, &errorCode); | |
727 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || 0!=strcmp(aBc, utf8Out)) { | |
728 | log_err("ucasemap_utf8ToUpper(overlap 2) failed\n"); | |
729 | } | |
730 | ||
731 | /* NULL destination */ | |
732 | errorCode=U_ZERO_ERROR; | |
733 | strcpy(utf8Out, defg); | |
734 | length=ucasemap_utf8ToLower(csm, NULL, (int32_t)sizeof(utf8Out), aBc, -1, &errorCode); | |
735 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || 0!=strcmp(defg, utf8Out)) { | |
736 | log_err("ucasemap_utf8ToLower(dest=NULL) failed\n"); | |
737 | } | |
738 | ||
739 | /* destCapacity<0 */ | |
740 | errorCode=U_ZERO_ERROR; | |
741 | strcpy(utf8Out, defg); | |
742 | length=ucasemap_utf8ToLower(csm, utf8Out, -2, aBc, -1, &errorCode); | |
743 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || 0!=strcmp(defg, utf8Out)) { | |
744 | log_err("ucasemap_utf8ToLower(destCapacity<0) failed\n"); | |
745 | } | |
746 | ||
747 | /* NULL source */ | |
748 | errorCode=U_ZERO_ERROR; | |
749 | strcpy(utf8Out, defg); | |
750 | length=ucasemap_utf8ToLower(csm, utf8Out, (int32_t)sizeof(utf8Out), NULL, -1, &errorCode); | |
751 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || 0!=strcmp(defg, utf8Out)) { | |
752 | log_err("ucasemap_utf8ToLower(src=NULL) failed\n"); | |
753 | } | |
754 | ||
755 | /* srcLength<-1 */ | |
756 | errorCode=U_ZERO_ERROR; | |
757 | strcpy(utf8Out, defg); | |
758 | length=ucasemap_utf8ToLower(csm, utf8Out, (int32_t)sizeof(utf8Out), aBc, -2, &errorCode); | |
759 | if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || 0!=strcmp(defg, utf8Out)) { | |
760 | log_err("ucasemap_utf8ToLower(srcLength<-1) failed\n"); | |
761 | } | |
762 | ||
763 | /* buffer overflow */ | |
764 | errorCode=U_ZERO_ERROR; | |
765 | strcpy(utf8Out, defg); | |
766 | length=ucasemap_utf8ToUpper(csm, utf8Out, 2, aBc, 3, &errorCode); | |
767 | if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=3 || 0!=strcmp(defg+2, utf8Out+2)) { | |
768 | log_err("ucasemap_utf8ToUpper(overflow) failed\n"); | |
769 | } | |
770 | ||
771 | /* dest not terminated (leaves g from defg alone) */ | |
772 | errorCode=U_ZERO_ERROR; | |
773 | strcpy(utf8Out, defg); | |
774 | length=ucasemap_utf8ToUpper(csm, utf8Out, 3, aBc, 3, &errorCode); | |
775 | if(errorCode!=U_STRING_NOT_TERMINATED_WARNING || length!=3 || 0!=strcmp(ABCg, utf8Out)) { | |
776 | log_err("ucasemap_utf8ToUpper(overflow) failed\n"); | |
777 | } | |
778 | ||
779 | ucasemap_close(csm); | |
780 | } | |
781 | ||
782 | void addCaseTest(TestNode** root); | |
783 | ||
784 | void addCaseTest(TestNode** root) { | |
785 | /* cstrcase.c functions, declared in cucdtst.h */ | |
786 | addTest(root, &TestCaseLower, "tsutil/cstrcase/TestCaseLower"); | |
787 | addTest(root, &TestCaseUpper, "tsutil/cstrcase/TestCaseUpper"); | |
788 | #if !UCONFIG_NO_BREAK_ITERATION | |
789 | addTest(root, &TestCaseTitle, "tsutil/cstrcase/TestCaseTitle"); | |
790 | #endif | |
791 | addTest(root, &TestCaseFolding, "tsutil/cstrcase/TestCaseFolding"); | |
792 | addTest(root, &TestCaseCompare, "tsutil/cstrcase/TestCaseCompare"); | |
793 | addTest(root, &TestUCaseMap, "tsutil/cstrcase/TestUCaseMap"); | |
794 | } |