2 ******************************************************************************
4 * Copyright (C) 2002-2010, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 ******************************************************************************
8 * file name: custrtst.c
10 * tab size: 8 (not used)
13 * created on: 2002oct09
14 * created by: Markus W. Scherer
16 * Tests of ustring.h Unicode string API functions.
19 #include "unicode/ustring.h"
20 #include "unicode/ucnv.h"
21 #include "unicode/uiter.h"
25 #define LENGTHOF(array) (sizeof(array)/sizeof((array)[0]))
27 /* get the sign of an integer */
28 #define _SIGN(value) ((value)==0 ? 0 : ((int32_t)(value)>>31)|1)
30 /* test setup --------------------------------------------------------------- */
32 static void setUpDataTable(void);
33 static void TestStringCopy(void);
34 static void TestStringFunctions(void);
35 static void TestStringSearching(void);
36 static void TestSurrogateSearching(void);
37 static void TestUnescape(void);
38 static void TestCountChar32(void);
39 static void TestUCharIterator(void);
40 static void TestUNormIterator(void);
41 static void TestBadUNormIterator(void);
43 void addUStringTest(TestNode
** root
);
45 void addUStringTest(TestNode
** root
)
47 addTest(root
, &TestStringCopy
, "tsutil/custrtst/TestStringCopy");
48 addTest(root
, &TestStringFunctions
, "tsutil/custrtst/TestStringFunctions");
49 addTest(root
, &TestStringSearching
, "tsutil/custrtst/TestStringSearching");
50 addTest(root
, &TestSurrogateSearching
, "tsutil/custrtst/TestSurrogateSearching");
51 addTest(root
, &TestUnescape
, "tsutil/custrtst/TestUnescape");
52 addTest(root
, &TestCountChar32
, "tsutil/custrtst/TestCountChar32");
53 addTest(root
, &TestUCharIterator
, "tsutil/custrtst/TestUCharIterator");
54 addTest(root
, &TestUNormIterator
, "tsutil/custrtst/TestUNormIterator");
55 addTest(root
, &TestBadUNormIterator
, "tsutil/custrtst/TestBadUNormIterator");
58 /* test data for TestStringFunctions ---------------------------------------- */
60 UChar
*** dataTable
= NULL
;
62 static const char* raw
[3][4] = {
65 { "English_", "French_", "Croatian_", "English_"},
67 { "United States", "France", "Croatia", "Unites States"},
69 /* Concatenated string */
70 { "English_United States", "French_France", "Croatian_Croatia", "English_United States"}
73 static void setUpDataTable()
76 if(dataTable
== NULL
) {
77 dataTable
= (UChar
***)calloc(sizeof(UChar
**),3);
79 for (i
= 0; i
< 3; i
++) {
80 dataTable
[i
] = (UChar
**)calloc(sizeof(UChar
*),4);
81 for (j
= 0; j
< 4; j
++){
82 dataTable
[i
][j
] = (UChar
*) malloc(sizeof(UChar
)*(strlen(raw
[i
][j
])+1));
83 u_uastrcpy(dataTable
[i
][j
],raw
[i
][j
]);
89 static void cleanUpDataTable()
92 if(dataTable
!= NULL
) {
94 for(j
= 0; j
<4; j
++) {
95 free(dataTable
[i
][j
]);
104 /*Tests for u_strcat(),u_strcmp(), u_strlen(), u_strcpy(),u_strncat(),u_strncmp(),u_strncpy, u_uastrcpy(),u_austrcpy(), u_uastrncpy(); */
105 static void TestStringFunctions()
115 log_verbose("Testing u_strlen()\n");
116 if( u_strlen(dataTable
[0][0])!= u_strlen(dataTable
[0][3]) || u_strlen(dataTable
[0][0]) == u_strlen(dataTable
[0][2]))
117 log_err("There is an error in u_strlen()");
119 log_verbose("Testing u_memcpy() and u_memcmp()\n");
125 log_verbose("Testing %s\n", u_austrcpy(tempOut
, dataTable
[i
][j
]));
127 temp
[7] = 0xA4; /* Mark the end */
128 u_memcpy(temp
,dataTable
[i
][j
], 7);
131 log_err("an error occured in u_memcpy()\n");
132 if(u_memcmp(temp
, dataTable
[i
][j
], 7)!=0)
133 log_err("an error occured in u_memcpy() or u_memcmp()\n");
136 if(u_memcmp(dataTable
[0][0], dataTable
[1][1], 7)==0)
137 log_err("an error occured in u_memcmp()\n");
139 log_verbose("Testing u_memset()\n");
142 u_memset(nullTemp
, 0xa4, 7);
143 for (i
= 0; i
< 7; i
++) {
144 if(nullTemp
[i
] != 0xa4) {
145 log_err("an error occured in u_memset()\n");
148 if(nullTemp
[7] != 0) {
149 log_err("u_memset() went too far\n");
152 u_memset(nullTemp
, 0, 7);
155 u_memcpy(temp
,nullTemp
, 7);
156 if(u_memcmp(temp
, nullTemp
, 7)!=0 || temp
[7]!=0)
157 log_err("an error occured in u_memcpy() or u_memcmp()\n");
160 log_verbose("Testing u_memmove()\n");
161 for (i
= 0; i
< 7; i
++) {
164 u_memmove(temp
+ 1, temp
, 7);
166 log_err("an error occured in u_memmove()\n");
168 for (i
= 1; i
<= 7; i
++) {
169 if(temp
[i
] != (i
- 1)) {
170 log_err("an error occured in u_memmove()\n");
174 log_verbose("Testing u_strcpy() and u_strcmp()\n");
180 log_verbose("Testing %s\n", u_austrcpy(tempOut
, dataTable
[i
][j
]));
182 u_strcpy(temp
,dataTable
[i
][j
]);
184 if(u_strcmp(temp
,dataTable
[i
][j
])!=0)
185 log_err("something threw an error in u_strcpy() or u_strcmp()\n");
188 if(u_strcmp(dataTable
[0][0], dataTable
[1][1])==0)
189 log_err("an error occured in u_memcmp()\n");
191 log_verbose("testing u_strcat()\n");
195 u_uastrcpy(temp
, "");
196 u_strcpy(temp
,dataTable
[i
][j
]);
197 u_strcat(temp
,dataTable
[i
+1][j
]);
198 if(u_strcmp(temp
,dataTable
[i
+2][j
])!=0)
199 log_err("something threw an error in u_strcat()\n");
202 log_verbose("Testing u_strncmp()\n");
203 for(i
=0,j
=0;j
<4; ++j
)
205 k
=u_strlen(dataTable
[i
][j
]);
206 if(u_strncmp(dataTable
[i
][j
],dataTable
[i
+2][j
],k
)!=0)
207 log_err("Something threw an error in u_strncmp\n");
209 if(u_strncmp(dataTable
[0][0], dataTable
[1][1], 7)==0)
210 log_err("an error occured in u_memcmp()\n");
213 log_verbose("Testing u_strncat\n");
214 for(i
=0,j
=0;j
<4; ++j
)
216 k
=u_strlen(dataTable
[i
][j
]);
220 if(u_strcmp(u_strncat(temp
,dataTable
[i
+2][j
],k
),dataTable
[i
][j
])!=0)
221 log_err("something threw an error in u_strncat or u_uastrcpy()\n");
225 log_verbose("Testing u_strncpy() and u_uastrcpy()\n");
226 for(i
=2,j
=0;j
<4; ++j
)
228 k
=u_strlen(dataTable
[i
][j
]);
229 u_strncpy(temp
, dataTable
[i
][j
],k
);
232 if(u_strncmp(temp
, dataTable
[i
][j
],k
)!=0)
233 log_err("something threw an error in u_strncpy()\n");
236 log_err("something threw an error in u_strncpy()\n");
238 u_memset(temp
, 0x3F, (sizeof(temp
) / sizeof(UChar
)) - 1);
239 u_uastrncpy(temp
, raw
[i
][j
], k
-1);
240 if(u_strncmp(temp
, dataTable
[i
][j
],k
-1)!=0)
241 log_err("something threw an error in u_uastrncpy(k-1)\n");
243 if(temp
[k
-1] != 0x3F)
244 log_err("something threw an error in u_uastrncpy(k-1)\n");
246 u_memset(temp
, 0x3F, (sizeof(temp
) / sizeof(UChar
)) - 1);
247 u_uastrncpy(temp
, raw
[i
][j
], k
+1);
248 if(u_strcmp(temp
, dataTable
[i
][j
])!=0)
249 log_err("something threw an error in u_uastrncpy(k+1)\n");
252 log_err("something threw an error in u_uastrncpy(k+1)\n");
254 u_memset(temp
, 0x3F, (sizeof(temp
) / sizeof(UChar
)) - 1);
255 u_uastrncpy(temp
, raw
[i
][j
], k
);
256 if(u_strncmp(temp
, dataTable
[i
][j
], k
)!=0)
257 log_err("something threw an error in u_uastrncpy(k)\n");
260 log_err("something threw an error in u_uastrncpy(k)\n");
263 log_verbose("Testing u_strchr() and u_memchr()\n");
267 UChar saveVal
= dataTable
[i
][j
][0];
268 UChar
*findPtr
= u_strchr(dataTable
[i
][j
], 0x005F);
269 int32_t dataSize
= (int32_t)(u_strlen(dataTable
[i
][j
]) + 1);
271 log_verbose("%s ", u_austrcpy(tempOut
, findPtr
));
273 if (findPtr
== NULL
|| *findPtr
!= 0x005F) {
274 log_err("u_strchr can't find '_' in the string\n");
277 findPtr
= u_strchr32(dataTable
[i
][j
], 0x005F);
278 if (findPtr
== NULL
|| *findPtr
!= 0x005F) {
279 log_err("u_strchr32 can't find '_' in the string\n");
282 findPtr
= u_strchr(dataTable
[i
][j
], 0);
283 if (findPtr
!= (&(dataTable
[i
][j
][dataSize
- 1]))) {
284 log_err("u_strchr can't find NULL in the string\n");
287 findPtr
= u_strchr32(dataTable
[i
][j
], 0);
288 if (findPtr
!= (&(dataTable
[i
][j
][dataSize
- 1]))) {
289 log_err("u_strchr32 can't find NULL in the string\n");
292 findPtr
= u_memchr(dataTable
[i
][j
], 0, dataSize
);
293 if (findPtr
!= (&(dataTable
[i
][j
][dataSize
- 1]))) {
294 log_err("u_memchr can't find NULL in the string\n");
297 findPtr
= u_memchr32(dataTable
[i
][j
], 0, dataSize
);
298 if (findPtr
!= (&(dataTable
[i
][j
][dataSize
- 1]))) {
299 log_err("u_memchr32 can't find NULL in the string\n");
302 dataTable
[i
][j
][0] = 0;
303 /* Make sure we skip over the NULL termination */
304 findPtr
= u_memchr(dataTable
[i
][j
], 0x005F, dataSize
);
305 if (findPtr
== NULL
|| *findPtr
!= 0x005F) {
306 log_err("u_memchr can't find '_' in the string\n");
309 findPtr
= u_memchr32(dataTable
[i
][j
], 0x005F, dataSize
);
310 if (findPtr
== NULL
|| *findPtr
!= 0x005F) {
311 log_err("u_memchr32 can't find '_' in the string\n");
313 findPtr
= u_memchr32(dataTable
[i
][j
], 0xFFFD, dataSize
);
314 if (findPtr
!= NULL
) {
315 log_err("Should have found NULL when the character is not there.\n");
317 dataTable
[i
][j
][0] = saveVal
; /* Put it back for the other tests */
321 * test that u_strchr32()
322 * does not find surrogate code points when they are part of matched pairs
323 * (= part of supplementary code points)
327 static const UChar s
[]={
328 /* 0 1 2 3 4 5 6 7 8 9 */
329 0x0061, 0xd841, 0xdc02, 0xd841, 0x0062, 0xdc02, 0xd841, 0xdc02, 0x0063, 0
332 if(u_strchr32(s
, 0xd841)!=(s
+3) || u_strchr32(s
, 0xdc02)!=(s
+5)) {
333 log_err("error: u_strchr32(surrogate) finds a partial supplementary code point\n");
335 if(u_memchr32(s
, 0xd841, 9)!=(s
+3) || u_memchr32(s
, 0xdc02, 9)!=(s
+5)) {
336 log_err("error: u_memchr32(surrogate) finds a partial supplementary code point\n");
340 log_verbose("Testing u_austrcpy()");
341 u_austrcpy(test
,dataTable
[0][0]);
342 if(strcmp(test
,raw
[0][0])!=0)
343 log_err("There is an error in u_austrcpy()");
346 log_verbose("Testing u_strtok_r()");
348 const char tokString
[] = " , 1 2 3 AHHHHH! 5.5 6 7 , 8\n";
349 const char *tokens
[] = {",", "1", "2", "3", "AHHHHH!", "5.5", "6", "7", "8\n"};
350 UChar delimBuf
[sizeof(test
)];
351 UChar currTokenBuf
[sizeof(tokString
)];
353 uint32_t currToken
= 0;
356 u_uastrcpy(temp
, tokString
);
357 u_uastrcpy(delimBuf
, " ");
359 ptr
= u_strtok_r(temp
, delimBuf
, &state
);
360 u_uastrcpy(delimBuf
, " ,");
361 while (ptr
!= NULL
) {
362 u_uastrcpy(currTokenBuf
, tokens
[currToken
]);
363 if (u_strcmp(ptr
, currTokenBuf
) != 0) {
364 log_err("u_strtok_r mismatch at %d. Got: %s, Expected: %s\n", currToken
, ptr
, tokens
[currToken
]);
366 ptr
= u_strtok_r(NULL
, delimBuf
, &state
);
370 if (currToken
!= sizeof(tokens
)/sizeof(tokens
[0])) {
371 log_err("Didn't get correct number of tokens\n");
373 state
= delimBuf
; /* Give it an "invalid" saveState */
374 u_uastrcpy(currTokenBuf
, "");
375 if (u_strtok_r(currTokenBuf
, delimBuf
, &state
) != NULL
) {
376 log_err("Didn't get NULL for empty string\n");
379 log_err("State should be NULL for empty string\n");
381 state
= delimBuf
; /* Give it an "invalid" saveState */
382 u_uastrcpy(currTokenBuf
, ", ,");
383 if (u_strtok_r(currTokenBuf
, delimBuf
, &state
) != NULL
) {
384 log_err("Didn't get NULL for a string of delimiters\n");
387 log_err("State should be NULL for a string of delimiters\n");
390 state
= delimBuf
; /* Give it an "invalid" saveState */
391 u_uastrcpy(currTokenBuf
, "q, ,");
392 if (u_strtok_r(currTokenBuf
, delimBuf
, &state
) == NULL
) {
393 log_err("Got NULL for a string that does not begin with delimiters\n");
395 if (u_strtok_r(NULL
, delimBuf
, &state
) != NULL
) {
396 log_err("Didn't get NULL for a string that ends in delimiters\n");
399 log_err("State should be NULL for empty string\n");
402 state
= delimBuf
; /* Give it an "invalid" saveState */
403 u_uastrcpy(currTokenBuf
, tokString
);
404 u_uastrcpy(temp
, tokString
);
405 u_uastrcpy(delimBuf
, "q"); /* Give it a delimiter that it can't find. */
406 ptr
= u_strtok_r(currTokenBuf
, delimBuf
, &state
);
407 if (ptr
== NULL
|| u_strcmp(ptr
, temp
) != 0) {
408 log_err("Should have recieved the same string when there are no delimiters\n");
410 if (u_strtok_r(NULL
, delimBuf
, &state
) != NULL
) {
411 log_err("Should not have found another token in a one token string\n");
415 /* test u_strcmpCodePointOrder() */
417 /* these strings are in ascending order */
418 static const UChar strings
[][4]={
419 { 0x61, 0 }, /* U+0061 */
420 { 0x20ac, 0xd801, 0 }, /* U+20ac U+d801 */
421 { 0x20ac, 0xd800, 0xdc00, 0 }, /* U+20ac U+10000 */
422 { 0xd800, 0 }, /* U+d800 */
423 { 0xd800, 0xff61, 0 }, /* U+d800 U+ff61 */
424 { 0xdfff, 0 }, /* U+dfff */
425 { 0xff61, 0xdfff, 0 }, /* U+ff61 U+dfff */
426 { 0xff61, 0xd800, 0xdc02, 0 }, /* U+ff61 U+10002 */
427 { 0xd800, 0xdc02, 0 }, /* U+10002 */
428 { 0xd84d, 0xdc56, 0 } /* U+23456 */
431 UCharIterator iter1
, iter2
;
432 int32_t len1
, len2
, r1
, r2
;
434 for(i
=0; i
<(sizeof(strings
)/sizeof(strings
[0])-1); ++i
) {
435 if(u_strcmpCodePointOrder(strings
[i
], strings
[i
+1])>=0) {
436 log_err("error: u_strcmpCodePointOrder() fails for string %d and the following one\n", i
);
438 if(u_strncmpCodePointOrder(strings
[i
], strings
[i
+1], 10)>=0) {
439 log_err("error: u_strncmpCodePointOrder() fails for string %d and the following one\n", i
);
442 /* There are at least 2 UChars in each string - verify that strncmp()==memcmp(). */
443 if(u_strncmpCodePointOrder(strings
[i
], strings
[i
+1], 2)!=u_memcmpCodePointOrder(strings
[i
], strings
[i
+1], 2)) {
444 log_err("error: u_strncmpCodePointOrder(2)!=u_memcmpCodePointOrder(2) for string %d and the following one\n", i
);
447 /* test u_strCompare(TRUE) */
448 len1
=u_strlen(strings
[i
]);
449 len2
=u_strlen(strings
[i
+1]);
450 if( u_strCompare(strings
[i
], -1, strings
[i
+1], -1, TRUE
)>=0 ||
451 u_strCompare(strings
[i
], -1, strings
[i
+1], len2
, TRUE
)>=0 ||
452 u_strCompare(strings
[i
], len1
, strings
[i
+1], -1, TRUE
)>=0 ||
453 u_strCompare(strings
[i
], len1
, strings
[i
+1], len2
, TRUE
)>=0
455 log_err("error: u_strCompare(code point order) fails for string %d and the following one\n", i
);
458 /* test u_strCompare(FALSE) */
459 r1
=u_strCompare(strings
[i
], -1, strings
[i
+1], -1, FALSE
);
460 r2
=u_strcmp(strings
[i
], strings
[i
+1]);
461 if(_SIGN(r1
)!=_SIGN(r2
)) {
462 log_err("error: u_strCompare(code unit order)!=u_strcmp() for string %d and the following one\n", i
);
465 /* test u_strCompareIter() */
466 uiter_setString(&iter1
, strings
[i
], len1
);
467 uiter_setString(&iter2
, strings
[i
+1], len2
);
468 if(u_strCompareIter(&iter1
, &iter2
, TRUE
)>=0) {
469 log_err("error: u_strCompareIter(code point order) fails for string %d and the following one\n", i
);
471 r1
=u_strCompareIter(&iter1
, &iter2
, FALSE
);
472 if(_SIGN(r1
)!=_SIGN(u_strcmp(strings
[i
], strings
[i
+1]))) {
473 log_err("error: u_strCompareIter(code unit order)!=u_strcmp() for string %d and the following one\n", i
);
481 static void TestStringSearching()
483 const UChar testString
[] = {0x0061, 0x0062, 0x0063, 0x0064, 0x0064, 0x0061, 0};
484 const UChar testSurrogateString
[] = {0xdbff, 0x0061, 0x0062, 0xdbff, 0xdfff, 0x0063, 0x0064, 0x0064, 0xdbff, 0xdfff, 0xdb00, 0xdf00, 0x0061, 0};
485 const UChar surrMatchSet1
[] = {0xdbff, 0xdfff, 0};
486 const UChar surrMatchSet2
[] = {0x0061, 0x0062, 0xdbff, 0xdfff, 0};
487 const UChar surrMatchSet3
[] = {0xdb00, 0xdf00, 0xdbff, 0xdfff, 0};
488 const UChar surrMatchSet4
[] = {0x0000};
489 const UChar surrMatchSetBad
[] = {0xdbff, 0x0061, 0};
490 const UChar surrMatchSetBad2
[] = {0x0061, 0xdbff, 0};
491 const UChar surrMatchSetBad3
[] = {0xdbff, 0x0061, 0x0062, 0xdbff, 0xdfff, 0}; /* has partial surrogate */
495 ab
[] = { 0x61, 0x62, 0 },
496 ba
[] = { 0x62, 0x61, 0 },
497 abcd
[] = { 0x61, 0x62, 0x63, 0x64, 0 },
498 cd
[] = { 0x63, 0x64, 0 },
499 dc
[] = { 0x64, 0x63, 0 },
500 cdh
[] = { 0x63, 0x64, 0x68, 0 },
502 fg
[] = { 0x66, 0x67, 0 },
503 gf
[] = { 0x67, 0x66, 0 };
505 log_verbose("Testing u_strpbrk()");
507 if (u_strpbrk(testString
, a
) != &testString
[0]) {
508 log_err("u_strpbrk couldn't find first letter a.\n");
510 if (u_strpbrk(testString
, dc
) != &testString
[2]) {
511 log_err("u_strpbrk couldn't find d or c.\n");
513 if (u_strpbrk(testString
, cd
) != &testString
[2]) {
514 log_err("u_strpbrk couldn't find c or d.\n");
516 if (u_strpbrk(testString
, cdh
) != &testString
[2]) {
517 log_err("u_strpbrk couldn't find c, d or h.\n");
519 if (u_strpbrk(testString
, f
) != NULL
) {
520 log_err("u_strpbrk didn't return NULL for \"f\".\n");
522 if (u_strpbrk(testString
, fg
) != NULL
) {
523 log_err("u_strpbrk didn't return NULL for \"fg\".\n");
525 if (u_strpbrk(testString
, gf
) != NULL
) {
526 log_err("u_strpbrk didn't return NULL for \"gf\".\n");
528 if (u_strpbrk(testString
, empty
) != NULL
) {
529 log_err("u_strpbrk didn't return NULL for \"\".\n");
532 log_verbose("Testing u_strpbrk() with surrogates");
534 if (u_strpbrk(testSurrogateString
, a
) != &testSurrogateString
[1]) {
535 log_err("u_strpbrk couldn't find first letter a.\n");
537 if (u_strpbrk(testSurrogateString
, dc
) != &testSurrogateString
[5]) {
538 log_err("u_strpbrk couldn't find d or c.\n");
540 if (u_strpbrk(testSurrogateString
, cd
) != &testSurrogateString
[5]) {
541 log_err("u_strpbrk couldn't find c or d.\n");
543 if (u_strpbrk(testSurrogateString
, cdh
) != &testSurrogateString
[5]) {
544 log_err("u_strpbrk couldn't find c, d or h.\n");
546 if (u_strpbrk(testSurrogateString
, f
) != NULL
) {
547 log_err("u_strpbrk didn't return NULL for \"f\".\n");
549 if (u_strpbrk(testSurrogateString
, fg
) != NULL
) {
550 log_err("u_strpbrk didn't return NULL for \"fg\".\n");
552 if (u_strpbrk(testSurrogateString
, gf
) != NULL
) {
553 log_err("u_strpbrk didn't return NULL for \"gf\".\n");
555 if (u_strpbrk(testSurrogateString
, surrMatchSet1
) != &testSurrogateString
[3]) {
556 log_err("u_strpbrk couldn't find \"0xdbff, 0xdfff\".\n");
558 if (u_strpbrk(testSurrogateString
, surrMatchSet2
) != &testSurrogateString
[1]) {
559 log_err("u_strpbrk couldn't find \"0xdbff, a, b, 0xdbff, 0xdfff\".\n");
561 if (u_strpbrk(testSurrogateString
, surrMatchSet3
) != &testSurrogateString
[3]) {
562 log_err("u_strpbrk couldn't find \"0xdb00, 0xdf00, 0xdbff, 0xdfff\".\n");
564 if (u_strpbrk(testSurrogateString
, surrMatchSet4
) != NULL
) {
565 log_err("u_strpbrk should have returned NULL for empty string.\n");
567 if (u_strpbrk(testSurrogateString
, surrMatchSetBad
) != &testSurrogateString
[0]) {
568 log_err("u_strpbrk should have found bad surrogate.\n");
571 log_verbose("Testing u_strcspn()");
573 if (u_strcspn(testString
, a
) != 0) {
574 log_err("u_strcspn couldn't find first letter a.\n");
576 if (u_strcspn(testString
, dc
) != 2) {
577 log_err("u_strcspn couldn't find d or c.\n");
579 if (u_strcspn(testString
, cd
) != 2) {
580 log_err("u_strcspn couldn't find c or d.\n");
582 if (u_strcspn(testString
, cdh
) != 2) {
583 log_err("u_strcspn couldn't find c, d or h.\n");
585 if (u_strcspn(testString
, f
) != u_strlen(testString
)) {
586 log_err("u_strcspn didn't return NULL for \"f\".\n");
588 if (u_strcspn(testString
, fg
) != u_strlen(testString
)) {
589 log_err("u_strcspn didn't return NULL for \"fg\".\n");
591 if (u_strcspn(testString
, gf
) != u_strlen(testString
)) {
592 log_err("u_strcspn didn't return NULL for \"gf\".\n");
595 log_verbose("Testing u_strcspn() with surrogates");
597 if (u_strcspn(testSurrogateString
, a
) != 1) {
598 log_err("u_strcspn couldn't find first letter a.\n");
600 if (u_strcspn(testSurrogateString
, dc
) != 5) {
601 log_err("u_strcspn couldn't find d or c.\n");
603 if (u_strcspn(testSurrogateString
, cd
) != 5) {
604 log_err("u_strcspn couldn't find c or d.\n");
606 if (u_strcspn(testSurrogateString
, cdh
) != 5) {
607 log_err("u_strcspn couldn't find c, d or h.\n");
609 if (u_strcspn(testSurrogateString
, f
) != u_strlen(testSurrogateString
)) {
610 log_err("u_strcspn didn't return NULL for \"f\".\n");
612 if (u_strcspn(testSurrogateString
, fg
) != u_strlen(testSurrogateString
)) {
613 log_err("u_strcspn didn't return NULL for \"fg\".\n");
615 if (u_strcspn(testSurrogateString
, gf
) != u_strlen(testSurrogateString
)) {
616 log_err("u_strcspn didn't return NULL for \"gf\".\n");
618 if (u_strcspn(testSurrogateString
, surrMatchSet1
) != 3) {
619 log_err("u_strcspn couldn't find \"0xdbff, 0xdfff\".\n");
621 if (u_strcspn(testSurrogateString
, surrMatchSet2
) != 1) {
622 log_err("u_strcspn couldn't find \"a, b, 0xdbff, 0xdfff\".\n");
624 if (u_strcspn(testSurrogateString
, surrMatchSet3
) != 3) {
625 log_err("u_strcspn couldn't find \"0xdb00, 0xdf00, 0xdbff, 0xdfff\".\n");
627 if (u_strcspn(testSurrogateString
, surrMatchSet4
) != u_strlen(testSurrogateString
)) {
628 log_err("u_strcspn should have returned strlen for empty string.\n");
632 log_verbose("Testing u_strspn()");
634 if (u_strspn(testString
, a
) != 1) {
635 log_err("u_strspn couldn't skip first letter a.\n");
637 if (u_strspn(testString
, ab
) != 2) {
638 log_err("u_strspn couldn't skip a or b.\n");
640 if (u_strspn(testString
, ba
) != 2) {
641 log_err("u_strspn couldn't skip a or b.\n");
643 if (u_strspn(testString
, f
) != 0) {
644 log_err("u_strspn didn't return 0 for \"f\".\n");
646 if (u_strspn(testString
, dc
) != 0) {
647 log_err("u_strspn couldn't find first letter a (skip d or c).\n");
649 if (u_strspn(testString
, abcd
) != u_strlen(testString
)) {
650 log_err("u_strspn couldn't skip over the whole string.\n");
652 if (u_strspn(testString
, empty
) != 0) {
653 log_err("u_strspn should have returned 0 for empty string.\n");
656 log_verbose("Testing u_strspn() with surrogates");
657 if (u_strspn(testSurrogateString
, surrMatchSetBad
) != 2) {
658 log_err("u_strspn couldn't skip 0xdbff or a.\n");
660 if (u_strspn(testSurrogateString
, surrMatchSetBad2
) != 2) {
661 log_err("u_strspn couldn't skip 0xdbff or a.\n");
663 if (u_strspn(testSurrogateString
, f
) != 0) {
664 log_err("u_strspn couldn't skip d or c (skip first letter).\n");
666 if (u_strspn(testSurrogateString
, dc
) != 0) {
667 log_err("u_strspn couldn't skip d or c (skip first letter).\n");
669 if (u_strspn(testSurrogateString
, cd
) != 0) {
670 log_err("u_strspn couldn't skip d or c (skip first letter).\n");
672 if (u_strspn(testSurrogateString
, testSurrogateString
) != u_strlen(testSurrogateString
)) {
673 log_err("u_strspn couldn't skip whole string.\n");
675 if (u_strspn(testSurrogateString
, surrMatchSet1
) != 0) {
676 log_err("u_strspn couldn't skip \"0xdbff, 0xdfff\" (get first letter).\n");
678 if (u_strspn(testSurrogateString
, surrMatchSetBad3
) != 5) {
679 log_err("u_strspn couldn't skip \"0xdbff, a, b, 0xdbff, 0xdfff\".\n");
681 if (u_strspn(testSurrogateString
, surrMatchSet4
) != 0) {
682 log_err("u_strspn should have returned 0 for empty string.\n");
687 * All binary Unicode string searches should behave the same for equivalent input.
688 * See Jitterbug 2145.
689 * There are some new functions, too - just test them all.
692 TestSurrogateSearching() {
693 static const UChar s
[]={
694 /* 0 1 2 3 4 5 6 7 8 9 10 11 */
695 0x61, 0xd801, 0xdc02, 0x61, 0xdc02, 0x61, 0xd801, 0x61, 0xd801, 0xdc02, 0x61, 0
715 static const UChar a
=0x61, b
=0x62, lead
=0xd801, trail
=0xdc02, nul
=0;
716 static const UChar32 supp
=0x10402, supp2
=0x10403, ill
=0x123456;
718 const UChar
*first
, *last
;
720 /* search for NUL code point: find end of string */
724 first
!=u_strchr(s
, nul
) ||
725 first
!=u_strchr32(s
, nul
) ||
726 first
!=u_memchr(s
, nul
, LENGTHOF(s
)) ||
727 first
!=u_memchr32(s
, nul
, LENGTHOF(s
)) ||
728 first
!=u_strrchr(s
, nul
) ||
729 first
!=u_strrchr32(s
, nul
) ||
730 first
!=u_memrchr(s
, nul
, LENGTHOF(s
)) ||
731 first
!=u_memrchr32(s
, nul
, LENGTHOF(s
))
733 log_err("error: one of the u_str[|mem][r]chr[32](s, nul) does not find the terminator of s\n");
736 /* search for empty substring: find beginning of string */
738 s
!=u_strstr(s
, &nul
) ||
739 s
!=u_strFindFirst(s
, -1, &nul
, -1) ||
740 s
!=u_strFindFirst(s
, -1, &nul
, 0) ||
741 s
!=u_strFindFirst(s
, LENGTHOF(s
), &nul
, -1) ||
742 s
!=u_strFindFirst(s
, LENGTHOF(s
), &nul
, 0) ||
743 s
!=u_strrstr(s
, &nul
) ||
744 s
!=u_strFindLast(s
, -1, &nul
, -1) ||
745 s
!=u_strFindLast(s
, -1, &nul
, 0) ||
746 s
!=u_strFindLast(s
, LENGTHOF(s
), &nul
, -1) ||
747 s
!=u_strFindLast(s
, LENGTHOF(s
), &nul
, 0)
749 log_err("error: one of the u_str[str etc](s, \"\") does not find s itself\n");
752 /* find 'a' in s[1..10[ */
756 first
!=u_strchr(s
+1, a
) ||
757 first
!=u_strchr32(s
+1, a
) ||
758 first
!=u_memchr(s
+1, a
, 9) ||
759 first
!=u_memchr32(s
+1, a
, 9) ||
760 first
!=u_strstr(s
+1, sub_a
) ||
761 first
!=u_strFindFirst(s
+1, -1, sub_a
, -1) ||
762 first
!=u_strFindFirst(s
+1, -1, &a
, 1) ||
763 first
!=u_strFindFirst(s
+1, 9, sub_a
, -1) ||
764 first
!=u_strFindFirst(s
+1, 9, &a
, 1) ||
765 (s
+10)!=u_strrchr(s
+1, a
) ||
766 (s
+10)!=u_strrchr32(s
+1, a
) ||
767 last
!=u_memrchr(s
+1, a
, 9) ||
768 last
!=u_memrchr32(s
+1, a
, 9) ||
769 (s
+10)!=u_strrstr(s
+1, sub_a
) ||
770 (s
+10)!=u_strFindLast(s
+1, -1, sub_a
, -1) ||
771 (s
+10)!=u_strFindLast(s
+1, -1, &a
, 1) ||
772 last
!=u_strFindLast(s
+1, 9, sub_a
, -1) ||
773 last
!=u_strFindLast(s
+1, 9, &a
, 1)
775 log_err("error: one of the u_str[chr etc]('a') does not find the correct place\n");
778 /* do not find 'b' in s[1..10[ */
780 NULL
!=u_strchr(s
+1, b
) ||
781 NULL
!=u_strchr32(s
+1, b
) ||
782 NULL
!=u_memchr(s
+1, b
, 9) ||
783 NULL
!=u_memchr32(s
+1, b
, 9) ||
784 NULL
!=u_strstr(s
+1, sub_b
) ||
785 NULL
!=u_strFindFirst(s
+1, -1, sub_b
, -1) ||
786 NULL
!=u_strFindFirst(s
+1, -1, &b
, 1) ||
787 NULL
!=u_strFindFirst(s
+1, 9, sub_b
, -1) ||
788 NULL
!=u_strFindFirst(s
+1, 9, &b
, 1) ||
789 NULL
!=u_strrchr(s
+1, b
) ||
790 NULL
!=u_strrchr32(s
+1, b
) ||
791 NULL
!=u_memrchr(s
+1, b
, 9) ||
792 NULL
!=u_memrchr32(s
+1, b
, 9) ||
793 NULL
!=u_strrstr(s
+1, sub_b
) ||
794 NULL
!=u_strFindLast(s
+1, -1, sub_b
, -1) ||
795 NULL
!=u_strFindLast(s
+1, -1, &b
, 1) ||
796 NULL
!=u_strFindLast(s
+1, 9, sub_b
, -1) ||
797 NULL
!=u_strFindLast(s
+1, 9, &b
, 1)
799 log_err("error: one of the u_str[chr etc]('b') incorrectly finds something\n");
802 /* do not find a non-code point in s[1..10[ */
804 NULL
!=u_strchr32(s
+1, ill
) ||
805 NULL
!=u_memchr32(s
+1, ill
, 9) ||
806 NULL
!=u_strrchr32(s
+1, ill
) ||
807 NULL
!=u_memrchr32(s
+1, ill
, 9)
809 log_err("error: one of the u_str[chr etc](illegal code point) incorrectly finds something\n");
812 /* find U+d801 in s[1..10[ */
815 first
!=u_strchr(s
+1, lead
) ||
816 first
!=u_strchr32(s
+1, lead
) ||
817 first
!=u_memchr(s
+1, lead
, 9) ||
818 first
!=u_memchr32(s
+1, lead
, 9) ||
819 first
!=u_strstr(s
+1, sub_lead
) ||
820 first
!=u_strFindFirst(s
+1, -1, sub_lead
, -1) ||
821 first
!=u_strFindFirst(s
+1, -1, &lead
, 1) ||
822 first
!=u_strFindFirst(s
+1, 9, sub_lead
, -1) ||
823 first
!=u_strFindFirst(s
+1, 9, &lead
, 1) ||
824 first
!=u_strrchr(s
+1, lead
) ||
825 first
!=u_strrchr32(s
+1, lead
) ||
826 first
!=u_memrchr(s
+1, lead
, 9) ||
827 first
!=u_memrchr32(s
+1, lead
, 9) ||
828 first
!=u_strrstr(s
+1, sub_lead
) ||
829 first
!=u_strFindLast(s
+1, -1, sub_lead
, -1) ||
830 first
!=u_strFindLast(s
+1, -1, &lead
, 1) ||
831 first
!=u_strFindLast(s
+1, 9, sub_lead
, -1) ||
832 first
!=u_strFindLast(s
+1, 9, &lead
, 1)
834 log_err("error: one of the u_str[chr etc](U+d801) does not find the correct place\n");
837 /* find U+dc02 in s[1..10[ */
840 first
!=u_strchr(s
+1, trail
) ||
841 first
!=u_strchr32(s
+1, trail
) ||
842 first
!=u_memchr(s
+1, trail
, 9) ||
843 first
!=u_memchr32(s
+1, trail
, 9) ||
844 first
!=u_strstr(s
+1, sub_trail
) ||
845 first
!=u_strFindFirst(s
+1, -1, sub_trail
, -1) ||
846 first
!=u_strFindFirst(s
+1, -1, &trail
, 1) ||
847 first
!=u_strFindFirst(s
+1, 9, sub_trail
, -1) ||
848 first
!=u_strFindFirst(s
+1, 9, &trail
, 1) ||
849 first
!=u_strrchr(s
+1, trail
) ||
850 first
!=u_strrchr32(s
+1, trail
) ||
851 first
!=u_memrchr(s
+1, trail
, 9) ||
852 first
!=u_memrchr32(s
+1, trail
, 9) ||
853 first
!=u_strrstr(s
+1, sub_trail
) ||
854 first
!=u_strFindLast(s
+1, -1, sub_trail
, -1) ||
855 first
!=u_strFindLast(s
+1, -1, &trail
, 1) ||
856 first
!=u_strFindLast(s
+1, 9, sub_trail
, -1) ||
857 first
!=u_strFindLast(s
+1, 9, &trail
, 1)
859 log_err("error: one of the u_str[chr etc](U+dc02) does not find the correct place\n");
862 /* find U+10402 in s[1..10[ */
866 first
!=u_strchr32(s
+1, supp
) ||
867 first
!=u_memchr32(s
+1, supp
, 9) ||
868 first
!=u_strstr(s
+1, sub_supp
) ||
869 first
!=u_strFindFirst(s
+1, -1, sub_supp
, -1) ||
870 first
!=u_strFindFirst(s
+1, -1, sub_supp
, 2) ||
871 first
!=u_strFindFirst(s
+1, 9, sub_supp
, -1) ||
872 first
!=u_strFindFirst(s
+1, 9, sub_supp
, 2) ||
873 last
!=u_strrchr32(s
+1, supp
) ||
874 last
!=u_memrchr32(s
+1, supp
, 9) ||
875 last
!=u_strrstr(s
+1, sub_supp
) ||
876 last
!=u_strFindLast(s
+1, -1, sub_supp
, -1) ||
877 last
!=u_strFindLast(s
+1, -1, sub_supp
, 2) ||
878 last
!=u_strFindLast(s
+1, 9, sub_supp
, -1) ||
879 last
!=u_strFindLast(s
+1, 9, sub_supp
, 2)
881 log_err("error: one of the u_str[chr etc](U+10402) does not find the correct place\n");
884 /* do not find U+10402 in a single UChar */
886 NULL
!=u_memchr32(s
+1, supp
, 1) ||
887 NULL
!=u_strFindFirst(s
+1, 1, sub_supp
, -1) ||
888 NULL
!=u_strFindFirst(s
+1, 1, sub_supp
, 2) ||
889 NULL
!=u_memrchr32(s
+1, supp
, 1) ||
890 NULL
!=u_strFindLast(s
+1, 1, sub_supp
, -1) ||
891 NULL
!=u_strFindLast(s
+1, 1, sub_supp
, 2) ||
892 NULL
!=u_memrchr32(s
+2, supp
, 1) ||
893 NULL
!=u_strFindLast(s
+2, 1, sub_supp
, -1) ||
894 NULL
!=u_strFindLast(s
+2, 1, sub_supp
, 2)
896 log_err("error: one of the u_str[chr etc](U+10402) incorrectly finds a supplementary c.p. in a single UChar\n");
899 /* do not find U+10403 in s[1..10[ */
901 NULL
!=u_strchr32(s
+1, supp2
) ||
902 NULL
!=u_memchr32(s
+1, supp2
, 9) ||
903 NULL
!=u_strstr(s
+1, sub_supp2
) ||
904 NULL
!=u_strFindFirst(s
+1, -1, sub_supp2
, -1) ||
905 NULL
!=u_strFindFirst(s
+1, -1, sub_supp2
, 2) ||
906 NULL
!=u_strFindFirst(s
+1, 9, sub_supp2
, -1) ||
907 NULL
!=u_strFindFirst(s
+1, 9, sub_supp2
, 2) ||
908 NULL
!=u_strrchr32(s
+1, supp2
) ||
909 NULL
!=u_memrchr32(s
+1, supp2
, 9) ||
910 NULL
!=u_strrstr(s
+1, sub_supp2
) ||
911 NULL
!=u_strFindLast(s
+1, -1, sub_supp2
, -1) ||
912 NULL
!=u_strFindLast(s
+1, -1, sub_supp2
, 2) ||
913 NULL
!=u_strFindLast(s
+1, 9, sub_supp2
, -1) ||
914 NULL
!=u_strFindLast(s
+1, 9, sub_supp2
, 2)
916 log_err("error: one of the u_str[chr etc](U+10403) incorrectly finds something\n");
919 /* find <0061 d801> in s[1..10[ */
922 first
!=u_strstr(s
+1, sub_a_lead
) ||
923 first
!=u_strFindFirst(s
+1, -1, sub_a_lead
, -1) ||
924 first
!=u_strFindFirst(s
+1, -1, sub_a_lead
, 2) ||
925 first
!=u_strFindFirst(s
+1, 9, sub_a_lead
, -1) ||
926 first
!=u_strFindFirst(s
+1, 9, sub_a_lead
, 2) ||
927 first
!=u_strrstr(s
+1, sub_a_lead
) ||
928 first
!=u_strFindLast(s
+1, -1, sub_a_lead
, -1) ||
929 first
!=u_strFindLast(s
+1, -1, sub_a_lead
, 2) ||
930 first
!=u_strFindLast(s
+1, 9, sub_a_lead
, -1) ||
931 first
!=u_strFindLast(s
+1, 9, sub_a_lead
, 2)
933 log_err("error: one of the u_str[str etc](<0061 d801>) does not find the correct place\n");
936 /* find <dc02 0061> in s[1..10[ */
939 first
!=u_strstr(s
+1, sub_trail_a
) ||
940 first
!=u_strFindFirst(s
+1, -1, sub_trail_a
, -1) ||
941 first
!=u_strFindFirst(s
+1, -1, sub_trail_a
, 2) ||
942 first
!=u_strFindFirst(s
+1, 9, sub_trail_a
, -1) ||
943 first
!=u_strFindFirst(s
+1, 9, sub_trail_a
, 2) ||
944 first
!=u_strrstr(s
+1, sub_trail_a
) ||
945 first
!=u_strFindLast(s
+1, -1, sub_trail_a
, -1) ||
946 first
!=u_strFindLast(s
+1, -1, sub_trail_a
, 2) ||
947 first
!=u_strFindLast(s
+1, 9, sub_trail_a
, -1) ||
948 first
!=u_strFindLast(s
+1, 9, sub_trail_a
, 2)
950 log_err("error: one of the u_str[str etc](<dc02 0061>) does not find the correct place\n");
953 /* do not find "aba" in s[1..10[ */
955 NULL
!=u_strstr(s
+1, sub_aba
) ||
956 NULL
!=u_strFindFirst(s
+1, -1, sub_aba
, -1) ||
957 NULL
!=u_strFindFirst(s
+1, -1, sub_aba
, 3) ||
958 NULL
!=u_strFindFirst(s
+1, 9, sub_aba
, -1) ||
959 NULL
!=u_strFindFirst(s
+1, 9, sub_aba
, 3) ||
960 NULL
!=u_strrstr(s
+1, sub_aba
) ||
961 NULL
!=u_strFindLast(s
+1, -1, sub_aba
, -1) ||
962 NULL
!=u_strFindLast(s
+1, -1, sub_aba
, 3) ||
963 NULL
!=u_strFindLast(s
+1, 9, sub_aba
, -1) ||
964 NULL
!=u_strFindLast(s
+1, 9, sub_aba
, 3)
966 log_err("error: one of the u_str[str etc](\"aba\") incorrectly finds something\n");
970 static void TestStringCopy()
975 UChar uchars
[]={0x61, 0x62, 0x63, 0x00};
977 char chars
[]="abc"; /* needs default codepage */
979 log_verbose("Testing u_uastrncpy() and u_uastrcpy()");
981 u_uastrcpy(temp
, "abc");
982 if(u_strcmp(temp
, uchars
) != 0) {
983 log_err("There is an error in u_uastrcpy() Expected %s Got %s\n", austrdup(uchars
), austrdup(temp
));
986 temp
[0] = 0xFB; /* load garbage into it */
991 u_uastrncpy(temp
, "abcabcabc", 3);
992 if(u_strncmp(uchars
, temp
, 3) != 0){
993 log_err("There is an error in u_uastrncpy() Expected %s Got %s\n", austrdup(uchars
), austrdup(temp
));
995 if(temp
[3] != 0xFB) {
996 log_err("u_uastrncpy wrote past it's bounds. Expected undisturbed byte at 3\n");
999 charOut
[0] = (char)0x7B; /* load garbage into it */
1000 charOut
[1] = (char)0x7B;
1001 charOut
[2] = (char)0x7B;
1002 charOut
[3] = (char)0x7B;
1012 u_austrncpy(charOut
, temp
, 3);
1013 if(strncmp(chars
, charOut
, 3) != 0){
1014 log_err("There is an error in u_austrncpy() Expected %s Got %s\n", austrdup(uchars
), austrdup(temp
));
1016 if(charOut
[3] != (char)0x7B) {
1017 log_err("u_austrncpy wrote past it's bounds. Expected undisturbed byte at 3\n");
1020 /*Testing u_strchr()*/
1021 log_verbose("Testing u_strchr\n");
1030 result
=u_strchr(temp
, (UChar
)0x62);
1031 if(result
!= temp
+1){
1032 log_err("There is an error in u_strchr() Expected match at position 1 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1034 /*Testing u_strstr()*/
1035 log_verbose("Testing u_strstr\n");
1039 result
=u_strstr(temp
, subString
);
1040 if(result
!= temp
+2){
1041 log_err("There is an error in u_strstr() Expected match at position 2 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1043 result
=u_strstr(temp
, subString
+2); /* subString+2 is an empty string */
1045 log_err("There is an error in u_strstr() Expected match at position 0 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1047 result
=u_strstr(subString
, temp
);
1049 log_err("There is an error in u_strstr() Expected NULL \"not found\" Got non-NULL \"found\" result\n");
1052 /*Testing u_strchr32*/
1053 log_verbose("Testing u_strchr32\n");
1054 result
=u_strchr32(temp
, (UChar32
)0x62);
1055 if(result
!= temp
+1){
1056 log_err("There is an error in u_strchr32() Expected match at position 1 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1058 result
=u_strchr32(temp
, (UChar32
)0xfb);
1060 log_err("There is an error in u_strchr32() Expected NULL \"not found\" Got non-NULL \"found\" result\n");
1062 result
=u_strchr32(temp
, (UChar32
)0x20402);
1063 if(result
!= temp
+5){
1064 log_err("There is an error in u_strchr32() Expected match at position 5 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1068 result
=u_memchr32(temp
, (UChar32
)0x20402, 7);
1069 if(result
!= temp
+5){
1070 log_err("There is an error in u_memchr32() Expected match at position 5 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1072 result
=u_memchr32(temp
, (UChar32
)0x20402, 6);
1074 log_err("There is an error in u_memchr32() Expected no match Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1076 result
=u_memchr32(temp
, (UChar32
)0x20402, 1);
1078 log_err("There is an error in u_memchr32() Expected no match Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1080 result
=u_memchr32(temp
, (UChar32
)0xfc00, 8);
1081 if(result
!= temp
+7){
1082 log_err("There is an error in u_memchr32() Expected match at position 7 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1086 /* test u_unescape() and u_unescapeAt() ------------------------------------- */
1090 static UChar buffer
[200];
1092 static const char* input
=
1093 "Sch\\u00f6nes Auto: \\u20ac 11240.\\fPrivates Zeichen: \\U00102345\\e\\cC\\n \\x1b\\x{263a}";
1095 static const UChar expect
[]={
1096 0x53, 0x63, 0x68, 0xf6, 0x6e, 0x65, 0x73, 0x20, 0x41, 0x75, 0x74, 0x6f, 0x3a, 0x20,
1097 0x20ac, 0x20, 0x31, 0x31, 0x32, 0x34, 0x30, 0x2e, 0x0c,
1098 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x73, 0x20,
1099 0x5a, 0x65, 0x69, 0x63, 0x68, 0x65, 0x6e, 0x3a, 0x20, 0xdbc8, 0xdf45, 0x1b, 0x03, 0x0a, 0x20, 0x1b, 0x263A, 0
1101 static const int32_t explength
= sizeof(expect
)/sizeof(expect
[0])-1;
1104 /* test u_unescape() */
1105 length
=u_unescape(input
, buffer
, sizeof(buffer
)/sizeof(buffer
[0]));
1106 if(length
!=explength
|| u_strcmp(buffer
, expect
)!=0) {
1107 log_err("failure in u_unescape(): length %d!=%d and/or incorrect result string\n", length
,
1111 /* try preflighting */
1112 length
=u_unescape(input
, NULL
, sizeof(buffer
)/sizeof(buffer
[0]));
1113 if(length
!=explength
|| u_strcmp(buffer
, expect
)!=0) {
1114 log_err("failure in u_unescape(preflighting): length %d!=%d\n", length
, explength
);
1117 /* ### TODO: test u_unescapeAt() */
1120 /* test code point counting functions --------------------------------------- */
1122 /* reference implementation of u_strHasMoreChar32Than() */
1124 _refStrHasMoreChar32Than(const UChar
*s
, int32_t length
, int32_t number
) {
1125 int32_t count
=u_countChar32(s
, length
);
1126 return count
>number
;
1129 /* compare the real function against the reference */
1131 _testStrHasMoreChar32Than(const UChar
*s
, int32_t i
, int32_t length
, int32_t number
) {
1132 if(u_strHasMoreChar32Than(s
, length
, number
)!=_refStrHasMoreChar32Than(s
, length
, number
)) {
1133 log_err("u_strHasMoreChar32Than(s+%d, %d, %d)=%hd is wrong\n",
1134 i
, length
, number
, u_strHasMoreChar32Than(s
, length
, number
));
1140 static const UChar string
[]={
1141 0x61, 0x62, 0xd800, 0xdc00,
1142 0xd801, 0xdc01, 0x63, 0xd802,
1143 0x64, 0xdc03, 0x65, 0x66,
1144 0xd804, 0xdc04, 0xd805, 0xdc05,
1148 int32_t i
, length
, number
;
1150 /* test u_strHasMoreChar32Than() with length>=0 */
1151 length
=LENGTHOF(string
);
1153 for(i
=0; i
<=length
; ++i
) {
1154 for(number
=-1; number
<=((length
-i
)+2); ++number
) {
1155 _testStrHasMoreChar32Than(string
+i
, i
, length
-i
, number
);
1161 /* test u_strHasMoreChar32Than() with NUL-termination (length=-1) */
1162 length
=LENGTHOF(string
);
1163 u_memcpy(buffer
, string
, length
);
1166 for(i
=0; i
<=length
; ++i
) {
1167 for(number
=-1; number
<=((length
-i
)+2); ++number
) {
1168 _testStrHasMoreChar32Than(string
+i
, i
, -1, number
);
1174 /* test u_strHasMoreChar32Than() with NULL string (bad input) */
1175 for(length
=-1; length
<=1; ++length
) {
1176 for(i
=0; i
<=length
; ++i
) {
1177 for(number
=-2; number
<=2; ++number
) {
1178 _testStrHasMoreChar32Than(NULL
, 0, length
, number
);
1184 /* UCharIterator ------------------------------------------------------------ */
1187 * Compare results from two iterators, should be same.
1188 * Assume that the text is not empty and that
1189 * iteration start==0 and iteration limit==length.
1192 compareIterators(UCharIterator
*iter1
, const char *n1
,
1193 UCharIterator
*iter2
, const char *n2
) {
1194 int32_t i
, pos1
, pos2
, middle
, length
;
1197 /* compare lengths */
1198 length
=iter1
->getIndex(iter1
, UITER_LENGTH
);
1199 pos2
=iter2
->getIndex(iter2
, UITER_LENGTH
);
1201 log_err("%s->getIndex(length)=%d != %d=%s->getIndex(length)\n", n1
, length
, pos2
, n2
);
1205 /* set into the middle */
1208 pos1
=iter1
->move(iter1
, middle
, UITER_ZERO
);
1210 log_err("%s->move(from 0 to middle %d)=%d does not move to the middle\n", n1
, middle
, pos1
);
1214 pos2
=iter2
->move(iter2
, middle
, UITER_ZERO
);
1216 log_err("%s->move(from 0 to middle %d)=%d does not move to the middle\n", n2
, middle
, pos2
);
1220 /* test current() */
1221 c1
=iter1
->current(iter1
);
1222 c2
=iter2
->current(iter2
);
1224 log_err("%s->current()=U+%04x != U+%04x=%s->current() at middle=%d\n", n1
, c1
, c2
, n2
, middle
);
1228 /* move forward 3 UChars */
1229 for(i
=0; i
<3; ++i
) {
1230 c1
=iter1
->next(iter1
);
1231 c2
=iter2
->next(iter2
);
1233 log_err("%s->next()=U+%04x != U+%04x=%s->next() at %d (started in middle)\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1238 /* move backward 5 UChars */
1239 for(i
=0; i
<5; ++i
) {
1240 c1
=iter1
->previous(iter1
);
1241 c2
=iter2
->previous(iter2
);
1243 log_err("%s->previous()=U+%04x != U+%04x=%s->previous() at %d (started in middle)\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1248 /* iterate forward from the beginning */
1249 pos1
=iter1
->move(iter1
, 0, UITER_START
);
1251 log_err("%s->move(start) failed\n", n1
);
1254 if(!iter1
->hasNext(iter1
)) {
1255 log_err("%s->hasNext() at the start returns FALSE\n", n1
);
1259 pos2
=iter2
->move(iter2
, 0, UITER_START
);
1261 log_err("%s->move(start) failed\n", n2
);
1264 if(!iter2
->hasNext(iter2
)) {
1265 log_err("%s->hasNext() at the start returns FALSE\n", n2
);
1270 c1
=iter1
->next(iter1
);
1271 c2
=iter2
->next(iter2
);
1273 log_err("%s->next()=U+%04x != U+%04x=%s->next() at %d\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1278 if(iter1
->hasNext(iter1
)) {
1279 log_err("%s->hasNext() at the end returns TRUE\n", n1
);
1282 if(iter2
->hasNext(iter2
)) {
1283 log_err("%s->hasNext() at the end returns TRUE\n", n2
);
1287 /* back to the middle */
1288 pos1
=iter1
->move(iter1
, middle
, UITER_ZERO
);
1290 log_err("%s->move(from end to middle %d)=%d does not move to the middle\n", n1
, middle
, pos1
);
1294 pos2
=iter2
->move(iter2
, middle
, UITER_ZERO
);
1296 log_err("%s->move(from end to middle %d)=%d does not move to the middle\n", n2
, middle
, pos2
);
1300 /* move to index 1 */
1301 pos1
=iter1
->move(iter1
, 1, UITER_ZERO
);
1303 log_err("%s->move(from middle %d to 1)=%d does not move to 1\n", n1
, middle
, pos1
);
1307 pos2
=iter2
->move(iter2
, 1, UITER_ZERO
);
1309 log_err("%s->move(from middle %d to 1)=%d does not move to 1\n", n2
, middle
, pos2
);
1313 /* iterate backward from the end */
1314 pos1
=iter1
->move(iter1
, 0, UITER_LIMIT
);
1316 log_err("%s->move(limit) failed\n", n1
);
1319 if(!iter1
->hasPrevious(iter1
)) {
1320 log_err("%s->hasPrevious() at the end returns FALSE\n", n1
);
1324 pos2
=iter2
->move(iter2
, 0, UITER_LIMIT
);
1326 log_err("%s->move(limit) failed\n", n2
);
1329 if(!iter2
->hasPrevious(iter2
)) {
1330 log_err("%s->hasPrevious() at the end returns FALSE\n", n2
);
1335 c1
=iter1
->previous(iter1
);
1336 c2
=iter2
->previous(iter2
);
1338 log_err("%s->previous()=U+%04x != U+%04x=%s->previous() at %d\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1343 if(iter1
->hasPrevious(iter1
)) {
1344 log_err("%s->hasPrevious() at the start returns TRUE\n", n1
);
1347 if(iter2
->hasPrevious(iter2
)) {
1348 log_err("%s->hasPrevious() at the start returns TRUE\n", n2
);
1354 * Test the iterator's getState() and setState() functions.
1355 * iter1 and iter2 must be set up for the same iterator type and the same string
1356 * but may be physically different structs (different addresses).
1358 * Assume that the text is not empty and that
1359 * iteration start==0 and iteration limit==length.
1360 * It must be 2<=middle<=length-2.
1363 testIteratorState(UCharIterator
*iter1
, UCharIterator
*iter2
, const char *n
, int32_t middle
) {
1366 UErrorCode errorCode
;
1371 /* get four UChars from the middle of the string */
1372 iter1
->move(iter1
, middle
-2, UITER_ZERO
);
1373 for(i
=0; i
<4; ++i
) {
1374 c
=iter1
->next(iter1
);
1376 /* the test violates the assumptions, see comment above */
1377 log_err("test error: %s[%d]=%d\n", n
, middle
-2+i
, c
);
1383 /* move to the middle and get the state */
1384 iter1
->move(iter1
, -2, UITER_CURRENT
);
1385 state
=uiter_getState(iter1
);
1387 /* set the state into the second iterator and compare the results */
1388 errorCode
=U_ZERO_ERROR
;
1389 uiter_setState(iter2
, state
, &errorCode
);
1390 if(U_FAILURE(errorCode
)) {
1391 log_err("%s->setState(0x%x) failed: %s\n", n
, state
, u_errorName(errorCode
));
1395 c
=iter2
->current(iter2
);
1397 log_err("%s->current(at %d)=U+%04x!=U+%04x\n", n
, middle
, c
, u
[2]);
1400 c
=iter2
->previous(iter2
);
1402 log_err("%s->previous(at %d)=U+%04x!=U+%04x\n", n
, middle
-1, c
, u
[1]);
1405 iter2
->move(iter2
, 2, UITER_CURRENT
);
1406 c
=iter2
->next(iter2
);
1408 log_err("%s->next(at %d)=U+%04x!=U+%04x\n", n
, middle
+1, c
, u
[3]);
1411 iter2
->move(iter2
, -3, UITER_CURRENT
);
1412 c
=iter2
->previous(iter2
);
1414 log_err("%s->previous(at %d)=U+%04x!=U+%04x\n", n
, middle
-2, c
, u
[0]);
1417 /* move the second iterator back to the middle */
1418 iter2
->move(iter2
, 1, UITER_CURRENT
);
1421 /* check that both are in the middle */
1422 i
=iter1
->getIndex(iter1
, UITER_CURRENT
);
1423 j
=iter2
->getIndex(iter2
, UITER_CURRENT
);
1425 log_err("%s->getIndex(current)=%d!=%d as expected\n", n
, i
, middle
);
1428 log_err("%s->getIndex(current)=%d!=%d after setState()\n", n
, j
, i
);
1431 /* compare lengths */
1432 i
=iter1
->getIndex(iter1
, UITER_LENGTH
);
1433 j
=iter2
->getIndex(iter2
, UITER_LENGTH
);
1435 log_err("%s->getIndex(length)=%d!=%d before/after setState()\n", n
, i
, j
);
1440 TestUCharIterator() {
1441 static const UChar text
[]={
1442 0x61, 0x62, 0x63, 0xd801, 0xdffd, 0x78, 0x79, 0x7a, 0
1446 UCharIterator iter
, iter1
, iter2
;
1448 UErrorCode errorCode
;
1451 /* simple API/code coverage - test NOOP UCharIterator */
1452 uiter_setString(&iter
, NULL
, 0);
1453 if( iter
.current(&iter
)!=-1 || iter
.next(&iter
)!=-1 || iter
.previous(&iter
)!=-1 ||
1454 iter
.move(&iter
, 1, UITER_CURRENT
) || iter
.getIndex(&iter
, UITER_CURRENT
)!=0 ||
1455 iter
.hasNext(&iter
) || iter
.hasPrevious(&iter
)
1457 log_err("NOOP UCharIterator behaves unexpectedly\n");
1460 /* test get/set state */
1461 length
=LENGTHOF(text
)-1;
1462 uiter_setString(&iter1
, text
, -1);
1463 uiter_setString(&iter2
, text
, length
);
1464 testIteratorState(&iter1
, &iter2
, "UTF16IteratorState", length
/2);
1465 testIteratorState(&iter1
, &iter2
, "UTF16IteratorStatePlus1", length
/2+1);
1467 /* compare the same string between UTF-16 and UTF-8 UCharIterators ------ */
1468 errorCode
=U_ZERO_ERROR
;
1469 u_strToUTF8(bytes
, sizeof(bytes
), &length
, text
, -1, &errorCode
);
1470 if(U_FAILURE(errorCode
)) {
1471 log_err("u_strToUTF8() failed, %s\n", u_errorName(errorCode
));
1475 uiter_setString(&iter1
, text
, -1);
1476 uiter_setUTF8(&iter2
, bytes
, length
);
1477 compareIterators(&iter1
, "UTF16Iterator", &iter2
, "UTF8Iterator");
1479 /* try again with length=-1 */
1480 uiter_setUTF8(&iter2
, bytes
, -1);
1481 compareIterators(&iter1
, "UTF16Iterator", &iter2
, "UTF8Iterator_1");
1483 /* test get/set state */
1484 length
=LENGTHOF(text
)-1;
1485 uiter_setUTF8(&iter1
, bytes
, -1);
1486 testIteratorState(&iter1
, &iter2
, "UTF8IteratorState", length
/2);
1487 testIteratorState(&iter1
, &iter2
, "UTF8IteratorStatePlus1", length
/2+1);
1489 /* compare the same string between UTF-16 and UTF-16BE UCharIterators --- */
1490 errorCode
=U_ZERO_ERROR
;
1491 cnv
=ucnv_open("UTF-16BE", &errorCode
);
1492 length
=ucnv_fromUChars(cnv
, bytes
, sizeof(bytes
), text
, -1, &errorCode
);
1494 if(U_FAILURE(errorCode
)) {
1495 log_err("ucnv_fromUChars(UTF-16BE) failed, %s\n", u_errorName(errorCode
));
1499 /* terminate with a _pair_ of 0 bytes - a UChar NUL in UTF-16BE (length is known to be ok) */
1500 bytes
[length
]=bytes
[length
+1]=0;
1502 uiter_setString(&iter1
, text
, -1);
1503 uiter_setUTF16BE(&iter2
, bytes
, length
);
1504 compareIterators(&iter1
, "UTF16Iterator", &iter2
, "UTF16BEIterator");
1506 /* try again with length=-1 */
1507 uiter_setUTF16BE(&iter2
, bytes
, -1);
1508 compareIterators(&iter1
, "UTF16Iterator", &iter2
, "UTF16BEIterator_1");
1510 /* try again after moving the bytes up one, and with length=-1 */
1511 memmove(bytes
+1, bytes
, length
+2);
1512 uiter_setUTF16BE(&iter2
, bytes
+1, -1);
1513 compareIterators(&iter1
, "UTF16Iterator", &iter2
, "UTF16BEIteratorMoved1");
1515 /* ### TODO test other iterators: CharacterIterator, Replaceable */
1518 #if UCONFIG_NO_COLLATION
1521 TestUNormIterator() {
1526 TestBadUNormIterator(void) {
1527 /* test nothing, as well */
1532 #include "unicode/unorm.h"
1533 #include "unorm_it.h"
1536 * Compare results from two iterators, should be same.
1537 * Assume that the text is not empty and that
1538 * iteration start==0 and iteration limit==length.
1540 * Modified version of compareIterators() but does not assume that indexes
1544 compareIterNoIndexes(UCharIterator
*iter1
, const char *n1
,
1545 UCharIterator
*iter2
, const char *n2
,
1550 UErrorCode errorCode
;
1552 /* code coverage for unorm_it.c/unormIteratorGetIndex() */
1554 iter2
->getIndex(iter2
, UITER_START
)!=0 ||
1555 iter2
->getIndex(iter2
, UITER_LENGTH
)!=UITER_UNKNOWN_INDEX
1557 log_err("UNormIterator.getIndex() failed\n");
1560 /* set into the middle */
1561 iter1
->move(iter1
, middle
, UITER_ZERO
);
1562 iter2
->move(iter2
, middle
, UITER_ZERO
);
1564 /* test current() */
1565 c1
=iter1
->current(iter1
);
1566 c2
=iter2
->current(iter2
);
1568 log_err("%s->current()=U+%04x != U+%04x=%s->current() at middle=%d\n", n1
, c1
, c2
, n2
, middle
);
1572 /* move forward 3 UChars */
1573 for(i
=0; i
<3; ++i
) {
1574 c1
=iter1
->next(iter1
);
1575 c2
=iter2
->next(iter2
);
1577 log_err("%s->next()=U+%04x != U+%04x=%s->next() at %d (started in middle)\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1582 /* move backward 5 UChars */
1583 for(i
=0; i
<5; ++i
) {
1584 c1
=iter1
->previous(iter1
);
1585 c2
=iter2
->previous(iter2
);
1587 log_err("%s->previous()=U+%04x != U+%04x=%s->previous() at %d (started in middle)\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1592 /* iterate forward from the beginning */
1593 iter1
->move(iter1
, 0, UITER_START
);
1594 if(!iter1
->hasNext(iter1
)) {
1595 log_err("%s->hasNext() at the start returns FALSE\n", n1
);
1599 iter2
->move(iter2
, 0, UITER_START
);
1600 if(!iter2
->hasNext(iter2
)) {
1601 log_err("%s->hasNext() at the start returns FALSE\n", n2
);
1606 c1
=iter1
->next(iter1
);
1607 c2
=iter2
->next(iter2
);
1609 log_err("%s->next()=U+%04x != U+%04x=%s->next() at %d\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1614 if(iter1
->hasNext(iter1
)) {
1615 log_err("%s->hasNext() at the end returns TRUE\n", n1
);
1618 if(iter2
->hasNext(iter2
)) {
1619 log_err("%s->hasNext() at the end returns TRUE\n", n2
);
1623 /* iterate backward */
1625 c1
=iter1
->previous(iter1
);
1626 c2
=iter2
->previous(iter2
);
1628 log_err("%s->previous()=U+%04x != U+%04x=%s->previous() at %d\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1633 /* back to the middle */
1634 iter1
->move(iter1
, middle
, UITER_ZERO
);
1635 iter2
->move(iter2
, middle
, UITER_ZERO
);
1637 /* try get/set state */
1638 while((state
=uiter_getState(iter2
))==UITER_NO_STATE
) {
1639 if(!iter2
->hasNext(iter2
)) {
1640 log_err("%s has no known state from middle=%d to the end\n", n2
, middle
);
1646 errorCode
=U_ZERO_ERROR
;
1648 c2
=iter2
->current(iter2
);
1649 iter2
->move(iter2
, 0, UITER_ZERO
);
1650 uiter_setState(iter2
, state
, &errorCode
);
1651 c1
=iter2
->current(iter2
);
1652 if(U_FAILURE(errorCode
) || c1
!=c2
) {
1653 log_err("%s->current() differs across get/set state, U+%04x vs. U+%04x\n", n2
, c2
, c1
);
1657 c2
=iter2
->previous(iter2
);
1658 iter2
->move(iter2
, 0, UITER_ZERO
);
1659 uiter_setState(iter2
, state
, &errorCode
);
1660 c1
=iter2
->previous(iter2
);
1661 if(U_FAILURE(errorCode
) || c1
!=c2
) {
1662 log_err("%s->previous() differs across get/set state, U+%04x vs. U+%04x\n", n2
, c2
, c1
);
1666 /* iterate backward from the end */
1667 iter1
->move(iter1
, 0, UITER_LIMIT
);
1668 if(!iter1
->hasPrevious(iter1
)) {
1669 log_err("%s->hasPrevious() at the end returns FALSE\n", n1
);
1673 iter2
->move(iter2
, 0, UITER_LIMIT
);
1674 if(!iter2
->hasPrevious(iter2
)) {
1675 log_err("%s->hasPrevious() at the end returns FALSE\n", n2
);
1680 c1
=iter1
->previous(iter1
);
1681 c2
=iter2
->previous(iter2
);
1683 log_err("%s->previous()=U+%04x != U+%04x=%s->previous() at %d\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1688 if(iter1
->hasPrevious(iter1
)) {
1689 log_err("%s->hasPrevious() at the start returns TRUE\n", n1
);
1692 if(iter2
->hasPrevious(iter2
)) {
1693 log_err("%s->hasPrevious() at the start returns TRUE\n", n2
);
1698 /* n2 must have a digit 1 at the end, will be incremented with the normalization mode */
1700 testUNormIteratorWithText(const UChar
*text
, int32_t textLength
, int32_t middle
,
1701 const char *name1
, const char *n2
) {
1705 UCharIterator iter1
, iter2
, *iter
;
1708 UNormalizationMode mode
;
1709 UErrorCode errorCode
;
1712 /* open a normalizing iterator */
1713 errorCode
=U_ZERO_ERROR
;
1714 uni
=unorm_openIter(NULL
, 0, &errorCode
);
1715 if(U_FAILURE(errorCode
)) {
1716 log_err("unorm_openIter() fails: %s\n", u_errorName(errorCode
));
1720 /* set iterator 2 to the original text */
1721 uiter_setString(&iter2
, text
, textLength
);
1725 /* test the normalizing iterator for each mode */
1726 for(mode
=UNORM_NONE
; mode
<UNORM_MODE_COUNT
; ++mode
) {
1727 length
=unorm_normalize(text
, textLength
, mode
, 0, buffer
, LENGTHOF(buffer
), &errorCode
);
1728 if(U_FAILURE(errorCode
)) {
1729 log_data_err("unorm_normalize(mode %d) failed: %s - (Are you missing data?)\n", mode
, u_errorName(errorCode
));
1733 /* set iterator 1 to the normalized text */
1734 uiter_setString(&iter1
, buffer
, length
);
1736 /* set the normalizing iterator to use iter2 */
1737 iter
=unorm_setIter(uni
, &iter2
, mode
, &errorCode
);
1738 if(U_FAILURE(errorCode
)) {
1739 log_err("unorm_setIter(mode %d) failed: %s\n", mode
, u_errorName(errorCode
));
1743 compareIterNoIndexes(&iter1
, name1
, iter
, name2
, middle
);
1744 ++name2
[strlen(name2
)-1];
1747 unorm_closeIter(uni
);
1751 TestUNormIterator() {
1752 static const UChar text
[]={ /* must contain <00C5 0327> see u_strchr() below */
1754 0xe4, 0x61, 0x308, /* variations of 'a'+umlaut */
1755 0xc5, 0x327, 0x41, 0x30a, 0x327, 0x41, 0x327, 0x30a, /* variations of 'A'+ring+cedilla */
1756 0xfb03, 0xfb00, 0x69, 0x66, 0x66, 0x69, 0x66, 0xfb01 /* variations of 'ffi' */
1758 static const UChar surrogateText
[]={
1759 0x6e, 0xd900, 0x6a, 0xdc00, 0xd900, 0xdc00, 0x61
1762 UChar longText
[600];
1763 int32_t i
, middle
, length
;
1765 length
=LENGTHOF(text
);
1766 testUNormIteratorWithText(text
, length
, length
/2, "UCharIter", "UNormIter1");
1767 testUNormIteratorWithText(text
, length
, length
, "UCharIterEnd", "UNormIterEnd1");
1769 /* test again, this time with an insane string to cause internal buffer overflows */
1770 middle
=(int32_t)(u_strchr(text
, 0x327)-text
); /* see comment at text[] */
1771 memcpy(longText
, text
, middle
*U_SIZEOF_UCHAR
);
1772 for(i
=0; i
<150; ++i
) {
1773 longText
[middle
+i
]=0x30a; /* insert many rings between 'A-ring' and cedilla */
1775 memcpy(longText
+middle
+i
, text
+middle
, (LENGTHOF(text
)-middle
)*U_SIZEOF_UCHAR
);
1776 length
=LENGTHOF(text
)+i
;
1778 /* append another copy of this string for more overflows */
1779 memcpy(longText
+length
, longText
, length
*U_SIZEOF_UCHAR
);
1782 /* the first test of the following two starts at length/4, inside the sea of combining rings */
1783 testUNormIteratorWithText(longText
, length
, length
/4, "UCharIterLong", "UNormIterLong1");
1784 testUNormIteratorWithText(longText
, length
, length
, "UCharIterLongEnd", "UNormIterLongEnd1");
1786 length
=LENGTHOF(surrogateText
);
1787 testUNormIteratorWithText(surrogateText
, length
, length
/4, "UCharIterSurr", "UNormIterSurr1");
1788 testUNormIteratorWithText(surrogateText
, length
, length
, "UCharIterSurrEnd", "UNormIterSurrEnd1");
1792 TestBadUNormIterator(void) {
1793 #if !UCONFIG_NO_NORMALIZATION
1794 UErrorCode status
= U_ILLEGAL_ESCAPE_SEQUENCE
;
1797 unorm_setIter(NULL
, NULL
, UNORM_NONE
, &status
);
1798 if (status
!= U_ILLEGAL_ESCAPE_SEQUENCE
) {
1799 log_err("unorm_setIter changed the error code to: %s\n", u_errorName(status
));
1801 status
= U_ZERO_ERROR
;
1802 unorm_setIter(NULL
, NULL
, UNORM_NONE
, &status
);
1803 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1804 log_err("unorm_setIter didn't react correctly to bad arguments: %s\n", u_errorName(status
));
1806 status
= U_ZERO_ERROR
;
1807 uni
=unorm_openIter(NULL
, 0, &status
);
1808 if(U_FAILURE(status
)) {
1809 log_err("unorm_openIter() fails: %s\n", u_errorName(status
));
1812 unorm_setIter(uni
, NULL
, UNORM_NONE
, &status
);
1813 unorm_closeIter(uni
);