]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/cintltst/callcoll.c
ICU-8.11.tar.gz
[apple/icu.git] / icuSources / test / cintltst / callcoll.c
CommitLineData
b75a7d8f
A
1/********************************************************************
2 * COPYRIGHT:
73c04bcf 3 * Copyright (c) 1997-2006, International Business Machines Corporation and
b75a7d8f
A
4 * others. All Rights Reserved.
5 ********************************************************************/
6/********************************************************************************
7*
8* File CALLCOLL.C
9*
10* Modification History:
11* Name Description
12* Madhu Katragadda Ported for C API
13*********************************************************************************
14*/
15
16/*
17 * Important: This file is included into intltest/allcoll.cpp so that the
18 * test data is shared. This makes it easier to maintain the test data,
19 * especially since the Unicode data must be portable and quoted character
20 * literals will not work.
21 * If it is included, then there will be a #define INCLUDE_CALLCOLL_C
22 * that must prevent the actual code in here from being part of the
23 * allcoll.cpp compilation.
24 */
25
26/**
27 * CollationDummyTest is a third level test class. This tests creation of
28 * a customized collator object. For example, number 1 to be sorted
29 * equlivalent to word 'one'.
30 */
31
32#include <string.h>
33#include <stdlib.h>
34
35#include "unicode/utypes.h"
36
37#if !UCONFIG_NO_COLLATION
38
39#include "unicode/ucol.h"
40#include "unicode/uloc.h"
41#include "unicode/ucoleitr.h"
42#include "unicode/ustring.h"
374ca955
A
43#include "unicode/uclean.h"
44#include "unicode/putil.h"
b75a7d8f
A
45
46#include "cintltst.h"
47#include "ccolltst.h"
48#include "callcoll.h"
49#include "calldata.h"
50#include "cstring.h"
51#include "cmemory.h"
52#include "ucol_imp.h"
53
54/* perform test with strength PRIMARY */
55static void TestPrimary(void);
56
57/* perform test with strength SECONDARY */
58static void TestSecondary(void);
59
60/* perform test with strength tertiary */
61static void TestTertiary(void);
62
63/*perform tests with strength Identical */
64static void TestIdentical(void);
65
66/* perform extra tests */
67static void TestExtra(void);
68
69/* Test jitterbug 581 */
70static void TestJB581(void);
71
72/* Test jitterbug 1401 */
73static void TestJB1401(void);
74
75/* Test [variable top] in the rule syntax */
76static void TestVariableTop(void);
77
78/* Test surrogates */
79static void TestSurrogates(void);
80
81static void TestInvalidRules(void);
82
83static void TestJitterbug1098(void);
84
374ca955
A
85static void TestFCDCrash(void);
86
b75a7d8f
A
87const UCollationResult results[] = {
88 UCOL_LESS,
89 UCOL_LESS, /*UCOL_GREATER,*/
90 UCOL_LESS,
91 UCOL_LESS,
92 UCOL_LESS,
93 UCOL_LESS,
94 UCOL_LESS,
95 UCOL_GREATER,
96 UCOL_GREATER,
97 UCOL_LESS, /* 10 */
98 UCOL_GREATER,
99 UCOL_LESS,
100 UCOL_GREATER,
101 UCOL_GREATER,
102 UCOL_LESS,
103 UCOL_LESS,
104 UCOL_LESS,
105 /* test primary > 17 */
106 UCOL_EQUAL,
107 UCOL_EQUAL,
108 UCOL_EQUAL, /* 20 */
109 UCOL_LESS,
110 UCOL_LESS,
111 UCOL_EQUAL,
112 UCOL_EQUAL,
113 UCOL_EQUAL,
114 UCOL_LESS,
115 /* test secondary > 26 */
116 UCOL_EQUAL,
117 UCOL_EQUAL,
118 UCOL_EQUAL,
119 UCOL_EQUAL,
120 UCOL_EQUAL, /* 30 */
121 UCOL_EQUAL,
122 UCOL_LESS,
123 UCOL_EQUAL, /* 34 */
124 UCOL_EQUAL,
125 UCOL_EQUAL,
126 UCOL_LESS /* 37 */
127};
128
129
73c04bcf
A
130static
131void uprv_appendByteToHexString(char *dst, uint8_t val) {
132 uint32_t len = (uint32_t)uprv_strlen(dst);
133 *(dst+len) = T_CString_itosOffset((val >> 4));
134 *(dst+len+1) = T_CString_itosOffset((val & 0xF));
135 *(dst+len+2) = 0;
136}
137
138/* this function makes a string with representation of a sortkey */
139static char* U_EXPORT2 sortKeyToString(const UCollator *coll, const uint8_t *sortkey, char *buffer, uint32_t *len) {
140 int32_t strength = UCOL_PRIMARY;
141 uint32_t res_size = 0;
142 UBool doneCase = FALSE;
143
144 char *current = buffer;
145 const uint8_t *currentSk = sortkey;
146
147 uprv_strcpy(current, "[");
148
149 while(strength <= UCOL_QUATERNARY && strength <= coll->strength) {
150 if(strength > UCOL_PRIMARY) {
151 uprv_strcat(current, " . ");
152 }
153 while(*currentSk != 0x01 && *currentSk != 0x00) { /* print a level */
154 uprv_appendByteToHexString(current, *currentSk++);
155 uprv_strcat(current, " ");
156 }
157 if(coll->caseLevel == UCOL_ON && strength == UCOL_SECONDARY && doneCase == FALSE) {
158 doneCase = TRUE;
159 } else if(coll->caseLevel == UCOL_OFF || doneCase == TRUE || strength != UCOL_SECONDARY) {
160 strength ++;
161 }
162 uprv_appendByteToHexString(current, *currentSk++); /* This should print '01' */
163 if(strength == UCOL_QUATERNARY && coll->alternateHandling == UCOL_NON_IGNORABLE) {
164 break;
165 }
166 }
167
168 if(coll->strength == UCOL_IDENTICAL) {
169 uprv_strcat(current, " . ");
170 while(*currentSk != 0) {
171 uprv_appendByteToHexString(current, *currentSk++);
172 uprv_strcat(current, " ");
173 }
174
175 uprv_appendByteToHexString(current, *currentSk++);
176 }
177 uprv_strcat(current, "]");
178
179 if(res_size > *len) {
180 return NULL;
181 }
182
183 return buffer;
184}
185
b75a7d8f
A
186void addAllCollTest(TestNode** root)
187{
188
189
190 addTest(root, &TestPrimary, "tscoll/callcoll/TestPrimary");
191 addTest(root, &TestSecondary, "tscoll/callcoll/TestSecondary");
192 addTest(root, &TestTertiary, "tscoll/callcoll/TestTertiary");
193 addTest(root, &TestIdentical, "tscoll/callcoll/TestIdentical");
194 addTest(root, &TestExtra, "tscoll/callcoll/TestExtra");
195 addTest(root, &TestJB581, "tscoll/callcoll/TestJB581");
196 addTest(root, &TestVariableTop, "tscoll/callcoll/TestVariableTop");
197 addTest(root, &TestSurrogates, "tscoll/callcoll/TestSurrogates");
198 addTest(root, &TestInvalidRules, "tscoll/callcoll/TestInvalidRules");
199 addTest(root, &TestJB1401, "tscoll/callcoll/TestJB1401");
374ca955
A
200 addTest(root, &TestJitterbug1098, "tscoll/callcoll/TestJitterbug1098");
201 addTest(root, &TestFCDCrash, "tscoll/callcoll/TestFCDCrash");
b75a7d8f
A
202
203 }
204
374ca955
A
205UBool hasCollationElements(const char *locName) {
206
207 UErrorCode status = U_ZERO_ERROR;
208 UResourceBundle *ColEl = NULL;
209
210 UResourceBundle *loc = ures_open(NULL, locName, &status);;
211
212 if(U_SUCCESS(status)) {
213 status = U_ZERO_ERROR;
214 ColEl = ures_getByKey(loc, "collations", ColEl, &status);
215 if(status == U_ZERO_ERROR) { /* do the test - there are real elements */
216 ures_close(ColEl);
217 ures_close(loc);
218 return TRUE;
219 }
220 ures_close(ColEl);
221 ures_close(loc);
222 }
223 return FALSE;
224}
225
b75a7d8f
A
226static UCollationResult compareUsingPartials(UCollator *coll, const UChar source[], int32_t sLen, const UChar target[], int32_t tLen, int32_t pieceSize, UErrorCode *status) {
227 int32_t partialSKResult = 0;
228 UCharIterator sIter, tIter;
229 uint32_t sState[2], tState[2];
230 int32_t sSize = pieceSize, tSize = pieceSize;
374ca955 231 /*int32_t i = 0;*/
b75a7d8f
A
232 uint8_t sBuf[16384], tBuf[16384];
233 if(pieceSize > 16384) {
234 log_err("Partial sortkey size buffer too small. Please consider increasing the buffer!\n");
235 *status = U_BUFFER_OVERFLOW_ERROR;
236 return UCOL_EQUAL;
237 }
238 *status = U_ZERO_ERROR;
239 sState[0] = 0; sState[1] = 0;
240 tState[0] = 0; tState[1] = 0;
241 while(sSize == pieceSize && tSize == pieceSize && partialSKResult == 0) {
242 uiter_setString(&sIter, source, sLen);
243 uiter_setString(&tIter, target, tLen);
244 sSize = ucol_nextSortKeyPart(coll, &sIter, sState, sBuf, pieceSize, status);
245 tSize = ucol_nextSortKeyPart(coll, &tIter, tState, tBuf, pieceSize, status);
246
247 if(sState[0] != 0 || tState[0] != 0) {
374ca955 248 /*log_verbose("State != 0 : %08X %08X\n", sState[0], tState[0]);*/
b75a7d8f 249 }
374ca955 250 /*log_verbose("%i ", i++);*/
b75a7d8f
A
251
252 partialSKResult = memcmp(sBuf, tBuf, pieceSize);
253 }
254
255 if(partialSKResult < 0) {
256 return UCOL_LESS;
257 } else if(partialSKResult > 0) {
258 return UCOL_GREATER;
259 } else {
260 return UCOL_EQUAL;
261 }
262}
263
264static void doTestVariant(UCollator* myCollation, const UChar source[], const UChar target[], UCollationResult result)
265{
266 int32_t sortklen1, sortklen2, sortklenmax, sortklenmin;
267 int temp=0, gSortklen1=0,gSortklen2=0;
268 UCollationResult compareResult, compareResulta, keyResult, compareResultIter = result;
269 uint8_t *sortKey1, *sortKey2, *sortKey1a, *sortKey2a;
270 uint32_t sLen = u_strlen(source);
271 uint32_t tLen = u_strlen(target);
272 char buffer[256];
273 uint32_t len;
274 UErrorCode status = U_ZERO_ERROR;
275 UColAttributeValue norm = ucol_getAttribute(myCollation, UCOL_NORMALIZATION_MODE, &status);
276
277 UCharIterator sIter, tIter;
278 uiter_setString(&sIter, source, sLen);
279 uiter_setString(&tIter, target, tLen);
280 compareResultIter = ucol_strcollIter(myCollation, &sIter, &tIter, &status);
281 if(compareResultIter != result) {
282 log_err("different results in iterative comparison for UTF-16 encoded strings. %s, %s\n", aescstrdup(source,-1), aescstrdup(target,-1));
283 }
284
285 /* convert the strings to UTF-8 and do try comparing with char iterator */
286 if(QUICK <= 0) { /*!QUICK*/
287 char utf8Source[256], utf8Target[256];
288 int32_t utf8SourceLen = 0, utf8TargetLen = 0;
289 u_strToUTF8(utf8Source, 256, &utf8SourceLen, source, sLen, &status);
290 if(U_FAILURE(status)) { /* probably buffer is not big enough */
291 log_verbose("Src UTF-8 buffer too small! Will not compare!\n");
292 } else {
293 u_strToUTF8(utf8Target, 256, &utf8TargetLen, target, tLen, &status);
294 if(U_SUCCESS(status)) { /* probably buffer is not big enough */
295 UCollationResult compareResultUTF8 = result, compareResultUTF8Norm = result;
296 /*UCharIterator sIter, tIter;*/
297 /*log_verbose("Strings converted to UTF-8:%s, %s\n", aescstrdup(source,-1), aescstrdup(target,-1));*/
298 uiter_setUTF8(&sIter, utf8Source, utf8SourceLen);
299 uiter_setUTF8(&tIter, utf8Target, utf8TargetLen);
300 /*uiter_setString(&sIter, source, sLen);
301 uiter_setString(&tIter, target, tLen);*/
302 compareResultUTF8 = ucol_strcollIter(myCollation, &sIter, &tIter, &status);
303 ucol_setAttribute(myCollation, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
304 sIter.move(&sIter, 0, UITER_START);
305 tIter.move(&tIter, 0, UITER_START);
306 compareResultUTF8Norm = ucol_strcollIter(myCollation, &sIter, &tIter, &status);
307 ucol_setAttribute(myCollation, UCOL_NORMALIZATION_MODE, norm, &status);
308 if(compareResultUTF8 != compareResultIter) {
309 log_err("different results in iterative comparison for UTF-16 and UTF-8 encoded strings. %s, %s\n", aescstrdup(source,-1), aescstrdup(target,-1));
310 }
311 if(compareResultUTF8 != compareResultUTF8Norm) {
312 log_err("different results in iterative when normalization is turned on with UTF-8 strings. %s, %s\n", aescstrdup(source,-1), aescstrdup(target,-1));
313 }
314 } else {
315 log_verbose("Target UTF-8 buffer too small! Did not compare!\n");
316 }
317 if(U_FAILURE(status)) {
318 log_verbose("UTF-8 strcoll failed! Ignoring result\n");
319 }
320 }
321 }
322
323 /* testing the partial sortkeys */
324 if(1) { /*!QUICK*/
325 int32_t i = 0;
326 int32_t partialSizes[] = { 3, 1, 2, 4, 8, 20, 80 }; /* just size 3 in the quick mode */
327 int32_t partialSizesSize = 1;
328 if(QUICK <= 0) {
329 partialSizesSize = 7;
330 }
374ca955 331 /*log_verbose("partial sortkey test piecesize=");*/
b75a7d8f
A
332 for(i = 0; i < partialSizesSize; i++) {
333 UCollationResult partialSKResult = result, partialNormalizedSKResult = result;
374ca955 334 /*log_verbose("%i ", partialSizes[i]);*/
b75a7d8f
A
335
336 partialSKResult = compareUsingPartials(myCollation, source, sLen, target, tLen, partialSizes[i], &status);
337 if(partialSKResult != result) {
73c04bcf
A
338 log_err("Partial sortkey comparison returned wrong result (%i exp. %i): %s, %s (size %i)\n",
339 partialSKResult, result,
b75a7d8f
A
340 aescstrdup(source,-1), aescstrdup(target,-1), partialSizes[i]);
341 }
342
343 if(QUICK <= 0 && norm != UCOL_ON) {
374ca955 344 /*log_verbose("N ");*/
b75a7d8f
A
345 ucol_setAttribute(myCollation, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
346 partialNormalizedSKResult = compareUsingPartials(myCollation, source, sLen, target, tLen, partialSizes[i], &status);
347 ucol_setAttribute(myCollation, UCOL_NORMALIZATION_MODE, norm, &status);
348 if(partialSKResult != partialNormalizedSKResult) {
349 log_err("Partial sortkey comparison gets different result when normalization is on: %s, %s (size %i)\n",
350 aescstrdup(source,-1), aescstrdup(target,-1), partialSizes[i]);
351 }
352 }
353 }
374ca955 354 /*log_verbose("\n");*/
b75a7d8f
A
355 }
356
357
358 compareResult = ucol_strcoll(myCollation, source, sLen, target, tLen);
359 compareResulta = ucol_strcoll(myCollation, source, -1, target, -1);
360 if (compareResult != compareResulta) {
361 log_err("ucol_strcoll result from null terminated and explicit length strings differs.\n");
362 }
363
364 sortklen1=ucol_getSortKey(myCollation, source, sLen, NULL, 0);
365 sortklen2=ucol_getSortKey(myCollation, target, tLen, NULL, 0);
366
367 sortklenmax = (sortklen1>sortklen2?sortklen1:sortklen2);
368 sortklenmin = (sortklen1<sortklen2?sortklen1:sortklen2);
369
370 sortKey1 =(uint8_t*)malloc(sizeof(uint8_t) * (sortklenmax+1));
371 sortKey1a=(uint8_t*)malloc(sizeof(uint8_t) * (sortklenmax+1));
372 ucol_getSortKey(myCollation, source, sLen, sortKey1, sortklen1+1);
373 ucol_getSortKey(myCollation, source, -1, sortKey1a, sortklen1+1);
374
375 sortKey2 =(uint8_t*)malloc(sizeof(uint8_t) * (sortklenmax+1));
376 sortKey2a=(uint8_t*)malloc(sizeof(uint8_t) * (sortklenmax+1));
377 ucol_getSortKey(myCollation, target, tLen, sortKey2, sortklen2+1);
378 ucol_getSortKey(myCollation, target, -1, sortKey2a, sortklen2+1);
379
380 /* Check that sort key generated with null terminated string is identical */
381 /* to that generted with a length specified. */
382 if (uprv_strcmp((const char *)sortKey1, (const char *)sortKey1a) != 0 ||
383 uprv_strcmp((const char *)sortKey2, (const char *)sortKey2a) != 0 ) {
384 log_err("Sort Keys from null terminated and explicit length strings differ.\n");
385 }
386
387 /*memcmp(sortKey1, sortKey2,sortklenmax);*/
388 temp= uprv_strcmp((const char *)sortKey1, (const char *)sortKey2);
389 gSortklen1 = uprv_strlen((const char *)sortKey1)+1;
390 gSortklen2 = uprv_strlen((const char *)sortKey2)+1;
391 if(sortklen1 != gSortklen1){
392 log_err("SortKey length does not match Expected: %i Got: %i\n",sortklen1, gSortklen1);
73c04bcf 393 log_verbose("Generated sortkey: %s\n", sortKeyToString(myCollation, sortKey1, buffer, &len));
b75a7d8f
A
394 }
395 if(sortklen2!= gSortklen2){
396 log_err("SortKey length does not match Expected: %i Got: %i\n", sortklen2, gSortklen2);
73c04bcf 397 log_verbose("Generated sortkey: %s\n", sortKeyToString(myCollation, sortKey2, buffer, &len));
b75a7d8f
A
398 }
399
400 if(temp < 0) {
401 keyResult=UCOL_LESS;
402 }
403 else if(temp > 0) {
404 keyResult= UCOL_GREATER;
405 }
406 else {
407 keyResult = UCOL_EQUAL;
408 }
409 reportCResult( source, target, sortKey1, sortKey2, compareResult, keyResult, compareResultIter, result );
410 free(sortKey1);
411 free(sortKey2);
412 free(sortKey1a);
413 free(sortKey2a);
414
415}
416
417void doTest(UCollator* myCollation, const UChar source[], const UChar target[], UCollationResult result)
418{
419 if(myCollation) {
420 doTestVariant(myCollation, source, target, result);
421 if(result == UCOL_LESS) {
422 doTestVariant(myCollation, target, source, UCOL_GREATER);
423 } else if(result == UCOL_GREATER) {
424 doTestVariant(myCollation, target, source, UCOL_LESS);
425 } else {
426 doTestVariant(myCollation, target, source, UCOL_EQUAL);
427 }
428 } else {
429 log_data_err("No collator! Any data around?\n");
430 }
431}
432
374ca955
A
433
434/**
435 * Return an integer array containing all of the collation orders
436 * returned by calls to next on the specified iterator
437 */
438int32_t* getOrders(UCollationElements *iter, int32_t *orderLength)
439{
440 UErrorCode status;
441 int32_t order;
442 int32_t maxSize = 100;
443 int32_t size = 0;
444 int32_t *temp;
445 int32_t *orders =(int32_t*)malloc(sizeof(int32_t) * maxSize);
446 status= U_ZERO_ERROR;
447
448
449 while ((order=ucol_next(iter, &status)) != UCOL_NULLORDER)
450 {
451 if (size == maxSize)
452 {
453 maxSize *= 2;
454 temp = (int32_t*)malloc(sizeof(int32_t) * maxSize);
455
456 memcpy(temp, orders, size * sizeof(int32_t));
457 free(orders);
458 orders = temp;
459
460 }
461
462 orders[size++] = order;
463 }
464
465 if (maxSize > size && size > 0)
466 {
467 temp = (int32_t*)malloc(sizeof(int32_t) * size);
468
469 memcpy(temp, orders, size * sizeof(int32_t));
470 free(orders);
471 orders = temp;
472
473
474 }
475
476 *orderLength = size;
477 return orders;
478}
479
480
481void
482backAndForth(UCollationElements *iter)
483{
484 /* Run through the iterator forwards and stick it into an array */
485 int32_t index, o;
486 UErrorCode status = U_ZERO_ERROR;
487 int32_t orderLength = 0;
488 int32_t *orders;
489 orders= getOrders(iter, &orderLength);
490
491
492 /* Now go through it backwards and make sure we get the same values */
493 index = orderLength;
494 ucol_reset(iter);
495
496 /* synwee : changed */
497 while ((o = ucol_previous(iter, &status)) != UCOL_NULLORDER)
498 {
499 if (o != orders[-- index])
500 {
501 if (o == 0)
502 index ++;
503 else
504 {
505 while (index > 0 && orders[-- index] == 0)
506 {
507 }
508 if (o != orders[index])
509 {
510 log_err("Mismatch at index : 0x%x\n", index);
511 return;
512 }
513
514 }
515 }
516 }
517
518 while (index != 0 && orders[index - 1] == 0) {
519 index --;
520 }
521
522 if (index != 0)
523 {
524 log_err("Didn't get back to beginning - index is %d\n", index);
525
526 ucol_reset(iter);
527 log_err("\nnext: ");
528 if ((o = ucol_next(iter, &status)) != UCOL_NULLORDER)
529 {
530 log_err("Error at %x\n", o);
531 }
532 log_err("\nprev: ");
533 if ((o = ucol_previous(iter, &status)) != UCOL_NULLORDER)
534 {
535 log_err("Error at %x\n", o);
536 }
537 log_verbose("\n");
538 }
539
540 free(orders);
541}
542
543void genericOrderingTestWithResult(UCollator *coll, const char *s[], uint32_t size, UCollationResult result) {
544 UChar t1[2048] = {0};
545 UChar t2[2048] = {0};
546 UCollationElements *iter;
547 UErrorCode status = U_ZERO_ERROR;
548
549 uint32_t i = 0, j = 0;
550 log_verbose("testing sequence:\n");
551 for(i = 0; i < size; i++) {
552 log_verbose("%s\n", s[i]);
553 }
554
555 iter = ucol_openElements(coll, t1, u_strlen(t1), &status);
556 if (U_FAILURE(status)) {
557 log_err("Creation of iterator failed\n");
558 }
559 for(i = 0; i < size-1; i++) {
560 for(j = i+1; j < size; j++) {
561 u_unescape(s[i], t1, 2048);
562 u_unescape(s[j], t2, 2048);
563 doTest(coll, t1, t2, result);
564 /* synwee : added collation element iterator test */
565 ucol_setText(iter, t1, u_strlen(t1), &status);
566 backAndForth(iter);
567 ucol_setText(iter, t2, u_strlen(t2), &status);
568 backAndForth(iter);
569 }
570 }
571 ucol_closeElements(iter);
572}
573
574void genericOrderingTest(UCollator *coll, const char *s[], uint32_t size) {
575 genericOrderingTestWithResult(coll, s, size, UCOL_LESS);
576}
577
578void genericLocaleStarter(const char *locale, const char *s[], uint32_t size) {
579 UErrorCode status = U_ZERO_ERROR;
580 UCollator *coll = ucol_open(locale, &status);
581
582 log_verbose("Locale starter for %s\n", locale);
583
584 if(U_SUCCESS(status)) {
585 genericOrderingTest(coll, s, size);
586 } else if(status == U_FILE_ACCESS_ERROR) {
587 log_data_err("Is your data around?\n");
588 return;
589 } else {
590 log_err("Unable to open collator for locale %s\n", locale);
591 }
592 ucol_close(coll);
593}
594
595void genericLocaleStarterWithResult(const char *locale, const char *s[], uint32_t size, UCollationResult result) {
596 UErrorCode status = U_ZERO_ERROR;
597 UCollator *coll = ucol_open(locale, &status);
598
599 log_verbose("Locale starter for %s\n", locale);
600
601 if(U_SUCCESS(status)) {
602 genericOrderingTestWithResult(coll, s, size, result);
603 } else if(status == U_FILE_ACCESS_ERROR) {
604 log_data_err("Is your data around?\n");
605 return;
606 } else {
607 log_err("Unable to open collator for locale %s\n", locale);
608 }
609 ucol_close(coll);
610}
611
374ca955 612/* currently not used with options */
73c04bcf 613void genericRulesStarterWithOptionsAndResult(const char *rules, const char *s[], uint32_t size, const UColAttribute *attrs, const UColAttributeValue *values, uint32_t attsize, UCollationResult result) {
374ca955
A
614 UErrorCode status = U_ZERO_ERROR;
615 UChar rlz[RULE_BUFFER_LEN] = { 0 };
616 uint32_t rlen = u_unescape(rules, rlz, RULE_BUFFER_LEN);
617 uint32_t i;
618
619 UCollator *coll = ucol_openRules(rlz, rlen, UCOL_DEFAULT, UCOL_DEFAULT,NULL, &status);
620
621 log_verbose("Rules starter for %s\n", rules);
622
623 if(U_SUCCESS(status)) {
624 log_verbose("Setting attributes\n");
625 for(i = 0; i < attsize; i++) {
626 ucol_setAttribute(coll, attrs[i], values[i], &status);
627 }
628
73c04bcf 629 genericOrderingTestWithResult(coll, s, size, result);
374ca955
A
630 } else {
631 log_err("Unable to open collator with rules %s\n", rules);
632 }
633 ucol_close(coll);
634}
374ca955 635
73c04bcf 636void genericLocaleStarterWithOptionsAndResult(const char *locale, const char *s[], uint32_t size, const UColAttribute *attrs, const UColAttributeValue *values, uint32_t attsize, UCollationResult result) {
374ca955
A
637 UErrorCode status = U_ZERO_ERROR;
638 uint32_t i;
639
640 UCollator *coll = ucol_open(locale, &status);
641
642 log_verbose("Locale starter for %s\n", locale);
643
644 if(U_SUCCESS(status)) {
645
646 log_verbose("Setting attributes\n");
647 for(i = 0; i < attsize; i++) {
648 ucol_setAttribute(coll, attrs[i], values[i], &status);
649 }
650
73c04bcf 651 genericOrderingTestWithResult(coll, s, size, result);
374ca955
A
652 } else {
653 log_err("Unable to open collator for locale %s\n", locale);
654 }
655 ucol_close(coll);
656}
657
73c04bcf
A
658void genericLocaleStarterWithOptions(const char *locale, const char *s[], uint32_t size, const UColAttribute *attrs, const UColAttributeValue *values, uint32_t attsize) {
659 genericLocaleStarterWithOptionsAndResult(locale, s, size, attrs, values, attsize, UCOL_LESS);
660}
661
662void genericRulesStarterWithResult(const char *rules, const char *s[], uint32_t size, UCollationResult result) {
374ca955
A
663 UErrorCode status = U_ZERO_ERROR;
664 UChar rlz[RULE_BUFFER_LEN] = { 0 };
665 uint32_t rlen = u_unescape(rules, rlz, RULE_BUFFER_LEN);
666
667 UCollator *coll = NULL;
668 coll = ucol_openRules(rlz, rlen, UCOL_DEFAULT, UCOL_DEFAULT,NULL, &status);
669 log_verbose("Rules starter for %s\n", rules);
670
671 if(U_SUCCESS(status)) {
672 genericOrderingTestWithResult(coll, s, size, result);
673 ucol_close(coll);
674 } else if(status == U_FILE_ACCESS_ERROR) {
675 log_data_err("Is your data around?\n");
676 } else {
677 log_err("Unable to open collator with rules %s\n", rules);
678 }
679}
680
681void genericRulesStarter(const char *rules, const char *s[], uint32_t size) {
73c04bcf 682 genericRulesStarterWithResult(rules, s, size, UCOL_LESS);
374ca955
A
683}
684
b75a7d8f
A
685static void TestTertiary()
686{
687 int32_t len,i;
688 UChar *rules;
689 UCollator *myCollation;
690 UErrorCode status=U_ZERO_ERROR;
691 const char* str="& C < ch, cH, Ch, CH & Five, 5 & Four, 4 & one, 1 & Ampersand; '&' & Two, 2 ";
692 len = strlen(str);
693 rules=(UChar*)malloc(sizeof(UChar*) * (len+1));
694 u_uastrcpy(rules, str);
695
696 myCollation=ucol_openRules(rules, len, UCOL_OFF, UCOL_DEFAULT_STRENGTH, NULL, &status);
697 if(U_FAILURE(status)){
698 log_err("ERROR: in creation of rule based collator :%s\n", myErrorName(status));
699 }
700
701 ucol_setStrength(myCollation, UCOL_TERTIARY);
702 for (i = 0; i < 17 ; i++)
703 {
704 doTest(myCollation, testSourceCases[i], testTargetCases[i], results[i]);
705 }
706 free(rules);
707 ucol_close(myCollation);
708 myCollation = 0;
709}
710
711static void TestPrimary( )
712{
713 int32_t len,i;
714 UChar *rules;
715 UCollator *myCollation;
716 UErrorCode status=U_ZERO_ERROR;
717 const char* str="& C < ch, cH, Ch, CH & Five, 5 & Four, 4 & one, 1 & Ampersand; '&' & Two, 2 ";
718 len = strlen(str);
719 rules=(UChar*)malloc(sizeof(UChar*) * (len+1));
720 u_uastrcpy(rules, str);
721
722 myCollation=ucol_openRules(rules, len, UCOL_OFF, UCOL_DEFAULT_STRENGTH,NULL, &status);
723 if(U_FAILURE(status)){
724 log_err("ERROR: in creation of rule based collator :%s\n", myErrorName(status));
725 }
726 ucol_setStrength(myCollation, UCOL_PRIMARY);
727
728 for (i = 17; i < 26 ; i++)
729 {
730
731 doTest(myCollation, testSourceCases[i], testTargetCases[i], results[i]);
732 }
733 free(rules);
734 ucol_close(myCollation);
735 myCollation = 0;
736}
737
738static void TestSecondary()
739{
740 int32_t i;
741 int32_t len;
742 UChar *rules;
743 UCollator *myCollation;
744 UErrorCode status=U_ZERO_ERROR;
745 const char* str="& C < ch, cH, Ch, CH & Five, 5 & Four, 4 & one, 1 & Ampersand; '&' & Two, 2 ";
746 len = strlen(str);
747 rules=(UChar*)malloc(sizeof(UChar*) * (len+1));
748 u_uastrcpy(rules, str);
749
750 myCollation=ucol_openRules(rules, len, UCOL_OFF, UCOL_DEFAULT_STRENGTH,NULL, &status);
751 if(U_FAILURE(status)){
752 log_err("ERROR: in creation of rule based collator :%s\n", myErrorName(status));
753 }
754 ucol_setStrength(myCollation, UCOL_SECONDARY);
755 for (i = 26; i < 34 ; i++)
756 {
757 doTest(myCollation, testSourceCases[i], testTargetCases[i], results[i]);
758 }
759 free(rules);
760 ucol_close(myCollation);
761 myCollation = 0;
762}
763
764static void TestIdentical()
765{
766 int32_t i;
767 int32_t len;
768 UChar *rules = 0;
769 UCollator *myCollation;
770 UErrorCode status=U_ZERO_ERROR;
771 const char* str="& C < ch, cH, Ch, CH & Five, 5 & Four, 4 & one, 1 & Ampersand; '&' & Two, 2 ";
772 len = strlen(str);
773 rules=(UChar*)malloc(sizeof(UChar*) * (len+1));
774 u_uastrcpy(rules, str);
775
776 myCollation=ucol_openRules(rules, len, UCOL_OFF, UCOL_IDENTICAL, NULL,&status);
777 if(U_FAILURE(status)){
778 log_err("ERROR: in creation of rule based collator :%s\n", myErrorName(status));
779 }
780 for(i= 34; i<37; i++)
781 {
782 doTest(myCollation, testSourceCases[i], testTargetCases[i], results[i]);
783 }
784 free(rules);
785 ucol_close(myCollation);
786 myCollation = 0;
787}
788
789static void TestExtra()
790{
791 int32_t i, j;
792 int32_t len;
793 UChar *rules;
794 UCollator *myCollation;
795 UErrorCode status = U_ZERO_ERROR;
796 const char* str="& C < ch, cH, Ch, CH & Five, 5 & Four, 4 & one, 1 & Ampersand; '&' & Two, 2 ";
797 len = strlen(str);
798 rules=(UChar*)malloc(sizeof(UChar*) * (len+1));
799 u_uastrcpy(rules, str);
800
801 myCollation=ucol_openRules(rules, len, UCOL_OFF, UCOL_DEFAULT_STRENGTH,NULL, &status);
802 if(U_FAILURE(status)){
803 log_err("ERROR: in creation of rule based collator :%s\n", myErrorName(status));
804 }
805 ucol_setStrength(myCollation, UCOL_TERTIARY);
806 for (i = 0; i < COUNT_TEST_CASES-1 ; i++)
807 {
808 for (j = i + 1; j < COUNT_TEST_CASES; j += 1)
809 {
810
811 doTest(myCollation, testCases[i], testCases[j], UCOL_LESS);
812 }
813 }
814 free(rules);
815 ucol_close(myCollation);
816 myCollation = 0;
817}
818
819static void TestJB581(void)
820{
821 UChar dispName [100];
822 int32_t bufferLen = 0;
823 UChar source [100];
824 UChar target [100];
825 UCollationResult result = UCOL_EQUAL;
826 uint8_t sourceKeyArray [100];
827 uint8_t targetKeyArray [100];
828 int32_t sourceKeyOut = 0,
829 targetKeyOut = 0;
830 UCollator *myCollator = 0;
831 UErrorCode status = U_ZERO_ERROR;
832
833 /*u_uastrcpy(source, "This is a test.");*/
834 /*u_uastrcpy(target, "THISISATEST.");*/
835 u_uastrcpy(source, "THISISATEST.");
836 u_uastrcpy(target, "Thisisatest.");
837
838 myCollator = ucol_open("en_US", &status);
839 if (U_FAILURE(status)){
840 bufferLen = uloc_getDisplayName("en_US", 0, dispName, 100, &status);
841 /*Report the error with display name... */
842 log_err("ERROR: Failed to create the collator for : \"%s\"\n", dispName);
843 return;
844 }
845 result = ucol_strcoll(myCollator, source, -1, target, -1);
846 /* result is 1, secondary differences only for ignorable space characters*/
847 if (result != 1)
848 {
849 log_err("Comparing two strings with only secondary differences in C failed.\n");
850 }
851 /* To compare them with just primary differences */
852 ucol_setStrength(myCollator, UCOL_PRIMARY);
853 result = ucol_strcoll(myCollator, source, -1, target, -1);
854 /* result is 0 */
855 if (result != 0)
856 {
857 log_err("Comparing two strings with no differences in C failed.\n");
858 }
859 /* Now, do the same comparison with keys */
860 sourceKeyOut = ucol_getSortKey(myCollator, source, -1, sourceKeyArray, 100);
861 targetKeyOut = ucol_getSortKey(myCollator, target, -1, targetKeyArray, 100);
b75a7d8f 862 bufferLen = ((targetKeyOut > 100) ? 100 : targetKeyOut);
73c04bcf 863 if (memcmp(sourceKeyArray, targetKeyArray, bufferLen) != 0)
b75a7d8f
A
864 {
865 log_err("Comparing two strings with sort keys in C failed.\n");
866 }
867 ucol_close(myCollator);
868}
869
870static void TestJB1401(void)
871{
872 UCollator *myCollator = 0;
873 UErrorCode status = U_ZERO_ERROR;
874 static UChar NFD_UnsafeStartChars[] = {
875 0x0f73, /* Tibetan Vowel Sign II */
876 0x0f75, /* Tibetan Vowel Sign UU */
877 0x0f81, /* Tibetan Vowel Sign Reversed II */
878 0
879 };
880 int i;
881
882
883 myCollator = ucol_open("en_US", &status);
884 if (U_FAILURE(status)){
885 int32_t bufferLen = 0;
886 UChar dispName [100];
887 bufferLen = uloc_getDisplayName("en_US", 0, dispName, 100, &status);
888 /*Report the error with display name... */
889 log_err("ERROR: Failed to create the collator for : \"%s\"\n", dispName);
890 return;
891 }
892 ucol_setAttribute(myCollator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
893 if (U_FAILURE(status)){
894 log_err("ERROR: Failed to set normalization mode ON for collator.\n");
895 return;
896 }
897
898 for (i=0; ; i++) {
899 UChar c;
900 UChar X[4];
901 UChar Y[20];
902 UChar Z[20];
903
904 /* Get the next funny character to be tested, and set up the
905 * three test strings X, Y, Z, consisting of an A-grave + test char,
906 * in original form, NFD, and then NFC form.
907 */
908 c = NFD_UnsafeStartChars[i];
909 if (c==0) {break;}
910
911 X[0]=0xC0; X[1]=c; X[2]=0; /* \u00C0 is A Grave*/
912
913 unorm_normalize(X, -1, UNORM_NFD, 0, Y, 20, &status);
914 unorm_normalize(Y, -1, UNORM_NFC, 0, Z, 20, &status);
915 if (U_FAILURE(status)){
916 log_err("ERROR: Failed to normalize test of character %x\n", c);
917 return;
918 }
919
920 /* Collation test. All three strings should be equal.
921 * doTest does both strcoll and sort keys, with params in both orders.
922 */
923 doTest(myCollator, X, Y, UCOL_EQUAL);
924 doTest(myCollator, X, Z, UCOL_EQUAL);
925 doTest(myCollator, Y, Z, UCOL_EQUAL);
926
927 /* Run collation element iterators over the three strings. Results should be same for each.
928 */
929 {
930 UCollationElements *ceiX, *ceiY, *ceiZ;
931 int32_t ceX, ceY, ceZ;
932 int j;
933
934 ceiX = ucol_openElements(myCollator, X, -1, &status);
935 ceiY = ucol_openElements(myCollator, Y, -1, &status);
936 ceiZ = ucol_openElements(myCollator, Z, -1, &status);
937 if (U_FAILURE(status)) {
938 log_err("ERROR: uucol_openElements failed.\n");
939 return;
940 }
941
942 for (j=0;; j++) {
943 ceX = ucol_next(ceiX, &status);
944 ceY = ucol_next(ceiY, &status);
945 ceZ = ucol_next(ceiZ, &status);
946 if (U_FAILURE(status)) {
947 log_err("ERROR: ucol_next failed for iteration #%d.\n", j);
948 break;
949 }
950 if (ceX != ceY || ceY != ceZ) {
951 log_err("ERROR: ucol_next failed for iteration #%d.\n", j);
952 break;
953 }
954 if (ceX == UCOL_NULLORDER) {
955 break;
956 }
957 }
958 ucol_closeElements(ceiX);
959 ucol_closeElements(ceiY);
960 ucol_closeElements(ceiZ);
961 }
962 }
963 ucol_close(myCollator);
964}
965
966
967
968/**
969* Tests the [variable top] tag in rule syntax. Since the default [alternate]
970* tag has the value shifted, any codepoints before [variable top] should give
971* a primary ce of 0.
972*/
973static void TestVariableTop(void)
974{
975 const char *str = "&z = [variable top]";
976 int len = strlen(str);
977 UChar *rules;
978 UCollator *myCollation;
979 UCollator *enCollation;
980 UErrorCode status = U_ZERO_ERROR;
981 UChar source[1];
982 UChar ch;
983 uint8_t result[20];
984 uint8_t expected[20];
985
986 rules = (UChar*)malloc(sizeof(UChar*) * (len + 1));
987 u_uastrcpy(rules, str);
988
989 enCollation = ucol_open("en_US", &status);
990 myCollation = ucol_openRules(rules, len, UCOL_OFF,
991 UCOL_PRIMARY,NULL, &status);
992 if (U_FAILURE(status)) {
993 log_err("ERROR: in creation of rule based collator :%s\n",
994 myErrorName(status));
995 return;
996 }
997
998 ucol_setStrength(enCollation, UCOL_PRIMARY);
999 ucol_setAttribute(enCollation, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED,
1000 &status);
1001 ucol_setAttribute(myCollation, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED,
1002 &status);
1003
1004 if (ucol_getAttribute(myCollation, UCOL_ALTERNATE_HANDLING, &status) !=
1005 UCOL_SHIFTED || U_FAILURE(status)) {
1006 log_err("ERROR: ALTERNATE_HANDLING value can not be set to SHIFTED\n");
1007 }
1008
1009 uprv_memset(expected, 0, 20);
1010
1011 /* space is supposed to be a variable */
1012 source[0] = ' ';
1013 len = ucol_getSortKey(enCollation, source, 1, result,
1014 sizeof(result));
1015
1016 if (uprv_memcmp(expected, result, len) != 0) {
1017 log_err("ERROR: SHIFTED alternate does not return 0 for primary of space\n");
1018 }
1019
1020 ch = 'a';
1021 while (ch < 'z') {
1022 source[0] = ch;
1023 len = ucol_getSortKey(myCollation, source, 1, result,
1024 sizeof(result));
1025 if (uprv_memcmp(expected, result, len) != 0) {
1026 log_err("ERROR: SHIFTED alternate does not return 0 for primary of %c\n",
1027 ch);
1028 }
1029 ch ++;
1030 }
1031
1032 free(rules);
1033 ucol_close(enCollation);
1034 ucol_close(myCollation);
1035 enCollation = NULL;
1036 myCollation = NULL;
1037}
1038
1039/**
1040 * Tests surrogate support.
1041 * NOTE: This test used \\uD801\\uDC01 pair, which is now assigned to Desseret
1042 * Therefore, another (unassigned) code point was used for this test.
1043 */
1044static void TestSurrogates(void)
1045{
1046 const char *str =
1047 "&z<'\\uD800\\uDC00'<'\\uD800\\uDC0A\\u0308'<A";
1048 int len = strlen(str);
1049 int rlen = 0;
1050 UChar *rules;
1051 UCollator *myCollation;
1052 UCollator *enCollation;
1053 UErrorCode status = U_ZERO_ERROR;
1054 UChar source[][4] =
1055 {{'z', 0, 0}, {0xD800, 0xDC00, 0}, {0xD800, 0xDC0A, 0x0308, 0}, {0xD800, 0xDC02}};
1056 UChar target[][4] =
1057 {{0xD800, 0xDC00, 0}, {0xD800, 0xDC0A, 0x0308, 0}, {'A', 0, 0}, {0xD800, 0xDC03}};
1058 int count = 0;
1059 uint8_t enresult[20], myresult[20];
1060 int enlen, mylen;
1061
1062 /* tests for open rules with surrogate rules */
1063 rules = (UChar*)malloc(sizeof(UChar*) * (len + 1));
1064 rlen = u_unescape(str, rules, len);
1065
1066 enCollation = ucol_open("en_US", &status);
1067 myCollation = ucol_openRules(rules, rlen, UCOL_OFF,
1068 UCOL_TERTIARY,NULL, &status);
1069 if (U_FAILURE(status)) {
1070 log_err("ERROR: in creation of rule based collator :%s\n",
1071 myErrorName(status));
1072 return;
1073 }
1074
1075 /*
1076 this test is to verify the supplementary sort key order in the english
1077 collator
1078 */
1079 log_verbose("start of english collation supplementary characters test\n");
1080 while (count < 2) {
1081 doTest(enCollation, source[count], target[count], UCOL_LESS);
1082 count ++;
1083 }
1084 doTest(enCollation, source[count], target[count], UCOL_GREATER);
1085
1086 log_verbose("start of tailored collation supplementary characters test\n");
1087 count = 0;
1088 /* tests getting collation elements for surrogates for tailored rules */
1089 while (count < 4) {
1090 doTest(myCollation, source[count], target[count], UCOL_LESS);
1091 count ++;
1092 }
1093
1094 /* tests that \uD800\uDC02 still has the same value, not changed */
1095 enlen = ucol_getSortKey(enCollation, source[3], 2, enresult, 20);
1096 mylen = ucol_getSortKey(myCollation, source[3], 2, myresult, 20);
1097 if (enlen != mylen ||
1098 uprv_memcmp(enresult, myresult, enlen) != 0) {
1099 log_verbose("Failed : non-tailored supplementary characters should have the same value\n");
1100 }
1101
1102 free(rules);
1103 ucol_close(enCollation);
1104 ucol_close(myCollation);
1105 enCollation = NULL;
1106 myCollation = NULL;
1107}
1108
1109/*
1110 *### TODO: Add more invalid rules to test all different scenarios.
1111 *
1112 */
1113static void
1114TestInvalidRules(){
1115#define MAX_ERROR_STATES 2
1116
1117 static const char* rulesArr[MAX_ERROR_STATES] = {
1118 "& C < ch, cH, Ch[this should fail]<d",
1119 "& C < ch, cH, & Ch[variable top]"
1120 };
1121 static const char* preContextArr[MAX_ERROR_STATES] = {
1122 "his should fail",
1123 "& C < ch, cH, ",
1124
1125 };
1126 static const char* postContextArr[MAX_ERROR_STATES] = {
1127 "<d",
1128 " Ch[variable t"
1129 };
1130 int i;
1131
1132 for(i = 0;i<MAX_ERROR_STATES;i++){
1133 UChar rules[1000] = { '\0' };
1134 UChar preContextExp[1000] = { '\0' };
1135 UChar postContextExp[1000] = { '\0' };
1136 UParseError parseError;
1137 UErrorCode status = U_ZERO_ERROR;
1138 UCollator* coll=0;
1139 u_charsToUChars(rulesArr[i],rules,uprv_strlen(rulesArr[i])+1);
1140 u_charsToUChars(preContextArr[i],preContextExp,uprv_strlen(preContextArr[i])+1);
1141 u_charsToUChars(postContextArr[i],postContextExp,uprv_strlen(postContextArr[i])+1);
1142 /* clean up stuff in parseError */
1143 u_memset(parseError.preContext,0x0000,U_PARSE_CONTEXT_LEN);
1144 u_memset(parseError.postContext,0x0000,U_PARSE_CONTEXT_LEN);
1145 /* open the rules and test */
1146 coll = ucol_openRules(rules,u_strlen(rules),UCOL_OFF,UCOL_DEFAULT_STRENGTH,&parseError,&status);
1147 if(u_strcmp(parseError.preContext,preContextExp)!=0){
1148 log_err("preContext in UParseError for ucol_openRules does not match\n");
1149 }
1150 if(u_strcmp(parseError.postContext,postContextExp)!=0){
1151 log_err("postContext in UParseError for ucol_openRules does not match\n");
1152 }
1153 }
1154}
1155
1156static void
1157TestJitterbug1098(){
1158 UChar rule[1000];
1159 UCollator* c1 = NULL;
1160 UErrorCode status = U_ZERO_ERROR;
1161 UParseError parseError;
1162 char preContext[200]={0};
1163 char postContext[200]={0};
1164 int i=0;
1165 const char* rules[] = {
1166 "&''<\\\\",
1167 "&\\'<\\\\",
1168 "&\\\"<'\\'",
1169 "&'\"'<\\'",
1170 '\0'
1171
1172 };
1173 const UCollationResult results1098[] = {
1174 UCOL_LESS,
1175 UCOL_LESS,
1176 UCOL_LESS,
1177 UCOL_LESS,
1178 };
1179 const UChar input[][2]= {
1180 {0x0027,0x005c},
1181 {0x0027,0x005c},
1182 {0x0022,0x005c},
1183 {0x0022,0x0027},
1184 };
1185 UChar X[2] ={0};
1186 UChar Y[2] ={0};
1187 u_memset(parseError.preContext,0x0000,U_PARSE_CONTEXT_LEN);
1188 u_memset(parseError.postContext,0x0000,U_PARSE_CONTEXT_LEN);
1189 for(;rules[i]!=0;i++){
1190 u_uastrcpy(rule, rules[i]);
1191 c1 = ucol_openRules(rule, u_strlen(rule), UCOL_OFF, UCOL_DEFAULT_STRENGTH, &parseError, &status);
1192 if(U_FAILURE(status)){
b75a7d8f 1193 log_err("Could not parse the rules syntax. Error: %s ", u_errorName(status));
374ca955
A
1194
1195 if (status == U_PARSE_ERROR) {
1196 u_UCharsToChars(parseError.preContext,preContext,20);
1197 u_UCharsToChars(parseError.postContext,postContext,20);
1198 log_verbose("\n\tPre-Context: %s \n\tPost-Context:%s \n",preContext,postContext);
1199 }
1200
b75a7d8f
A
1201 return;
1202 }
1203 X[0] = input[i][0];
1204 Y[0] = input[i][1];
1205 doTest(c1,X,Y,results1098[i]);
1206 ucol_close(c1);
1207 }
1208}
1209
374ca955
A
1210/* These tests do cleanup and reinitialize ICU in the course of their operation.
1211 * The ICU data directory must be preserved across these operations.
1212 * Here is a helper function to assist with that.
1213 */
1214static char *safeGetICUDataDirectory() {
1215 const char *dataDir = u_getDataDirectory(); /* Returned string vanashes with u_cleanup */
1216 char *retStr = NULL;
1217 if (dataDir != NULL) {
1218 retStr = (char *)malloc(strlen(dataDir)+1);
1219 strcpy(retStr, dataDir);
1220 }
1221 return retStr;
1222}
1223
1224
1225static void
1226TestFCDCrash(void) {
1227 static const char *test[] = {
1228 "Gr\\u00F6\\u00DFe",
1229 "Grossist"
1230 };
1231
1232 char *icuDataDir = safeGetICUDataDirectory();
1233 UErrorCode status = U_ZERO_ERROR;
1234 UCollator *coll = ucol_open("es", &status);
1235 if(U_FAILURE(status)) {
1236 log_err("Couldn't open collator\n");
1237 return;
1238 }
1239 ucol_close(coll);
1240 coll = NULL;
1241 u_cleanup();
1242 u_setDataDirectory(icuDataDir);
1243 coll = ucol_open("de_DE", &status);
1244 if(U_FAILURE(status)) {
1245 log_err("Couldn't open collator\n");
1246 return;
1247 }
1248 ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
1249 genericOrderingTest(coll, test, 2);
1250 ucol_close(coll);
1251 free(icuDataDir);
1252
1253}
b75a7d8f
A
1254
1255#endif /* #if !UCONFIG_NO_COLLATION */