2 ******************************************************************************
4 * Copyright (C) 2002-2004, 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/utypes.h"
20 #include "unicode/ustring.h"
21 #include "unicode/uloc.h"
22 #include "unicode/ucnv.h"
23 #include "unicode/uiter.h"
29 #define LENGTHOF(array) (sizeof(array)/sizeof((array)[0]))
31 /* get the sign of an integer */
32 #define _SIGN(value) ((value)==0 ? 0 : ((int32_t)(value)>>31)|1)
34 /* test setup --------------------------------------------------------------- */
36 static void setUpDataTable(void);
37 static void TestStringCopy(void);
38 static void TestStringFunctions(void);
39 static void TestStringSearching(void);
40 static void TestSurrogateSearching(void);
41 static void TestUnescape(void);
42 static void TestCountChar32(void);
43 static void TestUCharIterator(void);
44 static void TestUNormIterator(void);
46 void addUStringTest(TestNode
** root
);
48 void addUStringTest(TestNode
** root
)
50 addTest(root
, &TestStringCopy
, "tsutil/custrtst/TestStringCopy");
51 addTest(root
, &TestStringFunctions
, "tsutil/custrtst/TestStringFunctions");
52 addTest(root
, &TestStringSearching
, "tsutil/custrtst/TestStringSearching");
53 addTest(root
, &TestSurrogateSearching
, "tsutil/custrtst/TestSurrogateSearching");
54 addTest(root
, &TestUnescape
, "tsutil/custrtst/TestUnescape");
55 addTest(root
, &TestCountChar32
, "tsutil/custrtst/TestCountChar32");
56 addTest(root
, &TestUCharIterator
, "tsutil/custrtst/TestUCharIterator");
57 addTest(root
, &TestUNormIterator
, "tsutil/custrtst/TestUNormIterator");
59 /* cstrcase.c functions, declared in cucdtst.h */
60 addTest(root
, &TestCaseLower
, "tsutil/custrtst/TestCaseLower");
61 addTest(root
, &TestCaseUpper
, "tsutil/custrtst/TestCaseUpper");
62 #if !UCONFIG_NO_BREAK_ITERATION
63 addTest(root
, &TestCaseTitle
, "tsutil/custrtst/TestCaseTitle");
65 addTest(root
, &TestCaseFolding
, "tsutil/custrtst/TestCaseFolding");
66 addTest(root
, &TestCaseCompare
, "tsutil/custrtst/TestCaseCompare");
69 /* test data for TestStringFunctions ---------------------------------------- */
71 UChar
*** dataTable
= NULL
;
73 static const char* raw
[3][4] = {
76 { "English_", "French_", "Croatian_", "English_"},
78 { "United States", "France", "Croatia", "Unites States"},
80 /* Concatenated string */
81 { "English_United States", "French_France", "Croatian_Croatia", "English_United States"}
84 static void setUpDataTable()
87 if(dataTable
== NULL
) {
88 dataTable
= (UChar
***)calloc(sizeof(UChar
**),3);
90 for (i
= 0; i
< 3; i
++) {
91 dataTable
[i
] = (UChar
**)calloc(sizeof(UChar
*),4);
92 for (j
= 0; j
< 4; j
++){
93 dataTable
[i
][j
] = (UChar
*) malloc(sizeof(UChar
)*(strlen(raw
[i
][j
])+1));
94 u_uastrcpy(dataTable
[i
][j
],raw
[i
][j
]);
100 static void cleanUpDataTable()
103 if(dataTable
!= NULL
) {
104 for (i
=0; i
<3; i
++) {
105 for(j
= 0; j
<4; j
++) {
106 free(dataTable
[i
][j
]);
115 /*Tests for u_strcat(),u_strcmp(), u_strlen(), u_strcpy(),u_strncat(),u_strncmp(),u_strncpy, u_uastrcpy(),u_austrcpy(), u_uastrncpy(); */
116 static void TestStringFunctions()
126 log_verbose("Testing u_strlen()\n");
127 if( u_strlen(dataTable
[0][0])!= u_strlen(dataTable
[0][3]) || u_strlen(dataTable
[0][0]) == u_strlen(dataTable
[0][2]))
128 log_err("There is an error in u_strlen()");
130 log_verbose("Testing u_memcpy() and u_memcmp()\n");
136 log_verbose("Testing %s\n", u_austrcpy(tempOut
, dataTable
[i
][j
]));
138 temp
[7] = 0xA4; /* Mark the end */
139 u_memcpy(temp
,dataTable
[i
][j
], 7);
142 log_err("an error occured in u_memcpy()\n");
143 if(u_memcmp(temp
, dataTable
[i
][j
], 7)!=0)
144 log_err("an error occured in u_memcpy() or u_memcmp()\n");
147 if(u_memcmp(dataTable
[0][0], dataTable
[1][1], 7)==0)
148 log_err("an error occured in u_memcmp()\n");
150 log_verbose("Testing u_memset()\n");
153 u_memset(nullTemp
, 0xa4, 7);
154 for (i
= 0; i
< 7; i
++) {
155 if(nullTemp
[i
] != 0xa4) {
156 log_err("an error occured in u_memset()\n");
159 if(nullTemp
[7] != 0) {
160 log_err("u_memset() went too far\n");
163 u_memset(nullTemp
, 0, 7);
166 u_memcpy(temp
,nullTemp
, 7);
167 if(u_memcmp(temp
, nullTemp
, 7)!=0 || temp
[7]!=0)
168 log_err("an error occured in u_memcpy() or u_memcmp()\n");
171 log_verbose("Testing u_memmove()\n");
172 for (i
= 0; i
< 7; i
++) {
175 u_memmove(temp
+ 1, temp
, 7);
177 log_err("an error occured in u_memmove()\n");
179 for (i
= 1; i
<= 7; i
++) {
180 if(temp
[i
] != (i
- 1)) {
181 log_err("an error occured in u_memmove()\n");
185 log_verbose("Testing u_strcpy() and u_strcmp()\n");
191 log_verbose("Testing %s\n", u_austrcpy(tempOut
, dataTable
[i
][j
]));
193 u_strcpy(temp
,dataTable
[i
][j
]);
195 if(u_strcmp(temp
,dataTable
[i
][j
])!=0)
196 log_err("something threw an error in u_strcpy() or u_strcmp()\n");
199 if(u_strcmp(dataTable
[0][0], dataTable
[1][1])==0)
200 log_err("an error occured in u_memcmp()\n");
202 log_verbose("testing u_strcat()\n");
206 u_uastrcpy(temp
, "");
207 u_strcpy(temp
,dataTable
[i
][j
]);
208 u_strcat(temp
,dataTable
[i
+1][j
]);
209 if(u_strcmp(temp
,dataTable
[i
+2][j
])!=0)
210 log_err("something threw an error in u_strcat()\n");
213 log_verbose("Testing u_strncmp()\n");
214 for(i
=0,j
=0;j
<4; ++j
)
216 k
=u_strlen(dataTable
[i
][j
]);
217 if(u_strncmp(dataTable
[i
][j
],dataTable
[i
+2][j
],k
)!=0)
218 log_err("Something threw an error in u_strncmp\n");
220 if(u_strncmp(dataTable
[0][0], dataTable
[1][1], 7)==0)
221 log_err("an error occured in u_memcmp()\n");
224 log_verbose("Testing u_strncat\n");
225 for(i
=0,j
=0;j
<4; ++j
)
227 k
=u_strlen(dataTable
[i
][j
]);
231 if(u_strcmp(u_strncat(temp
,dataTable
[i
+2][j
],k
),dataTable
[i
][j
])!=0)
232 log_err("something threw an error in u_strncat or u_uastrcpy()\n");
236 log_verbose("Testing u_strncpy() and u_uastrcpy()\n");
237 for(i
=2,j
=0;j
<4; ++j
)
239 k
=u_strlen(dataTable
[i
][j
]);
240 u_strncpy(temp
, dataTable
[i
][j
],k
);
243 if(u_strncmp(temp
, dataTable
[i
][j
],k
)!=0)
244 log_err("something threw an error in u_strncpy()\n");
247 log_err("something threw an error in u_strncpy()\n");
249 u_memset(temp
, 0x3F, (sizeof(temp
) / sizeof(UChar
)) - 1);
250 u_uastrncpy(temp
, raw
[i
][j
], k
-1);
251 if(u_strncmp(temp
, dataTable
[i
][j
],k
-1)!=0)
252 log_err("something threw an error in u_uastrncpy(k-1)\n");
254 if(temp
[k
-1] != 0x3F)
255 log_err("something threw an error in u_uastrncpy(k-1)\n");
257 u_memset(temp
, 0x3F, (sizeof(temp
) / sizeof(UChar
)) - 1);
258 u_uastrncpy(temp
, raw
[i
][j
], k
+1);
259 if(u_strcmp(temp
, dataTable
[i
][j
])!=0)
260 log_err("something threw an error in u_uastrncpy(k+1)\n");
263 log_err("something threw an error in u_uastrncpy(k+1)\n");
265 u_memset(temp
, 0x3F, (sizeof(temp
) / sizeof(UChar
)) - 1);
266 u_uastrncpy(temp
, raw
[i
][j
], k
);
267 if(u_strncmp(temp
, dataTable
[i
][j
], k
)!=0)
268 log_err("something threw an error in u_uastrncpy(k)\n");
271 log_err("something threw an error in u_uastrncpy(k)\n");
274 log_verbose("Testing u_strchr() and u_memchr()\n");
278 UChar saveVal
= dataTable
[i
][j
][0];
279 UChar
*findPtr
= u_strchr(dataTable
[i
][j
], 0x005F);
280 int32_t dataSize
= (int32_t)(u_strlen(dataTable
[i
][j
]) + 1);
282 log_verbose("%s ", u_austrcpy(tempOut
, findPtr
));
284 if (findPtr
== NULL
|| *findPtr
!= 0x005F) {
285 log_err("u_strchr can't find '_' in the string\n");
288 findPtr
= u_strchr32(dataTable
[i
][j
], 0x005F);
289 if (findPtr
== NULL
|| *findPtr
!= 0x005F) {
290 log_err("u_strchr32 can't find '_' in the string\n");
293 findPtr
= u_strchr(dataTable
[i
][j
], 0);
294 if (findPtr
!= (&(dataTable
[i
][j
][dataSize
- 1]))) {
295 log_err("u_strchr can't find NULL in the string\n");
298 findPtr
= u_strchr32(dataTable
[i
][j
], 0);
299 if (findPtr
!= (&(dataTable
[i
][j
][dataSize
- 1]))) {
300 log_err("u_strchr32 can't find NULL in the string\n");
303 findPtr
= u_memchr(dataTable
[i
][j
], 0, dataSize
);
304 if (findPtr
!= (&(dataTable
[i
][j
][dataSize
- 1]))) {
305 log_err("u_memchr can't find NULL in the string\n");
308 findPtr
= u_memchr32(dataTable
[i
][j
], 0, dataSize
);
309 if (findPtr
!= (&(dataTable
[i
][j
][dataSize
- 1]))) {
310 log_err("u_memchr32 can't find NULL in the string\n");
313 dataTable
[i
][j
][0] = 0;
314 /* Make sure we skip over the NULL termination */
315 findPtr
= u_memchr(dataTable
[i
][j
], 0x005F, dataSize
);
316 if (findPtr
== NULL
|| *findPtr
!= 0x005F) {
317 log_err("u_memchr can't find '_' in the string\n");
320 findPtr
= u_memchr32(dataTable
[i
][j
], 0x005F, dataSize
);
321 if (findPtr
== NULL
|| *findPtr
!= 0x005F) {
322 log_err("u_memchr32 can't find '_' in the string\n");
324 findPtr
= u_memchr32(dataTable
[i
][j
], 0xFFFD, dataSize
);
325 if (findPtr
!= NULL
) {
326 log_err("Should have found NULL when the character is not there.\n");
328 dataTable
[i
][j
][0] = saveVal
; /* Put it back for the other tests */
332 * test that u_strchr32()
333 * does not find surrogate code points when they are part of matched pairs
334 * (= part of supplementary code points)
338 static const UChar s
[]={
339 /* 0 1 2 3 4 5 6 7 8 9 */
340 0x0061, 0xd841, 0xdc02, 0xd841, 0x0062, 0xdc02, 0xd841, 0xdc02, 0x0063, 0
343 if(u_strchr32(s
, 0xd841)!=(s
+3) || u_strchr32(s
, 0xdc02)!=(s
+5)) {
344 log_err("error: u_strchr32(surrogate) finds a partial supplementary code point\n");
346 if(u_memchr32(s
, 0xd841, 9)!=(s
+3) || u_memchr32(s
, 0xdc02, 9)!=(s
+5)) {
347 log_err("error: u_memchr32(surrogate) finds a partial supplementary code point\n");
351 log_verbose("Testing u_austrcpy()");
352 u_austrcpy(test
,dataTable
[0][0]);
353 if(strcmp(test
,raw
[0][0])!=0)
354 log_err("There is an error in u_austrcpy()");
357 log_verbose("Testing u_strtok_r()");
359 const char tokString
[] = " , 1 2 3 AHHHHH! 5.5 6 7 , 8\n";
360 const char *tokens
[] = {",", "1", "2", "3", "AHHHHH!", "5.5", "6", "7", "8\n"};
361 UChar delimBuf
[sizeof(test
)];
362 UChar currTokenBuf
[sizeof(tokString
)];
364 uint32_t currToken
= 0;
367 u_uastrcpy(temp
, tokString
);
368 u_uastrcpy(delimBuf
, " ");
370 ptr
= u_strtok_r(temp
, delimBuf
, &state
);
371 u_uastrcpy(delimBuf
, " ,");
372 while (ptr
!= NULL
) {
373 u_uastrcpy(currTokenBuf
, tokens
[currToken
]);
374 if (u_strcmp(ptr
, currTokenBuf
) != 0) {
375 log_err("u_strtok_r mismatch at %d. Got: %s, Expected: %s\n", currToken
, ptr
, tokens
[currToken
]);
377 ptr
= u_strtok_r(NULL
, delimBuf
, &state
);
381 if (currToken
!= sizeof(tokens
)/sizeof(tokens
[0])) {
382 log_err("Didn't get correct number of tokens\n");
384 state
= delimBuf
; /* Give it an "invalid" saveState */
385 u_uastrcpy(currTokenBuf
, "");
386 if (u_strtok_r(currTokenBuf
, delimBuf
, &state
) != NULL
) {
387 log_err("Didn't get NULL for empty string\n");
390 log_err("State should be NULL for empty string\n");
392 state
= delimBuf
; /* Give it an "invalid" saveState */
393 u_uastrcpy(currTokenBuf
, ", ,");
394 if (u_strtok_r(currTokenBuf
, delimBuf
, &state
) != NULL
) {
395 log_err("Didn't get NULL for a string of delimiters\n");
398 log_err("State should be NULL for a string of delimiters\n");
401 state
= delimBuf
; /* Give it an "invalid" saveState */
402 u_uastrcpy(currTokenBuf
, "q, ,");
403 if (u_strtok_r(currTokenBuf
, delimBuf
, &state
) == NULL
) {
404 log_err("Got NULL for a string that does not begin with delimiters\n");
406 if (u_strtok_r(NULL
, delimBuf
, &state
) != NULL
) {
407 log_err("Didn't get NULL for a string that ends in delimiters\n");
410 log_err("State should be NULL for empty string\n");
413 state
= delimBuf
; /* Give it an "invalid" saveState */
414 u_uastrcpy(currTokenBuf
, tokString
);
415 u_uastrcpy(temp
, tokString
);
416 u_uastrcpy(delimBuf
, "q"); /* Give it a delimiter that it can't find. */
417 ptr
= u_strtok_r(currTokenBuf
, delimBuf
, &state
);
418 if (ptr
== NULL
|| u_strcmp(ptr
, temp
) != 0) {
419 log_err("Should have recieved the same string when there are no delimiters\n");
421 if (u_strtok_r(NULL
, delimBuf
, &state
) != NULL
) {
422 log_err("Should not have found another token in a one token string\n");
426 /* test u_strcmpCodePointOrder() */
428 /* these strings are in ascending order */
429 static const UChar strings
[][4]={
430 { 0x61, 0 }, /* U+0061 */
431 { 0x20ac, 0xd801, 0 }, /* U+20ac U+d801 */
432 { 0x20ac, 0xd800, 0xdc00, 0 }, /* U+20ac U+10000 */
433 { 0xd800, 0 }, /* U+d800 */
434 { 0xd800, 0xff61, 0 }, /* U+d800 U+ff61 */
435 { 0xdfff, 0 }, /* U+dfff */
436 { 0xff61, 0xdfff, 0 }, /* U+ff61 U+dfff */
437 { 0xff61, 0xd800, 0xdc02, 0 }, /* U+ff61 U+10002 */
438 { 0xd800, 0xdc02, 0 }, /* U+10002 */
439 { 0xd84d, 0xdc56, 0 } /* U+23456 */
442 UCharIterator iter1
, iter2
;
443 int32_t len1
, len2
, r1
, r2
;
445 for(i
=0; i
<(sizeof(strings
)/sizeof(strings
[0])-1); ++i
) {
446 if(u_strcmpCodePointOrder(strings
[i
], strings
[i
+1])>=0) {
447 log_err("error: u_strcmpCodePointOrder() fails for string %d and the following one\n", i
);
449 if(u_strncmpCodePointOrder(strings
[i
], strings
[i
+1], 10)>=0) {
450 log_err("error: u_strncmpCodePointOrder() fails for string %d and the following one\n", i
);
453 /* There are at least 2 UChars in each string - verify that strncmp()==memcmp(). */
454 if(u_strncmpCodePointOrder(strings
[i
], strings
[i
+1], 2)!=u_memcmpCodePointOrder(strings
[i
], strings
[i
+1], 2)) {
455 log_err("error: u_strncmpCodePointOrder(2)!=u_memcmpCodePointOrder(2) for string %d and the following one\n", i
);
458 /* test u_strCompare(TRUE) */
459 len1
=u_strlen(strings
[i
]);
460 len2
=u_strlen(strings
[i
+1]);
461 if( u_strCompare(strings
[i
], -1, strings
[i
+1], -1, TRUE
)>=0 ||
462 u_strCompare(strings
[i
], -1, strings
[i
+1], len2
, TRUE
)>=0 ||
463 u_strCompare(strings
[i
], len1
, strings
[i
+1], -1, TRUE
)>=0 ||
464 u_strCompare(strings
[i
], len1
, strings
[i
+1], len2
, TRUE
)>=0
466 log_err("error: u_strCompare(code point order) fails for string %d and the following one\n", i
);
469 /* test u_strCompare(FALSE) */
470 r1
=u_strCompare(strings
[i
], -1, strings
[i
+1], -1, FALSE
);
471 r2
=u_strcmp(strings
[i
], strings
[i
+1]);
472 if(_SIGN(r1
)!=_SIGN(r2
)) {
473 log_err("error: u_strCompare(code unit order)!=u_strcmp() for string %d and the following one\n", i
);
476 /* test u_strCompareIter() */
477 uiter_setString(&iter1
, strings
[i
], len1
);
478 uiter_setString(&iter2
, strings
[i
+1], len2
);
479 if(u_strCompareIter(&iter1
, &iter2
, TRUE
)>=0) {
480 log_err("error: u_strCompareIter(code point order) fails for string %d and the following one\n", i
);
482 r1
=u_strCompareIter(&iter1
, &iter2
, FALSE
);
483 if(_SIGN(r1
)!=_SIGN(u_strcmp(strings
[i
], strings
[i
+1]))) {
484 log_err("error: u_strCompareIter(code unit order)!=u_strcmp() for string %d and the following one\n", i
);
492 static void TestStringSearching()
494 const UChar testString
[] = {0x0061, 0x0062, 0x0063, 0x0064, 0x0064, 0x0061, 0};
495 const UChar testSurrogateString
[] = {0xdbff, 0x0061, 0x0062, 0xdbff, 0xdfff, 0x0063, 0x0064, 0x0064, 0xdbff, 0xdfff, 0xdb00, 0xdf00, 0x0061, 0};
496 const UChar surrMatchSet1
[] = {0xdbff, 0xdfff, 0};
497 const UChar surrMatchSet2
[] = {0x0061, 0x0062, 0xdbff, 0xdfff, 0};
498 const UChar surrMatchSet3
[] = {0xdb00, 0xdf00, 0xdbff, 0xdfff, 0};
499 const UChar surrMatchSet4
[] = {0x0000};
500 const UChar surrMatchSetBad
[] = {0xdbff, 0x0061, 0};
501 const UChar surrMatchSetBad2
[] = {0x0061, 0xdbff, 0};
502 const UChar surrMatchSetBad3
[] = {0xdbff, 0x0061, 0x0062, 0xdbff, 0xdfff, 0}; /* has partial surrogate */
506 ab
[] = { 0x61, 0x62, 0 },
507 ba
[] = { 0x62, 0x61, 0 },
508 abcd
[] = { 0x61, 0x62, 0x63, 0x64, 0 },
509 cd
[] = { 0x63, 0x64, 0 },
510 dc
[] = { 0x64, 0x63, 0 },
511 cdh
[] = { 0x63, 0x64, 0x68, 0 },
513 fg
[] = { 0x66, 0x67, 0 },
514 gf
[] = { 0x67, 0x66, 0 };
516 log_verbose("Testing u_strpbrk()");
518 if (u_strpbrk(testString
, a
) != &testString
[0]) {
519 log_err("u_strpbrk couldn't find first letter a.\n");
521 if (u_strpbrk(testString
, dc
) != &testString
[2]) {
522 log_err("u_strpbrk couldn't find d or c.\n");
524 if (u_strpbrk(testString
, cd
) != &testString
[2]) {
525 log_err("u_strpbrk couldn't find c or d.\n");
527 if (u_strpbrk(testString
, cdh
) != &testString
[2]) {
528 log_err("u_strpbrk couldn't find c, d or h.\n");
530 if (u_strpbrk(testString
, f
) != NULL
) {
531 log_err("u_strpbrk didn't return NULL for \"f\".\n");
533 if (u_strpbrk(testString
, fg
) != NULL
) {
534 log_err("u_strpbrk didn't return NULL for \"fg\".\n");
536 if (u_strpbrk(testString
, gf
) != NULL
) {
537 log_err("u_strpbrk didn't return NULL for \"gf\".\n");
539 if (u_strpbrk(testString
, empty
) != NULL
) {
540 log_err("u_strpbrk didn't return NULL for \"\".\n");
543 log_verbose("Testing u_strpbrk() with surrogates");
545 if (u_strpbrk(testSurrogateString
, a
) != &testSurrogateString
[1]) {
546 log_err("u_strpbrk couldn't find first letter a.\n");
548 if (u_strpbrk(testSurrogateString
, dc
) != &testSurrogateString
[5]) {
549 log_err("u_strpbrk couldn't find d or c.\n");
551 if (u_strpbrk(testSurrogateString
, cd
) != &testSurrogateString
[5]) {
552 log_err("u_strpbrk couldn't find c or d.\n");
554 if (u_strpbrk(testSurrogateString
, cdh
) != &testSurrogateString
[5]) {
555 log_err("u_strpbrk couldn't find c, d or h.\n");
557 if (u_strpbrk(testSurrogateString
, f
) != NULL
) {
558 log_err("u_strpbrk didn't return NULL for \"f\".\n");
560 if (u_strpbrk(testSurrogateString
, fg
) != NULL
) {
561 log_err("u_strpbrk didn't return NULL for \"fg\".\n");
563 if (u_strpbrk(testSurrogateString
, gf
) != NULL
) {
564 log_err("u_strpbrk didn't return NULL for \"gf\".\n");
566 if (u_strpbrk(testSurrogateString
, surrMatchSet1
) != &testSurrogateString
[3]) {
567 log_err("u_strpbrk couldn't find \"0xdbff, 0xdfff\".\n");
569 if (u_strpbrk(testSurrogateString
, surrMatchSet2
) != &testSurrogateString
[1]) {
570 log_err("u_strpbrk couldn't find \"0xdbff, a, b, 0xdbff, 0xdfff\".\n");
572 if (u_strpbrk(testSurrogateString
, surrMatchSet3
) != &testSurrogateString
[3]) {
573 log_err("u_strpbrk couldn't find \"0xdb00, 0xdf00, 0xdbff, 0xdfff\".\n");
575 if (u_strpbrk(testSurrogateString
, surrMatchSet4
) != NULL
) {
576 log_err("u_strpbrk should have returned NULL for empty string.\n");
578 if (u_strpbrk(testSurrogateString
, surrMatchSetBad
) != &testSurrogateString
[0]) {
579 log_err("u_strpbrk should have found bad surrogate.\n");
582 log_verbose("Testing u_strcspn()");
584 if (u_strcspn(testString
, a
) != 0) {
585 log_err("u_strcspn couldn't find first letter a.\n");
587 if (u_strcspn(testString
, dc
) != 2) {
588 log_err("u_strcspn couldn't find d or c.\n");
590 if (u_strcspn(testString
, cd
) != 2) {
591 log_err("u_strcspn couldn't find c or d.\n");
593 if (u_strcspn(testString
, cdh
) != 2) {
594 log_err("u_strcspn couldn't find c, d or h.\n");
596 if (u_strcspn(testString
, f
) != u_strlen(testString
)) {
597 log_err("u_strcspn didn't return NULL for \"f\".\n");
599 if (u_strcspn(testString
, fg
) != u_strlen(testString
)) {
600 log_err("u_strcspn didn't return NULL for \"fg\".\n");
602 if (u_strcspn(testString
, gf
) != u_strlen(testString
)) {
603 log_err("u_strcspn didn't return NULL for \"gf\".\n");
606 log_verbose("Testing u_strcspn() with surrogates");
608 if (u_strcspn(testSurrogateString
, a
) != 1) {
609 log_err("u_strcspn couldn't find first letter a.\n");
611 if (u_strcspn(testSurrogateString
, dc
) != 5) {
612 log_err("u_strcspn couldn't find d or c.\n");
614 if (u_strcspn(testSurrogateString
, cd
) != 5) {
615 log_err("u_strcspn couldn't find c or d.\n");
617 if (u_strcspn(testSurrogateString
, cdh
) != 5) {
618 log_err("u_strcspn couldn't find c, d or h.\n");
620 if (u_strcspn(testSurrogateString
, f
) != u_strlen(testSurrogateString
)) {
621 log_err("u_strcspn didn't return NULL for \"f\".\n");
623 if (u_strcspn(testSurrogateString
, fg
) != u_strlen(testSurrogateString
)) {
624 log_err("u_strcspn didn't return NULL for \"fg\".\n");
626 if (u_strcspn(testSurrogateString
, gf
) != u_strlen(testSurrogateString
)) {
627 log_err("u_strcspn didn't return NULL for \"gf\".\n");
629 if (u_strcspn(testSurrogateString
, surrMatchSet1
) != 3) {
630 log_err("u_strcspn couldn't find \"0xdbff, 0xdfff\".\n");
632 if (u_strcspn(testSurrogateString
, surrMatchSet2
) != 1) {
633 log_err("u_strcspn couldn't find \"a, b, 0xdbff, 0xdfff\".\n");
635 if (u_strcspn(testSurrogateString
, surrMatchSet3
) != 3) {
636 log_err("u_strcspn couldn't find \"0xdb00, 0xdf00, 0xdbff, 0xdfff\".\n");
638 if (u_strcspn(testSurrogateString
, surrMatchSet4
) != u_strlen(testSurrogateString
)) {
639 log_err("u_strcspn should have returned strlen for empty string.\n");
643 log_verbose("Testing u_strspn()");
645 if (u_strspn(testString
, a
) != 1) {
646 log_err("u_strspn couldn't skip first letter a.\n");
648 if (u_strspn(testString
, ab
) != 2) {
649 log_err("u_strspn couldn't skip a or b.\n");
651 if (u_strspn(testString
, ba
) != 2) {
652 log_err("u_strspn couldn't skip a or b.\n");
654 if (u_strspn(testString
, f
) != 0) {
655 log_err("u_strspn didn't return 0 for \"f\".\n");
657 if (u_strspn(testString
, dc
) != 0) {
658 log_err("u_strspn couldn't find first letter a (skip d or c).\n");
660 if (u_strspn(testString
, abcd
) != u_strlen(testString
)) {
661 log_err("u_strspn couldn't skip over the whole string.\n");
663 if (u_strspn(testString
, empty
) != 0) {
664 log_err("u_strspn should have returned 0 for empty string.\n");
667 log_verbose("Testing u_strspn() with surrogates");
668 if (u_strspn(testSurrogateString
, surrMatchSetBad
) != 2) {
669 log_err("u_strspn couldn't skip 0xdbff or a.\n");
671 if (u_strspn(testSurrogateString
, surrMatchSetBad2
) != 2) {
672 log_err("u_strspn couldn't skip 0xdbff or a.\n");
674 if (u_strspn(testSurrogateString
, f
) != 0) {
675 log_err("u_strspn couldn't skip d or c (skip first letter).\n");
677 if (u_strspn(testSurrogateString
, dc
) != 0) {
678 log_err("u_strspn couldn't skip d or c (skip first letter).\n");
680 if (u_strspn(testSurrogateString
, cd
) != 0) {
681 log_err("u_strspn couldn't skip d or c (skip first letter).\n");
683 if (u_strspn(testSurrogateString
, testSurrogateString
) != u_strlen(testSurrogateString
)) {
684 log_err("u_strspn couldn't skip whole string.\n");
686 if (u_strspn(testSurrogateString
, surrMatchSet1
) != 0) {
687 log_err("u_strspn couldn't skip \"0xdbff, 0xdfff\" (get first letter).\n");
689 if (u_strspn(testSurrogateString
, surrMatchSetBad3
) != 5) {
690 log_err("u_strspn couldn't skip \"0xdbff, a, b, 0xdbff, 0xdfff\".\n");
692 if (u_strspn(testSurrogateString
, surrMatchSet4
) != 0) {
693 log_err("u_strspn should have returned 0 for empty string.\n");
698 * All binary Unicode string searches should behave the same for equivalent input.
699 * See Jitterbug 2145.
700 * There are some new functions, too - just test them all.
703 TestSurrogateSearching() {
704 static const UChar s
[]={
705 /* 0 1 2 3 4 5 6 7 8 9 10 11 */
706 0x61, 0xd801, 0xdc02, 0x61, 0xdc02, 0x61, 0xd801, 0x61, 0xd801, 0xdc02, 0x61, 0
726 static const UChar a
=0x61, b
=0x62, lead
=0xd801, trail
=0xdc02, nul
=0;
727 static const UChar32 supp
=0x10402, supp2
=0x10403, ill
=0x123456;
729 const UChar
*first
, *last
;
731 /* search for NUL code point: find end of string */
735 first
!=u_strchr(s
, nul
) ||
736 first
!=u_strchr32(s
, nul
) ||
737 first
!=u_memchr(s
, nul
, LENGTHOF(s
)) ||
738 first
!=u_memchr32(s
, nul
, LENGTHOF(s
)) ||
739 first
!=u_strrchr(s
, nul
) ||
740 first
!=u_strrchr32(s
, nul
) ||
741 first
!=u_memrchr(s
, nul
, LENGTHOF(s
)) ||
742 first
!=u_memrchr32(s
, nul
, LENGTHOF(s
))
744 log_err("error: one of the u_str[|mem][r]chr[32](s, nul) does not find the terminator of s\n");
747 /* search for empty substring: find beginning of string */
749 s
!=u_strstr(s
, &nul
) ||
750 s
!=u_strFindFirst(s
, -1, &nul
, -1) ||
751 s
!=u_strFindFirst(s
, -1, &nul
, 0) ||
752 s
!=u_strFindFirst(s
, LENGTHOF(s
), &nul
, -1) ||
753 s
!=u_strFindFirst(s
, LENGTHOF(s
), &nul
, 0) ||
754 s
!=u_strrstr(s
, &nul
) ||
755 s
!=u_strFindLast(s
, -1, &nul
, -1) ||
756 s
!=u_strFindLast(s
, -1, &nul
, 0) ||
757 s
!=u_strFindLast(s
, LENGTHOF(s
), &nul
, -1) ||
758 s
!=u_strFindLast(s
, LENGTHOF(s
), &nul
, 0)
760 log_err("error: one of the u_str[str etc](s, \"\") does not find s itself\n");
763 /* find 'a' in s[1..10[ */
767 first
!=u_strchr(s
+1, a
) ||
768 first
!=u_strchr32(s
+1, a
) ||
769 first
!=u_memchr(s
+1, a
, 9) ||
770 first
!=u_memchr32(s
+1, a
, 9) ||
771 first
!=u_strstr(s
+1, sub_a
) ||
772 first
!=u_strFindFirst(s
+1, -1, sub_a
, -1) ||
773 first
!=u_strFindFirst(s
+1, -1, &a
, 1) ||
774 first
!=u_strFindFirst(s
+1, 9, sub_a
, -1) ||
775 first
!=u_strFindFirst(s
+1, 9, &a
, 1) ||
776 (s
+10)!=u_strrchr(s
+1, a
) ||
777 (s
+10)!=u_strrchr32(s
+1, a
) ||
778 last
!=u_memrchr(s
+1, a
, 9) ||
779 last
!=u_memrchr32(s
+1, a
, 9) ||
780 (s
+10)!=u_strrstr(s
+1, sub_a
) ||
781 (s
+10)!=u_strFindLast(s
+1, -1, sub_a
, -1) ||
782 (s
+10)!=u_strFindLast(s
+1, -1, &a
, 1) ||
783 last
!=u_strFindLast(s
+1, 9, sub_a
, -1) ||
784 last
!=u_strFindLast(s
+1, 9, &a
, 1)
786 log_err("error: one of the u_str[chr etc]('a') does not find the correct place\n");
789 /* do not find 'b' in s[1..10[ */
791 NULL
!=u_strchr(s
+1, b
) ||
792 NULL
!=u_strchr32(s
+1, b
) ||
793 NULL
!=u_memchr(s
+1, b
, 9) ||
794 NULL
!=u_memchr32(s
+1, b
, 9) ||
795 NULL
!=u_strstr(s
+1, sub_b
) ||
796 NULL
!=u_strFindFirst(s
+1, -1, sub_b
, -1) ||
797 NULL
!=u_strFindFirst(s
+1, -1, &b
, 1) ||
798 NULL
!=u_strFindFirst(s
+1, 9, sub_b
, -1) ||
799 NULL
!=u_strFindFirst(s
+1, 9, &b
, 1) ||
800 NULL
!=u_strrchr(s
+1, b
) ||
801 NULL
!=u_strrchr32(s
+1, b
) ||
802 NULL
!=u_memrchr(s
+1, b
, 9) ||
803 NULL
!=u_memrchr32(s
+1, b
, 9) ||
804 NULL
!=u_strrstr(s
+1, sub_b
) ||
805 NULL
!=u_strFindLast(s
+1, -1, sub_b
, -1) ||
806 NULL
!=u_strFindLast(s
+1, -1, &b
, 1) ||
807 NULL
!=u_strFindLast(s
+1, 9, sub_b
, -1) ||
808 NULL
!=u_strFindLast(s
+1, 9, &b
, 1)
810 log_err("error: one of the u_str[chr etc]('b') incorrectly finds something\n");
813 /* do not find a non-code point in s[1..10[ */
815 NULL
!=u_strchr32(s
+1, ill
) ||
816 NULL
!=u_memchr32(s
+1, ill
, 9) ||
817 NULL
!=u_strrchr32(s
+1, ill
) ||
818 NULL
!=u_memrchr32(s
+1, ill
, 9)
820 log_err("error: one of the u_str[chr etc](illegal code point) incorrectly finds something\n");
823 /* find U+d801 in s[1..10[ */
826 first
!=u_strchr(s
+1, lead
) ||
827 first
!=u_strchr32(s
+1, lead
) ||
828 first
!=u_memchr(s
+1, lead
, 9) ||
829 first
!=u_memchr32(s
+1, lead
, 9) ||
830 first
!=u_strstr(s
+1, sub_lead
) ||
831 first
!=u_strFindFirst(s
+1, -1, sub_lead
, -1) ||
832 first
!=u_strFindFirst(s
+1, -1, &lead
, 1) ||
833 first
!=u_strFindFirst(s
+1, 9, sub_lead
, -1) ||
834 first
!=u_strFindFirst(s
+1, 9, &lead
, 1) ||
835 first
!=u_strrchr(s
+1, lead
) ||
836 first
!=u_strrchr32(s
+1, lead
) ||
837 first
!=u_memrchr(s
+1, lead
, 9) ||
838 first
!=u_memrchr32(s
+1, lead
, 9) ||
839 first
!=u_strrstr(s
+1, sub_lead
) ||
840 first
!=u_strFindLast(s
+1, -1, sub_lead
, -1) ||
841 first
!=u_strFindLast(s
+1, -1, &lead
, 1) ||
842 first
!=u_strFindLast(s
+1, 9, sub_lead
, -1) ||
843 first
!=u_strFindLast(s
+1, 9, &lead
, 1)
845 log_err("error: one of the u_str[chr etc](U+d801) does not find the correct place\n");
848 /* find U+dc02 in s[1..10[ */
851 first
!=u_strchr(s
+1, trail
) ||
852 first
!=u_strchr32(s
+1, trail
) ||
853 first
!=u_memchr(s
+1, trail
, 9) ||
854 first
!=u_memchr32(s
+1, trail
, 9) ||
855 first
!=u_strstr(s
+1, sub_trail
) ||
856 first
!=u_strFindFirst(s
+1, -1, sub_trail
, -1) ||
857 first
!=u_strFindFirst(s
+1, -1, &trail
, 1) ||
858 first
!=u_strFindFirst(s
+1, 9, sub_trail
, -1) ||
859 first
!=u_strFindFirst(s
+1, 9, &trail
, 1) ||
860 first
!=u_strrchr(s
+1, trail
) ||
861 first
!=u_strrchr32(s
+1, trail
) ||
862 first
!=u_memrchr(s
+1, trail
, 9) ||
863 first
!=u_memrchr32(s
+1, trail
, 9) ||
864 first
!=u_strrstr(s
+1, sub_trail
) ||
865 first
!=u_strFindLast(s
+1, -1, sub_trail
, -1) ||
866 first
!=u_strFindLast(s
+1, -1, &trail
, 1) ||
867 first
!=u_strFindLast(s
+1, 9, sub_trail
, -1) ||
868 first
!=u_strFindLast(s
+1, 9, &trail
, 1)
870 log_err("error: one of the u_str[chr etc](U+dc02) does not find the correct place\n");
873 /* find U+10402 in s[1..10[ */
877 first
!=u_strchr32(s
+1, supp
) ||
878 first
!=u_memchr32(s
+1, supp
, 9) ||
879 first
!=u_strstr(s
+1, sub_supp
) ||
880 first
!=u_strFindFirst(s
+1, -1, sub_supp
, -1) ||
881 first
!=u_strFindFirst(s
+1, -1, sub_supp
, 2) ||
882 first
!=u_strFindFirst(s
+1, 9, sub_supp
, -1) ||
883 first
!=u_strFindFirst(s
+1, 9, sub_supp
, 2) ||
884 last
!=u_strrchr32(s
+1, supp
) ||
885 last
!=u_memrchr32(s
+1, supp
, 9) ||
886 last
!=u_strrstr(s
+1, sub_supp
) ||
887 last
!=u_strFindLast(s
+1, -1, sub_supp
, -1) ||
888 last
!=u_strFindLast(s
+1, -1, sub_supp
, 2) ||
889 last
!=u_strFindLast(s
+1, 9, sub_supp
, -1) ||
890 last
!=u_strFindLast(s
+1, 9, sub_supp
, 2)
892 log_err("error: one of the u_str[chr etc](U+10402) does not find the correct place\n");
895 /* do not find U+10402 in a single UChar */
897 NULL
!=u_memchr32(s
+1, supp
, 1) ||
898 NULL
!=u_strFindFirst(s
+1, 1, sub_supp
, -1) ||
899 NULL
!=u_strFindFirst(s
+1, 1, sub_supp
, 2) ||
900 NULL
!=u_memrchr32(s
+1, supp
, 1) ||
901 NULL
!=u_strFindLast(s
+1, 1, sub_supp
, -1) ||
902 NULL
!=u_strFindLast(s
+1, 1, sub_supp
, 2) ||
903 NULL
!=u_memrchr32(s
+2, supp
, 1) ||
904 NULL
!=u_strFindLast(s
+2, 1, sub_supp
, -1) ||
905 NULL
!=u_strFindLast(s
+2, 1, sub_supp
, 2)
907 log_err("error: one of the u_str[chr etc](U+10402) incorrectly finds a supplementary c.p. in a single UChar\n");
910 /* do not find U+10403 in s[1..10[ */
912 NULL
!=u_strchr32(s
+1, supp2
) ||
913 NULL
!=u_memchr32(s
+1, supp2
, 9) ||
914 NULL
!=u_strstr(s
+1, sub_supp2
) ||
915 NULL
!=u_strFindFirst(s
+1, -1, sub_supp2
, -1) ||
916 NULL
!=u_strFindFirst(s
+1, -1, sub_supp2
, 2) ||
917 NULL
!=u_strFindFirst(s
+1, 9, sub_supp2
, -1) ||
918 NULL
!=u_strFindFirst(s
+1, 9, sub_supp2
, 2) ||
919 NULL
!=u_strrchr32(s
+1, supp2
) ||
920 NULL
!=u_memrchr32(s
+1, supp2
, 9) ||
921 NULL
!=u_strrstr(s
+1, sub_supp2
) ||
922 NULL
!=u_strFindLast(s
+1, -1, sub_supp2
, -1) ||
923 NULL
!=u_strFindLast(s
+1, -1, sub_supp2
, 2) ||
924 NULL
!=u_strFindLast(s
+1, 9, sub_supp2
, -1) ||
925 NULL
!=u_strFindLast(s
+1, 9, sub_supp2
, 2)
927 log_err("error: one of the u_str[chr etc](U+10403) incorrectly finds something\n");
930 /* find <0061 d801> in s[1..10[ */
933 first
!=u_strstr(s
+1, sub_a_lead
) ||
934 first
!=u_strFindFirst(s
+1, -1, sub_a_lead
, -1) ||
935 first
!=u_strFindFirst(s
+1, -1, sub_a_lead
, 2) ||
936 first
!=u_strFindFirst(s
+1, 9, sub_a_lead
, -1) ||
937 first
!=u_strFindFirst(s
+1, 9, sub_a_lead
, 2) ||
938 first
!=u_strrstr(s
+1, sub_a_lead
) ||
939 first
!=u_strFindLast(s
+1, -1, sub_a_lead
, -1) ||
940 first
!=u_strFindLast(s
+1, -1, sub_a_lead
, 2) ||
941 first
!=u_strFindLast(s
+1, 9, sub_a_lead
, -1) ||
942 first
!=u_strFindLast(s
+1, 9, sub_a_lead
, 2)
944 log_err("error: one of the u_str[str etc](<0061 d801>) does not find the correct place\n");
947 /* find <dc02 0061> in s[1..10[ */
950 first
!=u_strstr(s
+1, sub_trail_a
) ||
951 first
!=u_strFindFirst(s
+1, -1, sub_trail_a
, -1) ||
952 first
!=u_strFindFirst(s
+1, -1, sub_trail_a
, 2) ||
953 first
!=u_strFindFirst(s
+1, 9, sub_trail_a
, -1) ||
954 first
!=u_strFindFirst(s
+1, 9, sub_trail_a
, 2) ||
955 first
!=u_strrstr(s
+1, sub_trail_a
) ||
956 first
!=u_strFindLast(s
+1, -1, sub_trail_a
, -1) ||
957 first
!=u_strFindLast(s
+1, -1, sub_trail_a
, 2) ||
958 first
!=u_strFindLast(s
+1, 9, sub_trail_a
, -1) ||
959 first
!=u_strFindLast(s
+1, 9, sub_trail_a
, 2)
961 log_err("error: one of the u_str[str etc](<dc02 0061>) does not find the correct place\n");
964 /* do not find "aba" in s[1..10[ */
966 NULL
!=u_strstr(s
+1, sub_aba
) ||
967 NULL
!=u_strFindFirst(s
+1, -1, sub_aba
, -1) ||
968 NULL
!=u_strFindFirst(s
+1, -1, sub_aba
, 3) ||
969 NULL
!=u_strFindFirst(s
+1, 9, sub_aba
, -1) ||
970 NULL
!=u_strFindFirst(s
+1, 9, sub_aba
, 3) ||
971 NULL
!=u_strrstr(s
+1, sub_aba
) ||
972 NULL
!=u_strFindLast(s
+1, -1, sub_aba
, -1) ||
973 NULL
!=u_strFindLast(s
+1, -1, sub_aba
, 3) ||
974 NULL
!=u_strFindLast(s
+1, 9, sub_aba
, -1) ||
975 NULL
!=u_strFindLast(s
+1, 9, sub_aba
, 3)
977 log_err("error: one of the u_str[str etc](\"aba\") incorrectly finds something\n");
981 static void TestStringCopy()
986 UChar uchars
[]={0x61, 0x62, 0x63, 0x00};
988 char chars
[]="abc"; /* needs default codepage */
990 log_verbose("Testing u_uastrncpy() and u_uastrcpy()");
992 u_uastrcpy(temp
, "abc");
993 if(u_strcmp(temp
, uchars
) != 0) {
994 log_err("There is an error in u_uastrcpy() Expected %s Got %s\n", austrdup(uchars
), austrdup(temp
));
997 temp
[0] = 0xFB; /* load garbage into it */
1002 u_uastrncpy(temp
, "abcabcabc", 3);
1003 if(u_strncmp(uchars
, temp
, 3) != 0){
1004 log_err("There is an error in u_uastrncpy() Expected %s Got %s\n", austrdup(uchars
), austrdup(temp
));
1006 if(temp
[3] != 0xFB) {
1007 log_err("u_uastrncpy wrote past it's bounds. Expected undisturbed byte at 3\n");
1010 charOut
[0] = (char)0x7B; /* load garbage into it */
1011 charOut
[1] = (char)0x7B;
1012 charOut
[2] = (char)0x7B;
1013 charOut
[3] = (char)0x7B;
1023 u_austrncpy(charOut
, temp
, 3);
1024 if(strncmp(chars
, charOut
, 3) != 0){
1025 log_err("There is an error in u_austrncpy() Expected %s Got %s\n", austrdup(uchars
), austrdup(temp
));
1027 if(charOut
[3] != (char)0x7B) {
1028 log_err("u_austrncpy wrote past it's bounds. Expected undisturbed byte at 3\n");
1031 /*Testing u_strchr()*/
1032 log_verbose("Testing u_strchr\n");
1041 result
=u_strchr(temp
, (UChar
)0x62);
1042 if(result
!= temp
+1){
1043 log_err("There is an error in u_strchr() Expected match at position 1 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1045 /*Testing u_strstr()*/
1046 log_verbose("Testing u_strstr\n");
1050 result
=u_strstr(temp
, subString
);
1051 if(result
!= temp
+2){
1052 log_err("There is an error in u_strstr() Expected match at position 2 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1054 result
=u_strstr(temp
, subString
+2); /* subString+2 is an empty string */
1056 log_err("There is an error in u_strstr() Expected match at position 0 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1058 result
=u_strstr(subString
, temp
);
1060 log_err("There is an error in u_strstr() Expected NULL \"not found\" Got non-NULL \"found\" result\n");
1063 /*Testing u_strchr32*/
1064 log_verbose("Testing u_strchr32\n");
1065 result
=u_strchr32(temp
, (UChar32
)0x62);
1066 if(result
!= temp
+1){
1067 log_err("There is an error in u_strchr32() Expected match at position 1 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1069 result
=u_strchr32(temp
, (UChar32
)0xfb);
1071 log_err("There is an error in u_strchr32() Expected NULL \"not found\" Got non-NULL \"found\" result\n");
1073 result
=u_strchr32(temp
, (UChar32
)0x20402);
1074 if(result
!= temp
+5){
1075 log_err("There is an error in u_strchr32() Expected match at position 5 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1079 result
=u_memchr32(temp
, (UChar32
)0x20402, 7);
1080 if(result
!= temp
+5){
1081 log_err("There is an error in u_memchr32() Expected match at position 5 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1083 result
=u_memchr32(temp
, (UChar32
)0x20402, 6);
1085 log_err("There is an error in u_memchr32() Expected no match Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1087 result
=u_memchr32(temp
, (UChar32
)0x20402, 1);
1089 log_err("There is an error in u_memchr32() Expected no match Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1091 result
=u_memchr32(temp
, (UChar32
)0xfc00, 8);
1092 if(result
!= temp
+7){
1093 log_err("There is an error in u_memchr32() Expected match at position 7 Got %ld (pointer 0x%lx)\n", result
-temp
, result
);
1097 /* test u_unescape() and u_unescapeAt() ------------------------------------- */
1101 static UChar buffer
[200];
1103 static const char* input
=
1104 "Sch\\u00f6nes Auto: \\u20ac 11240.\\fPrivates Zeichen: \\U00102345\\e\\cC\\n \\x1b\\x{263a}";
1106 static const UChar expect
[]={
1107 0x53, 0x63, 0x68, 0xf6, 0x6e, 0x65, 0x73, 0x20, 0x41, 0x75, 0x74, 0x6f, 0x3a, 0x20,
1108 0x20ac, 0x20, 0x31, 0x31, 0x32, 0x34, 0x30, 0x2e, 0x0c,
1109 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x73, 0x20,
1110 0x5a, 0x65, 0x69, 0x63, 0x68, 0x65, 0x6e, 0x3a, 0x20, 0xdbc8, 0xdf45, 0x1b, 0x03, 0x0a, 0x20, 0x1b, 0x263A, 0
1112 static const int32_t explength
= sizeof(expect
)/sizeof(expect
[0])-1;
1115 /* test u_unescape() */
1116 length
=u_unescape(input
, buffer
, sizeof(buffer
)/sizeof(buffer
[0]));
1117 if(length
!=explength
|| u_strcmp(buffer
, expect
)!=0) {
1118 log_err("failure in u_unescape(): length %d!=%d and/or incorrect result string\n", length
,
1122 /* try preflighting */
1123 length
=u_unescape(input
, NULL
, sizeof(buffer
)/sizeof(buffer
[0]));
1124 if(length
!=explength
|| u_strcmp(buffer
, expect
)!=0) {
1125 log_err("failure in u_unescape(preflighting): length %d!=%d\n", length
, explength
);
1128 /* ### TODO: test u_unescapeAt() */
1131 /* test code point counting functions --------------------------------------- */
1133 /* reference implementation of u_strHasMoreChar32Than() */
1135 _refStrHasMoreChar32Than(const UChar
*s
, int32_t length
, int32_t number
) {
1136 int32_t count
=u_countChar32(s
, length
);
1137 return count
>number
;
1140 /* compare the real function against the reference */
1142 _testStrHasMoreChar32Than(const UChar
*s
, int32_t i
, int32_t length
, int32_t number
) {
1143 if(u_strHasMoreChar32Than(s
, length
, number
)!=_refStrHasMoreChar32Than(s
, length
, number
)) {
1144 log_err("u_strHasMoreChar32Than(s+%d, %d, %d)=%hd is wrong\n",
1145 i
, length
, number
, u_strHasMoreChar32Than(s
, length
, number
));
1151 static const UChar string
[]={
1152 0x61, 0x62, 0xd800, 0xdc00,
1153 0xd801, 0xdc01, 0x63, 0xd802,
1154 0x64, 0xdc03, 0x65, 0x66,
1155 0xd804, 0xdc04, 0xd805, 0xdc05,
1159 int32_t i
, length
, number
;
1161 /* test u_strHasMoreChar32Than() with length>=0 */
1162 length
=LENGTHOF(string
);
1164 for(i
=0; i
<=length
; ++i
) {
1165 for(number
=-1; number
<=((length
-i
)+2); ++number
) {
1166 _testStrHasMoreChar32Than(string
+i
, i
, length
-i
, number
);
1172 /* test u_strHasMoreChar32Than() with NUL-termination (length=-1) */
1173 length
=LENGTHOF(string
);
1174 u_memcpy(buffer
, string
, length
);
1177 for(i
=0; i
<=length
; ++i
) {
1178 for(number
=-1; number
<=((length
-i
)+2); ++number
) {
1179 _testStrHasMoreChar32Than(string
+i
, i
, -1, number
);
1185 /* test u_strHasMoreChar32Than() with NULL string (bad input) */
1186 for(length
=-1; length
<=1; ++length
) {
1187 for(i
=0; i
<=length
; ++i
) {
1188 for(number
=-2; number
<=2; ++number
) {
1189 _testStrHasMoreChar32Than(NULL
, 0, length
, number
);
1195 /* UCharIterator ------------------------------------------------------------ */
1198 * Compare results from two iterators, should be same.
1199 * Assume that the text is not empty and that
1200 * iteration start==0 and iteration limit==length.
1203 compareIterators(UCharIterator
*iter1
, const char *n1
,
1204 UCharIterator
*iter2
, const char *n2
) {
1205 int32_t i
, pos1
, pos2
, middle
, length
;
1208 /* compare lengths */
1209 length
=iter1
->getIndex(iter1
, UITER_LENGTH
);
1210 pos2
=iter2
->getIndex(iter2
, UITER_LENGTH
);
1212 log_err("%s->getIndex(length)=%d != %d=%s->getIndex(length)\n", n1
, length
, pos2
, n2
);
1216 /* set into the middle */
1219 pos1
=iter1
->move(iter1
, middle
, UITER_ZERO
);
1221 log_err("%s->move(from 0 to middle %d)=%d does not move to the middle\n", n1
, middle
, pos1
);
1225 pos2
=iter2
->move(iter2
, middle
, UITER_ZERO
);
1227 log_err("%s->move(from 0 to middle %d)=%d does not move to the middle\n", n2
, middle
, pos2
);
1231 /* test current() */
1232 c1
=iter1
->current(iter1
);
1233 c2
=iter2
->current(iter2
);
1235 log_err("%s->current()=U+%04x != U+%04x=%s->current() at middle=%d\n", n1
, c1
, c2
, n2
, middle
);
1239 /* move forward 3 UChars */
1240 for(i
=0; i
<3; ++i
) {
1241 c1
=iter1
->next(iter1
);
1242 c2
=iter2
->next(iter2
);
1244 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
));
1249 /* move backward 5 UChars */
1250 for(i
=0; i
<5; ++i
) {
1251 c1
=iter1
->previous(iter1
);
1252 c2
=iter2
->previous(iter2
);
1254 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
));
1259 /* iterate forward from the beginning */
1260 pos1
=iter1
->move(iter1
, 0, UITER_START
);
1262 log_err("%s->move(start) failed\n", n1
);
1265 if(!iter1
->hasNext(iter1
)) {
1266 log_err("%s->hasNext() at the start returns FALSE\n", n1
);
1270 pos2
=iter2
->move(iter2
, 0, UITER_START
);
1272 log_err("%s->move(start) failed\n", n2
);
1275 if(!iter2
->hasNext(iter2
)) {
1276 log_err("%s->hasNext() at the start returns FALSE\n", n2
);
1281 c1
=iter1
->next(iter1
);
1282 c2
=iter2
->next(iter2
);
1284 log_err("%s->next()=U+%04x != U+%04x=%s->next() at %d\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1289 if(iter1
->hasNext(iter1
)) {
1290 log_err("%s->hasNext() at the end returns TRUE\n", n1
);
1293 if(iter2
->hasNext(iter2
)) {
1294 log_err("%s->hasNext() at the end returns TRUE\n", n2
);
1298 /* back to the middle */
1299 pos1
=iter1
->move(iter1
, middle
, UITER_ZERO
);
1301 log_err("%s->move(from end to middle %d)=%d does not move to the middle\n", n1
, middle
, pos1
);
1305 pos2
=iter2
->move(iter2
, middle
, UITER_ZERO
);
1307 log_err("%s->move(from end to middle %d)=%d does not move to the middle\n", n2
, middle
, pos2
);
1311 /* move to index 1 */
1312 pos1
=iter1
->move(iter1
, 1, UITER_ZERO
);
1314 log_err("%s->move(from middle %d to 1)=%d does not move to 1\n", n1
, middle
, pos1
);
1318 pos2
=iter2
->move(iter2
, 1, UITER_ZERO
);
1320 log_err("%s->move(from middle %d to 1)=%d does not move to 1\n", n2
, middle
, pos2
);
1324 /* iterate backward from the end */
1325 pos1
=iter1
->move(iter1
, 0, UITER_LIMIT
);
1327 log_err("%s->move(limit) failed\n", n1
);
1330 if(!iter1
->hasPrevious(iter1
)) {
1331 log_err("%s->hasPrevious() at the end returns FALSE\n", n1
);
1335 pos2
=iter2
->move(iter2
, 0, UITER_LIMIT
);
1337 log_err("%s->move(limit) failed\n", n2
);
1340 if(!iter2
->hasPrevious(iter2
)) {
1341 log_err("%s->hasPrevious() at the end returns FALSE\n", n2
);
1346 c1
=iter1
->previous(iter1
);
1347 c2
=iter2
->previous(iter2
);
1349 log_err("%s->previous()=U+%04x != U+%04x=%s->previous() at %d\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1354 if(iter1
->hasPrevious(iter1
)) {
1355 log_err("%s->hasPrevious() at the start returns TRUE\n", n1
);
1358 if(iter2
->hasPrevious(iter2
)) {
1359 log_err("%s->hasPrevious() at the start returns TRUE\n", n2
);
1365 * Test the iterator's getState() and setState() functions.
1366 * iter1 and iter2 must be set up for the same iterator type and the same string
1367 * but may be physically different structs (different addresses).
1369 * Assume that the text is not empty and that
1370 * iteration start==0 and iteration limit==length.
1371 * It must be 2<=middle<=length-2.
1374 testIteratorState(UCharIterator
*iter1
, UCharIterator
*iter2
, const char *n
, int32_t middle
) {
1377 UErrorCode errorCode
;
1382 /* get four UChars from the middle of the string */
1383 iter1
->move(iter1
, middle
-2, UITER_ZERO
);
1384 for(i
=0; i
<4; ++i
) {
1385 c
=iter1
->next(iter1
);
1387 /* the test violates the assumptions, see comment above */
1388 log_err("test error: %s[%d]=%d\n", n
, middle
-2+i
, c
);
1394 /* move to the middle and get the state */
1395 iter1
->move(iter1
, -2, UITER_CURRENT
);
1396 state
=uiter_getState(iter1
);
1398 /* set the state into the second iterator and compare the results */
1399 errorCode
=U_ZERO_ERROR
;
1400 uiter_setState(iter2
, state
, &errorCode
);
1401 if(U_FAILURE(errorCode
)) {
1402 log_err("%s->setState(0x%x) failed: %s\n", n
, state
, u_errorName(errorCode
));
1406 c
=iter2
->current(iter2
);
1408 log_err("%s->current(at %d)=U+%04x!=U+%04x\n", n
, middle
, c
, u
[2]);
1411 c
=iter2
->previous(iter2
);
1413 log_err("%s->previous(at %d)=U+%04x!=U+%04x\n", n
, middle
-1, c
, u
[1]);
1416 iter2
->move(iter2
, 2, UITER_CURRENT
);
1417 c
=iter2
->next(iter2
);
1419 log_err("%s->next(at %d)=U+%04x!=U+%04x\n", n
, middle
+1, c
, u
[3]);
1422 iter2
->move(iter2
, -3, UITER_CURRENT
);
1423 c
=iter2
->previous(iter2
);
1425 log_err("%s->previous(at %d)=U+%04x!=U+%04x\n", n
, middle
-2, c
, u
[0]);
1428 /* move the second iterator back to the middle */
1429 iter2
->move(iter2
, 1, UITER_CURRENT
);
1432 /* check that both are in the middle */
1433 i
=iter1
->getIndex(iter1
, UITER_CURRENT
);
1434 j
=iter2
->getIndex(iter2
, UITER_CURRENT
);
1436 log_err("%s->getIndex(current)=%d!=%d as expected\n", n
, i
, middle
);
1439 log_err("%s->getIndex(current)=%d!=%d after setState()\n", n
, j
, i
);
1442 /* compare lengths */
1443 i
=iter1
->getIndex(iter1
, UITER_LENGTH
);
1444 j
=iter2
->getIndex(iter2
, UITER_LENGTH
);
1446 log_err("%s->getIndex(length)=%d!=%d before/after setState()\n", n
, i
, j
);
1451 TestUCharIterator() {
1452 static const UChar text
[]={
1453 0x61, 0x62, 0x63, 0xd801, 0xdffd, 0x78, 0x79, 0x7a, 0
1457 UCharIterator iter
, iter1
, iter2
;
1459 UErrorCode errorCode
;
1462 /* simple API/code coverage - test NOOP UCharIterator */
1463 uiter_setString(&iter
, NULL
, 0);
1464 if( iter
.current(&iter
)!=-1 || iter
.next(&iter
)!=-1 || iter
.previous(&iter
)!=-1 ||
1465 iter
.move(&iter
, 1, UITER_CURRENT
) || iter
.getIndex(&iter
, UITER_CURRENT
)!=0 ||
1466 iter
.hasNext(&iter
) || iter
.hasPrevious(&iter
)
1468 log_err("NOOP UCharIterator behaves unexpectedly\n");
1471 /* test get/set state */
1472 length
=LENGTHOF(text
)-1;
1473 uiter_setString(&iter1
, text
, -1);
1474 uiter_setString(&iter2
, text
, length
);
1475 testIteratorState(&iter1
, &iter2
, "UTF16IteratorState", length
/2);
1476 testIteratorState(&iter1
, &iter2
, "UTF16IteratorStatePlus1", length
/2+1);
1478 /* compare the same string between UTF-16 and UTF-8 UCharIterators ------ */
1479 errorCode
=U_ZERO_ERROR
;
1480 u_strToUTF8(bytes
, sizeof(bytes
), &length
, text
, -1, &errorCode
);
1481 if(U_FAILURE(errorCode
)) {
1482 log_err("u_strToUTF8() failed, %s\n", u_errorName(errorCode
));
1486 uiter_setString(&iter1
, text
, -1);
1487 uiter_setUTF8(&iter2
, bytes
, length
);
1488 compareIterators(&iter1
, "UTF16Iterator", &iter2
, "UTF8Iterator");
1490 /* try again with length=-1 */
1491 uiter_setUTF8(&iter2
, bytes
, -1);
1492 compareIterators(&iter1
, "UTF16Iterator", &iter2
, "UTF8Iterator_1");
1494 /* test get/set state */
1495 length
=LENGTHOF(text
)-1;
1496 uiter_setUTF8(&iter1
, bytes
, -1);
1497 testIteratorState(&iter1
, &iter2
, "UTF8IteratorState", length
/2);
1498 testIteratorState(&iter1
, &iter2
, "UTF8IteratorStatePlus1", length
/2+1);
1500 /* compare the same string between UTF-16 and UTF-16BE UCharIterators --- */
1501 errorCode
=U_ZERO_ERROR
;
1502 cnv
=ucnv_open("UTF-16BE", &errorCode
);
1503 length
=ucnv_fromUChars(cnv
, bytes
, sizeof(bytes
), text
, -1, &errorCode
);
1505 if(U_FAILURE(errorCode
)) {
1506 log_err("ucnv_fromUChars(UTF-16BE) failed, %s\n", u_errorName(errorCode
));
1510 /* terminate with a _pair_ of 0 bytes - a UChar NUL in UTF-16BE (length is known to be ok) */
1511 bytes
[length
]=bytes
[length
+1]=0;
1513 uiter_setString(&iter1
, text
, -1);
1514 uiter_setUTF16BE(&iter2
, bytes
, length
);
1515 compareIterators(&iter1
, "UTF16Iterator", &iter2
, "UTF16BEIterator");
1517 /* try again with length=-1 */
1518 uiter_setUTF16BE(&iter2
, bytes
, -1);
1519 compareIterators(&iter1
, "UTF16Iterator", &iter2
, "UTF16BEIterator_1");
1521 /* try again after moving the bytes up one, and with length=-1 */
1522 memmove(bytes
+1, bytes
, length
+2);
1523 uiter_setUTF16BE(&iter2
, bytes
+1, -1);
1524 compareIterators(&iter1
, "UTF16Iterator", &iter2
, "UTF16BEIteratorMoved1");
1526 /* ### TODO test other iterators: CharacterIterator, Replaceable */
1529 #if UCONFIG_NO_COLLATION
1532 TestUNormIterator() {
1538 #include "unicode/unorm.h"
1539 #include "unorm_it.h"
1542 * Compare results from two iterators, should be same.
1543 * Assume that the text is not empty and that
1544 * iteration start==0 and iteration limit==length.
1546 * Modified version of compareIterators() but does not assume that indexes
1550 compareIterNoIndexes(UCharIterator
*iter1
, const char *n1
,
1551 UCharIterator
*iter2
, const char *n2
,
1556 UErrorCode errorCode
;
1558 /* set into the middle */
1559 iter1
->move(iter1
, middle
, UITER_ZERO
);
1560 iter2
->move(iter2
, middle
, UITER_ZERO
);
1562 /* test current() */
1563 c1
=iter1
->current(iter1
);
1564 c2
=iter2
->current(iter2
);
1566 log_err("%s->current()=U+%04x != U+%04x=%s->current() at middle=%d\n", n1
, c1
, c2
, n2
, middle
);
1570 /* move forward 3 UChars */
1571 for(i
=0; i
<3; ++i
) {
1572 c1
=iter1
->next(iter1
);
1573 c2
=iter2
->next(iter2
);
1575 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
));
1580 /* move backward 5 UChars */
1581 for(i
=0; i
<5; ++i
) {
1582 c1
=iter1
->previous(iter1
);
1583 c2
=iter2
->previous(iter2
);
1585 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
));
1590 /* iterate forward from the beginning */
1591 iter1
->move(iter1
, 0, UITER_START
);
1592 if(!iter1
->hasNext(iter1
)) {
1593 log_err("%s->hasNext() at the start returns FALSE\n", n1
);
1597 iter2
->move(iter2
, 0, UITER_START
);
1598 if(!iter2
->hasNext(iter2
)) {
1599 log_err("%s->hasNext() at the start returns FALSE\n", n2
);
1604 c1
=iter1
->next(iter1
);
1605 c2
=iter2
->next(iter2
);
1607 log_err("%s->next()=U+%04x != U+%04x=%s->next() at %d\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1612 if(iter1
->hasNext(iter1
)) {
1613 log_err("%s->hasNext() at the end returns TRUE\n", n1
);
1616 if(iter2
->hasNext(iter2
)) {
1617 log_err("%s->hasNext() at the end returns TRUE\n", n2
);
1621 /* iterate backward */
1623 c1
=iter1
->previous(iter1
);
1624 c2
=iter2
->previous(iter2
);
1626 log_err("%s->previous()=U+%04x != U+%04x=%s->previous() at %d\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1631 /* back to the middle */
1632 iter1
->move(iter1
, middle
, UITER_ZERO
);
1633 iter2
->move(iter2
, middle
, UITER_ZERO
);
1635 /* try get/set state */
1636 while((state
=uiter_getState(iter2
))==UITER_NO_STATE
) {
1637 if(!iter2
->hasNext(iter2
)) {
1638 log_err("%s has no known state from middle=%d to the end\n", n2
, middle
);
1644 errorCode
=U_ZERO_ERROR
;
1646 c2
=iter2
->current(iter2
);
1647 iter2
->move(iter2
, 0, UITER_ZERO
);
1648 uiter_setState(iter2
, state
, &errorCode
);
1649 c1
=iter2
->current(iter2
);
1650 if(U_FAILURE(errorCode
) || c1
!=c2
) {
1651 log_err("%s->current() differs across get/set state, U+%04x vs. U+%04x\n", n2
, c2
, c1
);
1655 c2
=iter2
->previous(iter2
);
1656 iter2
->move(iter2
, 0, UITER_ZERO
);
1657 uiter_setState(iter2
, state
, &errorCode
);
1658 c1
=iter2
->previous(iter2
);
1659 if(U_FAILURE(errorCode
) || c1
!=c2
) {
1660 log_err("%s->previous() differs across get/set state, U+%04x vs. U+%04x\n", n2
, c2
, c1
);
1664 /* iterate backward from the end */
1665 iter1
->move(iter1
, 0, UITER_LIMIT
);
1666 if(!iter1
->hasPrevious(iter1
)) {
1667 log_err("%s->hasPrevious() at the end returns FALSE\n", n1
);
1671 iter2
->move(iter2
, 0, UITER_LIMIT
);
1672 if(!iter2
->hasPrevious(iter2
)) {
1673 log_err("%s->hasPrevious() at the end returns FALSE\n", n2
);
1678 c1
=iter1
->previous(iter1
);
1679 c2
=iter2
->previous(iter2
);
1681 log_err("%s->previous()=U+%04x != U+%04x=%s->previous() at %d\n", n1
, c1
, c2
, n2
, iter1
->getIndex(iter1
, UITER_CURRENT
));
1686 if(iter1
->hasPrevious(iter1
)) {
1687 log_err("%s->hasPrevious() at the start returns TRUE\n", n1
);
1690 if(iter2
->hasPrevious(iter2
)) {
1691 log_err("%s->hasPrevious() at the start returns TRUE\n", n2
);
1696 /* n2 must have a digit 1 at the end, will be incremented with the normalization mode */
1698 testUNormIteratorWithText(const UChar
*text
, int32_t textLength
, int32_t middle
,
1699 const char *name1
, const char *n2
) {
1703 UCharIterator iter1
, iter2
, *iter
;
1706 UNormalizationMode mode
;
1707 UErrorCode errorCode
;
1710 /* open a normalizing iterator */
1711 errorCode
=U_ZERO_ERROR
;
1712 uni
=unorm_openIter(NULL
, 0, &errorCode
);
1713 if(U_FAILURE(errorCode
)) {
1714 log_err("unorm_openIter() fails: %s\n", u_errorName(errorCode
));
1718 /* set iterator 2 to the original text */
1719 uiter_setString(&iter2
, text
, textLength
);
1723 /* test the normalizing iterator for each mode */
1724 for(mode
=UNORM_NONE
; mode
<UNORM_MODE_COUNT
; ++mode
) {
1725 length
=unorm_normalize(text
, textLength
, mode
, 0, buffer
, LENGTHOF(buffer
), &errorCode
);
1726 if(U_FAILURE(errorCode
)) {
1727 log_err("unorm_normalize(mode %d) failed: %s\n", mode
, u_errorName(errorCode
));
1731 /* set iterator 1 to the normalized text */
1732 uiter_setString(&iter1
, buffer
, length
);
1734 /* set the normalizing iterator to use iter2 */
1735 iter
=unorm_setIter(uni
, &iter2
, mode
, &errorCode
);
1736 if(U_FAILURE(errorCode
)) {
1737 log_err("unorm_setIter(mode %d) failed: %s\n", mode
, u_errorName(errorCode
));
1741 compareIterNoIndexes(&iter1
, name1
, iter
, name2
, middle
);
1742 ++name2
[strlen(name2
)-1];
1745 unorm_closeIter(uni
);
1749 TestUNormIterator() {
1750 static const UChar text
[]={ /* must contain <00C5 0327> see u_strchr() below */
1752 0xe4, 0x61, 0x308, /* variations of 'a'+umlaut */
1753 0xc5, 0x327, 0x41, 0x30a, 0x327, 0x41, 0x327, 0x30a, /* variations of 'A'+ring+cedilla */
1754 0xfb03, 0xfb00, 0x69, 0x66, 0x66, 0x69, 0x66, 0xfb01 /* variations of 'ffi' */
1756 static const UChar surrogateText
[]={
1757 0x6e, 0xd900, 0x6a, 0xdc00, 0xd900, 0xdc00, 0x61
1760 UChar longText
[600];
1761 int32_t i
, middle
, length
;
1763 length
=LENGTHOF(text
);
1764 testUNormIteratorWithText(text
, length
, length
/2, "UCharIter", "UNormIter1");
1765 testUNormIteratorWithText(text
, length
, length
, "UCharIterEnd", "UNormIterEnd1");
1767 /* test again, this time with an insane string to cause internal buffer overflows */
1768 middle
=(int32_t)(u_strchr(text
, 0x327)-text
); /* see comment at text[] */
1769 memcpy(longText
, text
, middle
*U_SIZEOF_UCHAR
);
1770 for(i
=0; i
<150; ++i
) {
1771 longText
[middle
+i
]=0x30a; /* insert many rings between 'A-ring' and cedilla */
1773 memcpy(longText
+middle
+i
, text
+middle
, (LENGTHOF(text
)-middle
)*U_SIZEOF_UCHAR
);
1774 length
=LENGTHOF(text
)+i
;
1776 /* append another copy of this string for more overflows */
1777 memcpy(longText
+length
, longText
, length
*U_SIZEOF_UCHAR
);
1780 /* the first test of the following two starts at length/4, inside the sea of combining rings */
1781 testUNormIteratorWithText(longText
, length
, length
/4, "UCharIterLong", "UNormIterLong1");
1782 testUNormIteratorWithText(longText
, length
, length
, "UCharIterLongEnd", "UNormIterLongEnd1");
1784 length
=LENGTHOF(surrogateText
);
1785 testUNormIteratorWithText(surrogateText
, length
, length
/4, "UCharIterSurr", "UNormIterSurr1");
1786 testUNormIteratorWithText(surrogateText
, length
, length
, "UCharIterSurrEnd", "UNormIterSurrEnd1");