2 *******************************************************************************
4 * Copyright (C) 2002-2012, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * file name: uenumtst.c
10 * tab size: 8 (not used)
13 * created on: 2002jul08
14 * created by: Vladimir Weinstein
21 #include "unicode/ustring.h"
23 static char quikBuf
[256];
24 static char* quikU2C(const UChar
* str
, int32_t len
) {
25 u_UCharsToChars(str
, quikBuf
, len
);
30 static const char* test1
[] = {
37 struct chArrayContext
{
45 typedef struct chArrayContext chArrayContext
;
47 #define cont ((chArrayContext *)en->context)
49 static void U_CALLCONV
50 chArrayClose(UEnumeration
*en
) {
51 if(cont
->currUChar
!= NULL
) {
52 free(cont
->currUChar
);
53 cont
->currUChar
= NULL
;
58 static int32_t U_CALLCONV
59 chArrayCount(UEnumeration
*en
, UErrorCode
*status
) {
60 return cont
->maxIndex
;
63 static const UChar
* U_CALLCONV
64 chArrayUNext(UEnumeration
*en
, int32_t *resultLength
, UErrorCode
*status
) {
65 if(cont
->currIndex
>= cont
->maxIndex
) {
69 if(cont
->currUChar
== NULL
) {
70 cont
->currUChar
= (UChar
*)malloc(1024*sizeof(UChar
));
73 cont
->currChar
= (cont
->array
)[cont
->currIndex
];
74 *resultLength
= (int32_t)strlen(cont
->currChar
);
75 u_charsToUChars(cont
->currChar
, cont
->currUChar
, *resultLength
);
77 return cont
->currUChar
;
80 static const char* U_CALLCONV
81 chArrayNext(UEnumeration
*en
, int32_t *resultLength
, UErrorCode
*status
) {
82 if(cont
->currIndex
>= cont
->maxIndex
) {
86 cont
->currChar
= (cont
->array
)[cont
->currIndex
];
87 *resultLength
= (int32_t)strlen(cont
->currChar
);
89 return cont
->currChar
;
92 static void U_CALLCONV
93 chArrayReset(UEnumeration
*en
, UErrorCode
*status
) {
97 chArrayContext myCont
= {
103 UEnumeration chEnum
= {
113 static const UEnumeration emptyEnumerator
= {
123 static const UEnumeration emptyPartialEnumerator
= {
133 /********************************************************************/
134 static const UChar _first
[] = {102,105,114,115,116,0}; /* "first" */
135 static const UChar _second
[]= {115,101,99,111,110,100,0}; /* "second" */
136 static const UChar _third
[] = {116,104,105,114,100,0}; /* "third" */
137 static const UChar _fourth
[]= {102,111,117,114,116,104,0};/* "fourth" */
139 static const UChar
* test2
[] = {
140 _first
, _second
, _third
, _fourth
143 struct uchArrayContext
{
150 typedef struct uchArrayContext uchArrayContext
;
152 #define ucont ((uchArrayContext *)en->context)
154 static void U_CALLCONV
155 uchArrayClose(UEnumeration
*en
) {
159 static int32_t U_CALLCONV
160 uchArrayCount(UEnumeration
*en
, UErrorCode
*status
) {
161 return ucont
->maxIndex
;
164 static const UChar
* U_CALLCONV
165 uchArrayUNext(UEnumeration
*en
, int32_t *resultLength
, UErrorCode
*status
) {
166 if(ucont
->currIndex
>= ucont
->maxIndex
) {
170 ucont
->currUChar
= (ucont
->array
)[ucont
->currIndex
];
171 *resultLength
= u_strlen(ucont
->currUChar
);
173 return ucont
->currUChar
;
176 static void U_CALLCONV
177 uchArrayReset(UEnumeration
*en
, UErrorCode
*status
) {
178 ucont
->currIndex
= 0;
181 uchArrayContext myUCont
= {
186 UEnumeration uchEnum
= {
196 /********************************************************************/
198 static UEnumeration
*getchArrayEnum(const char** source
, int32_t size
) {
199 UEnumeration
*en
= (UEnumeration
*)malloc(sizeof(UEnumeration
));
200 memcpy(en
, &chEnum
, sizeof(UEnumeration
));
201 cont
->array
= (char **)source
;
202 cont
->maxIndex
= size
;
206 static void EnumerationTest(void) {
207 UErrorCode status
= U_ZERO_ERROR
;
209 UEnumeration
*en
= getchArrayEnum(test1
, sizeof(test1
)/sizeof(test1
[0]));
210 const char *string
= NULL
;
211 const UChar
*uString
= NULL
;
212 while ((string
= uenum_next(en
, &len
, &status
))) {
213 log_verbose("read \"%s\", length %i\n", string
, len
);
215 uenum_reset(en
, &status
);
216 while ((uString
= uenum_unext(en
, &len
, &status
))) {
217 log_verbose("read \"%s\" (UChar), length %i\n", quikU2C(uString
, len
), len
);
223 static void EmptyEnumerationTest(void) {
224 UErrorCode status
= U_ZERO_ERROR
;
225 UEnumeration
*emptyEnum
= uprv_malloc(sizeof(UEnumeration
));
227 uprv_memcpy(emptyEnum
, &emptyEnumerator
, sizeof(UEnumeration
));
228 if (uenum_count(emptyEnum
, &status
) != -1 || status
!= U_UNSUPPORTED_ERROR
) {
229 log_err("uenum_count failed\n");
231 status
= U_ZERO_ERROR
;
232 if (uenum_next(emptyEnum
, NULL
, &status
) != NULL
|| status
!= U_UNSUPPORTED_ERROR
) {
233 log_err("uenum_next failed\n");
235 status
= U_ZERO_ERROR
;
236 if (uenum_unext(emptyEnum
, NULL
, &status
) != NULL
|| status
!= U_UNSUPPORTED_ERROR
) {
237 log_err("uenum_unext failed\n");
239 status
= U_ZERO_ERROR
;
240 uenum_reset(emptyEnum
, &status
);
241 if (status
!= U_UNSUPPORTED_ERROR
) {
242 log_err("uenum_reset failed\n");
244 uenum_close(emptyEnum
);
246 status
= U_ZERO_ERROR
;
247 if (uenum_next(NULL
, NULL
, &status
) != NULL
|| status
!= U_ZERO_ERROR
) {
248 log_err("uenum_next(NULL) failed\n");
250 status
= U_ZERO_ERROR
;
251 if (uenum_unext(NULL
, NULL
, &status
) != NULL
|| status
!= U_ZERO_ERROR
) {
252 log_err("uenum_unext(NULL) failed\n");
254 status
= U_ZERO_ERROR
;
255 uenum_reset(NULL
, &status
);
256 if (status
!= U_ZERO_ERROR
) {
257 log_err("uenum_reset(NULL) failed\n");
260 emptyEnum
= uprv_malloc(sizeof(UEnumeration
));
261 uprv_memcpy(emptyEnum
, &emptyPartialEnumerator
, sizeof(UEnumeration
));
262 status
= U_ZERO_ERROR
;
263 if (uenum_unext(emptyEnum
, NULL
, &status
) != NULL
|| status
!= U_UNSUPPORTED_ERROR
) {
264 log_err("partial uenum_unext failed\n");
266 uenum_close(emptyEnum
);
269 static UEnumeration
*getuchArrayEnum(const UChar
** source
, int32_t size
) {
270 UEnumeration
*en
= (UEnumeration
*)malloc(sizeof(UEnumeration
));
271 memcpy(en
, &uchEnum
, sizeof(UEnumeration
));
272 ucont
->array
= (UChar
**)source
;
273 ucont
->maxIndex
= size
;
277 static void DefaultNextTest(void) {
278 UErrorCode status
= U_ZERO_ERROR
;
280 UEnumeration
*en
= getuchArrayEnum(test2
, sizeof(test2
)/sizeof(test2
[0]));
281 const char *string
= NULL
;
282 const UChar
*uString
= NULL
;
283 while ((uString
= uenum_unext(en
, &len
, &status
))) {
284 log_verbose("read \"%s\" (UChar), length %i\n", quikU2C(uString
, len
), len
);
286 if (U_FAILURE(status
)) {
287 log_err("FAIL: uenum_unext => %s\n", u_errorName(status
));
289 uenum_reset(en
, &status
);
290 while ((string
= uenum_next(en
, &len
, &status
))) {
291 log_verbose("read \"%s\", length %i\n", string
, len
);
293 if (U_FAILURE(status
)) {
294 log_err("FAIL: uenum_next => %s\n", u_errorName(status
));
300 static void verifyEnumeration(int line
, UEnumeration
*u
, const char * const * compareToChar
, const UChar
* const * compareToUChar
, int32_t expect_count
) {
301 UErrorCode status
= U_ZERO_ERROR
;
302 int32_t got_count
,i
,len
;
306 log_verbose("%s:%d: verifying enumeration..\n", __FILE__
, line
);
308 uenum_reset(u
, &status
);
309 if(U_FAILURE(status
)) {
310 log_err("%s:%d: FAIL: could not reset char strings enumeration: %s\n", __FILE__
, line
, u_errorName(status
));
314 got_count
= uenum_count(u
, &status
);
315 if(U_FAILURE(status
)) {
316 log_err("%s:%d: FAIL: could not count char strings enumeration: %s\n", __FILE__
, line
, u_errorName(status
));
320 if(got_count
!=expect_count
) {
321 log_err("%s:%d: FAIL: expect count %d got %d\n", __FILE__
, line
, expect_count
, got_count
);
323 log_verbose("%s:%d: OK: got count %d\n", __FILE__
, line
, got_count
);
326 if(compareToChar
!=NULL
) { /* else, not invariant */
327 for(i
=0;i
<got_count
;i
++) {
328 c
= uenum_next(u
,&len
, &status
);
329 if(U_FAILURE(status
)) {
330 log_err("%s:%d: FAIL: could not iterate to next after %d: %s\n", __FILE__
, line
, i
, u_errorName(status
));
334 log_err("%s:%d: FAIL: got NULL for next after %d: %s\n", __FILE__
, line
, i
, u_errorName(status
));
338 if(strcmp(c
,compareToChar
[i
])) {
339 log_err("%s:%d: FAIL: string #%d expected '%s' got '%s'\n", __FILE__
, line
, i
, compareToChar
[i
], c
);
341 log_verbose("%s:%d: OK: string #%d got '%s'\n", __FILE__
, line
, i
, c
);
344 if(len
!=strlen(compareToChar
[i
])) {
345 log_err("%s:%d: FAIL: string #%d expected len %d got %d\n", __FILE__
, line
, i
, strlen(compareToChar
[i
]), len
);
347 log_verbose("%s:%d: OK: string #%d got len %d\n", __FILE__
, line
, i
, len
);
353 uenum_reset(u
, &status
);
354 if(U_FAILURE(status
)) {
355 log_err("%s:%d: FAIL: could not reset again char strings enumeration: %s\n", __FILE__
, line
, u_errorName(status
));
359 for(i
=0;i
<got_count
;i
++) {
360 const UChar
*ustr
= uenum_unext(u
,&len
, &status
);
361 if(U_FAILURE(status
)) {
362 log_err("%s:%d: FAIL: could not iterate to unext after %d: %s\n", __FILE__
, line
, i
, u_errorName(status
));
366 log_err("%s:%d: FAIL: got NULL for unext after %d: %s\n", __FILE__
, line
, i
, u_errorName(status
));
369 if(compareToChar
!=NULL
) {
370 u_charsToUChars(compareToChar
[i
], buf
, strlen(compareToChar
[i
])+1);
371 if(u_strncmp(ustr
,buf
,len
)) {
373 log_err("%s:%d: FAIL: ustring #%d expected '%s' got '%s'\n", __FILE__
, line
, i
, compareToChar
[i
], austrdup(ustr
));
374 for(j
=0;ustr
[j
]&&buf
[j
];j
++) {
375 log_verbose(" @ %d\t<U+%04X> vs <U+%04X>\n", j
, ustr
[j
],buf
[j
]);
378 log_verbose("%s:%d: OK: ustring #%d got '%s'\n", __FILE__
, line
, i
, compareToChar
[i
]);
381 if(len
!=strlen(compareToChar
[i
])) {
382 log_err("%s:%d: FAIL: ustring #%d expected len %d got %d\n", __FILE__
, line
, i
, strlen(compareToChar
[i
]), len
);
384 log_verbose("%s:%d: OK: ustring #%d got len %d\n", __FILE__
, line
, i
, len
);
388 if(compareToUChar
!=NULL
) {
389 if(u_strcmp(ustr
,compareToUChar
[i
])) {
391 log_err("%s:%d: FAIL: ustring #%d expected '%s' got '%s'\n", __FILE__
, line
, i
, austrdup(compareToUChar
[i
]), austrdup(ustr
));
392 for(j
=0;ustr
[j
]&&compareToUChar
[j
];j
++) {
393 log_verbose(" @ %d\t<U+%04X> vs <U+%04X>\n", j
, ustr
[j
],compareToUChar
[j
]);
396 log_verbose("%s:%d: OK: ustring #%d got '%s'\n", __FILE__
, line
, i
, austrdup(compareToUChar
[i
]));
399 if(len
!=u_strlen(compareToUChar
[i
])) {
400 log_err("%s:%d: FAIL: ustring #%d expected len %d got %d\n", __FILE__
, line
, i
, u_strlen(compareToUChar
[i
]), len
);
402 log_verbose("%s:%d: OK: ustring #%d got len %d\n", __FILE__
, line
, i
, len
);
412 static void TestCharStringsEnumeration(void) {
413 UErrorCode status
= U_ZERO_ERROR
;
415 /* //! [uenum_openCharStringsEnumeration] */
416 const char* strings
[] = { "Firstly", "Secondly", "Thirdly", "Fourthly" };
417 UEnumeration
*u
= uenum_openCharStringsEnumeration(strings
, 4, &status
);
418 /* //! [uenum_openCharStringsEnumeration] */
419 if(U_FAILURE(status
)) {
420 log_err("FAIL: could not open char strings enumeration: %s\n", u_errorName(status
));
424 verifyEnumeration(__LINE__
, u
, strings
, NULL
, 4);
429 static void TestUCharStringsEnumeration(void) {
430 UErrorCode status
= U_ZERO_ERROR
;
431 /* //! [uenum_openUCharStringsEnumeration] */
432 static const UChar nko_1
[] = {0x07c1,0}, nko_2
[] = {0x07c2}, nko_3
[] = {0x07c3,0}, nko_4
[] = {0x07c4,0};
433 static const UChar
* ustrings
[] = { nko_1
, nko_2
, nko_3
, nko_4
};
434 UEnumeration
*u
= uenum_openUCharStringsEnumeration(ustrings
, 4, &status
);
435 /* //! [uenum_openUCharStringsEnumeration] */
436 if(U_FAILURE(status
)) {
437 log_err("FAIL: could not open uchar strings enumeration: %s\n", u_errorName(status
));
441 verifyEnumeration(__LINE__
, u
, NULL
, ustrings
, 4);
445 u
= uenum_openUCharStringsEnumeration(test2
, 4, &status
);
446 if(U_FAILURE(status
)) {
447 log_err("FAIL: could not reopen uchar strings enumeration: %s\n", u_errorName(status
));
450 verifyEnumeration(__LINE__
, u
, test1
, NULL
, 4); /* same string */
455 void addEnumerationTest(TestNode
** root
);
457 void addEnumerationTest(TestNode
** root
)
459 addTest(root
, &EnumerationTest
, "tsutil/uenumtst/EnumerationTest");
460 addTest(root
, &EmptyEnumerationTest
, "tsutil/uenumtst/EmptyEnumerationTest");
461 addTest(root
, &DefaultNextTest
, "tsutil/uenumtst/DefaultNextTest");
462 addTest(root
, &TestCharStringsEnumeration
, "tsutil/uenumtst/TestCharStringsEnumeration");
463 addTest(root
, &TestUCharStringsEnumeration
, "tsutil/uenumtst/TestUCharStringsEnumeration");