]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/cintltst/uenumtst.c
ICU-551.51.4.tar.gz
[apple/icu.git] / icuSources / test / cintltst / uenumtst.c
CommitLineData
b75a7d8f
A
1/*
2*******************************************************************************
3*
51004dcb 4* Copyright (C) 2002-2012, International Business Machines
b75a7d8f
A
5* Corporation and others. All Rights Reserved.
6*
7*******************************************************************************
8* file name: uenumtst.c
9* encoding: US-ASCII
10* tab size: 8 (not used)
11* indentation:2
12*
13* created on: 2002jul08
14* created by: Vladimir Weinstein
15*/
16
17#include "cintltst.h"
18#include "uenumimp.h"
19#include "cmemory.h"
20#include "cstring.h"
21#include "unicode/ustring.h"
22
23static char quikBuf[256];
24static char* quikU2C(const UChar* str, int32_t len) {
25 u_UCharsToChars(str, quikBuf, len);
26 quikBuf[len] = 0;
27 return quikBuf;
28}
29
30static const char* test1[] = {
31 "first",
32 "second",
33 "third",
34 "fourth"
35};
36
37struct chArrayContext {
38 int32_t currIndex;
39 int32_t maxIndex;
40 char *currChar;
41 UChar *currUChar;
42 char **array;
43};
44
45typedef struct chArrayContext chArrayContext;
46
47#define cont ((chArrayContext *)en->context)
48
49static void U_CALLCONV
50chArrayClose(UEnumeration *en) {
51 if(cont->currUChar != NULL) {
52 free(cont->currUChar);
53 cont->currUChar = NULL;
54 }
55 free(en);
56}
57
58static int32_t U_CALLCONV
59chArrayCount(UEnumeration *en, UErrorCode *status) {
60 return cont->maxIndex;
61}
62
63static const UChar* U_CALLCONV
64chArrayUNext(UEnumeration *en, int32_t *resultLength, UErrorCode *status) {
65 if(cont->currIndex >= cont->maxIndex) {
66 return NULL;
67 }
68
69 if(cont->currUChar == NULL) {
70 cont->currUChar = (UChar *)malloc(1024*sizeof(UChar));
71 }
72
73 cont->currChar = (cont->array)[cont->currIndex];
374ca955 74 *resultLength = (int32_t)strlen(cont->currChar);
b75a7d8f
A
75 u_charsToUChars(cont->currChar, cont->currUChar, *resultLength);
76 cont->currIndex++;
77 return cont->currUChar;
78}
79
80static const char* U_CALLCONV
81chArrayNext(UEnumeration *en, int32_t *resultLength, UErrorCode *status) {
82 if(cont->currIndex >= cont->maxIndex) {
83 return NULL;
84 }
85
86 cont->currChar = (cont->array)[cont->currIndex];
374ca955 87 *resultLength = (int32_t)strlen(cont->currChar);
b75a7d8f
A
88 cont->currIndex++;
89 return cont->currChar;
90}
91
92static void U_CALLCONV
93chArrayReset(UEnumeration *en, UErrorCode *status) {
94 cont->currIndex = 0;
95}
96
97chArrayContext myCont = {
98 0, 0,
99 NULL, NULL,
100 NULL
101};
102
103UEnumeration chEnum = {
104 NULL,
105 &myCont,
106 chArrayClose,
107 chArrayCount,
108 chArrayUNext,
109 chArrayNext,
110 chArrayReset
111};
112
113static const UEnumeration emptyEnumerator = {
114 NULL,
115 NULL,
116 NULL,
117 NULL,
118 NULL,
119 NULL,
120 NULL,
121};
122
123static const UEnumeration emptyPartialEnumerator = {
124 NULL,
125 NULL,
126 NULL,
127 NULL,
128 uenum_unextDefault,
129 NULL,
130 NULL,
131};
132
133/********************************************************************/
134static const UChar _first[] = {102,105,114,115,116,0}; /* "first" */
135static const UChar _second[]= {115,101,99,111,110,100,0}; /* "second" */
136static const UChar _third[] = {116,104,105,114,100,0}; /* "third" */
137static const UChar _fourth[]= {102,111,117,114,116,104,0};/* "fourth" */
138
139static const UChar* test2[] = {
140 _first, _second, _third, _fourth
141};
142
143struct uchArrayContext {
144 int32_t currIndex;
145 int32_t maxIndex;
146 UChar *currUChar;
147 UChar **array;
148};
149
150typedef struct uchArrayContext uchArrayContext;
151
152#define ucont ((uchArrayContext *)en->context)
153
154static void U_CALLCONV
155uchArrayClose(UEnumeration *en) {
156 free(en);
157}
158
159static int32_t U_CALLCONV
160uchArrayCount(UEnumeration *en, UErrorCode *status) {
161 return ucont->maxIndex;
162}
163
164static const UChar* U_CALLCONV
165uchArrayUNext(UEnumeration *en, int32_t *resultLength, UErrorCode *status) {
166 if(ucont->currIndex >= ucont->maxIndex) {
167 return NULL;
168 }
169
170 ucont->currUChar = (ucont->array)[ucont->currIndex];
171 *resultLength = u_strlen(ucont->currUChar);
172 ucont->currIndex++;
173 return ucont->currUChar;
174}
175
176static void U_CALLCONV
177uchArrayReset(UEnumeration *en, UErrorCode *status) {
178 ucont->currIndex = 0;
179}
180
181uchArrayContext myUCont = {
182 0, 0,
183 NULL, NULL
184};
185
186UEnumeration uchEnum = {
187 NULL,
188 &myUCont,
189 uchArrayClose,
190 uchArrayCount,
191 uchArrayUNext,
192 uenum_nextDefault,
193 uchArrayReset
194};
195
196/********************************************************************/
197
198static 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;
203 return en;
204}
205
206static void EnumerationTest(void) {
207 UErrorCode status = U_ZERO_ERROR;
208 int32_t len = 0;
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);
214 }
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);
218 }
219
220 uenum_close(en);
221}
222
223static void EmptyEnumerationTest(void) {
224 UErrorCode status = U_ZERO_ERROR;
225 UEnumeration *emptyEnum = uprv_malloc(sizeof(UEnumeration));
226
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");
230 }
231 status = U_ZERO_ERROR;
232 if (uenum_next(emptyEnum, NULL, &status) != NULL || status != U_UNSUPPORTED_ERROR) {
233 log_err("uenum_next failed\n");
234 }
235 status = U_ZERO_ERROR;
236 if (uenum_unext(emptyEnum, NULL, &status) != NULL || status != U_UNSUPPORTED_ERROR) {
237 log_err("uenum_unext failed\n");
238 }
239 status = U_ZERO_ERROR;
240 uenum_reset(emptyEnum, &status);
241 if (status != U_UNSUPPORTED_ERROR) {
242 log_err("uenum_reset failed\n");
243 }
244 uenum_close(emptyEnum);
245
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");
249 }
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");
253 }
254 status = U_ZERO_ERROR;
255 uenum_reset(NULL, &status);
256 if (status != U_ZERO_ERROR) {
257 log_err("uenum_reset(NULL) failed\n");
258 }
259
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");
265 }
266 uenum_close(emptyEnum);
267}
268
269static 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;
274 return en;
275}
276
277static void DefaultNextTest(void) {
278 UErrorCode status = U_ZERO_ERROR;
279 int32_t len = 0;
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);
285 }
286 if (U_FAILURE(status)) {
287 log_err("FAIL: uenum_unext => %s\n", u_errorName(status));
288 }
289 uenum_reset(en, &status);
290 while ((string = uenum_next(en, &len, &status))) {
291 log_verbose("read \"%s\", length %i\n", string, len);
292 }
293 if (U_FAILURE(status)) {
294 log_err("FAIL: uenum_next => %s\n", u_errorName(status));
295 }
296
297 uenum_close(en);
298}
299
51004dcb
A
300static 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;
303 const char *c;
304 UChar buf[1024];
305
306 log_verbose("%s:%d: verifying enumeration..\n", __FILE__, line);
307
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));
311 return;
312 }
313
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));
317 return;
318 }
319
320 if(got_count!=expect_count) {
321 log_err("%s:%d: FAIL: expect count %d got %d\n", __FILE__, line, expect_count, got_count);
322 } else {
323 log_verbose("%s:%d: OK: got count %d\n", __FILE__, line, got_count);
324 }
325
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));
331 return;
332 }
333 if(c==NULL) {
334 log_err("%s:%d: FAIL: got NULL for next after %d: %s\n", __FILE__, line, i, u_errorName(status));
335 return;
336 }
337
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);
340 } else {
341 log_verbose("%s:%d: OK: string #%d got '%s'\n", __FILE__, line, i, c);
342 }
343
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);
346 } else {
347 log_verbose("%s:%d: OK: string #%d got len %d\n", __FILE__, line, i, len);
348 }
349 }
350 }
351
352 /* now try U */
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));
356 return;
357 }
358
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));
363 return;
364 }
365 if(ustr==NULL) {
366 log_err("%s:%d: FAIL: got NULL for unext after %d: %s\n", __FILE__, line, i, u_errorName(status));
367 return;
368 }
369 if(compareToChar!=NULL) {
370 u_charsToUChars(compareToChar[i], buf, strlen(compareToChar[i])+1);
371 if(u_strncmp(ustr,buf,len)) {
372 int j;
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]);
376 }
377 } else {
378 log_verbose("%s:%d: OK: ustring #%d got '%s'\n", __FILE__, line, i, compareToChar[i]);
379 }
380
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);
383 } else {
384 log_verbose("%s:%d: OK: ustring #%d got len %d\n", __FILE__, line, i, len);
385 }
386 }
387
388 if(compareToUChar!=NULL) {
389 if(u_strcmp(ustr,compareToUChar[i])) {
390 int j;
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]);
394 }
395 } else {
396 log_verbose("%s:%d: OK: ustring #%d got '%s'\n", __FILE__, line, i, austrdup(compareToUChar[i]));
397 }
398
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);
401 } else {
402 log_verbose("%s:%d: OK: ustring #%d got len %d\n", __FILE__, line, i, len);
403 }
404 }
405 }
406}
407
408
409
410
411
412static void TestCharStringsEnumeration(void) {
413 UErrorCode status = U_ZERO_ERROR;
414
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));
421 return;
422 }
423
424 verifyEnumeration(__LINE__, u, strings, NULL, 4);
425
426 uenum_close(u);
427}
428
429static 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));
438 return;
439 }
440
441 verifyEnumeration(__LINE__, u, NULL, ustrings, 4);
442 uenum_close(u);
443
444
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));
448 return;
449 }
450 verifyEnumeration(__LINE__, u, test1, NULL, 4); /* same string */
451 uenum_close(u);
452
453}
454
b75a7d8f
A
455void addEnumerationTest(TestNode** root);
456
457void addEnumerationTest(TestNode** root)
458{
459 addTest(root, &EnumerationTest, "tsutil/uenumtst/EnumerationTest");
460 addTest(root, &EmptyEnumerationTest, "tsutil/uenumtst/EmptyEnumerationTest");
461 addTest(root, &DefaultNextTest, "tsutil/uenumtst/DefaultNextTest");
51004dcb
A
462 addTest(root, &TestCharStringsEnumeration, "tsutil/uenumtst/TestCharStringsEnumeration");
463 addTest(root, &TestUCharStringsEnumeration, "tsutil/uenumtst/TestUCharStringsEnumeration");
b75a7d8f 464}