- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / icu / source / test / cintltst / capitst.c
1 /********************************************************************
2  * Copyright (c) 1997-2010 International Business Machines
3  * Corporation and others. All Rights Reserved.
4  ********************************************************************/
5 /*****************************************************************************
6 *
7 * File CAPITEST.C
8 *
9 * Modification History:
10 *        Name                     Description
11 *     Madhu Katragadda             Ported for C API
12 *     Brian Rower                  Added TestOpenVsOpenRules
13 ******************************************************************************
14 *//* C API TEST For COLLATOR */
15
16 #include "unicode/utypes.h"
17
18 #if !UCONFIG_NO_COLLATION
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include "unicode/uloc.h"
24 #include "unicode/ulocdata.h"
25 #include "unicode/ustring.h"
26 #include "unicode/ures.h"
27 #include "unicode/ucoleitr.h"
28 #include "cintltst.h"
29 #include "capitst.h"
30 #include "ccolltst.h"
31 #include "putilimp.h"
32 #include "cmemory.h"
33 #include "cstring.h"
34
35 static void TestAttribute(void);
36 static void TestDefault(void);
37 static void TestDefaultKeyword(void);
38         int TestBufferSize();    /* defined in "colutil.c" */
39
40
41
42
43 /* next two function is modified from "i18n/ucol.cpp" to avoid include "ucol_imp.h" */
44 static void uprv_appendByteToHexString(char *dst, uint8_t val) {
45   uint32_t len = (uint32_t)strlen(dst);
46   sprintf(dst+len, "%02X", val);
47 }
48
49 static char* U_EXPORT2 ucol_sortKeyToString(const UCollator *coll, const uint8_t *sortkey, char *buffer, uint32_t *len) {
50   int32_t strength = UCOL_PRIMARY;
51   uint32_t res_size = 0;
52   UBool doneCase = FALSE;
53
54   char *current = buffer;
55   const uint8_t *currentSk = sortkey;
56
57   UErrorCode error_code = U_ZERO_ERROR;
58
59   strcpy(current, "[");
60
61   while(strength <= UCOL_QUATERNARY && strength <= ucol_getAttribute(coll,UCOL_STRENGTH, &error_code)) {
62     if(U_FAILURE(error_code)) {
63       log_err("ucol_getAttribute returned error: %s\n", u_errorName(error_code));
64     }
65     if(strength > UCOL_PRIMARY) {
66       strcat(current, " . ");
67     }
68     while(*currentSk != 0x01 && *currentSk != 0x00) { /* print a level */
69       uprv_appendByteToHexString(current, *currentSk++);
70       strcat(current, " ");
71     }
72     if(ucol_getAttribute(coll,UCOL_CASE_LEVEL, &error_code) == UCOL_ON && strength == UCOL_SECONDARY && doneCase == FALSE) {
73         doneCase = TRUE;
74     } else if(ucol_getAttribute(coll,UCOL_CASE_LEVEL, &error_code) == UCOL_OFF || doneCase == TRUE || strength != UCOL_SECONDARY) {
75       strength ++;
76     }
77     if(U_FAILURE(error_code)) {
78       log_err("ucol_getAttribute returned error: %s\n", u_errorName(error_code));
79     }
80     uprv_appendByteToHexString(current, *currentSk++); /* This should print '01' */
81     if(strength == UCOL_QUATERNARY && ucol_getAttribute(coll,UCOL_ALTERNATE_HANDLING, &error_code) == UCOL_NON_IGNORABLE) {
82       break;
83     }
84   }
85
86   if(ucol_getAttribute(coll,UCOL_STRENGTH, &error_code) == UCOL_IDENTICAL) {
87     strcat(current, " . ");
88     while(*currentSk != 0) {
89       uprv_appendByteToHexString(current, *currentSk++);
90       strcat(current, " ");
91     }
92
93     uprv_appendByteToHexString(current, *currentSk++);
94   }
95   if(U_FAILURE(error_code)) {
96     log_err("ucol_getAttribute returned error: %s\n", u_errorName(error_code));
97   }
98   strcat(current, "]");
99
100   if(res_size > *len) {
101     return NULL;
102   }
103
104   return buffer;
105 }
106 /* end of  avoid include "ucol_imp.h" */
107
108
109 void addCollAPITest(TestNode** root)
110 {
111     /* WEIVTODO: return tests here */
112     addTest(root, &TestProperty,      "tscoll/capitst/TestProperty");
113     addTest(root, &TestRuleBasedColl, "tscoll/capitst/TestRuleBasedColl");
114     addTest(root, &TestCompare,       "tscoll/capitst/TestCompare");
115     addTest(root, &TestSortKey,       "tscoll/capitst/TestSortKey");
116     addTest(root, &TestHashCode,      "tscoll/capitst/TestHashCode");
117     addTest(root, &TestElemIter,      "tscoll/capitst/TestElemIter");
118     addTest(root, &TestGetAll,        "tscoll/capitst/TestGetAll");
119     /*addTest(root, &TestGetDefaultRules, "tscoll/capitst/TestGetDefaultRules");*/
120     addTest(root, &TestDecomposition, "tscoll/capitst/TestDecomposition");
121     addTest(root, &TestSafeClone, "tscoll/capitst/TestSafeClone");
122     addTest(root, &TestCloneBinary, "tscoll/capitst/TestCloneBinary");
123     addTest(root, &TestGetSetAttr, "tscoll/capitst/TestGetSetAttr");
124     addTest(root, &TestBounds, "tscoll/capitst/TestBounds");
125     addTest(root, &TestGetLocale, "tscoll/capitst/TestGetLocale");
126     addTest(root, &TestSortKeyBufferOverrun, "tscoll/capitst/TestSortKeyBufferOverrun");
127     addTest(root, &TestAttribute, "tscoll/capitst/TestAttribute");
128     addTest(root, &TestGetTailoredSet, "tscoll/capitst/TestGetTailoredSet");
129     addTest(root, &TestMergeSortKeys, "tscoll/capitst/TestMergeSortKeys");
130     addTest(root, &TestShortString, "tscoll/capitst/TestShortString");
131     addTest(root, &TestGetContractionsAndUnsafes, "tscoll/capitst/TestGetContractionsAndUnsafes");
132     addTest(root, &TestOpenBinary, "tscoll/capitst/TestOpenBinary");
133     addTest(root, &TestDefault, "tscoll/capitst/TestDefault");
134     addTest(root, &TestDefaultKeyword, "tscoll/capitst/TestDefaultKeyword");
135     addTest(root, &TestOpenVsOpenRules, "tscoll/capitst/TestOpenVsOpenRules");
136     addTest(root, &TestGetKeywordValuesForLocale, "tscoll/capitst/TestGetKeywordValuesForLocale");
137 }
138
139 void TestGetSetAttr(void) {
140   UErrorCode status = U_ZERO_ERROR;
141   UCollator *coll = ucol_open(NULL, &status);
142   struct attrTest {
143     UColAttribute att;
144     UColAttributeValue val[5];
145     uint32_t valueSize;
146     UColAttributeValue nonValue;
147   } attrs[] = {
148     {UCOL_FRENCH_COLLATION, {UCOL_ON, UCOL_OFF}, 2, UCOL_SHIFTED},
149     {UCOL_ALTERNATE_HANDLING, {UCOL_NON_IGNORABLE, UCOL_SHIFTED}, 2, UCOL_OFF},/* attribute for handling variable elements*/
150     {UCOL_CASE_FIRST, {UCOL_OFF, UCOL_LOWER_FIRST, UCOL_UPPER_FIRST}, 3, UCOL_SHIFTED},/* who goes first, lower case or uppercase */
151     {UCOL_CASE_LEVEL, {UCOL_ON, UCOL_OFF}, 2, UCOL_SHIFTED},/* do we have an extra case level */
152     {UCOL_NORMALIZATION_MODE, {UCOL_ON, UCOL_OFF}, 2, UCOL_SHIFTED},/* attribute for normalization */
153     {UCOL_DECOMPOSITION_MODE, {UCOL_ON, UCOL_OFF}, 2, UCOL_SHIFTED},
154     {UCOL_STRENGTH,         {UCOL_PRIMARY, UCOL_SECONDARY, UCOL_TERTIARY, UCOL_QUATERNARY, UCOL_IDENTICAL}, 5, UCOL_SHIFTED},/* attribute for strength */
155     {UCOL_HIRAGANA_QUATERNARY_MODE, {UCOL_ON, UCOL_OFF}, 2, UCOL_SHIFTED},/* when turned on, this attribute */
156   };
157   UColAttribute currAttr;
158   UColAttributeValue value;
159   uint32_t i = 0, j = 0;
160
161   if (coll == NULL) {
162     log_err_status(status, "Unable to open collator. %s\n", u_errorName(status));
163     return;
164   } 
165   for(i = 0; i<sizeof(attrs)/sizeof(attrs[0]); i++) {
166     currAttr = attrs[i].att;
167     ucol_setAttribute(coll, currAttr, UCOL_DEFAULT, &status);
168     if(U_FAILURE(status)) {
169       log_err_status(status, "ucol_setAttribute with the default value returned error: %s\n", u_errorName(status));
170       break;
171     }
172     value = ucol_getAttribute(coll, currAttr, &status);
173     if(U_FAILURE(status)) {
174       log_err("ucol_getAttribute returned error: %s\n", u_errorName(status));
175       break;
176     }
177     for(j = 0; j<attrs[i].valueSize; j++) {
178       ucol_setAttribute(coll, currAttr, attrs[i].val[j], &status);
179       if(U_FAILURE(status)) {
180         log_err("ucol_setAttribute with the value %i returned error: %s\n", attrs[i].val[j], u_errorName(status));
181         break;
182       }
183     }
184     status = U_ZERO_ERROR;
185     ucol_setAttribute(coll, currAttr, attrs[i].nonValue, &status);
186     if(U_SUCCESS(status)) {
187       log_err("ucol_setAttribute with the bad value didn't return an error\n");
188       break;
189     }
190     status = U_ZERO_ERROR;
191
192     ucol_setAttribute(coll, currAttr, value, &status);
193     if(U_FAILURE(status)) {
194       log_err("ucol_setAttribute with the default valuereturned error: %s\n", u_errorName(status));
195       break;
196     }
197   }
198   status = U_ZERO_ERROR;
199   value = ucol_getAttribute(coll, UCOL_ATTRIBUTE_COUNT, &status);
200   if(U_SUCCESS(status)) {
201     log_err("ucol_getAttribute for UCOL_ATTRIBUTE_COUNT didn't return an error\n");
202   }
203   status = U_ZERO_ERROR;
204   ucol_setAttribute(coll, UCOL_ATTRIBUTE_COUNT, UCOL_DEFAULT, &status);
205   if(U_SUCCESS(status)) {
206     log_err("ucol_setAttribute for UCOL_ATTRIBUTE_COUNT didn't return an error\n");
207   }
208   status = U_ZERO_ERROR;
209   ucol_close(coll);
210 }
211
212
213 static void doAssert(int condition, const char *message)
214 {
215     if (condition==0) {
216         log_err("ERROR :  %s\n", message);
217     }
218 }
219
220 #if 0
221 /* We don't have default rules, at least not in the previous sense */
222 void TestGetDefaultRules(){
223     uint32_t size=0;
224     UErrorCode status=U_ZERO_ERROR;
225     UCollator *coll=NULL;
226     int32_t len1 = 0, len2=0;
227     uint8_t *binColData = NULL;
228
229     UResourceBundle *res = NULL;
230     UResourceBundle *binColl = NULL;
231     uint8_t *binResult = NULL;
232
233
234     const UChar * defaultRulesArray=ucol_getDefaultRulesArray(&size);
235     log_verbose("Test the function ucol_getDefaultRulesArray()\n");
236
237     coll = ucol_openRules(defaultRulesArray, size, UCOL_ON, UCOL_PRIMARY, &status);
238     if(U_SUCCESS(status) && coll !=NULL) {
239         binColData = (uint8_t*)ucol_cloneRuleData(coll, &len1, &status);
240
241     }
242
243
244     status=U_ZERO_ERROR;
245     res=ures_open(NULL, "root", &status);
246     if(U_FAILURE(status)){
247         log_err("ERROR: Failed to get resource for \"root Locale\" with %s", myErrorName(status));
248         return;
249     }
250     binColl=ures_getByKey(res, "%%Collation", binColl, &status);
251     if(U_SUCCESS(status)){
252         binResult=(uint8_t*)ures_getBinary(binColl,  &len2, &status);
253         if(U_FAILURE(status)){
254             log_err("ERROR: ures_getBinary() failed\n");
255         }
256     }else{
257         log_err("ERROR: ures_getByKey(locale(default), %%Collation) failed");
258     }
259
260
261     if(len1 != len2){
262         log_err("Error: ucol_getDefaultRulesArray() failed to return the correct length.\n");
263     }
264     if(memcmp(binColData, binResult, len1) != 0){
265         log_err("Error: ucol_getDefaultRulesArray() failed\n");
266     }
267
268     free(binColData);
269     ures_close(binColl);
270     ures_close(res);
271     ucol_close(coll);
272
273 }
274 #endif
275
276 /* Collator Properties
277  ucol_open, ucol_strcoll,  getStrength/setStrength
278  getDecomposition/setDecomposition, getDisplayName*/
279 void TestProperty()
280 {
281     UCollator *col, *ruled;
282     UChar *disName;
283     int32_t len = 0;
284     UChar *source, *target;
285     int32_t tempLength;
286     UErrorCode status = U_ZERO_ERROR;
287     /*
288      * Expected version of the English collator.
289      * Currently, the major/minor version numbers change when the builder code
290      * changes,
291      * number 2 is from the tailoring data version and
292      * number 3 is the UCA version.
293      * This changes with every UCA version change, and the expected value
294      * needs to be adjusted.
295      * Same in intltest/apicoll.cpp.
296      */
297     UVersionInfo currVersionArray = {0x31, 0xC0, 0x05, 0x2A};  /* from ICU 4.4/UCA 5.2 */
298     UVersionInfo versionArray = {0, 0, 0, 0};
299     UVersionInfo versionUCAArray = {0, 0, 0, 0};
300     UVersionInfo versionUCDArray = {0, 0, 0, 0};
301
302     log_verbose("The property tests begin : \n");
303     log_verbose("Test ucol_strcoll : \n");
304     col = ucol_open("en_US", &status);
305     if (U_FAILURE(status)) {
306         log_err_status(status, "Default Collator creation failed.: %s\n", myErrorName(status));
307         return;
308     }
309
310     ucol_getVersion(col, versionArray);
311     /* Check for a version greater than some value rather than equality
312      * so that we need not update the expected version each time. */
313     if (uprv_memcmp(versionArray, currVersionArray, 4)<0) {
314       log_err("Testing ucol_getVersion() - unexpected result: %02x.%02x.%02x.%02x\n",
315               versionArray[0], versionArray[1], versionArray[2], versionArray[3]);
316     } else {
317       log_verbose("ucol_getVersion() result: %02x.%02x.%02x.%02x\n",
318                   versionArray[0], versionArray[1], versionArray[2], versionArray[3]);
319     }
320
321     /* Assume that the UCD and UCA versions are the same,
322      * rather than hardcoding (and updating each time) a particular UCA version. */
323     u_getUnicodeVersion(versionUCDArray);
324     ucol_getUCAVersion(col, versionUCAArray);
325     if (0!=uprv_memcmp(versionUCAArray, versionUCDArray, 4)) {
326       log_err("Testing ucol_getUCAVersion() - unexpected result: %hu.%hu.%hu.%hu\n",
327               versionUCAArray[0], versionUCAArray[1], versionUCAArray[2], versionUCAArray[3]);
328     }
329
330     source=(UChar*)malloc(sizeof(UChar) * 12);
331     target=(UChar*)malloc(sizeof(UChar) * 12);
332
333
334     u_uastrcpy(source, "ab");
335     u_uastrcpy(target, "abc");
336
337     doAssert((ucol_strcoll(col, source, u_strlen(source), target, u_strlen(target)) == UCOL_LESS), "ab < abc comparison failed");
338
339     u_uastrcpy(source, "ab");
340     u_uastrcpy(target, "AB");
341
342     doAssert((ucol_strcoll(col, source, u_strlen(source), target, u_strlen(target)) == UCOL_LESS), "ab < AB comparison failed");
343 /*    u_uastrcpy(source, "black-bird");
344     u_uastrcpy(target, "blackbird"); */
345     u_uastrcpy(target, "black-bird");
346     u_uastrcpy(source, "blackbird");
347
348     doAssert((ucol_strcoll(col, source, u_strlen(source), target, u_strlen(target)) == UCOL_GREATER),
349         "black-bird > blackbird comparison failed");
350     u_uastrcpy(source, "black bird");
351     u_uastrcpy(target, "black-bird");
352     doAssert((ucol_strcoll(col, source, u_strlen(source), target, u_strlen(target)) == UCOL_LESS),
353         "black bird < black-bird comparison failed");
354     u_uastrcpy(source, "Hello");
355     u_uastrcpy(target, "hello");
356
357     doAssert((ucol_strcoll(col, source, u_strlen(source), target, u_strlen(target)) == UCOL_GREATER),
358         "Hello > hello comparison failed");
359     free(source);
360     free(target);
361     log_verbose("Test ucol_strcoll ends.\n");
362
363     log_verbose("testing ucol_getStrength() method ...\n");
364     doAssert( (ucol_getStrength(col) == UCOL_TERTIARY), "collation object has the wrong strength");
365     doAssert( (ucol_getStrength(col) != UCOL_PRIMARY), "collation object's strength is primary difference");
366
367     log_verbose("testing ucol_setStrength() method ...\n");
368     ucol_setStrength(col, UCOL_SECONDARY);
369     doAssert( (ucol_getStrength(col) != UCOL_TERTIARY), "collation object's strength is secondary difference");
370     doAssert( (ucol_getStrength(col) != UCOL_PRIMARY), "collation object's strength is primary difference");
371     doAssert( (ucol_getStrength(col) == UCOL_SECONDARY), "collation object has the wrong strength");
372
373
374     log_verbose("Get display name for the default collation in German : \n");
375
376     len=ucol_getDisplayName("en_US", "de_DE", NULL, 0,  &status);
377     if(status==U_BUFFER_OVERFLOW_ERROR){
378         status=U_ZERO_ERROR;
379         disName=(UChar*)malloc(sizeof(UChar) * (len+1));
380         ucol_getDisplayName("en_US", "de_DE", disName, len+1,  &status);
381         log_verbose("the display name for default collation in german: %s\n", austrdup(disName) );
382         free(disName);
383     }
384     if(U_FAILURE(status)){
385         log_err("ERROR: in getDisplayName: %s\n", myErrorName(status));
386         return;
387     }
388     log_verbose("Default collation getDisplayName ended.\n");
389
390     ruled = ucol_open("da_DK", &status);
391     log_verbose("ucol_getRules() testing ...\n");
392     ucol_getRules(ruled, &tempLength);
393     doAssert( tempLength != 0, "getRules() result incorrect" );
394     log_verbose("getRules tests end.\n");
395     {
396         UChar *buffer = (UChar *)malloc(200000*sizeof(UChar));
397         int32_t bufLen = 200000;
398         buffer[0] = '\0';
399         log_verbose("ucol_getRulesEx() testing ...\n");
400         tempLength = ucol_getRulesEx(col,UCOL_TAILORING_ONLY,buffer,bufLen );
401         doAssert( tempLength == 0x00, "getRulesEx() result incorrect" );
402         log_verbose("getRules tests end.\n");
403
404         log_verbose("ucol_getRulesEx() testing ...\n");
405         tempLength=ucol_getRulesEx(col,UCOL_FULL_RULES,buffer,bufLen );
406         doAssert( tempLength != 0, "getRulesEx() result incorrect" );
407         log_verbose("getRules tests end.\n");
408         free(buffer);
409     }
410     ucol_close(ruled);
411     ucol_close(col);
412
413     log_verbose("open an collator for french locale");
414     col = ucol_open("fr_FR", &status);
415     if (U_FAILURE(status)) {
416        log_err("ERROR: Creating French collation failed.: %s\n", myErrorName(status));
417         return;
418     }
419     ucol_setStrength(col, UCOL_PRIMARY);
420     log_verbose("testing ucol_getStrength() method again ...\n");
421     doAssert( (ucol_getStrength(col) != UCOL_TERTIARY), "collation object has the wrong strength");
422     doAssert( (ucol_getStrength(col) == UCOL_PRIMARY), "collation object's strength is not primary difference");
423
424     log_verbose("testing French ucol_setStrength() method ...\n");
425     ucol_setStrength(col, UCOL_TERTIARY);
426     doAssert( (ucol_getStrength(col) == UCOL_TERTIARY), "collation object's strength is not tertiary difference");
427     doAssert( (ucol_getStrength(col) != UCOL_PRIMARY), "collation object's strength is primary difference");
428     doAssert( (ucol_getStrength(col) != UCOL_SECONDARY), "collation object's strength is secondary difference");
429     ucol_close(col);
430
431     log_verbose("Get display name for the french collation in english : \n");
432     len=ucol_getDisplayName("fr_FR", "en_US", NULL, 0,  &status);
433     if(status==U_BUFFER_OVERFLOW_ERROR){
434         status=U_ZERO_ERROR;
435         disName=(UChar*)malloc(sizeof(UChar) * (len+1));
436         ucol_getDisplayName("fr_FR", "en_US", disName, len+1,  &status);
437         log_verbose("the display name for french collation in english: %s\n", austrdup(disName) );
438         free(disName);
439     }
440     if(U_FAILURE(status)){
441         log_err("ERROR: in getDisplayName: %s\n", myErrorName(status));
442         return;
443     }
444     log_verbose("Default collation getDisplayName ended.\n");
445
446 }
447
448 /* Test RuleBasedCollator and getRules*/
449 void TestRuleBasedColl()
450 {
451     UCollator *col1, *col2, *col3, *col4;
452     UCollationElements *iter1, *iter2;
453     UChar ruleset1[60];
454     UChar ruleset2[50];
455     UChar teststr[10];
456     UChar teststr2[10];
457     const UChar *rule1, *rule2, *rule3, *rule4;
458     int32_t tempLength;
459     UErrorCode status = U_ZERO_ERROR;
460     u_uastrcpy(ruleset1, "&9 < a, A < b, B < c, C; ch, cH, Ch, CH < d, D, e, E");
461     u_uastrcpy(ruleset2, "&9 < a, A < b, B < c, C < d, D, e, E");
462
463
464     col1 = ucol_openRules(ruleset1, u_strlen(ruleset1), UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL,&status);
465     if (U_FAILURE(status)) {
466         log_err_status(status, "RuleBased Collator creation failed.: %s\n", myErrorName(status));
467         return;
468     }
469     else
470         log_verbose("PASS: RuleBased Collator creation passed\n");
471
472     status = U_ZERO_ERROR;
473     col2 = ucol_openRules(ruleset2, u_strlen(ruleset2),  UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL, &status);
474     if (U_FAILURE(status)) {
475         log_err("RuleBased Collator creation failed.: %s\n", myErrorName(status));
476         return;
477     }
478     else
479         log_verbose("PASS: RuleBased Collator creation passed\n");
480
481
482     status = U_ZERO_ERROR;
483     col3= ucol_open(NULL, &status);
484     if (U_FAILURE(status)) {
485         log_err("Default Collator creation failed.: %s\n", myErrorName(status));
486         return;
487     }
488     else
489         log_verbose("PASS: Default Collator creation passed\n");
490
491     rule1 = ucol_getRules(col1, &tempLength);
492     rule2 = ucol_getRules(col2, &tempLength);
493     rule3 = ucol_getRules(col3, &tempLength);
494
495     doAssert((u_strcmp(rule1, rule2) != 0), "Default collator getRules failed");
496     doAssert((u_strcmp(rule2, rule3) != 0), "Default collator getRules failed");
497     doAssert((u_strcmp(rule1, rule3) != 0), "Default collator getRules failed");
498
499     col4=ucol_openRules(rule2, u_strlen(rule2), UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL, &status);
500     if (U_FAILURE(status)) {
501         log_err("RuleBased Collator creation failed.: %s\n", myErrorName(status));
502         return;
503     }
504     rule4= ucol_getRules(col4, &tempLength);
505     doAssert((u_strcmp(rule2, rule4) == 0), "Default collator getRules failed");
506
507     ucol_close(col1);
508     ucol_close(col2);
509     ucol_close(col3);
510     ucol_close(col4);
511
512     /* tests that modifier ! is always ignored */
513     u_uastrcpy(ruleset1, "!&a<b");
514     teststr[0] = 0x0e40;
515     teststr[1] = 0x0e01;
516     teststr[2] = 0x0e2d;
517     col1 = ucol_openRules(ruleset1, u_strlen(ruleset1), UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL, &status);
518     if (U_FAILURE(status)) {
519         log_err("RuleBased Collator creation failed.: %s\n", myErrorName(status));
520         return;
521     }
522     col2 = ucol_open("en_US", &status);
523     if (U_FAILURE(status)) {
524         log_err("en_US Collator creation failed.: %s\n", myErrorName(status));
525         return;
526     }
527     iter1 = ucol_openElements(col1, teststr, 3, &status);
528     iter2 = ucol_openElements(col2, teststr, 3, &status);
529     if(U_FAILURE(status)) {
530         log_err("ERROR: CollationElement iterator creation failed.: %s\n", myErrorName(status));
531         return;
532     }
533     while (TRUE) {
534         /* testing with en since thai has its own tailoring */
535         uint32_t ce = ucol_next(iter1, &status);
536         uint32_t ce2 = ucol_next(iter2, &status);
537         if(U_FAILURE(status)) {
538             log_err("ERROR: CollationElement iterator creation failed.: %s\n", myErrorName(status));
539             return;
540         }
541         if (ce2 != ce) {
542              log_err("! modifier test failed");
543         }
544         if (ce == UCOL_NULLORDER) {
545             break;
546         }
547     }
548     ucol_closeElements(iter1);
549     ucol_closeElements(iter2);
550     ucol_close(col1);
551     ucol_close(col2);
552     /* test that we can start a rule without a & or < */
553     u_uastrcpy(ruleset1, "< z < a");
554     col1 = ucol_openRules(ruleset1, u_strlen(ruleset1), UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL, &status);
555     if (U_FAILURE(status)) {
556         log_err("RuleBased Collator creation failed.: %s\n", myErrorName(status));
557         return;
558     }
559     u_uastrcpy(teststr, "z");
560     u_uastrcpy(teststr2, "a");
561     if (ucol_greaterOrEqual(col1, teststr, 1, teststr2, 1)) {
562         log_err("Rule \"z < a\" fails");
563     }
564     ucol_close(col1);
565 }
566
567 void TestCompare()
568 {
569     UErrorCode status = U_ZERO_ERROR;
570     UCollator *col;
571     UChar* test1;
572     UChar* test2;
573
574     log_verbose("The compare tests begin : \n");
575     status=U_ZERO_ERROR;
576     col = ucol_open("en_US", &status);
577     if(U_FAILURE(status)) {
578         log_err_status(status, "ucal_open() collation creation failed.: %s\n", myErrorName(status));
579         return;
580     }
581     test1=(UChar*)malloc(sizeof(UChar) * 6);
582     test2=(UChar*)malloc(sizeof(UChar) * 6);
583     u_uastrcpy(test1, "Abcda");
584     u_uastrcpy(test2, "abcda");
585
586     log_verbose("Use tertiary comparison level testing ....\n");
587
588     doAssert( (!ucol_equal(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" != \"abcda\" ");
589     doAssert( (ucol_greater(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" >>> \"abcda\" ");
590     doAssert( (ucol_greaterOrEqual(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" >>> \"abcda\"");
591
592     ucol_setStrength(col, UCOL_SECONDARY);
593     log_verbose("Use secondary comparison level testing ....\n");
594
595     doAssert( (ucol_equal(col, test1, u_strlen(test1), test2, u_strlen(test2) )), "Result should be \"Abcda\" == \"abcda\"");
596     doAssert( (!ucol_greater(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" == \"abcda\"");
597     doAssert( (ucol_greaterOrEqual(col, test1, u_strlen(test1), test2, u_strlen(test2) )), "Result should be \"Abcda\" == \"abcda\"");
598
599     ucol_setStrength(col, UCOL_PRIMARY);
600     log_verbose("Use primary comparison level testing ....\n");
601
602     doAssert( (ucol_equal(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" == \"abcda\"");
603     doAssert( (!ucol_greater(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" == \"abcda\"");
604     doAssert( (ucol_greaterOrEqual(col, test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"Abcda\" == \"abcda\"");
605
606
607     log_verbose("The compare tests end.\n");
608     ucol_close(col);
609     free(test1);
610     free(test2);
611
612 }
613 /*
614 ---------------------------------------------
615  tests decomposition setting
616 */
617 void TestDecomposition() {
618     UErrorCode status = U_ZERO_ERROR;
619     UCollator *en_US, *el_GR, *vi_VN;
620     en_US = ucol_open("en_US", &status);
621     el_GR = ucol_open("el_GR", &status);
622     vi_VN = ucol_open("vi_VN", &status);
623
624     if (U_FAILURE(status)) {
625         log_err_status(status, "ERROR: collation creation failed.: %s\n", myErrorName(status));
626         return;
627     }
628
629     if (ucol_getAttribute(vi_VN, UCOL_NORMALIZATION_MODE, &status) != UCOL_ON ||
630         U_FAILURE(status))
631     {
632         log_err("ERROR: vi_VN collation did not have cannonical decomposition for normalization!\n");
633     }
634
635     status = U_ZERO_ERROR;
636     if (ucol_getAttribute(el_GR, UCOL_NORMALIZATION_MODE, &status) != UCOL_ON ||
637         U_FAILURE(status))
638     {
639         log_err("ERROR: el_GR collation did not have cannonical decomposition for normalization!\n");
640     }
641
642     status = U_ZERO_ERROR;
643     if (ucol_getAttribute(en_US, UCOL_NORMALIZATION_MODE, &status) != UCOL_OFF ||
644         U_FAILURE(status))
645     {
646         log_err("ERROR: en_US collation had cannonical decomposition for normalization!\n");
647     }
648
649     ucol_close(en_US);
650     ucol_close(el_GR);
651     ucol_close(vi_VN);
652 }
653
654 #define CLONETEST_COLLATOR_COUNT 4
655
656 void TestSafeClone() {
657     UChar test1[6];
658     UChar test2[6];
659     static const UChar umlautUStr[] = {0x00DC, 0};
660     static const UChar oeStr[] = {0x0055, 0x0045, 0};
661     UCollator * someCollators [CLONETEST_COLLATOR_COUNT];
662     UCollator * someClonedCollators [CLONETEST_COLLATOR_COUNT];
663     UCollator * col;
664     UErrorCode err = U_ZERO_ERROR;
665     int8_t index = 6;    /* Leave this here to test buffer alingment in memory*/
666     uint8_t buffer [CLONETEST_COLLATOR_COUNT] [U_COL_SAFECLONE_BUFFERSIZE];
667     int32_t bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
668     const char sampleRuleChars[] = "&Z < CH";
669     UChar sampleRule[sizeof(sampleRuleChars)];
670
671     if (TestBufferSize()) {
672         log_err("U_COL_SAFECLONE_BUFFERSIZE should be larger than sizeof(UCollator)\n");
673         return;
674     }
675
676     u_uastrcpy(test1, "abCda");
677     u_uastrcpy(test2, "abcda");
678     u_uastrcpy(sampleRule, sampleRuleChars);
679
680     /* one default collator & two complex ones */
681     someCollators[0] = ucol_open("en_US", &err);
682     someCollators[1] = ucol_open("ko", &err);
683     someCollators[2] = ucol_open("ja_JP", &err);
684     someCollators[3] = ucol_openRules(sampleRule, -1, UCOL_ON, UCOL_TERTIARY, NULL, &err);
685     if(U_FAILURE(err)) {
686         for (index = 0; index < CLONETEST_COLLATOR_COUNT; index++) {
687             ucol_close(someCollators[index]);
688         }
689         log_data_err("Couldn't open one or more collators\n");
690         return;
691     }
692
693     /* Check the various error & informational states: */
694
695     /* Null status - just returns NULL */
696     if (0 != ucol_safeClone(someCollators[0], buffer[0], &bufferSize, 0))
697     {
698         log_err("FAIL: Cloned Collator failed to deal correctly with null status\n");
699     }
700     /* error status - should return 0 & keep error the same */
701     err = U_MEMORY_ALLOCATION_ERROR;
702     if (0 != ucol_safeClone(someCollators[0], buffer[0], &bufferSize, &err) || err != U_MEMORY_ALLOCATION_ERROR)
703     {
704         log_err("FAIL: Cloned Collator failed to deal correctly with incoming error status\n");
705     }
706     err = U_ZERO_ERROR;
707
708     /* Null buffer size pointer - just returns NULL & set error to U_ILLEGAL_ARGUMENT_ERROR*/
709     if (0 != ucol_safeClone(someCollators[0], buffer[0], 0, &err) || err != U_ILLEGAL_ARGUMENT_ERROR)
710     {
711         log_err("FAIL: Cloned Collator failed to deal correctly with null bufferSize pointer\n");
712     }
713     err = U_ZERO_ERROR;
714
715     /* buffer size pointer is 0 - fill in pbufferSize with a size */
716     bufferSize = 0;
717     if (0 != ucol_safeClone(someCollators[0], buffer[0], &bufferSize, &err) || U_FAILURE(err) || bufferSize <= 0)
718     {
719         log_err("FAIL: Cloned Collator failed a sizing request ('preflighting')\n");
720     }
721     /* Verify our define is large enough  */
722     if (U_COL_SAFECLONE_BUFFERSIZE < bufferSize)
723     {
724         log_err("FAIL: Pre-calculated buffer size is too small\n");
725     }
726     /* Verify we can use this run-time calculated size */
727     if (0 == (col = ucol_safeClone(someCollators[0], buffer[0], &bufferSize, &err)) || U_FAILURE(err))
728     {
729         log_err("FAIL: Collator can't be cloned with run-time size\n");
730     }
731     if (col) ucol_close(col);
732     /* size one byte too small - should allocate & let us know */
733     --bufferSize;
734     if (0 == (col = ucol_safeClone(someCollators[0], 0, &bufferSize, &err)) || err != U_SAFECLONE_ALLOCATED_WARNING)
735     {
736         log_err("FAIL: Cloned Collator failed to deal correctly with too-small buffer size\n");
737     }
738     if (col) ucol_close(col);
739     err = U_ZERO_ERROR;
740     bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
741
742
743     /* Null buffer pointer - return Collator & set error to U_SAFECLONE_ALLOCATED_ERROR */
744     if (0 == (col = ucol_safeClone(someCollators[0], 0, &bufferSize, &err)) || err != U_SAFECLONE_ALLOCATED_WARNING)
745     {
746         log_err("FAIL: Cloned Collator failed to deal correctly with null buffer pointer\n");
747     }
748     if (col) ucol_close(col);
749     err = U_ZERO_ERROR;
750
751     /* Null Collator - return NULL & set U_ILLEGAL_ARGUMENT_ERROR */
752     if (0 != ucol_safeClone(0, buffer[0], &bufferSize, &err) || err != U_ILLEGAL_ARGUMENT_ERROR)
753     {
754         log_err("FAIL: Cloned Collator failed to deal correctly with null Collator pointer\n");
755     }
756
757     err = U_ZERO_ERROR;
758
759     /* Test that a cloned collator doesn't accidentally use UCA. */
760     col=ucol_open("de@collation=phonebook", &err);
761     bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
762     someClonedCollators[0] = ucol_safeClone(col, buffer[0], &bufferSize, &err);
763     doAssert( (ucol_greater(col, umlautUStr, u_strlen(umlautUStr), oeStr, u_strlen(oeStr))), "Original German phonebook collation sorts differently than expected");
764     doAssert( (ucol_greater(someClonedCollators[0], umlautUStr, u_strlen(umlautUStr), oeStr, u_strlen(oeStr))), "Cloned German phonebook collation sorts differently than expected");
765     if (!ucol_equals(someClonedCollators[0], col)) {
766         log_err("FAIL: Cloned German phonebook collator is not equal to original.\n");
767     }
768     ucol_close(col);
769     ucol_close(someClonedCollators[0]);
770
771     err = U_ZERO_ERROR;
772
773     /* change orig & clone & make sure they are independent */
774
775     for (index = 0; index < CLONETEST_COLLATOR_COUNT; index++)
776     {
777         ucol_setStrength(someCollators[index], UCOL_IDENTICAL);
778         bufferSize = 1;
779         err = U_ZERO_ERROR;
780         ucol_close(ucol_safeClone(someCollators[index], buffer[index], &bufferSize, &err));
781         if (err != U_SAFECLONE_ALLOCATED_WARNING) {
782             log_err("FAIL: collator number %d was not allocated.\n", index);
783             log_err("FAIL: status of Collator[%d] is %d  (hex: %x).\n", index, err, err);
784         }
785
786         bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
787         err = U_ZERO_ERROR;
788         someClonedCollators[index] = ucol_safeClone(someCollators[index], buffer[index], &bufferSize, &err);
789         if (someClonedCollators[index] == NULL
790             || someClonedCollators[index] < (UCollator *)buffer[index]
791             || someClonedCollators[index] > (UCollator *)(buffer[index]+(U_COL_SAFECLONE_BUFFERSIZE-1)))
792         {
793             log_err("FAIL: Cloned collator didn't use provided buffer.\n");
794             return;
795         }
796         if (!ucol_equals(someClonedCollators[index], someCollators[index])) {
797             log_err("FAIL: Cloned collator is not equal to original at index = %d.\n", index);
798         }
799
800         /* Check the usability */
801         ucol_setStrength(someCollators[index], UCOL_PRIMARY);
802         ucol_setAttribute(someCollators[index], UCOL_CASE_LEVEL, UCOL_OFF, &err);
803
804         doAssert( (ucol_equal(someCollators[index], test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"abcda\" == \"abCda\"");
805
806         /* Close the original to make sure that the clone is usable. */
807         ucol_close(someCollators[index]);
808
809         ucol_setStrength(someClonedCollators[index], UCOL_TERTIARY);
810         ucol_setAttribute(someClonedCollators[index], UCOL_CASE_LEVEL, UCOL_OFF, &err);
811         doAssert( (ucol_greater(someClonedCollators[index], test1, u_strlen(test1), test2, u_strlen(test2))), "Result should be \"abCda\" >>> \"abcda\" ");
812
813         ucol_close(someClonedCollators[index]);
814     }
815 }
816
817 void TestCloneBinary(){
818     UErrorCode err = U_ZERO_ERROR;
819     UCollator * col = ucol_open("en_US", &err);
820     UCollator * c;
821     int32_t size;
822     uint8_t * buffer;
823
824     if (U_FAILURE(err)) {
825         log_data_err("Couldn't open collator. Error: %s\n", u_errorName(err));
826         return;
827     }
828
829     size = ucol_cloneBinary(col, NULL, 0, &err);
830     if(size==0 || err!=U_BUFFER_OVERFLOW_ERROR) {
831         log_err("ucol_cloneBinary - couldn't check size. Error: %s\n", u_errorName(err));
832         return;
833     }
834     err = U_ZERO_ERROR;
835
836     buffer = (uint8_t *) malloc(size);
837     ucol_cloneBinary(col, buffer, size, &err);
838     if(U_FAILURE(err)) {
839         log_err("ucol_cloneBinary - couldn't clone.. Error: %s\n", u_errorName(err));
840         free(buffer);
841         return;
842     }
843
844     /* how to check binary result ? */
845
846     c = ucol_openBinary(buffer, size, col, &err);
847     if(U_FAILURE(err)) {
848         log_err("ucol_openBinary failed. Error: %s\n", u_errorName(err));
849     } else {
850         UChar t[] = {0x41, 0x42, 0x43, 0};  /* ABC */
851         uint8_t  *k1, *k2;
852         int l1, l2;
853         l1 = ucol_getSortKey(col, t, -1, NULL,0);
854         l2 = ucol_getSortKey(c, t, -1, NULL,0);
855         k1 = (uint8_t *) malloc(sizeof(uint8_t) * l1);
856         k2 = (uint8_t *) malloc(sizeof(uint8_t) * l2);
857         ucol_getSortKey(col, t, -1, k1, l1);
858         ucol_getSortKey(col, t, -1, k2, l2);
859         if (strcmp((char *)k1,(char *)k2) != 0){
860             log_err("ucol_openBinary - new collator should equal to old one\n");
861         };
862         free(k1);
863         free(k2);
864     }
865     free(buffer);
866     ucol_close(c);
867     ucol_close(col);
868 }
869 /*
870     TestOpenVsOpenRules ensures that collators from ucol_open and ucol_openRules
871     will generate identical sort keys
872 */
873 void TestOpenVsOpenRules(){
874
875     /* create an array of all the locales */
876     int32_t numLocales = uloc_countAvailable();
877     int32_t sizeOfStdSet;
878     uint32_t adder;
879     UChar str[41]; /* create an array of UChar of size maximum strSize + 1 */
880     USet *stdSet;
881     char* curLoc;
882     UCollator * c1;
883     UCollator * c2;
884     const UChar* rules;
885     int32_t rulesLength;
886     int32_t sortKeyLen1, sortKeyLen2;
887     uint8_t *sortKey1 = NULL, *sortKey2 = NULL;
888     ULocaleData *uld;
889     int32_t x, y, z;
890     USet *eSet;
891     int32_t eSize;
892     int strSize;
893
894     UErrorCode err = U_ZERO_ERROR;
895
896     /* create a set of standard characters that aren't very interesting...
897     and then we can find some interesting ones later */
898
899     stdSet = uset_open(0x61, 0x7A);
900     uset_addRange(stdSet, 0x41, 0x5A);
901     uset_addRange(stdSet, 0x30, 0x39);
902     sizeOfStdSet = uset_size(stdSet);
903
904     adder = 1;
905     if(getTestOption(QUICK_OPTION))
906     {
907         adder = 10;
908     }
909
910     for(x = 0; x < numLocales; x+=adder){
911         curLoc = (char *)uloc_getAvailable(x);
912         log_verbose("Processing %s\n", curLoc);
913
914         /* create a collator the normal API way */
915         c1 = ucol_open(curLoc, &err);
916         if (U_FAILURE(err)) {
917             log_err("ERROR: Normal collation creation failed with locale: %s : %s\n", curLoc, myErrorName(err));
918             return;
919         }
920
921         /* grab the rules */
922         rules = ucol_getRules(c1, &rulesLength);
923
924         /* use those rules to create a collator from rules */
925         c2 = ucol_openRules(rules, rulesLength, UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH, NULL, &err);
926         if (U_FAILURE(err)) {
927             log_err("ERROR: Creating collator from rules failed with locale: %s : %s\n", curLoc, myErrorName(err));
928             return;
929         }
930
931         uld = ulocdata_open(curLoc, &err);
932
933         /*now that we have some collators, we get several strings */
934
935         for(y = 0; y < 5; y++){
936
937             /* get a set of ALL the characters in this locale */
938             eSet =  ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &err);
939             eSize = uset_size(eSet);
940
941             /* make a string with these characters in it */
942             strSize = (rand()%40) + 1;
943
944             for(z = 0; z < strSize; z++){
945                 str[z] = uset_charAt(eSet, rand()%eSize);
946             }
947
948             /* change the set to only include 'abnormal' characters (not A-Z, a-z, 0-9 */
949             uset_removeAll(eSet, stdSet);
950             eSize = uset_size(eSet);
951
952             /* if there are some non-normal characters left, put a few into the string, just to make sure we have some */
953             if(eSize > 0){
954                 str[2%strSize] = uset_charAt(eSet, rand()%eSize);
955                 str[3%strSize] = uset_charAt(eSet, rand()%eSize);
956                 str[5%strSize] = uset_charAt(eSet, rand()%eSize);
957                 str[10%strSize] = uset_charAt(eSet, rand()%eSize);
958                 str[13%strSize] = uset_charAt(eSet, rand()%eSize);
959             }
960             /* terminate the string */
961             str[strSize-1] = '\0';
962             log_verbose("String used: %S\n", str);
963
964             /* get sort keys for both of them, and check that the keys are identicle */
965             sortKeyLen1 = ucol_getSortKey(c1, str, u_strlen(str),  NULL, 0);
966             sortKey1 = (uint8_t*)malloc(sizeof(uint8_t) * (sortKeyLen1 + 1));
967             /*memset(sortKey1, 0xFE, sortKeyLen1);*/
968             ucol_getSortKey(c1, str, u_strlen(str), sortKey1, sortKeyLen1 + 1);
969
970             sortKeyLen2 = ucol_getSortKey(c2, str, u_strlen(str),  NULL, 0);
971             sortKey2 = (uint8_t*)malloc(sizeof(uint8_t) * (sortKeyLen2 + 1));
972             /*memset(sortKey2, 0xFE, sortKeyLen2);*/
973             ucol_getSortKey(c2, str, u_strlen(str), sortKey2, sortKeyLen2 + 1);
974
975             /* Check that the lengths are the same */
976             doAssert((sortKeyLen1 == sortKeyLen2), "Sort key lengths do not match.");
977
978             /* check that the keys are the same */
979             doAssert((memcmp(sortKey1, sortKey2, sortKeyLen1) == 0), "Keys are not equivalent");
980
981             /* clean up after each string */
982             free(sortKey1);
983             free(sortKey2);
984             uset_close(eSet);
985         }
986         /* clean up after each locale */
987         ulocdata_close(uld);
988         ucol_close(c1);
989         ucol_close(c2);
990     }
991     /* final clean up */
992     uset_close(stdSet);
993 }
994 /*
995 ----------------------------------------------------------------------------
996  ctor -- Tests the getSortKey
997 */
998 void TestSortKey()
999 {
1000     uint8_t *sortk1 = NULL, *sortk2 = NULL, *sortk3 = NULL, *sortkEmpty = NULL;
1001     int32_t sortklen, osortklen;
1002     uint32_t toStringLen=0;
1003     UCollator *col;
1004     UChar *test1, *test2, *test3;
1005     UErrorCode status = U_ZERO_ERROR;
1006     char toStringBuffer[256], *resultP;
1007
1008
1009     uint8_t s1[] = { 0x9f, 0x00 };
1010     uint8_t s2[] = { 0x61, 0x00 };
1011     int  strcmpResult;
1012
1013     strcmpResult = strcmp((const char *)s1, (const char *)s2);
1014     log_verbose("strcmp(0x9f..., 0x61...) = %d\n", strcmpResult);
1015
1016     if(strcmpResult <= 0) {
1017       log_err("ERR: expected strcmp(\"9f 00\", \"61 00\") to be >=0 (GREATER).. got %d. Calling strcmp() for sortkeys may not work! \n",
1018               strcmpResult);
1019     }
1020
1021
1022     log_verbose("testing SortKey begins...\n");
1023     /* this is supposed to open default date format, but later on it treats it like it is "en_US"
1024        - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
1025     /* col = ucol_open(NULL, &status); */
1026     col = ucol_open("en_US", &status);
1027     if (U_FAILURE(status)) {
1028         log_err_status(status, "ERROR: Default collation creation failed.: %s\n", myErrorName(status));
1029         return;
1030     }
1031
1032
1033     if(ucol_getStrength(col) != UCOL_DEFAULT_STRENGTH)
1034     {
1035         log_err("ERROR: default collation did not have UCOL_DEFAULT_STRENGTH !\n");
1036     }
1037     /* Need to use identical strength */
1038     ucol_setAttribute(col, UCOL_STRENGTH, UCOL_IDENTICAL, &status);
1039
1040     test1=(UChar*)malloc(sizeof(UChar) * 6);
1041     test2=(UChar*)malloc(sizeof(UChar) * 6);
1042     test3=(UChar*)malloc(sizeof(UChar) * 6);
1043
1044     memset(test1,0xFE, sizeof(UChar)*6);
1045     memset(test2,0xFE, sizeof(UChar)*6);
1046     memset(test3,0xFE, sizeof(UChar)*6);
1047
1048
1049     u_uastrcpy(test1, "Abcda");
1050     u_uastrcpy(test2, "abcda");
1051     u_uastrcpy(test3, "abcda");
1052
1053     log_verbose("Use tertiary comparison level testing ....\n");
1054
1055     sortklen=ucol_getSortKey(col, test1, u_strlen(test1),  NULL, 0);
1056     sortk1=(uint8_t*)malloc(sizeof(uint8_t) * (sortklen+1));
1057     memset(sortk1,0xFE, sortklen);
1058     ucol_getSortKey(col, test1, u_strlen(test1), sortk1, sortklen+1);
1059
1060     sortklen=ucol_getSortKey(col, test2, u_strlen(test2),  NULL, 0);
1061     sortk2=(uint8_t*)malloc(sizeof(uint8_t) * (sortklen+1));
1062     memset(sortk2,0xFE, sortklen);
1063     ucol_getSortKey(col, test2, u_strlen(test2), sortk2, sortklen+1);
1064
1065     osortklen = sortklen;
1066     sortklen=ucol_getSortKey(col, test2, u_strlen(test3),  NULL, 0);
1067     sortk3=(uint8_t*)malloc(sizeof(uint8_t) * (sortklen+1));
1068     memset(sortk3,0xFE, sortklen);
1069     ucol_getSortKey(col, test2, u_strlen(test2), sortk3, sortklen+1);
1070
1071     doAssert( (sortklen == osortklen), "Sortkey length should be the same (abcda, abcda)");
1072
1073     doAssert( (memcmp(sortk1, sortk2, sortklen) > 0), "Result should be \"Abcda\" > \"abcda\"");
1074     doAssert( (memcmp(sortk2, sortk1, sortklen) < 0), "Result should be \"abcda\" < \"Abcda\"");
1075     doAssert( (memcmp(sortk2, sortk3, sortklen) == 0), "Result should be \"abcda\" ==  \"abcda\"");
1076
1077     resultP = ucol_sortKeyToString(col, sortk3, toStringBuffer, &toStringLen);
1078     doAssert( (resultP != 0), "sortKeyToString failed!");
1079
1080 #if 1 /* verobse log of sortkeys */
1081     {
1082       char junk2[1000];
1083       char junk3[1000];
1084       int i;
1085
1086       strcpy(junk2, "abcda[2] ");
1087       strcpy(junk3, " abcda[3] ");
1088
1089       for(i=0;i<sortklen;i++)
1090         {
1091           sprintf(junk2+strlen(junk2), "%02X ",(int)( 0xFF & sortk2[i]));
1092           sprintf(junk3+strlen(junk3), "%02X ",(int)( 0xFF & sortk3[i]));
1093         }
1094
1095       log_verbose("%s\n", junk2);
1096       log_verbose("%s\n", junk3);
1097     }
1098 #endif
1099
1100     free(sortk1);
1101     free(sortk2);
1102     free(sortk3);
1103
1104     log_verbose("Use secondary comparision level testing ...\n");
1105     ucol_setStrength(col, UCOL_SECONDARY);
1106     sortklen=ucol_getSortKey(col, test1, u_strlen(test1),  NULL, 0);
1107     sortk1=(uint8_t*)malloc(sizeof(uint8_t) * (sortklen+1));
1108     ucol_getSortKey(col, test1, u_strlen(test1), sortk1, sortklen+1);
1109     sortklen=ucol_getSortKey(col, test2, u_strlen(test2),  NULL, 0);
1110     sortk2=(uint8_t*)malloc(sizeof(uint8_t) * (sortklen+1));
1111     ucol_getSortKey(col, test2, u_strlen(test2), sortk2, sortklen+1);
1112
1113     doAssert( !(memcmp(sortk1, sortk2, sortklen) > 0), "Result should be \"Abcda\" == \"abcda\"");
1114     doAssert( !(memcmp(sortk2, sortk1, sortklen) < 0), "Result should be \"abcda\" == \"Abcda\"");
1115     doAssert( (memcmp(sortk1, sortk2, sortklen) == 0), "Result should be \"abcda\" ==  \"abcda\"");
1116
1117     log_verbose("getting sortkey for an empty string\n");
1118     ucol_setAttribute(col, UCOL_STRENGTH, UCOL_TERTIARY, &status);
1119     sortklen = ucol_getSortKey(col, test1, 0, NULL, 0);
1120     sortkEmpty = (uint8_t*)malloc(sizeof(uint8_t) * sortklen+1);
1121     sortklen = ucol_getSortKey(col, test1, 0, sortkEmpty, sortklen+1);
1122     if(sortklen != 3 || sortkEmpty[0] != 1 || sortkEmpty[0] != 1 || sortkEmpty[2] != 0) {
1123       log_err("Empty string generated wrong sortkey!\n");
1124     }
1125     free(sortkEmpty);
1126
1127     log_verbose("testing passing invalid string\n");
1128     sortklen = ucol_getSortKey(col, NULL, 0, NULL, 0);
1129     if(sortklen != 0) {
1130       log_err("Invalid string didn't return sortkey size of 0\n");
1131     }
1132
1133
1134     log_verbose("testing sortkey ends...\n");
1135     ucol_close(col);
1136     free(test1);
1137     free(test2);
1138     free(test3);
1139     free(sortk1);
1140     free(sortk2);
1141
1142 }
1143 void TestHashCode()
1144 {
1145     uint8_t *sortk1, *sortk2, *sortk3;
1146     int32_t sortk1len, sortk2len, sortk3len;
1147     UCollator *col;
1148     UChar *test1, *test2, *test3;
1149     UErrorCode status = U_ZERO_ERROR;
1150     log_verbose("testing getHashCode begins...\n");
1151     col = ucol_open("en_US", &status);
1152     if (U_FAILURE(status)) {
1153         log_err_status(status, "ERROR: Default collation creation failed.: %s\n", myErrorName(status));
1154         return;
1155     }
1156     test1=(UChar*)malloc(sizeof(UChar) * 6);
1157     test2=(UChar*)malloc(sizeof(UChar) * 6);
1158     test3=(UChar*)malloc(sizeof(UChar) * 6);
1159     u_uastrcpy(test1, "Abcda");
1160     u_uastrcpy(test2, "abcda");
1161     u_uastrcpy(test3, "abcda");
1162
1163     log_verbose("Use tertiary comparison level testing ....\n");
1164     sortk1len=ucol_getSortKey(col, test1, u_strlen(test1),  NULL, 0);
1165     sortk1=(uint8_t*)malloc(sizeof(uint8_t) * (sortk1len+1));
1166     ucol_getSortKey(col, test1, u_strlen(test1), sortk1, sortk1len+1);
1167     sortk2len=ucol_getSortKey(col, test2, u_strlen(test2),  NULL, 0);
1168     sortk2=(uint8_t*)malloc(sizeof(uint8_t) * (sortk2len+1));
1169     ucol_getSortKey(col, test2, u_strlen(test2), sortk2, sortk2len+1);
1170     sortk3len=ucol_getSortKey(col, test2, u_strlen(test3),  NULL, 0);
1171     sortk3=(uint8_t*)malloc(sizeof(uint8_t) * (sortk3len+1));
1172     ucol_getSortKey(col, test2, u_strlen(test2), sortk3, sortk3len+1);
1173
1174
1175     log_verbose("ucol_hashCode() testing ...\n");
1176
1177     doAssert( ucol_keyHashCode(sortk1, sortk1len) != ucol_keyHashCode(sortk2, sortk2len), "Hash test1 result incorrect" );
1178     doAssert( !(ucol_keyHashCode(sortk1, sortk1len) == ucol_keyHashCode(sortk2, sortk2len)), "Hash test2 result incorrect" );
1179     doAssert( ucol_keyHashCode(sortk2, sortk2len) == ucol_keyHashCode(sortk3, sortk3len), "Hash result not equal" );
1180
1181     log_verbose("hashCode tests end.\n");
1182     ucol_close(col);
1183     free(sortk1);
1184     free(sortk2);
1185     free(sortk3);
1186     free(test1);
1187     free(test2);
1188     free(test3);
1189
1190
1191 }
1192 /*
1193  *----------------------------------------------------------------------------
1194  * Tests the UCollatorElements API.
1195  *
1196  */
1197 void TestElemIter()
1198 {
1199     int32_t offset;
1200     int32_t order1, order2, order3;
1201     UChar *testString1, *testString2;
1202     UCollator *col;
1203     UCollationElements *iterator1, *iterator2, *iterator3;
1204     UErrorCode status = U_ZERO_ERROR;
1205     log_verbose("testing UCollatorElements begins...\n");
1206     col = ucol_open("en_US", &status);
1207     ucol_setAttribute(col, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
1208     if (U_FAILURE(status)) {
1209         log_err_status(status, "ERROR: Default collation creation failed.: %s\n", myErrorName(status));
1210         return;
1211     }
1212
1213     testString1=(UChar*)malloc(sizeof(UChar) * 150);
1214     testString2=(UChar*)malloc(sizeof(UChar) * 150);
1215     u_uastrcpy(testString1, "XFILE What subset of all possible test cases has the highest probability of detecting the most errors?");
1216     u_uastrcpy(testString2, "Xf_ile What subset of all possible test cases has the lowest probability of detecting the least errors?");
1217
1218     log_verbose("Constructors and comparison testing....\n");
1219
1220     iterator1 = ucol_openElements(col, testString1, u_strlen(testString1), &status);
1221     if(U_FAILURE(status)) {
1222         log_err("ERROR: Default collationElement iterator creation failed.: %s\n", myErrorName(status));
1223         ucol_close(col);
1224         return;
1225     }
1226     else{ log_verbose("PASS: Default collationElement iterator1 creation passed\n");}
1227
1228     iterator2 = ucol_openElements(col, testString1, u_strlen(testString1), &status);
1229     if(U_FAILURE(status)) {
1230         log_err("ERROR: Default collationElement iterator creation failed.: %s\n", myErrorName(status));
1231         ucol_close(col);
1232         return;
1233     }
1234     else{ log_verbose("PASS: Default collationElement iterator2 creation passed\n");}
1235
1236     iterator3 = ucol_openElements(col, testString2, u_strlen(testString2), &status);
1237     if(U_FAILURE(status)) {
1238         log_err("ERROR: Default collationElement iterator creation failed.: %s\n", myErrorName(status));
1239         ucol_close(col);
1240         return;
1241     }
1242     else{ log_verbose("PASS: Default collationElement iterator3 creation passed\n");}
1243
1244     offset=ucol_getOffset(iterator1);
1245     ucol_setOffset(iterator1, 6, &status);
1246     if (U_FAILURE(status)) {
1247         log_err("Error in setOffset for UCollatorElements iterator.: %s\n", myErrorName(status));
1248         return;
1249     }
1250     if(ucol_getOffset(iterator1)==6)
1251         log_verbose("setOffset and getOffset working fine\n");
1252     else{
1253         log_err("error in set and get Offset got %d instead of 6\n", ucol_getOffset(iterator1));
1254     }
1255
1256     ucol_setOffset(iterator1, 0, &status);
1257     order1 = ucol_next(iterator1, &status);
1258     if (U_FAILURE(status)) {
1259         log_err("Somehow ran out of memory stepping through the iterator1.: %s\n", myErrorName(status));
1260         return;
1261     }
1262     order2=ucol_getOffset(iterator2);
1263     doAssert((order1 != order2), "The first iterator advance failed");
1264     order2 = ucol_next(iterator2, &status);
1265     if (U_FAILURE(status)) {
1266         log_err("Somehow ran out of memory stepping through the iterator2.: %s\n", myErrorName(status));
1267         return;
1268     }
1269     order3 = ucol_next(iterator3, &status);
1270     if (U_FAILURE(status)) {
1271         log_err("Somehow ran out of memory stepping through the iterator3.: %s\n", myErrorName(status));
1272         return;
1273     }
1274
1275     doAssert((order1 == order2), "The second iterator advance failed should be the same as first one");
1276
1277 doAssert( (ucol_primaryOrder(order1) == ucol_primaryOrder(order3)), "The primary orders should be identical");
1278 doAssert( (ucol_secondaryOrder(order1) == ucol_secondaryOrder(order3)), "The secondary orders should be identical");
1279 doAssert( (ucol_tertiaryOrder(order1) == ucol_tertiaryOrder(order3)), "The tertiary orders should be identical");
1280
1281     order1=ucol_next(iterator1, &status);
1282     if (U_FAILURE(status)) {
1283         log_err("Somehow ran out of memory stepping through the iterator2.: %s\n", myErrorName(status));
1284         return;
1285     }
1286     order3=ucol_next(iterator3, &status);
1287     if (U_FAILURE(status)) {
1288         log_err("Somehow ran out of memory stepping through the iterator2.: %s\n", myErrorName(status));
1289         return;
1290     }
1291 doAssert( (ucol_primaryOrder(order1) == ucol_primaryOrder(order3)), "The primary orders should be identical");
1292 doAssert( (ucol_tertiaryOrder(order1) != ucol_tertiaryOrder(order3)), "The tertiary orders should be different");
1293
1294     order1=ucol_next(iterator1, &status);
1295     if (U_FAILURE(status)) {
1296         log_err("Somehow ran out of memory stepping through the iterator2.: %s\n", myErrorName(status));
1297         return;
1298     }
1299     order3=ucol_next(iterator3, &status);
1300     if (U_FAILURE(status)) {
1301         log_err("Somehow ran out of memory stepping through the iterator2.: %s\n", myErrorName(status));
1302         return;
1303     }
1304     /* this here, my friends, is either pure lunacy or something so obsolete that even it's mother
1305      * doesn't care about it. Essentialy, this test complains if secondary values for 'I' and '_'
1306      * are the same. According to the UCA, this is not true. Therefore, remove the test.
1307      * Besides, if primary strengths for two code points are different, it doesn't matter one bit
1308      * what is the relation between secondary or any other strengths.
1309      * killed by weiv 06/11/2002.
1310      */
1311     /*
1312     doAssert( ((order1 & UCOL_SECONDARYMASK) != (order3 & UCOL_SECONDARYMASK)), "The secondary orders should be different");
1313     */
1314     doAssert( (order1 != UCOL_NULLORDER), "Unexpected end of iterator reached");
1315
1316     free(testString1);
1317     free(testString2);
1318     ucol_closeElements(iterator1);
1319     ucol_closeElements(iterator2);
1320     ucol_closeElements(iterator3);
1321     ucol_close(col);
1322
1323     log_verbose("testing CollationElementIterator ends...\n");
1324 }
1325
1326 void TestGetLocale() {
1327   UErrorCode status = U_ZERO_ERROR;
1328   const char *rules = "&a<x<y<z";
1329   UChar rlz[256] = {0};
1330   uint32_t rlzLen = u_unescape(rules, rlz, 256);
1331
1332   UCollator *coll = NULL;
1333   const char *locale = NULL;
1334
1335   int32_t i = 0;
1336
1337   /* Now that the collation tree is separate, actual==valid at all times. [alan] */
1338   static const struct {
1339     const char* requestedLocale;
1340     const char* validLocale;
1341     const char* actualLocale;
1342   } testStruct[] = {
1343     { "sr_RS", "sr_Cyrl_RS", "sr" },
1344     { "sh_YU", "sr_Latn_RS", "hr" }, /* this used to be sh, but now sh collation aliases hr */
1345     { "en_BE_FOO", "en_BE", "root" },
1346     { "de_DE_NONEXISTANT", "de_DE", "de" }
1347   };
1348
1349   /* test opening collators for different locales */
1350   for(i = 0; i<sizeof(testStruct)/sizeof(testStruct[0]); i++) {
1351     status = U_ZERO_ERROR;
1352     coll = ucol_open(testStruct[i].requestedLocale, &status);
1353     if(U_FAILURE(status)) {
1354       log_err_status(status, "Failed to open collator for %s with %s\n", testStruct[i].requestedLocale, u_errorName(status));
1355       ucol_close(coll);
1356       continue;
1357     }
1358    locale = ucol_getLocaleByType(coll, ULOC_REQUESTED_LOCALE, &status);
1359     if(strcmp(locale, testStruct[i].requestedLocale) != 0) {
1360       log_err("[Coll %s]: Error in requested locale, expected %s, got %s\n", testStruct[i].requestedLocale, testStruct[i].requestedLocale, locale);
1361     }
1362     locale = ucol_getLocaleByType(coll, ULOC_VALID_LOCALE, &status);
1363     if(strcmp(locale, testStruct[i].validLocale) != 0) {
1364       log_err("[Coll %s]: Error in valid locale, expected %s, got %s\n", testStruct[i].requestedLocale, testStruct[i].validLocale, locale);
1365     }
1366     locale = ucol_getLocaleByType(coll, ULOC_ACTUAL_LOCALE, &status);
1367     if(strcmp(locale, testStruct[i].actualLocale) != 0) {
1368       log_err("[Coll %s]: Error in actual locale, expected %s, got %s\n", testStruct[i].requestedLocale, testStruct[i].actualLocale, locale);
1369     }
1370     ucol_close(coll);
1371   }
1372
1373   /* completely non-existant locale for collator should get a default collator */
1374   {
1375     UCollator *defaultColl = ucol_open(NULL, &status);
1376     coll = ucol_open("blahaha", &status);
1377     if(U_SUCCESS(status)) {
1378       if(strcmp(ucol_getLocaleByType(coll, ULOC_REQUESTED_LOCALE, &status), "blahaha")) {
1379         log_err("Nonexisting locale didn't preserve the requested locale\n");
1380       }
1381       if(strcmp(ucol_getLocaleByType(coll, ULOC_VALID_LOCALE, &status),
1382         ucol_getLocaleByType(defaultColl, ULOC_VALID_LOCALE, &status))) {
1383         log_err("Valid locale for nonexisting locale locale collator differs "
1384           "from valid locale for default collator\n");
1385       }
1386       if(strcmp(ucol_getLocaleByType(coll, ULOC_ACTUAL_LOCALE, &status),
1387         ucol_getLocaleByType(defaultColl, ULOC_ACTUAL_LOCALE, &status))) {
1388         log_err("Actual locale for nonexisting locale locale collator differs "
1389           "from actual locale for default collator\n");
1390       }
1391       ucol_close(coll);
1392       ucol_close(defaultColl);
1393     } else {
1394       log_data_err("Couldn't open collators\n");
1395     }
1396   }
1397
1398
1399
1400   /* collator instantiated from rules should have all three locales NULL */
1401   coll = ucol_openRules(rlz, rlzLen, UCOL_DEFAULT, UCOL_DEFAULT, NULL, &status);
1402   locale = ucol_getLocaleByType(coll, ULOC_REQUESTED_LOCALE, &status);
1403   if(locale != NULL) {
1404     log_err("For collator instantiated from rules, requested locale returned %s instead of NULL\n", locale);
1405   }
1406   locale = ucol_getLocaleByType(coll, ULOC_VALID_LOCALE, &status);
1407   if(locale != NULL) {
1408     log_err("For collator instantiated from rules,  valid locale returned %s instead of NULL\n", locale);
1409   }
1410   locale = ucol_getLocaleByType(coll, ULOC_ACTUAL_LOCALE, &status);
1411   if(locale != NULL) {
1412     log_err("For collator instantiated from rules, actual locale returned %s instead of NULL\n", locale);
1413   }
1414   ucol_close(coll);
1415
1416 }
1417
1418
1419 void TestGetAll()
1420 {
1421     int32_t i, count;
1422     count=ucol_countAvailable();
1423     /* use something sensible w/o hardcoding the count */
1424     if(count < 0){
1425         log_err("Error in countAvailable(), it returned %d\n", count);
1426     }
1427     else{
1428         log_verbose("PASS: countAvailable() successful, it returned %d\n", count);
1429     }
1430     for(i=0;i<count;i++)
1431         log_verbose("%s\n", ucol_getAvailable(i));
1432
1433
1434 }
1435
1436
1437 struct teststruct {
1438     const char *original;
1439     uint8_t key[256];
1440 } ;
1441
1442 static int compare_teststruct(const void *string1, const void *string2) {
1443     return(strcmp((const char *)((struct teststruct *)string1)->key, (const char *)((struct teststruct *)string2)->key));
1444 }
1445
1446 void TestBounds() {
1447     UErrorCode status = U_ZERO_ERROR;
1448
1449     UCollator *coll = ucol_open("sh", &status);
1450
1451     uint8_t sortkey[512], lower[512], upper[512];
1452     UChar buffer[512];
1453
1454     static const char * const test[] = {
1455         "John Smith",
1456         "JOHN SMITH",
1457         "john SMITH",
1458         "j\\u00F6hn sm\\u00EFth",
1459         "J\\u00F6hn Sm\\u00EFth",
1460         "J\\u00D6HN SM\\u00CFTH",
1461         "john smithsonian",
1462         "John Smithsonian",
1463     };
1464
1465     struct teststruct tests[] = {
1466         {"\\u010CAKI MIHALJ" } ,
1467         {"\\u010CAKI MIHALJ" } ,
1468         {"\\u010CAKI PIRO\\u0160KA" },
1469         {"\\u010CABAI ANDRIJA" } ,
1470         {"\\u010CABAI LAJO\\u0160" } ,
1471         {"\\u010CABAI MARIJA" } ,
1472         {"\\u010CABAI STEVAN" } ,
1473         {"\\u010CABAI STEVAN" } ,
1474         {"\\u010CABARKAPA BRANKO" } ,
1475         {"\\u010CABARKAPA MILENKO" } ,
1476         {"\\u010CABARKAPA MIROSLAV" } ,
1477         {"\\u010CABARKAPA SIMO" } ,
1478         {"\\u010CABARKAPA STANKO" } ,
1479         {"\\u010CABARKAPA TAMARA" } ,
1480         {"\\u010CABARKAPA TOMA\\u0160" } ,
1481         {"\\u010CABDARI\\u0106 NIKOLA" } ,
1482         {"\\u010CABDARI\\u0106 ZORICA" } ,
1483         {"\\u010CABI NANDOR" } ,
1484         {"\\u010CABOVI\\u0106 MILAN" } ,
1485         {"\\u010CABRADI AGNEZIJA" } ,
1486         {"\\u010CABRADI IVAN" } ,
1487         {"\\u010CABRADI JELENA" } ,
1488         {"\\u010CABRADI LJUBICA" } ,
1489         {"\\u010CABRADI STEVAN" } ,
1490         {"\\u010CABRDA MARTIN" } ,
1491         {"\\u010CABRILO BOGDAN" } ,
1492         {"\\u010CABRILO BRANISLAV" } ,
1493         {"\\u010CABRILO LAZAR" } ,
1494         {"\\u010CABRILO LJUBICA" } ,
1495         {"\\u010CABRILO SPASOJA" } ,
1496         {"\\u010CADE\\u0160 ZDENKA" } ,
1497         {"\\u010CADESKI BLAGOJE" } ,
1498         {"\\u010CADOVSKI VLADIMIR" } ,
1499         {"\\u010CAGLJEVI\\u0106 TOMA" } ,
1500         {"\\u010CAGOROVI\\u0106 VLADIMIR" } ,
1501         {"\\u010CAJA VANKA" } ,
1502         {"\\u010CAJI\\u0106 BOGOLJUB" } ,
1503         {"\\u010CAJI\\u0106 BORISLAV" } ,
1504         {"\\u010CAJI\\u0106 RADOSLAV" } ,
1505         {"\\u010CAK\\u0160IRAN MILADIN" } ,
1506         {"\\u010CAKAN EUGEN" } ,
1507         {"\\u010CAKAN EVGENIJE" } ,
1508         {"\\u010CAKAN IVAN" } ,
1509         {"\\u010CAKAN JULIJAN" } ,
1510         {"\\u010CAKAN MIHAJLO" } ,
1511         {"\\u010CAKAN STEVAN" } ,
1512         {"\\u010CAKAN VLADIMIR" } ,
1513         {"\\u010CAKAN VLADIMIR" } ,
1514         {"\\u010CAKAN VLADIMIR" } ,
1515         {"\\u010CAKARA ANA" } ,
1516         {"\\u010CAKAREVI\\u0106 MOMIR" } ,
1517         {"\\u010CAKAREVI\\u0106 NEDELJKO" } ,
1518         {"\\u010CAKI \\u0160ANDOR" } ,
1519         {"\\u010CAKI AMALIJA" } ,
1520         {"\\u010CAKI ANDRA\\u0160" } ,
1521         {"\\u010CAKI LADISLAV" } ,
1522         {"\\u010CAKI LAJO\\u0160" } ,
1523         {"\\u010CAKI LASLO" } ,
1524     };
1525
1526
1527
1528     int32_t i = 0, j = 0, k = 0, buffSize = 0, skSize = 0, lowerSize = 0, upperSize = 0;
1529     int32_t arraySize = sizeof(tests)/sizeof(tests[0]);
1530
1531     if(U_SUCCESS(status) && coll) {
1532         for(i = 0; i<arraySize; i++) {
1533             buffSize = u_unescape(tests[i].original, buffer, 512);
1534             skSize = ucol_getSortKey(coll, buffer, buffSize, tests[i].key, 512);
1535         }
1536
1537         qsort(tests, arraySize, sizeof(struct teststruct), compare_teststruct);
1538
1539         for(i = 0; i < arraySize-1; i++) {
1540             for(j = i+1; j < arraySize; j++) {
1541                 lowerSize = ucol_getBound(tests[i].key, -1, UCOL_BOUND_LOWER, 1, lower, 512, &status);
1542                 upperSize = ucol_getBound(tests[j].key, -1, UCOL_BOUND_UPPER, 1, upper, 512, &status);
1543                 for(k = i; k <= j; k++) {
1544                     if(strcmp((const char *)lower, (const char *)tests[k].key) > 0) {
1545                         log_err("Problem with lower! j = %i (%s vs %s)\n", k, tests[k].original, tests[i].original);
1546                     }
1547                     if(strcmp((const char *)upper, (const char *)tests[k].key) <= 0) {
1548                         log_err("Problem with upper! j = %i (%s vs %s)\n", k, tests[k].original, tests[j].original);
1549                     }
1550                 }
1551             }
1552         }
1553
1554
1555 #if 0
1556         for(i = 0; i < 1000; i++) {
1557             lowerRND = (rand()/(RAND_MAX/arraySize));
1558             upperRND = lowerRND + (rand()/(RAND_MAX/(arraySize-lowerRND)));
1559
1560             lowerSize = ucol_getBound(tests[lowerRND].key, -1, UCOL_BOUND_LOWER, 1, lower, 512, &status);
1561             upperSize = ucol_getBound(tests[upperRND].key, -1, UCOL_BOUND_UPPER_LONG, 1, upper, 512, &status);
1562
1563             for(j = lowerRND; j<=upperRND; j++) {
1564                 if(strcmp(lower, tests[j].key) > 0) {
1565                     log_err("Problem with lower! j = %i (%s vs %s)\n", j, tests[j].original, tests[lowerRND].original);
1566                 }
1567                 if(strcmp(upper, tests[j].key) <= 0) {
1568                     log_err("Problem with upper! j = %i (%s vs %s)\n", j, tests[j].original, tests[upperRND].original);
1569                 }
1570             }
1571         }
1572 #endif
1573
1574
1575
1576
1577
1578         for(i = 0; i<sizeof(test)/sizeof(test[0]); i++) {
1579             buffSize = u_unescape(test[i], buffer, 512);
1580             skSize = ucol_getSortKey(coll, buffer, buffSize, sortkey, 512);
1581             lowerSize = ucol_getBound(sortkey, skSize, UCOL_BOUND_LOWER, 1, lower, 512, &status);
1582             upperSize = ucol_getBound(sortkey, skSize, UCOL_BOUND_UPPER_LONG, 1, upper, 512, &status);
1583             for(j = i+1; j<sizeof(test)/sizeof(test[0]); j++) {
1584                 buffSize = u_unescape(test[j], buffer, 512);
1585                 skSize = ucol_getSortKey(coll, buffer, buffSize, sortkey, 512);
1586                 if(strcmp((const char *)lower, (const char *)sortkey) > 0) {
1587                     log_err("Problem with lower! i = %i, j = %i (%s vs %s)\n", i, j, test[i], test[j]);
1588                 }
1589                 if(strcmp((const char *)upper, (const char *)sortkey) <= 0) {
1590                     log_err("Problem with upper! i = %i, j = %i (%s vs %s)\n", i, j, test[i], test[j]);
1591                 }
1592             }
1593         }
1594         ucol_close(coll);
1595     } else {
1596         log_data_err("Couldn't open collator\n");
1597     }
1598
1599 }
1600
1601 static void doOverrunTest(UCollator *coll, const UChar *uString, int32_t strLen) {
1602     int32_t skLen = 0, skLen2 = 0;
1603     uint8_t sortKey[256];
1604     int32_t i, j;
1605     uint8_t filler = 0xFF;
1606
1607     skLen = ucol_getSortKey(coll, uString, strLen, NULL, 0);
1608
1609     for(i = 0; i < skLen; i++) {
1610         memset(sortKey, filler, 256);
1611         skLen2 = ucol_getSortKey(coll, uString, strLen, sortKey, i);
1612         if(skLen != skLen2) {
1613             log_err("For buffer size %i, got different sortkey length. Expected %i got %i\n", i, skLen, skLen2);
1614         }
1615         for(j = i; j < 256; j++) {
1616             if(sortKey[j] != filler) {
1617                 log_err("Something run over index %i\n", j);
1618                 break;
1619             }
1620         }
1621     }
1622 }
1623
1624 /* j1865 reports that if a shorter buffer is passed to
1625 * to get sort key, a buffer overrun happens in some
1626 * cases. This test tries to check this.
1627 */
1628 void TestSortKeyBufferOverrun(void) {
1629     UErrorCode status = U_ZERO_ERROR;
1630     const char* cString = "A very Merry liTTle-lamB..";
1631     UChar uString[256];
1632     int32_t strLen = 0;
1633     UCollator *coll = ucol_open("root", &status);
1634     strLen = u_unescape(cString, uString, 256);
1635
1636     if(U_SUCCESS(status)) {
1637         log_verbose("testing non ignorable\n");
1638         ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status);
1639         doOverrunTest(coll, uString, strLen);
1640
1641         log_verbose("testing shifted\n");
1642         ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
1643         doOverrunTest(coll, uString, strLen);
1644
1645         log_verbose("testing shifted quaternary\n");
1646         ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_QUATERNARY, &status);
1647         doOverrunTest(coll, uString, strLen);
1648
1649         log_verbose("testing with french secondaries\n");
1650         ucol_setAttribute(coll, UCOL_FRENCH_COLLATION, UCOL_ON, &status);
1651         ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_TERTIARY, &status);
1652         ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status);
1653         doOverrunTest(coll, uString, strLen);
1654
1655     }
1656     ucol_close(coll);
1657 }
1658
1659 static void TestAttribute()
1660 {
1661     UErrorCode error = U_ZERO_ERROR;
1662     UCollator *coll = ucol_open(NULL, &error);
1663
1664     if (U_FAILURE(error)) {
1665         log_err_status(error, "Creation of default collator failed\n");
1666         return;
1667     }
1668
1669     ucol_setAttribute(coll, UCOL_FRENCH_COLLATION, UCOL_OFF, &error);
1670     if (ucol_getAttribute(coll, UCOL_FRENCH_COLLATION, &error) != UCOL_OFF ||
1671         U_FAILURE(error)) {
1672         log_err_status(error, "Setting and retrieving of the french collation failed\n");
1673     }
1674
1675     ucol_setAttribute(coll, UCOL_FRENCH_COLLATION, UCOL_ON, &error);
1676     if (ucol_getAttribute(coll, UCOL_FRENCH_COLLATION, &error) != UCOL_ON ||
1677         U_FAILURE(error)) {
1678         log_err_status(error, "Setting and retrieving of the french collation failed\n");
1679     }
1680
1681     ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &error);
1682     if (ucol_getAttribute(coll, UCOL_ALTERNATE_HANDLING, &error) != UCOL_SHIFTED ||
1683         U_FAILURE(error)) {
1684         log_err_status(error, "Setting and retrieving of the alternate handling failed\n");
1685     }
1686
1687     ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &error);
1688     if (ucol_getAttribute(coll, UCOL_ALTERNATE_HANDLING, &error) != UCOL_NON_IGNORABLE ||
1689         U_FAILURE(error)) {
1690         log_err_status(error, "Setting and retrieving of the alternate handling failed\n");
1691     }
1692
1693     ucol_setAttribute(coll, UCOL_CASE_FIRST, UCOL_LOWER_FIRST, &error);
1694     if (ucol_getAttribute(coll, UCOL_CASE_FIRST, &error) != UCOL_LOWER_FIRST ||
1695         U_FAILURE(error)) {
1696         log_err_status(error, "Setting and retrieving of the case first attribute failed\n");
1697     }
1698
1699     ucol_setAttribute(coll, UCOL_CASE_FIRST, UCOL_UPPER_FIRST, &error);
1700     if (ucol_getAttribute(coll, UCOL_CASE_FIRST, &error) != UCOL_UPPER_FIRST ||
1701         U_FAILURE(error)) {
1702         log_err_status(error, "Setting and retrieving of the case first attribute failed\n");
1703     }
1704
1705     ucol_setAttribute(coll, UCOL_CASE_LEVEL, UCOL_ON, &error);
1706     if (ucol_getAttribute(coll, UCOL_CASE_LEVEL, &error) != UCOL_ON ||
1707         U_FAILURE(error)) {
1708         log_err_status(error, "Setting and retrieving of the case level attribute failed\n");
1709     }
1710
1711     ucol_setAttribute(coll, UCOL_CASE_LEVEL, UCOL_OFF, &error);
1712     if (ucol_getAttribute(coll, UCOL_CASE_LEVEL, &error) != UCOL_OFF ||
1713         U_FAILURE(error)) {
1714         log_err_status(error, "Setting and retrieving of the case level attribute failed\n");
1715     }
1716
1717     ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_ON, &error);
1718     if (ucol_getAttribute(coll, UCOL_NORMALIZATION_MODE, &error) != UCOL_ON ||
1719         U_FAILURE(error)) {
1720         log_err_status(error, "Setting and retrieving of the normalization on/off attribute failed\n");
1721     }
1722
1723     ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_OFF, &error);
1724     if (ucol_getAttribute(coll, UCOL_NORMALIZATION_MODE, &error) != UCOL_OFF ||
1725         U_FAILURE(error)) {
1726         log_err_status(error, "Setting and retrieving of the normalization on/off attribute failed\n");
1727     }
1728
1729     ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_PRIMARY, &error);
1730     if (ucol_getAttribute(coll, UCOL_STRENGTH, &error) != UCOL_PRIMARY ||
1731         U_FAILURE(error)) {
1732         log_err_status(error, "Setting and retrieving of the collation strength failed\n");
1733     }
1734
1735     ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_SECONDARY, &error);
1736     if (ucol_getAttribute(coll, UCOL_STRENGTH, &error) != UCOL_SECONDARY ||
1737         U_FAILURE(error)) {
1738         log_err_status(error, "Setting and retrieving of the collation strength failed\n");
1739     }
1740
1741     ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_TERTIARY, &error);
1742     if (ucol_getAttribute(coll, UCOL_STRENGTH, &error) != UCOL_TERTIARY ||
1743         U_FAILURE(error)) {
1744         log_err_status(error, "Setting and retrieving of the collation strength failed\n");
1745     }
1746
1747     ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_QUATERNARY, &error);
1748     if (ucol_getAttribute(coll, UCOL_STRENGTH, &error) != UCOL_QUATERNARY ||
1749         U_FAILURE(error)) {
1750         log_err_status(error, "Setting and retrieving of the collation strength failed\n");
1751     }
1752
1753     ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_IDENTICAL, &error);
1754     if (ucol_getAttribute(coll, UCOL_STRENGTH, &error) != UCOL_IDENTICAL ||
1755         U_FAILURE(error)) {
1756         log_err_status(error, "Setting and retrieving of the collation strength failed\n");
1757     }
1758
1759     ucol_close(coll);
1760 }
1761
1762 void TestGetTailoredSet() {
1763   struct {
1764     const char *rules;
1765     const char *tests[20];
1766     int32_t testsize;
1767   } setTest[] = {
1768     { "&a < \\u212b", { "\\u212b", "A\\u030a", "\\u00c5" }, 3},
1769     { "& S < \\u0161 <<< \\u0160", { "\\u0161", "s\\u030C", "\\u0160", "S\\u030C" }, 4}
1770   };
1771
1772   int32_t i = 0, j = 0;
1773   UErrorCode status = U_ZERO_ERROR;
1774   UParseError pError;
1775
1776   UCollator *coll = NULL;
1777   UChar buff[1024];
1778   int32_t buffLen = 0;
1779   USet *set = NULL;
1780
1781   for(i = 0; i < sizeof(setTest)/sizeof(setTest[0]); i++) {
1782     buffLen = u_unescape(setTest[i].rules, buff, 1024);
1783     coll = ucol_openRules(buff, buffLen, UCOL_DEFAULT, UCOL_DEFAULT, &pError, &status);
1784     if(U_SUCCESS(status)) {
1785       set = ucol_getTailoredSet(coll, &status);
1786       if(uset_size(set) != setTest[i].testsize) {
1787         log_err("Tailored set size different (%d) than expected (%d)\n", uset_size(set), setTest[i].testsize);
1788       }
1789       for(j = 0; j < setTest[i].testsize; j++) {
1790         buffLen = u_unescape(setTest[i].tests[j], buff, 1024);
1791         if(!uset_containsString(set, buff, buffLen)) {
1792           log_err("Tailored set doesn't contain %s... It should\n", setTest[i].tests[j]);
1793         }
1794       }
1795       uset_close(set);
1796     } else {
1797       log_err_status(status, "Couldn't open collator with rules %s\n", setTest[i].rules);
1798     }
1799     ucol_close(coll);
1800   }
1801 }
1802
1803 static int tMemCmp(const uint8_t *first, const uint8_t *second) {
1804    int32_t firstLen = (int32_t)strlen((const char *)first);
1805    int32_t secondLen = (int32_t)strlen((const char *)second);
1806    return memcmp(first, second, uprv_min(firstLen, secondLen));
1807 }
1808 static const char * strengthsC[] = {
1809      "UCOL_PRIMARY",
1810      "UCOL_SECONDARY",
1811      "UCOL_TERTIARY",
1812      "UCOL_QUATERNARY",
1813      "UCOL_IDENTICAL"
1814 };
1815
1816 void TestMergeSortKeys(void) {
1817    UErrorCode status = U_ZERO_ERROR;
1818    UCollator *coll = ucol_open("en", &status);
1819    if(U_SUCCESS(status)) {
1820
1821      const char* cases[] = {
1822        "abc",
1823          "abcd",
1824          "abcde"
1825      };
1826      uint32_t casesSize = sizeof(cases)/sizeof(cases[0]);
1827      const char* prefix = "foo";
1828      const char* suffix = "egg";
1829      char outBuff1[256], outBuff2[256];
1830
1831      uint8_t **sortkeys = (uint8_t **)malloc(casesSize*sizeof(uint8_t *));
1832      uint8_t **mergedPrefixkeys = (uint8_t **)malloc(casesSize*sizeof(uint8_t *));
1833      uint8_t **mergedSuffixkeys = (uint8_t **)malloc(casesSize*sizeof(uint8_t *));
1834      uint32_t *sortKeysLen = (uint32_t *)malloc(casesSize*sizeof(uint32_t));
1835      uint8_t prefixKey[256], suffixKey[256];
1836      uint32_t prefixKeyLen = 0, suffixKeyLen = 0, i = 0;
1837      UChar buffer[256];
1838      uint32_t unescapedLen = 0, l1 = 0, l2 = 0;
1839      UColAttributeValue strength;
1840
1841      log_verbose("ucol_mergeSortkeys test\n");
1842      log_verbose("Testing order of the test cases\n");
1843      genericLocaleStarter("en", cases, casesSize);
1844
1845      for(i = 0; i<casesSize; i++) {
1846        sortkeys[i] = (uint8_t *)malloc(256*sizeof(uint8_t));
1847        mergedPrefixkeys[i] = (uint8_t *)malloc(256*sizeof(uint8_t));
1848        mergedSuffixkeys[i] = (uint8_t *)malloc(256*sizeof(uint8_t));
1849      }
1850
1851      unescapedLen = u_unescape(prefix, buffer, 256);
1852      prefixKeyLen = ucol_getSortKey(coll, buffer, unescapedLen, prefixKey, 256);
1853
1854      unescapedLen = u_unescape(suffix, buffer, 256);
1855      suffixKeyLen = ucol_getSortKey(coll, buffer, unescapedLen, suffixKey, 256);
1856
1857      log_verbose("Massaging data with prefixes and different strengths\n");
1858      strength = UCOL_PRIMARY;
1859      while(strength <= UCOL_IDENTICAL) {
1860        log_verbose("Strength %s\n", strengthsC[strength<=UCOL_QUATERNARY?strength:4]);
1861        ucol_setAttribute(coll, UCOL_STRENGTH, strength, &status);
1862        for(i = 0; i<casesSize; i++) {
1863          unescapedLen = u_unescape(cases[i], buffer, 256);
1864          sortKeysLen[i] = ucol_getSortKey(coll, buffer, unescapedLen, sortkeys[i], 256);
1865          ucol_mergeSortkeys(prefixKey, prefixKeyLen, sortkeys[i], sortKeysLen[i], mergedPrefixkeys[i], 256);
1866          ucol_mergeSortkeys(sortkeys[i], sortKeysLen[i], suffixKey, suffixKeyLen, mergedSuffixkeys[i], 256);
1867          if(i>0) {
1868            if(tMemCmp(mergedPrefixkeys[i-1], mergedPrefixkeys[i]) >= 0) {
1869              log_err("Error while comparing prefixed keys @ strength %s:\n", strengthsC[strength<=UCOL_QUATERNARY?strength:4]);
1870              log_err("%s\n%s\n",
1871                          ucol_sortKeyToString(coll, mergedPrefixkeys[i-1], outBuff1, &l1),
1872                          ucol_sortKeyToString(coll, mergedPrefixkeys[i], outBuff2, &l2));
1873            }
1874            if(tMemCmp(mergedSuffixkeys[i-1], mergedSuffixkeys[i]) >= 0) {
1875              log_err("Error while comparing suffixed keys @ strength %s:\n", strengthsC[strength<=UCOL_QUATERNARY?strength:4]);
1876              log_err("%s\n%s\n",
1877                          ucol_sortKeyToString(coll, mergedSuffixkeys[i-1], outBuff1, &l1),
1878                          ucol_sortKeyToString(coll, mergedSuffixkeys[i], outBuff2, &l2));
1879            }
1880          }
1881        }
1882        if(strength == UCOL_QUATERNARY) {
1883          strength = UCOL_IDENTICAL;
1884        } else {
1885          strength++;
1886        }
1887      }
1888
1889      {
1890        uint8_t smallBuf[3];
1891        uint32_t reqLen = 0;
1892        log_verbose("testing buffer overflow\n");
1893        reqLen = ucol_mergeSortkeys(prefixKey, prefixKeyLen, suffixKey, suffixKeyLen, smallBuf, 3);
1894        if(reqLen != (prefixKeyLen+suffixKeyLen-1)) {
1895          log_err("Wrong preflight size for merged sortkey\n");
1896        }
1897      }
1898
1899      {
1900        UChar empty = 0;
1901        uint8_t emptyKey[20], abcKey[50], mergedKey[100];
1902        int32_t emptyKeyLen = 0, abcKeyLen = 0, mergedKeyLen = 0;
1903
1904        log_verbose("testing merging with sortkeys generated for empty strings\n");
1905        emptyKeyLen = ucol_getSortKey(coll, &empty, 0, emptyKey, 20);
1906        unescapedLen = u_unescape(cases[0], buffer, 256);
1907        abcKeyLen = ucol_getSortKey(coll, buffer, unescapedLen, abcKey, 50);
1908        mergedKeyLen = ucol_mergeSortkeys(emptyKey, emptyKeyLen, abcKey, abcKeyLen, mergedKey, 100);
1909        if(mergedKey[0] != 2) {
1910          log_err("Empty sortkey didn't produce a level separator\n");
1911        }
1912        /* try with zeros */
1913        mergedKeyLen = ucol_mergeSortkeys(emptyKey, 0, abcKey, abcKeyLen, mergedKey, 100);
1914        if(mergedKeyLen != 0 || mergedKey[0] != 0) {
1915          log_err("Empty key didn't produce null mergedKey\n");
1916        }
1917        mergedKeyLen = ucol_mergeSortkeys(abcKey, abcKeyLen, emptyKey, 0, mergedKey, 100);
1918        if(mergedKeyLen != 0 || mergedKey[0] != 0) {
1919          log_err("Empty key didn't produce null mergedKey\n");
1920        }
1921
1922      }
1923
1924      for(i = 0; i<casesSize; i++) {
1925        free(sortkeys[i]);
1926        free(mergedPrefixkeys[i]);
1927        free(mergedSuffixkeys[i]);
1928      }
1929      free(sortkeys);
1930      free(mergedPrefixkeys);
1931      free(mergedSuffixkeys);
1932      free(sortKeysLen);
1933      ucol_close(coll);
1934      /* need to finish this up */
1935    } else {
1936      log_data_err("Couldn't open collator");
1937    }
1938 }
1939 static void TestShortString(void)
1940 {
1941     struct {
1942         const char *input;
1943         const char *expectedOutput;
1944         const char *locale;
1945         UErrorCode expectedStatus;
1946         int32_t    expectedOffset;
1947         uint32_t   expectedIdentifier;
1948     } testCases[] = {
1949         /*
1950          * The following expectedOutput contains a collation weight (2700 from UCA 6.0)
1951          * which is the primary weight for the T character (U+0041) in the input.
1952          * When that character gets a different weight in FractionalUCA.txt,
1953          * the expectedOutput needs to be adjusted.
1954          * That is, when we upgrade to a new UCA version or change collation
1955          * in such a way that the absolute weight for 'A' changes,
1956          * we will get a test failure here and need to adjust the test case.
1957          */
1958         {"LDE_RDE_KPHONEBOOK_T0041_ZLATN","B2700_KPHONEBOOK_LDE", "de@collation=phonebook", U_USING_FALLBACK_WARNING, 0, 0 },
1959
1960         {"LEN_RUS_NO_AS_S4","AS_LROOT_NO_S4", NULL, U_USING_DEFAULT_WARNING, 0, 0 },
1961         {"LDE_VPHONEBOOK_EO_SI","EO_KPHONEBOOK_LDE_SI", "de@collation=phonebook", U_ZERO_ERROR, 0, 0 },
1962         {"LDE_Kphonebook","KPHONEBOOK_LDE", "de@collation=phonebook", U_ZERO_ERROR, 0, 0 },
1963         {"Xqde_DE@collation=phonebookq_S3_EX","KPHONEBOOK_LDE", "de@collation=phonebook", U_USING_FALLBACK_WARNING, 0, 0 },
1964         {"LFR_FO", "FO_LROOT", NULL, U_USING_DEFAULT_WARNING, 0, 0 },
1965         {"SO_LX_AS", "", NULL, U_ILLEGAL_ARGUMENT_ERROR, 8, 0 },
1966         {"S3_ASS_MMM", "", NULL, U_ILLEGAL_ARGUMENT_ERROR, 5, 0 }
1967     };
1968
1969     int32_t i = 0;
1970     UCollator *coll = NULL, *fromNormalized = NULL;
1971     UParseError parseError;
1972     UErrorCode status = U_ZERO_ERROR;
1973     char fromShortBuffer[256], normalizedBuffer[256], fromNormalizedBuffer[256];
1974     const char* locale = NULL;
1975
1976
1977     for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) {
1978         status = U_ZERO_ERROR;
1979         if(testCases[i].locale) {
1980             locale = testCases[i].locale;
1981         } else {
1982             locale = NULL;
1983         }
1984
1985         coll = ucol_openFromShortString(testCases[i].input, FALSE, &parseError, &status);
1986         if(status != testCases[i].expectedStatus) {
1987             log_err_status(status, "Got status '%s' that is different from expected '%s' for '%s'\n",
1988                 u_errorName(status), u_errorName(testCases[i].expectedStatus), testCases[i].input);
1989             continue;
1990         }
1991
1992         if(U_SUCCESS(status)) {
1993             ucol_getShortDefinitionString(coll, locale, fromShortBuffer, 256, &status);
1994
1995             if(strcmp(fromShortBuffer, testCases[i].expectedOutput)) {
1996                 log_err("Got short string '%s' from the collator. Expected '%s' for input '%s'\n",
1997                     fromShortBuffer, testCases[i].expectedOutput, testCases[i].input);
1998             }
1999
2000             ucol_normalizeShortDefinitionString(testCases[i].input, normalizedBuffer, 256, &parseError, &status);
2001             fromNormalized = ucol_openFromShortString(normalizedBuffer, FALSE, &parseError, &status);
2002             ucol_getShortDefinitionString(fromNormalized, locale, fromNormalizedBuffer, 256, &status);
2003
2004             if(strcmp(fromShortBuffer, fromNormalizedBuffer)) {
2005                 log_err("Strings obtained from collators instantiated by short string ('%s') and from normalized string ('%s') differ\n",
2006                     fromShortBuffer, fromNormalizedBuffer);
2007             }
2008
2009
2010             if(!ucol_equals(coll, fromNormalized)) {
2011                 log_err("Collator from short string ('%s') differs from one obtained through a normalized version ('%s')\n",
2012                     testCases[i].input, normalizedBuffer);
2013             }
2014
2015             ucol_close(fromNormalized);
2016             ucol_close(coll);
2017
2018         } else {
2019             if(parseError.offset != testCases[i].expectedOffset) {
2020                 log_err("Got parse error offset %i, but expected %i instead for '%s'\n",
2021                     parseError.offset, testCases[i].expectedOffset, testCases[i].input);
2022             }
2023         }
2024     }
2025
2026 }
2027
2028 static void
2029 doSetsTest(const char *locale, const USet *ref, USet *set, const char* inSet, const char* outSet, UErrorCode *status) {
2030     UChar buffer[512];
2031     int32_t bufLen;
2032
2033     uset_clear(set);
2034     bufLen = u_unescape(inSet, buffer, 512);
2035     uset_applyPattern(set, buffer, bufLen, 0, status);
2036     if(U_FAILURE(*status)) {
2037         log_err("%s: Failure setting pattern %s\n", locale, u_errorName(*status));
2038     }
2039
2040     if(!uset_containsAll(ref, set)) {
2041         log_err("%s: Some stuff from %s is not present in the set\n", locale, inSet);
2042     }
2043
2044     uset_clear(set);
2045     bufLen = u_unescape(outSet, buffer, 512);
2046     uset_applyPattern(set, buffer, bufLen, 0, status);
2047     if(U_FAILURE(*status)) {
2048         log_err("%s: Failure setting pattern %s\n", locale, u_errorName(*status));
2049     }
2050
2051     if(!uset_containsNone(ref, set)) {
2052         log_err("%s: Some stuff from %s is present in the set\n", locale, outSet);
2053     }
2054 }
2055
2056
2057
2058
2059 static void
2060 TestGetContractionsAndUnsafes(void)
2061 {
2062     static struct {
2063         const char* locale;
2064         const char* inConts;
2065         const char* outConts;
2066         const char* inExp;
2067         const char* outExp;
2068         const char* unsafeCodeUnits;
2069         const char* safeCodeUnits;
2070     } tests[] = {
2071         { "ru",
2072             "[{\\u0418\\u0306}{\\u0438\\u0306}]",
2073             "[\\u0439\\u0457]",
2074             "[\\u00e6]",
2075             "[ae]",
2076             "[\\u0418\\u0438]",
2077             "[aAbB\\u0430\\u0410\\u0433\\u0413]"
2078         },
2079         { "uk",
2080             "[{\\u0406\\u0308}{\\u0456\\u0308}{\\u0418\\u0306}{\\u0438\\u0306}]",
2081             "[\\u0407\\u0419\\u0439\\u0457]",
2082             "[\\u00e6]",
2083             "[ae]",
2084             "[\\u0406\\u0456\\u0418\\u0438]",
2085             "[aAbBxv]",
2086         },
2087         { "sh",
2088             "[{C\\u0301}{C\\u030C}{C\\u0341}{DZ\\u030C}{Dz\\u030C}{D\\u017D}{D\\u017E}{lj}{nj}]",
2089             "[{\\u309d\\u3099}{\\u30fd\\u3099}]",
2090             "[\\u00e6]",
2091             "[a]",
2092             "[nlcdzNLCDZ]",
2093             "[jabv]"
2094         },
2095         { "ja",
2096           "[{\\u3053\\u3099\\u309D}{\\u3053\\u3099\\u309D\\u3099}{\\u3053\\u3099\\u309E}{\\u3053\\u3099\\u30FC}{\\u3053\\u309D}{\\u3053\\u309D\\u3099}{\\u3053\\u309E}{\\u3053\\u30FC}{\\u30B3\\u3099\\u30FC}{\\u30B3\\u3099\\u30FD}{\\u30B3\\u3099\\u30FD\\u3099}{\\u30B3\\u3099\\u30FE}{\\u30B3\\u30FC}{\\u30B3\\u30FD}{\\u30B3\\u30FD\\u3099}{\\u30B3\\u30FE}]",
2097           "[{\\u30FD\\u3099}{\\u309D\\u3099}{\\u3053\\u3099}{\\u30B3\\u3099}{lj}{nj}]",
2098             "[\\u30FE\\u00e6]",
2099             "[a]",
2100             "[\\u3099]",
2101             "[]"
2102         }
2103     };
2104
2105
2106
2107
2108     UErrorCode status = U_ZERO_ERROR;
2109     UCollator *coll = NULL;
2110     int32_t i = 0;
2111     int32_t noConts = 0;
2112     USet *conts = uset_open(0,0);
2113     USet *exp = uset_open(0, 0);
2114     USet *set  = uset_open(0,0);
2115     int32_t setBufferLen = 65536;
2116     UChar buffer[65536];
2117     int32_t setLen = 0;
2118
2119     for(i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
2120         log_verbose("Testing locale: %s\n", tests[i].locale);
2121         coll = ucol_open(tests[i].locale, &status);
2122         if (coll == NULL || U_FAILURE(status)) {
2123             log_err_status(status, "Unable to open collator for locale %s ==> %s\n", tests[i].locale, u_errorName(status));
2124             continue;
2125         }
2126         ucol_getContractionsAndExpansions(coll, conts, exp, TRUE, &status);
2127         doSetsTest(tests[i].locale, conts, set, tests[i].inConts, tests[i].outConts, &status);
2128         setLen = uset_toPattern(conts, buffer, setBufferLen, TRUE, &status);
2129         if(U_SUCCESS(status)) {
2130             /*log_verbose("Contractions %i: %s\n", uset_getItemCount(conts), aescstrdup(buffer, setLen));*/
2131         } else {
2132             log_err("error %s. %i\n", u_errorName(status), setLen);
2133             status = U_ZERO_ERROR;
2134         }
2135         doSetsTest(tests[i].locale, exp, set, tests[i].inExp, tests[i].outExp, &status);
2136         setLen = uset_toPattern(exp, buffer, setBufferLen, TRUE, &status);
2137         if(U_SUCCESS(status)) {
2138             /*log_verbose("Expansions %i: %s\n", uset_getItemCount(exp), aescstrdup(buffer, setLen));*/
2139         } else {
2140             log_err("error %s. %i\n", u_errorName(status), setLen);
2141             status = U_ZERO_ERROR;
2142         }
2143
2144         noConts = ucol_getUnsafeSet(coll, conts, &status);
2145         doSetsTest(tests[i].locale, conts, set, tests[i].unsafeCodeUnits, tests[i].safeCodeUnits, &status);
2146         setLen = uset_toPattern(conts, buffer, setBufferLen, TRUE, &status);
2147         if(U_SUCCESS(status)) {
2148             log_verbose("Unsafe %i: %s\n", uset_getItemCount(exp), aescstrdup(buffer, setLen));
2149         } else {
2150             log_err("error %s. %i\n", u_errorName(status), setLen);
2151             status = U_ZERO_ERROR;
2152         }
2153
2154         ucol_close(coll);
2155     }
2156
2157
2158     uset_close(conts);
2159     uset_close(exp);
2160     uset_close(set);
2161 }
2162
2163 static void
2164 TestOpenBinary(void)
2165 {
2166     UErrorCode status = U_ZERO_ERROR;
2167     /*
2168     char rule[] = "&h < d < c < b";
2169     char *wUCA[] = { "a", "h", "d", "c", "b", "i" };
2170     char *noUCA[] = {"d", "c", "b", "a", "h", "i" };
2171     */
2172     /* we have to use Cyrillic letters because latin-1 always gets copied */
2173     const char rule[] = "&\\u0452 < \\u0434 < \\u0433 < \\u0432"; /* &dje < d < g < v */
2174     const char *wUCA[] = { "\\u0430", "\\u0452", "\\u0434", "\\u0433", "\\u0432", "\\u0435" }; /* a, dje, d, g, v, e */
2175     const char *noUCA[] = {"\\u0434", "\\u0433", "\\u0432", "\\u0430", "\\u0435", "\\u0452" }; /* d, g, v, a, e, dje */
2176
2177     UChar uRules[256];
2178     int32_t uRulesLen = u_unescape(rule, uRules, 256);
2179
2180     UCollator *coll = ucol_openRules(uRules, uRulesLen, UCOL_DEFAULT, UCOL_DEFAULT, NULL, &status);
2181     UCollator *UCA = NULL;
2182     UCollator *cloneNOUCA = NULL, *cloneWUCA = NULL;
2183
2184     uint8_t imageBuffer[32768];
2185     uint8_t *image = imageBuffer;
2186     int32_t imageBufferCapacity = 32768;
2187
2188     int32_t imageSize;
2189
2190     if((coll==NULL)||(U_FAILURE(status))) {
2191         log_data_err("could not load collators or error occured: %s\n",
2192             u_errorName(status));
2193         return;
2194     }
2195     UCA = ucol_open("root", &status);
2196     if((UCA==NULL)||(U_FAILURE(status))) {
2197         log_data_err("could not load UCA collator or error occured: %s\n",
2198             u_errorName(status));
2199         return;
2200     }
2201     imageSize = ucol_cloneBinary(coll, image, imageBufferCapacity, &status);
2202     if(U_FAILURE(status)) {
2203         image = (uint8_t *)malloc(imageSize*sizeof(uint8_t));
2204         status = U_ZERO_ERROR;
2205         imageSize = ucol_cloneBinary(coll, imageBuffer, imageSize, &status);
2206     }
2207
2208
2209     cloneWUCA = ucol_openBinary(image, imageSize, UCA, &status);
2210     cloneNOUCA = ucol_openBinary(image, imageSize, NULL, &status);
2211
2212     genericOrderingTest(coll, wUCA, sizeof(wUCA)/sizeof(wUCA[0]));
2213
2214     genericOrderingTest(cloneWUCA, wUCA, sizeof(wUCA)/sizeof(wUCA[0]));
2215     genericOrderingTest(cloneNOUCA, noUCA, sizeof(noUCA)/sizeof(noUCA[0]));
2216
2217     if(image != imageBuffer) {
2218         free(image);
2219     }
2220     ucol_close(coll);
2221     ucol_close(cloneNOUCA);
2222     ucol_close(cloneWUCA);
2223     ucol_close(UCA);
2224 }
2225
2226 static void TestDefault(void) {
2227     /* Tests for code coverage. */
2228     UErrorCode status = U_ZERO_ERROR;
2229     UCollator *coll = ucol_open("es@collation=pinyin", &status);
2230     if (coll == NULL || status == U_FILE_ACCESS_ERROR) {
2231         log_data_err("Unable to open collator es@collation=pinyin\n");
2232         return;
2233     }
2234     if (status != U_USING_DEFAULT_WARNING) {
2235         /* What do you mean that you know about using pinyin collation in Spanish!? This should be in the zh locale. */
2236         log_err("es@collation=pinyin should return U_USING_DEFAULT_WARNING, but returned %s\n", u_errorName(status));
2237     }
2238     ucol_close(coll);
2239     if (ucol_getKeywordValues("funky", &status) != NULL) {
2240         log_err("Collators should not know about the funky keyword.\n");
2241     }
2242     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
2243         log_err("funky keyword didn't fail as expected %s\n", u_errorName(status));
2244     }
2245     if (ucol_getKeywordValues("collation", &status) != NULL) {
2246         log_err("ucol_getKeywordValues should not work when given a bad status.\n");
2247     }
2248 }
2249
2250 static void TestDefaultKeyword(void) {
2251     /* Tests for code coverage. */
2252     UErrorCode status = U_ZERO_ERROR;
2253     const char *loc = "zh_TW@collation=default";
2254     UCollator *coll = ucol_open(loc, &status);
2255     if(U_FAILURE(status)) {
2256         log_info("Warning: ucol_open(%s, ...) returned %s, at least it didn't crash.\n", loc, u_errorName(status));
2257     } else if (status != U_USING_FALLBACK_WARNING) {
2258         /* Hmm, skip the following test for CLDR 1.9 data and/or ICU 4.6, no longer seems to apply */
2259         #if 0
2260         log_err("ucol_open(%s, ...) should return an error or some sort of U_USING_FALLBACK_WARNING, but returned %s\n", loc, u_errorName(status));
2261         #endif
2262     }
2263     ucol_close(coll);
2264 }
2265
2266 static void TestGetKeywordValuesForLocale(void) {
2267 #define INCLUDE_UNIHAN_COLLATION 0
2268 #define PREFERRED_SIZE 16
2269 #define MAX_NUMBER_OF_KEYWORDS 8
2270     const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS+1] = {
2271             { "und",            "standard", "ducet", "search", NULL, NULL, NULL, NULL, NULL },
2272             { "en_US",          "standard", "ducet", "search", NULL, NULL, NULL, NULL, NULL },
2273             { "en_029",         "standard", "ducet", "search", NULL, NULL, NULL, NULL, NULL },
2274             { "de_DE",          "standard", "phonebook", "search", "ducet", NULL, NULL, NULL, NULL },
2275             { "de_Latn_DE",     "standard", "phonebook", "search", "ducet", NULL, NULL, NULL, NULL },
2276 #if INCLUDE_UNIHAN_COLLATION
2277             { "zh",             "pinyin", "big5han", "gb2312han", "standard", "stroke", "unihan", "ducet", "search" },
2278             { "zh_Hans",        "pinyin", "big5han", "gb2312han", "standard", "stroke", "unihan", "ducet", "search" },
2279             { "zh_CN",          "pinyin", "big5han", "gb2312han", "standard", "stroke", "unihan", "ducet", "search" },
2280             { "zh_Hant",        "stroke", "big5han", "gb2312han", "pinyin", "standard", "unihan", "ducet", "search" },
2281             { "zh_TW",          "stroke", "big5han", "gb2312han", "pinyin", "standard", "unihan", "ducet", "search" },
2282             { "zh__PINYIN",     "pinyin", "big5han", "gb2312han", "standard", "stroke", "unihan", "ducet", "search" },
2283 #else
2284             { "zh",             "pinyin", "big5han", "gb2312han", "standard", "stroke", "ducet", "search", NULL },
2285             { "zh_Hans",        "pinyin", "big5han", "gb2312han", "standard", "stroke", "ducet", "search", NULL },
2286             { "zh_CN",          "pinyin", "big5han", "gb2312han", "standard", "stroke", "ducet", "search", NULL },
2287             { "zh_Hant",        "stroke", "big5han", "gb2312han", "pinyin", "standard", "ducet", "search", NULL },
2288             { "zh_TW",          "stroke", "big5han", "gb2312han", "pinyin", "standard", "ducet", "search", NULL },
2289             { "zh__PINYIN",     "pinyin", "big5han", "gb2312han", "standard", "stroke", "ducet", "search", NULL },
2290 #endif
2291             { "es_ES",          "standard", "search", "traditional", "ducet", NULL, NULL, NULL, NULL },
2292             { "es__TRADITIONAL","traditional", "search", "standard", "ducet", NULL, NULL, NULL, NULL },
2293             { "und@collation=phonebook",    "standard", "ducet", "search", NULL, NULL, NULL, NULL, NULL },
2294             { "de_DE@collation=big5han",    "standard", "phonebook", "search", "ducet", NULL, NULL, NULL, NULL },
2295             { "zzz@collation=xxx",          "standard", "ducet", "search", NULL, NULL, NULL, NULL, NULL }
2296     };
2297 #if INCLUDE_UNIHAN_COLLATION
2298     const int32_t expectedLength[PREFERRED_SIZE] = { 3, 3, 3, 4, 4, 8, 8, 8, 8, 8, 8, 4, 4, 3, 4, 3 };
2299 #else
2300     const int32_t expectedLength[PREFERRED_SIZE] = { 3, 3, 3, 4, 4, 7, 7, 7, 7, 7, 7, 4, 4, 3, 4, 3 };
2301 #endif
2302
2303     UErrorCode status = U_ZERO_ERROR;
2304     UEnumeration *keywordValues = NULL;
2305     int32_t i, n, size, valueLength;
2306     const char *locale = NULL, *value = NULL;
2307     UBool errorOccurred = FALSE;
2308
2309     for (i = 0; i < PREFERRED_SIZE; i++) {
2310         locale = PREFERRED[i][0];
2311         value = NULL;
2312         valueLength = 0;
2313         size = 0;
2314
2315         keywordValues = ucol_getKeywordValuesForLocale("collation", locale, TRUE, &status);
2316         if (keywordValues == NULL || U_FAILURE(status)) {
2317             log_err_status(status, "Error getting keyword values: %s\n", u_errorName(status));
2318             break;
2319         }
2320         size = uenum_count(keywordValues, &status);
2321
2322         if (size == expectedLength[i]) {
2323             for (n = 0; n < expectedLength[i]; n++) {
2324                 if ((value = uenum_next(keywordValues, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
2325                     if (uprv_strcmp(value, PREFERRED[i][n+1]) != 0) {
2326                         log_err("Keyword values differ: Got [%s] Expected [%s] for locale: %s\n", value, PREFERRED[i][n+1], locale);
2327                         errorOccurred = TRUE;
2328                         break;
2329                     }
2330
2331                 } else {
2332                     log_err("While getting keyword value from locale: %s got this error: %s\n", locale, u_errorName(status));
2333                     errorOccurred = TRUE;
2334                     break;
2335                 }
2336             }
2337             if (errorOccurred) {
2338                 break;
2339             }
2340         } else {
2341             log_err("Number of keywords (%d) does not match expected size (%d) for locale: %s\n", size, expectedLength[i], locale);
2342             break;
2343         }
2344         uenum_close(keywordValues);
2345         keywordValues = NULL;
2346     }
2347     if (keywordValues != NULL) {
2348         uenum_close(keywordValues);
2349     }
2350 }
2351
2352
2353 #endif /* #if !UCONFIG_NO_COLLATION */