1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
4 * Copyright (c) 2001-2016 International Business Machines
5 * Corporation and others. All Rights Reserved.
6 ********************************************************************
8 * Modification History:
9 * Name Date Description
10 * synwee July 19 2001 creation
11 ********************************************************************/
13 #include "unicode/utypes.h"
15 #if !UCONFIG_NO_COLLATION && !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILE_IO
17 #include "unicode/usearch.h"
18 #include "unicode/ustring.h"
23 #include "unicode/ubrk.h"
26 static UBool TOCLOSE_
= TRUE
;
27 static UCollator
*EN_US_
;
28 static UCollator
*FR_FR_
;
29 static UCollator
*DE_
;
30 static UCollator
*ES_
;
33 * CHECK_BREAK(char *brk)
34 * Test if a break iterator is passed in AND break iteration is disabled.
35 * Skip the test if so.
36 * CHECK_BREAK_BOOL(char *brk)
37 * Same as above, but returns 'TRUE' as a passing result
40 #if !UCONFIG_NO_BREAK_ITERATION
41 static UBreakIterator
*EN_WORDBREAKER_
;
42 static UBreakIterator
*EN_CHARACTERBREAKER_
;
43 #define CHECK_BREAK(x)
44 #define CHECK_BREAK_BOOL(x)
46 #define CHECK_BREAK(x) if(x) { log_info("Skipping test on %s:%d because UCONFIG_NO_BREAK_ITERATION is on\n", __FILE__, __LINE__); return; }
47 #define CHECK_BREAK_BOOL(x) if(x) { log_info("Skipping test on %s:%d because UCONFIG_NO_BREAK_ITERATION is on\n", __FILE__, __LINE__); return TRUE; }
51 * Opening all static collators and break iterators
53 static void open(UErrorCode
* status
)
57 int32_t rulelength
= 0;
58 *status
= U_ZERO_ERROR
;
60 EN_US_
= ucol_open("en_US", status
);
61 if(U_FAILURE(*status
)) {
62 log_err_status(*status
, "Error opening collator\n");
65 FR_FR_
= ucol_open("fr_FR", status
);
66 DE_
= ucol_open("de_DE", status
);
67 ES_
= ucol_open("es_ES", status
);
69 u_strcpy(rules
, ucol_getRules(DE_
, &rulelength
));
70 u_unescape(EXTRACOLLATIONRULE
, rules
+ rulelength
, 1024 - rulelength
);
74 DE_
= ucol_openRules(rules
, u_strlen(rules
), UCOL_ON
, UCOL_TERTIARY
,
75 (UParseError
*)NULL
, status
);
76 u_strcpy(rules
, ucol_getRules(ES_
, &rulelength
));
77 u_unescape(EXTRACOLLATIONRULE
, rules
+ rulelength
, 1024 - rulelength
);
80 ES_
= ucol_openRules(rules
, u_strlen(rules
), UCOL_ON
, UCOL_TERTIARY
,
82 #if !UCONFIG_NO_BREAK_ITERATION
83 EN_WORDBREAKER_
= ubrk_open(UBRK_WORD
, "en_US", NULL
, 0, status
);
84 EN_CHARACTERBREAKER_
= ubrk_open(UBRK_CHARACTER
, "en_US", NULL
, 0,
92 * Start opening all static collators and break iterators
94 static void TestStart(void)
96 UErrorCode status
= U_ZERO_ERROR
;
98 if (U_FAILURE(status
)) {
99 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
106 * Closing all static collators and break iterators
108 static void close(void)
115 #if !UCONFIG_NO_BREAK_ITERATION
116 ubrk_close(EN_WORDBREAKER_
);
117 ubrk_close(EN_CHARACTERBREAKER_
);
124 * End closing all static collators and break iterators
126 static void TestEnd(void)
134 * output UChar strings for printing.
136 static char *toCharString(const UChar
* unichars
)
138 static char result
[1024];
141 int length
= u_strlen(unichars
);
143 for (; count
< length
; count
++) {
144 UChar ch
= unichars
[count
];
145 if (ch
>= 0x20 && ch
<= 0x7e) {
149 sprintf(temp
, "\\u%04x", ch
);
150 temp
+= 6; /* \uxxxx */
159 * Getting the collator
161 static UCollator
*getCollator(const char *collator
)
163 if (collator
== NULL
) {
166 if (strcmp(collator
, "fr") == 0) {
169 else if (strcmp(collator
, "de") == 0) {
172 else if (strcmp(collator
, "es") == 0) {
181 * Getting the breakiterator
183 static UBreakIterator
*getBreakIterator(const char *breaker
)
185 if (breaker
== NULL
) {
188 #if !UCONFIG_NO_BREAK_ITERATION
189 if (strcmp(breaker
, "wordbreaker") == 0) {
190 return EN_WORDBREAKER_
;
193 return EN_CHARACTERBREAKER_
;
200 static void TestOpenClose(void)
202 UErrorCode status
= U_ZERO_ERROR
;
203 UStringSearch
*result
;
204 const UChar pattern
[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
205 const UChar text
[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67};
206 #if !UCONFIG_NO_BREAK_ITERATION
207 UBreakIterator
*breakiter
= ubrk_open(UBRK_WORD
, "en_US",
210 /* testing null arguments */
211 result
= usearch_open(NULL
, 0, NULL
, 0, NULL
, NULL
, &status
);
212 if (U_SUCCESS(status
) || result
!= NULL
) {
213 log_err("Error: NULL arguments should produce an error and a NULL result\n");
215 status
= U_ZERO_ERROR
;
216 result
= usearch_openFromCollator(NULL
, 0, NULL
, 0, NULL
, NULL
, &status
);
217 if (U_SUCCESS(status
) || result
!= NULL
) {
218 log_err("Error: NULL arguments should produce an error and a NULL result\n");
221 status
= U_ZERO_ERROR
;
222 result
= usearch_open(pattern
, 3, NULL
, 0, NULL
, NULL
, &status
);
223 if (U_SUCCESS(status
) || result
!= NULL
) {
224 log_err("Error: NULL arguments should produce an error and a NULL result\n");
226 status
= U_ZERO_ERROR
;
227 result
= usearch_openFromCollator(pattern
, 3, NULL
, 0, NULL
, NULL
,
229 if (U_SUCCESS(status
) || result
!= NULL
) {
230 log_err("Error: NULL arguments should produce an error and a NULL result\n");
233 status
= U_ZERO_ERROR
;
234 result
= usearch_open(pattern
, 3, text
, 6, NULL
, NULL
, &status
);
235 if (U_SUCCESS(status
) || result
!= NULL
) {
236 log_err("Error: NULL arguments should produce an error and a NULL result\n");
238 status
= U_ZERO_ERROR
;
239 result
= usearch_openFromCollator(pattern
, 3, text
, 6, NULL
, NULL
,
241 if (U_SUCCESS(status
) || result
!= NULL
) {
242 log_err("Error: NULL arguments should produce an error and a NULL result\n");
245 status
= U_ZERO_ERROR
;
246 result
= usearch_open(pattern
, 3, text
, 6, "en_US", NULL
, &status
);
247 if (U_FAILURE(status
) || result
== NULL
) {
248 log_err_status(status
, "Error: NULL break iterator is valid for opening search\n");
251 usearch_close(result
);
254 if (U_FAILURE(status
)) {
255 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
258 status
= U_ZERO_ERROR
;
259 result
= usearch_openFromCollator(pattern
, 3, text
, 6, EN_US_
, NULL
,
261 if (U_FAILURE(status
) || result
== NULL
) {
262 if (EN_US_
== NULL
) {
263 log_data_err("Opening collator failed.\n");
265 log_err("Error: NULL break iterator is valid for opening search\n");
269 usearch_close(result
);
273 status
= U_ZERO_ERROR
;
274 #if !UCONFIG_NO_BREAK_ITERATION
276 result
= usearch_open(pattern
, 3, text
, 6, "en_US", breakiter
, &status
);
277 if (U_FAILURE(status
) || result
== NULL
) {
278 log_err_status(status
, "Error: Break iterator is valid for opening search\n");
281 usearch_close(result
);
283 status
= U_ZERO_ERROR
;
284 result
= usearch_openFromCollator(pattern
, 3, text
, 6, EN_US_
, breakiter
,
286 if (U_FAILURE(status
) || result
== NULL
) {
287 if (EN_US_
== NULL
) {
288 log_data_err("Opening collator failed.\n");
290 log_err("Error: Break iterator is valid for opening search\n");
294 usearch_close(result
);
296 ubrk_close(breakiter
);
301 static void TestInitialization(void)
303 UErrorCode status
= U_ZERO_ERROR
;
305 const UChar text
[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
307 UStringSearch
*result
;
309 /* simple test on the pattern ce construction */
313 if (U_FAILURE(status
)) {
314 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
317 result
= usearch_openFromCollator(pattern
, 2, text
, 3, EN_US_
, NULL
,
319 if (U_FAILURE(status
)) {
320 log_err("Error opening search %s\n", u_errorName(status
));
322 usearch_close(result
);
324 /* testing if an extremely large pattern will fail the initialization */
325 for(i
= 0; i
< 512; i
++) {
328 /*uprv_memset(pattern, 0x41, 512);*/
329 result
= usearch_openFromCollator(pattern
, 512, text
, 3, EN_US_
, NULL
,
331 if (U_FAILURE(status
)) {
332 log_err("Error opening search %s\n", u_errorName(status
));
334 usearch_close(result
);
338 static UBool
assertEqualWithUStringSearch( UStringSearch
*strsrch
,
339 const SearchData search
)
342 UErrorCode status
= U_ZERO_ERROR
;
343 int32_t matchindex
= search
.offset
[count
];
345 UChar matchtext
[128];
350 usearch_setAttribute(strsrch
, USEARCH_ELEMENT_COMPARISON
, search
.elemCompare
, &status
);
351 if (U_FAILURE(status
)) {
352 log_err("Error setting USEARCH_ELEMENT_COMPARISON attribute %s\n", u_errorName(status
));
356 if (usearch_getMatchedStart(strsrch
) != USEARCH_DONE
||
357 usearch_getMatchedLength(strsrch
) != 0) {
358 log_err("Error with the initialization of match start and length\n");
360 /* start of next matches */
361 while (U_SUCCESS(status
) && matchindex
>= 0) {
362 matchlength
= search
.size
[count
];
363 usearch_next(strsrch
, &status
);
364 if (matchindex
!= usearch_getMatchedStart(strsrch
) ||
365 matchlength
!= (uint32_t)usearch_getMatchedLength(strsrch
)) {
366 char *str
= toCharString(usearch_getText(strsrch
, &textlength
));
367 log_err("Text: %s\n", str
);
368 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
369 log_err("Pattern: %s\n", str
);
370 log_err("Error next match found at idx %d (len:%d); expected %d (len:%d)\n",
371 usearch_getMatchedStart(strsrch
), usearch_getMatchedLength(strsrch
),
372 matchindex
, matchlength
);
377 if (usearch_getMatchedText(strsrch
, matchtext
, 128, &status
) !=
378 (int32_t) matchlength
|| U_FAILURE(status
) ||
380 usearch_getText(strsrch
, &textlength
) + matchindex
,
381 matchlength
* sizeof(UChar
)) != 0) {
382 log_err("Error getting next matched text\n");
385 matchindex
= search
.offset
[count
];
387 usearch_next(strsrch
, &status
);
388 if (usearch_getMatchedStart(strsrch
) != USEARCH_DONE
||
389 usearch_getMatchedLength(strsrch
) != 0) {
390 char *str
= toCharString(usearch_getText(strsrch
, &textlength
));
391 log_err("Text: %s\n", str
);
392 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
393 log_err("Pattern: %s\n", str
);
394 log_err("Error next match found at %d (len:%d); expected <NO MATCH>\n",
395 usearch_getMatchedStart(strsrch
),
396 usearch_getMatchedLength(strsrch
));
399 /* start of previous matches */
400 count
= count
== 0 ? 0 : count
- 1;
401 matchindex
= search
.offset
[count
];
403 while (U_SUCCESS(status
) && matchindex
>= 0) {
404 matchlength
= search
.size
[count
];
405 usearch_previous(strsrch
, &status
);
406 if (matchindex
!= usearch_getMatchedStart(strsrch
) ||
407 matchlength
!= (uint32_t)usearch_getMatchedLength(strsrch
)) {
408 char *str
= toCharString(usearch_getText(strsrch
, &textlength
));
409 log_err("Text: %s\n", str
);
410 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
411 log_err("Pattern: %s\n", str
);
412 log_err("Error previous match found at %d (len:%d); expected %d (len:%d)\n",
413 usearch_getMatchedStart(strsrch
), usearch_getMatchedLength(strsrch
),
414 matchindex
, matchlength
);
418 if (usearch_getMatchedText(strsrch
, matchtext
, 128, &status
) !=
419 (int32_t) matchlength
|| U_FAILURE(status
) ||
421 usearch_getText(strsrch
, &textlength
) + matchindex
,
422 matchlength
* sizeof(UChar
)) != 0) {
423 log_err("Error getting previous matched text\n");
426 matchindex
= count
> 0 ? search
.offset
[count
- 1] : -1;
429 usearch_previous(strsrch
, &status
);
430 if (usearch_getMatchedStart(strsrch
) != USEARCH_DONE
||
431 usearch_getMatchedLength(strsrch
) != 0) {
432 char *str
= toCharString(usearch_getText(strsrch
, &textlength
));
433 log_err("Text: %s\n", str
);
434 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
435 log_err("Pattern: %s\n", str
);
436 log_err("Error previous match found at %d (len:%d); expected <NO MATCH>\n",
437 usearch_getMatchedStart(strsrch
),
438 usearch_getMatchedLength(strsrch
));
443 isOverlap
= (usearch_getAttribute(strsrch
, USEARCH_OVERLAP
) == USEARCH_ON
);
445 /* start of following matches */
447 matchindex
= search
.offset
[count
];
451 usearch_following(strsrch
, nextStart
, &status
);
453 if (matchindex
< 0) {
454 if (usearch_getMatchedStart(strsrch
) != USEARCH_DONE
|| usearch_getMatchedLength(strsrch
) != 0) {
455 char *str
= toCharString(usearch_getText(strsrch
, &textlength
));
456 log_err("Text: %s\n", str
);
457 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
458 log_err("Pattern: %s\n", str
);
459 log_err("Error following match starting at %d (overlap:%d) found at %d (len:%d); expected <NO MATCH>\n",
460 nextStart
, isOverlap
,
461 usearch_getMatchedStart(strsrch
),
462 usearch_getMatchedLength(strsrch
));
465 /* no more matches */
469 matchlength
= search
.size
[count
];
470 if (usearch_getMatchedStart(strsrch
) != matchindex
471 || usearch_getMatchedLength(strsrch
) != matchlength
472 || U_FAILURE(status
)) {
473 char *str
= toCharString(usearch_getText(strsrch
, &textlength
));
474 log_err("Text: %s\n", str
);
475 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
476 log_err("Pattern: %s\n", str
);
477 log_err("Error following match starting at %d (overlap: %d) found at %d (len:%d); expected %d (len:%d)\n",
478 nextStart
, isOverlap
,
479 usearch_getMatchedStart(strsrch
), usearch_getMatchedLength(strsrch
),
480 matchindex
, matchlength
);
484 if (isOverlap
|| usearch_getMatchedLength(strsrch
) == 0) {
485 nextStart
= usearch_getMatchedStart(strsrch
) + 1;
487 nextStart
= usearch_getMatchedStart(strsrch
) + usearch_getMatchedLength(strsrch
);
491 matchindex
= search
.offset
[count
];
494 /* start of preceding matches */
495 count
= -1; /* last non-negative offset index, could be -1 if no match */
496 while (search
.offset
[count
+ 1] >= 0) {
499 usearch_getText(strsrch
, &nextStart
);
502 usearch_preceding(strsrch
, nextStart
, &status
);
505 if (usearch_getMatchedStart(strsrch
) != USEARCH_DONE
|| usearch_getMatchedLength(strsrch
) != 0) {
506 char *str
= toCharString(usearch_getText(strsrch
, &textlength
));
507 log_err("Text: %s\n", str
);
508 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
509 log_err("Pattern: %s\n", str
);
510 log_err("Error preceding match starting at %d (overlap: %d) found at %d (len:%d); expected <NO MATCH>\n",
511 nextStart
, isOverlap
,
512 usearch_getMatchedStart(strsrch
),
513 usearch_getMatchedLength(strsrch
));
516 /* no more matches */
520 matchindex
= search
.offset
[count
];
521 matchlength
= search
.size
[count
];
522 if (usearch_getMatchedStart(strsrch
) != matchindex
523 || usearch_getMatchedLength(strsrch
) != matchlength
524 || U_FAILURE(status
)) {
525 char *str
= toCharString(usearch_getText(strsrch
, &textlength
));
526 log_err("Text: %s\n", str
);
527 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
528 log_err("Pattern: %s\n", str
);
529 log_err("Error preceding match starting at %d (overlap: %d) found at %d (len:%d); expected %d (len:%d)\n",
530 nextStart
, isOverlap
,
531 usearch_getMatchedStart(strsrch
), usearch_getMatchedLength(strsrch
),
532 matchindex
, matchlength
);
536 nextStart
= matchindex
;
540 usearch_setAttribute(strsrch
, USEARCH_ELEMENT_COMPARISON
, USEARCH_STANDARD_ELEMENT_COMPARISON
, &status
);
544 static UBool
assertEqual(const SearchData search
)
546 UErrorCode status
= U_ZERO_ERROR
;
549 UCollator
*collator
= getCollator(search
.collator
);
550 UBreakIterator
*breaker
= getBreakIterator(search
.breaker
);
551 UStringSearch
*strsrch
;
553 CHECK_BREAK_BOOL(search
.breaker
);
555 u_unescape(search
.text
, text
, 128);
556 u_unescape(search
.pattern
, pattern
, 32);
557 ucol_setStrength(collator
, search
.strength
);
558 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, collator
,
560 if (U_FAILURE(status
)) {
561 log_err("Error opening string search %s\n", u_errorName(status
));
565 if (!assertEqualWithUStringSearch(strsrch
, search
)) {
566 ucol_setStrength(collator
, UCOL_TERTIARY
);
567 usearch_close(strsrch
);
570 ucol_setStrength(collator
, UCOL_TERTIARY
);
571 usearch_close(strsrch
);
575 static UBool
assertCanonicalEqual(const SearchData search
)
577 UErrorCode status
= U_ZERO_ERROR
;
580 UCollator
*collator
= getCollator(search
.collator
);
581 UBreakIterator
*breaker
= getBreakIterator(search
.breaker
);
582 UStringSearch
*strsrch
;
585 CHECK_BREAK_BOOL(search
.breaker
);
586 u_unescape(search
.text
, text
, 128);
587 u_unescape(search
.pattern
, pattern
, 32);
588 ucol_setStrength(collator
, search
.strength
);
589 ucol_setAttribute(collator
, UCOL_NORMALIZATION_MODE
, UCOL_ON
, &status
);
590 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, collator
,
592 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
594 if (U_FAILURE(status
)) {
595 log_err("Error opening string search %s\n", u_errorName(status
));
600 if (!assertEqualWithUStringSearch(strsrch
, search
)) {
601 ucol_setStrength(collator
, UCOL_TERTIARY
);
602 usearch_close(strsrch
);
608 ucol_setAttribute(collator
, UCOL_NORMALIZATION_MODE
, UCOL_OFF
, &status
);
609 ucol_setStrength(collator
, UCOL_TERTIARY
);
610 usearch_close(strsrch
);
614 static UBool
assertEqualWithAttribute(const SearchData search
,
615 USearchAttributeValue canonical
,
616 USearchAttributeValue overlap
)
618 UErrorCode status
= U_ZERO_ERROR
;
621 UCollator
*collator
= getCollator(search
.collator
);
622 UBreakIterator
*breaker
= getBreakIterator(search
.breaker
);
623 UStringSearch
*strsrch
;
625 CHECK_BREAK_BOOL(search
.breaker
);
626 u_unescape(search
.text
, text
, 128);
627 u_unescape(search
.pattern
, pattern
, 32);
628 ucol_setStrength(collator
, search
.strength
);
629 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, collator
,
631 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, canonical
,
633 usearch_setAttribute(strsrch
, USEARCH_OVERLAP
, overlap
, &status
);
635 if (U_FAILURE(status
)) {
636 log_err("Error opening string search %s\n", u_errorName(status
));
640 if (!assertEqualWithUStringSearch(strsrch
, search
)) {
641 ucol_setStrength(collator
, UCOL_TERTIARY
);
642 usearch_close(strsrch
);
645 ucol_setStrength(collator
, UCOL_TERTIARY
);
646 usearch_close(strsrch
);
650 static void TestBasic(void)
653 UErrorCode status
= U_ZERO_ERROR
;
655 if (U_FAILURE(status
)) {
656 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
659 while (BASIC
[count
].text
!= NULL
) {
660 if (!assertEqual(BASIC
[count
])) {
661 log_err("Error at test number %d\n", count
);
668 static void TestNormExact(void)
671 UErrorCode status
= U_ZERO_ERROR
;
673 if (U_FAILURE(status
)) {
674 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
677 ucol_setAttribute(EN_US_
, UCOL_NORMALIZATION_MODE
, UCOL_ON
, &status
);
678 if (U_FAILURE(status
)) {
679 log_err("Error setting collation normalization %s\n",
680 u_errorName(status
));
682 while (BASIC
[count
].text
!= NULL
) {
683 if (!assertEqual(BASIC
[count
])) {
684 log_err("Error at test number %d\n", count
);
689 while (NORMEXACT
[count
].text
!= NULL
) {
690 if (!assertEqual(NORMEXACT
[count
])) {
691 log_err("Error at test number %d\n", count
);
695 ucol_setAttribute(EN_US_
, UCOL_NORMALIZATION_MODE
, UCOL_OFF
, &status
);
697 while (NONNORMEXACT
[count
].text
!= NULL
) {
698 if (!assertEqual(NONNORMEXACT
[count
])) {
699 log_err("Error at test number %d\n", count
);
706 static void TestStrength(void)
709 UErrorCode status
= U_ZERO_ERROR
;
711 if (U_FAILURE(status
)) {
712 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
715 while (STRENGTH
[count
].text
!= NULL
) {
716 if (!assertEqual(STRENGTH
[count
])) {
717 log_err("Error at test number %d\n", count
);
724 static void TestBreakIterator(void) {
725 UErrorCode status
= U_ZERO_ERROR
;
726 UStringSearch
*strsrch
;
733 #if !UCONFIG_NO_BREAK_ITERATION
735 if (U_FAILURE(status
)) {
736 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
739 if (usearch_getBreakIterator(NULL
) != NULL
) {
740 log_err("Expected NULL breakiterator from NULL string search\n");
742 u_unescape(BREAKITERATOREXACT
[0].text
, text
, 128);
743 u_unescape(BREAKITERATOREXACT
[0].pattern
, pattern
, 32);
744 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, EN_US_
, NULL
,
746 if (U_FAILURE(status
)) {
747 log_err("Error opening string search %s\n", u_errorName(status
));
748 goto ENDTESTBREAKITERATOR
;
751 usearch_setBreakIterator(strsrch
, NULL
, &status
);
752 if (U_FAILURE(status
) || usearch_getBreakIterator(strsrch
) != NULL
) {
753 log_err("Error usearch_getBreakIterator returned wrong object");
754 goto ENDTESTBREAKITERATOR
;
757 usearch_setBreakIterator(strsrch
, EN_CHARACTERBREAKER_
, &status
);
758 if (U_FAILURE(status
) ||
759 usearch_getBreakIterator(strsrch
) != EN_CHARACTERBREAKER_
) {
760 log_err("Error usearch_getBreakIterator returned wrong object");
761 goto ENDTESTBREAKITERATOR
;
764 usearch_setBreakIterator(strsrch
, EN_WORDBREAKER_
, &status
);
765 if (U_FAILURE(status
) ||
766 usearch_getBreakIterator(strsrch
) != EN_WORDBREAKER_
) {
767 log_err("Error usearch_getBreakIterator returned wrong object");
768 goto ENDTESTBREAKITERATOR
;
771 usearch_close(strsrch
);
775 /* 0-3 test are fixed */
776 const SearchData
*search
= &(BREAKITERATOREXACT
[count
]);
777 UCollator
*collator
= getCollator(search
->collator
);
778 UBreakIterator
*breaker
= getBreakIterator(search
->breaker
);
780 u_unescape(search
->text
, text
, 128);
781 u_unescape(search
->pattern
, pattern
, 32);
782 ucol_setStrength(collator
, search
->strength
);
784 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, collator
,
786 if (U_FAILURE(status
) ||
787 usearch_getBreakIterator(strsrch
) != breaker
) {
788 log_err("Error setting break iterator\n");
789 if (strsrch
!= NULL
) {
790 usearch_close(strsrch
);
793 if (!assertEqualWithUStringSearch(strsrch
, *search
)) {
794 ucol_setStrength(collator
, UCOL_TERTIARY
);
795 usearch_close(strsrch
);
796 goto ENDTESTBREAKITERATOR
;
798 search
= &(BREAKITERATOREXACT
[count
+ 1]);
799 breaker
= getBreakIterator(search
->breaker
);
800 usearch_setBreakIterator(strsrch
, breaker
, &status
);
801 if (U_FAILURE(status
) || usearch_getBreakIterator(strsrch
) != breaker
) {
802 log_err("Error setting break iterator\n");
803 usearch_close(strsrch
);
804 goto ENDTESTBREAKITERATOR
;
806 usearch_reset(strsrch
);
807 if (!assertEqualWithUStringSearch(strsrch
, *search
)) {
808 log_err("Error at test number %d\n", count
);
809 usearch_close(strsrch
);
810 goto ENDTESTBREAKITERATOR
;
812 usearch_close(strsrch
);
816 while (BREAKITERATOREXACT
[count
].text
!= NULL
) {
817 if (!assertEqual(BREAKITERATOREXACT
[count
])) {
818 log_err("Error at test number %d\n", count
);
819 goto ENDTESTBREAKITERATOR
;
824 ENDTESTBREAKITERATOR
:
829 static void TestVariable(void)
832 UErrorCode status
= U_ZERO_ERROR
;
834 if (U_FAILURE(status
)) {
835 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
838 ucol_setAttribute(EN_US_
, UCOL_ALTERNATE_HANDLING
, UCOL_SHIFTED
, &status
);
839 if (U_FAILURE(status
)) {
840 log_err("Error setting collation alternate attribute %s\n",
841 u_errorName(status
));
843 while (VARIABLE
[count
].text
!= NULL
) {
844 log_verbose("variable %d\n", count
);
845 if (!assertEqual(VARIABLE
[count
])) {
846 log_err("Error at test number %d\n", count
);
850 ucol_setAttribute(EN_US_
, UCOL_ALTERNATE_HANDLING
,
851 UCOL_NON_IGNORABLE
, &status
);
855 static void TestOverlap(void)
858 UErrorCode status
= U_ZERO_ERROR
;
860 if (U_FAILURE(status
)) {
861 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
864 while (OVERLAP
[count
].text
!= NULL
) {
865 if (!assertEqualWithAttribute(OVERLAP
[count
], USEARCH_OFF
,
867 log_err("Error at overlap test number %d\n", count
);
872 while (NONOVERLAP
[count
].text
!= NULL
) {
873 if (!assertEqual(NONOVERLAP
[count
])) {
874 log_err("Error at non overlap test number %d\n", count
);
883 const SearchData
*search
= &(OVERLAP
[count
]);
884 UCollator
*collator
= getCollator(search
->collator
);
885 UStringSearch
*strsrch
;
886 status
= U_ZERO_ERROR
;
888 u_unescape(search
->text
, text
, 128);
889 u_unescape(search
->pattern
, pattern
, 32);
890 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, collator
,
892 if(status
== U_FILE_ACCESS_ERROR
) {
893 log_data_err("Is your data around?\n");
895 } else if(U_FAILURE(status
)) {
896 log_err("Error opening searcher\n");
899 usearch_setAttribute(strsrch
, USEARCH_OVERLAP
, USEARCH_ON
, &status
);
900 if (U_FAILURE(status
) ||
901 usearch_getAttribute(strsrch
, USEARCH_OVERLAP
) != USEARCH_ON
) {
902 log_err("Error setting overlap option\n");
904 if (!assertEqualWithUStringSearch(strsrch
, *search
)) {
905 usearch_close(strsrch
);
908 search
= &(NONOVERLAP
[count
]);
909 usearch_setAttribute(strsrch
, USEARCH_OVERLAP
, USEARCH_OFF
, &status
);
910 if (U_FAILURE(status
) ||
911 usearch_getAttribute(strsrch
, USEARCH_OVERLAP
) != USEARCH_OFF
) {
912 log_err("Error setting overlap option\n");
914 usearch_reset(strsrch
);
915 if (!assertEqualWithUStringSearch(strsrch
, *search
)) {
916 usearch_close(strsrch
);
917 log_err("Error at test number %d\n", count
);
921 usearch_close(strsrch
);
926 static void TestCollator(void)
928 /* test collator that thinks "o" and "p" are the same thing */
930 UCollator
*tailored
= NULL
;
931 UErrorCode status
= U_ZERO_ERROR
;
934 UStringSearch
*strsrch
;
943 strsrch
= usearch_open(pattern
, 2, text
, 5, "en_US", NULL
, &status
);
944 if(status
== U_FILE_ACCESS_ERROR
) {
945 log_data_err("Is your data around?\n");
947 } else if(U_FAILURE(status
)) {
948 log_err("Error opening searcher\n");
951 tailored
= usearch_getCollator(strsrch
);
952 if (usearch_next(strsrch
, &status
) != -1) {
953 log_err("Error: Found case insensitive match, when we shouldn't\n");
955 ucol_setStrength(tailored
, UCOL_PRIMARY
);
956 usearch_reset(strsrch
);
957 if (usearch_next(strsrch
, &status
) != 1) {
958 log_err("Error: Found case insensitive match not found\n");
960 usearch_close(strsrch
);
964 if (usearch_getCollator(NULL
) != NULL
) {
965 log_err("Expected NULL collator from NULL string search\n");
967 u_unescape(COLLATOR
[0].text
, text
, 128);
968 u_unescape(COLLATOR
[0].pattern
, pattern
, 32);
970 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, EN_US_
,
972 if (U_FAILURE(status
)) {
973 log_err("Error opening string search %s\n", u_errorName(status
));
975 if (!assertEqualWithUStringSearch(strsrch
, COLLATOR
[0])) {
976 goto ENDTESTCOLLATOR
;
979 u_unescape(TESTCOLLATORRULE
, rules
, 32);
980 tailored
= ucol_openRules(rules
, -1, UCOL_ON
, COLLATOR
[1].strength
,
982 if (U_FAILURE(status
)) {
983 log_err("Error opening rule based collator %s\n", u_errorName(status
));
986 usearch_setCollator(strsrch
, tailored
, &status
);
987 if (U_FAILURE(status
) || usearch_getCollator(strsrch
) != tailored
) {
988 log_err("Error setting rule based collator\n");
990 usearch_reset(strsrch
);
991 if (!assertEqualWithUStringSearch(strsrch
, COLLATOR
[1])) {
992 goto ENDTESTCOLLATOR
;
995 usearch_setCollator(strsrch
, EN_US_
, &status
);
996 usearch_reset(strsrch
);
997 if (U_FAILURE(status
) || usearch_getCollator(strsrch
) != EN_US_
) {
998 log_err("Error setting rule based collator\n");
1000 if (!assertEqualWithUStringSearch(strsrch
, COLLATOR
[0])) {
1001 goto ENDTESTCOLLATOR
;
1005 usearch_close(strsrch
);
1006 if (tailored
!= NULL
) {
1007 ucol_close(tailored
);
1012 static void TestPattern(void)
1014 UStringSearch
*strsrch
;
1016 UChar bigpattern
[512];
1020 UErrorCode status
= U_ZERO_ERROR
;
1023 if (U_FAILURE(status
)) {
1024 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1027 if (usearch_getPattern(NULL
, &templength
) != NULL
) {
1028 log_err("Error NULL string search expected returning NULL pattern\n");
1030 usearch_setPattern(NULL
, pattern
, 3, &status
);
1031 if (U_SUCCESS(status
)) {
1032 log_err("Error expected setting pattern in NULL strings search\n");
1034 status
= U_ZERO_ERROR
;
1035 u_unescape(PATTERN
[0].text
, text
, 128);
1036 u_unescape(PATTERN
[0].pattern
, pattern
, 32);
1038 ucol_setStrength(EN_US_
, PATTERN
[0].strength
);
1039 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, EN_US_
,
1041 if(status
== U_FILE_ACCESS_ERROR
) {
1042 log_data_err("Is your data around?\n");
1044 } else if(U_FAILURE(status
)) {
1045 log_err("Error opening searcher\n");
1049 status
= U_ZERO_ERROR
;
1050 usearch_setPattern(strsrch
, NULL
, 3, &status
);
1051 if (U_SUCCESS(status
)) {
1052 log_err("Error expected setting NULL pattern in strings search\n");
1054 status
= U_ZERO_ERROR
;
1055 usearch_setPattern(strsrch
, pattern
, 0, &status
);
1056 if (U_SUCCESS(status
)) {
1057 log_err("Error expected setting pattern with length 0 in strings search\n");
1059 status
= U_ZERO_ERROR
;
1060 if (U_FAILURE(status
)) {
1061 log_err("Error opening string search %s\n", u_errorName(status
));
1062 goto ENDTESTPATTERN
;
1064 temp
= usearch_getPattern(strsrch
, &templength
);
1065 if (u_strcmp(pattern
, temp
) != 0) {
1066 log_err("Error setting pattern\n");
1068 if (!assertEqualWithUStringSearch(strsrch
, PATTERN
[0])) {
1069 goto ENDTESTPATTERN
;
1072 u_unescape(PATTERN
[1].pattern
, pattern
, 32);
1073 usearch_setPattern(strsrch
, pattern
, -1, &status
);
1074 temp
= usearch_getPattern(strsrch
, &templength
);
1075 if (u_strcmp(pattern
, temp
) != 0) {
1076 log_err("Error setting pattern\n");
1077 goto ENDTESTPATTERN
;
1079 usearch_reset(strsrch
);
1080 if (U_FAILURE(status
)) {
1081 log_err("Error setting pattern %s\n", u_errorName(status
));
1083 if (!assertEqualWithUStringSearch(strsrch
, PATTERN
[1])) {
1084 goto ENDTESTPATTERN
;
1087 u_unescape(PATTERN
[0].pattern
, pattern
, 32);
1088 usearch_setPattern(strsrch
, pattern
, -1, &status
);
1089 temp
= usearch_getPattern(strsrch
, &templength
);
1090 if (u_strcmp(pattern
, temp
) != 0) {
1091 log_err("Error setting pattern\n");
1092 goto ENDTESTPATTERN
;
1094 usearch_reset(strsrch
);
1095 if (U_FAILURE(status
)) {
1096 log_err("Error setting pattern %s\n", u_errorName(status
));
1098 if (!assertEqualWithUStringSearch(strsrch
, PATTERN
[0])) {
1099 goto ENDTESTPATTERN
;
1101 /* enormous pattern size to see if this crashes */
1102 for (templength
= 0; templength
!= 512; templength
++) {
1103 bigpattern
[templength
] = 0x61;
1105 bigpattern
[511] = 0;
1106 usearch_setPattern(strsrch
, bigpattern
, -1, &status
);
1107 if (U_FAILURE(status
)) {
1108 log_err("Error setting pattern with size 512, %s \n",
1109 u_errorName(status
));
1112 ucol_setStrength(EN_US_
, UCOL_TERTIARY
);
1113 if (strsrch
!= NULL
) {
1114 usearch_close(strsrch
);
1119 static void TestText(void)
1121 UStringSearch
*strsrch
;
1126 UErrorCode status
= U_ZERO_ERROR
;
1128 u_unescape(TEXT
[0].text
, text
, 128);
1129 u_unescape(TEXT
[0].pattern
, pattern
, 32);
1132 if (U_FAILURE(status
)) {
1133 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1137 if (usearch_getText(NULL
, &templength
) != NULL
) {
1138 log_err("Error NULL string search should return NULL text\n");
1141 usearch_setText(NULL
, text
, 10, &status
);
1142 if (U_SUCCESS(status
)) {
1143 log_err("Error NULL string search should have an error when setting text\n");
1146 status
= U_ZERO_ERROR
;
1147 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, EN_US_
,
1150 if (U_FAILURE(status
)) {
1151 log_err("Error opening string search %s\n", u_errorName(status
));
1152 goto ENDTESTPATTERN
;
1154 temp
= usearch_getText(strsrch
, &templength
);
1155 if (u_strcmp(text
, temp
) != 0) {
1156 log_err("Error setting text\n");
1158 if (!assertEqualWithUStringSearch(strsrch
, TEXT
[0])) {
1159 goto ENDTESTPATTERN
;
1162 u_unescape(TEXT
[1].text
, text
, 32);
1163 usearch_setText(strsrch
, text
, -1, &status
);
1164 temp
= usearch_getText(strsrch
, &templength
);
1165 if (u_strcmp(text
, temp
) != 0) {
1166 log_err("Error setting text\n");
1167 goto ENDTESTPATTERN
;
1169 if (U_FAILURE(status
)) {
1170 log_err("Error setting text %s\n", u_errorName(status
));
1172 if (!assertEqualWithUStringSearch(strsrch
, TEXT
[1])) {
1173 goto ENDTESTPATTERN
;
1176 u_unescape(TEXT
[0].text
, text
, 32);
1177 usearch_setText(strsrch
, text
, -1, &status
);
1178 temp
= usearch_getText(strsrch
, &templength
);
1179 if (u_strcmp(text
, temp
) != 0) {
1180 log_err("Error setting text\n");
1181 goto ENDTESTPATTERN
;
1183 if (U_FAILURE(status
)) {
1184 log_err("Error setting pattern %s\n", u_errorName(status
));
1186 if (!assertEqualWithUStringSearch(strsrch
, TEXT
[0])) {
1187 goto ENDTESTPATTERN
;
1190 if (strsrch
!= NULL
) {
1191 usearch_close(strsrch
);
1196 static void TestCompositeBoundaries(void)
1199 UErrorCode status
= U_ZERO_ERROR
;
1201 if (U_FAILURE(status
)) {
1202 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1205 while (COMPOSITEBOUNDARIES
[count
].text
!= NULL
) {
1206 log_verbose("composite %d\n", count
);
1207 if (!assertEqual(COMPOSITEBOUNDARIES
[count
])) {
1208 log_err("Error at test number %d\n", count
);
1215 static void TestGetSetOffset(void)
1217 int searchDataIndex
= 0;
1220 UErrorCode status
= U_ZERO_ERROR
;
1221 UStringSearch
*strsrch
;
1222 memset(pattern
, 0, 32*sizeof(UChar
));
1223 memset(text
, 0, 128*sizeof(UChar
));
1226 if (U_FAILURE(status
)) {
1227 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1230 if (usearch_getOffset(NULL
) != USEARCH_DONE
) {
1231 log_err("usearch_getOffset(NULL) expected USEARCH_DONE\n");
1233 strsrch
= usearch_openFromCollator(pattern
, 16, text
, 32, EN_US_
, NULL
,
1235 /* testing out of bounds error */
1236 usearch_setOffset(strsrch
, -1, &status
);
1237 if (U_SUCCESS(status
)) {
1238 log_err("Error expecting set offset error\n");
1240 usearch_setOffset(strsrch
, 128, &status
);
1241 if (U_SUCCESS(status
)) {
1242 log_err("Error expecting set offset error\n");
1244 while (BASIC
[searchDataIndex
].text
!= NULL
) {
1246 SearchData search
= BASIC
[searchDataIndex
++];
1247 int32_t matchindex
= search
.offset
[count
];
1250 u_unescape(search
.text
, text
, 128);
1251 u_unescape(search
.pattern
, pattern
, 32);
1252 status
= U_ZERO_ERROR
;
1253 usearch_setText(strsrch
, text
, -1, &status
);
1254 usearch_setPattern(strsrch
, pattern
, -1, &status
);
1255 ucol_setStrength(usearch_getCollator(strsrch
), search
.strength
);
1256 usearch_reset(strsrch
);
1257 while (U_SUCCESS(status
) && matchindex
>= 0) {
1258 uint32_t matchlength
= search
.size
[count
];
1259 usearch_next(strsrch
, &status
);
1260 if (matchindex
!= usearch_getMatchedStart(strsrch
) ||
1261 matchlength
!= (uint32_t)usearch_getMatchedLength(strsrch
)) {
1262 char *str
= toCharString(usearch_getText(strsrch
,
1264 log_err("Text: %s\n", str
);
1265 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
1266 log_err("Pattern: %s\n", str
);
1267 log_err("Error match found at %d %d\n",
1268 usearch_getMatchedStart(strsrch
),
1269 usearch_getMatchedLength(strsrch
));
1272 usearch_setOffset(strsrch
, matchindex
+ matchlength
, &status
);
1273 usearch_previous(strsrch
, &status
);
1274 if (matchindex
!= usearch_getMatchedStart(strsrch
) ||
1275 matchlength
!= (uint32_t)usearch_getMatchedLength(strsrch
)) {
1276 char *str
= toCharString(usearch_getText(strsrch
,
1278 log_err("Text: %s\n", str
);
1279 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
1280 log_err("Pattern: %s\n", str
);
1281 log_err("Error match found at %d %d\n",
1282 usearch_getMatchedStart(strsrch
),
1283 usearch_getMatchedLength(strsrch
));
1286 usearch_setOffset(strsrch
, matchindex
+ matchlength
, &status
);
1287 matchindex
= search
.offset
[count
+ 1] == -1 ? -1 :
1288 search
.offset
[count
+ 2];
1289 if (search
.offset
[count
+ 1] != -1) {
1290 usearch_setOffset(strsrch
, search
.offset
[count
+ 1] + 1,
1292 if (usearch_getOffset(strsrch
) != search
.offset
[count
+ 1] + 1) {
1293 log_err("Error setting offset\n");
1300 usearch_next(strsrch
, &status
);
1301 if (usearch_getMatchedStart(strsrch
) != USEARCH_DONE
) {
1302 char *str
= toCharString(usearch_getText(strsrch
, &textlength
));
1303 log_err("Text: %s\n", str
);
1304 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
1305 log_err("Pattern: %s\n", str
);
1306 log_err("Error match found at %d %d\n",
1307 usearch_getMatchedStart(strsrch
),
1308 usearch_getMatchedLength(strsrch
));
1312 ucol_setStrength(usearch_getCollator(strsrch
), UCOL_TERTIARY
);
1313 usearch_close(strsrch
);
1317 static void TestGetSetAttribute(void)
1319 UErrorCode status
= U_ZERO_ERROR
;
1322 UStringSearch
*strsrch
;
1324 memset(pattern
, 0, 32*sizeof(UChar
));
1325 memset(text
, 0, 128*sizeof(UChar
));
1328 if (U_FAILURE(status
)) {
1329 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1332 if (usearch_getAttribute(NULL
, USEARCH_OVERLAP
) != USEARCH_DEFAULT
||
1333 usearch_getAttribute(NULL
, USEARCH_CANONICAL_MATCH
) !=
1336 "Attributes for NULL string search should be USEARCH_DEFAULT\n");
1338 strsrch
= usearch_openFromCollator(pattern
, 16, text
, 32, EN_US_
, NULL
,
1340 if (U_FAILURE(status
)) {
1341 log_err("Error opening search %s\n", u_errorName(status
));
1345 usearch_setAttribute(strsrch
, USEARCH_OVERLAP
, USEARCH_DEFAULT
, &status
);
1346 if (U_FAILURE(status
) ||
1347 usearch_getAttribute(strsrch
, USEARCH_OVERLAP
) != USEARCH_OFF
) {
1348 log_err("Error setting overlap to the default\n");
1350 usearch_setAttribute(strsrch
, USEARCH_OVERLAP
, USEARCH_ON
, &status
);
1351 if (U_FAILURE(status
) ||
1352 usearch_getAttribute(strsrch
, USEARCH_OVERLAP
) != USEARCH_ON
) {
1353 log_err("Error setting overlap true\n");
1355 usearch_setAttribute(strsrch
, USEARCH_OVERLAP
, USEARCH_OFF
, &status
);
1356 if (U_FAILURE(status
) ||
1357 usearch_getAttribute(strsrch
, USEARCH_OVERLAP
) != USEARCH_OFF
) {
1358 log_err("Error setting overlap false\n");
1360 usearch_setAttribute(strsrch
, USEARCH_OVERLAP
,
1361 USEARCH_ATTRIBUTE_VALUE_COUNT
, &status
);
1362 if (U_SUCCESS(status
)) {
1363 log_err("Error setting overlap to illegal value\n");
1365 status
= U_ZERO_ERROR
;
1366 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_DEFAULT
,
1368 if (U_FAILURE(status
) ||
1369 usearch_getAttribute(strsrch
, USEARCH_CANONICAL_MATCH
) !=
1371 log_err("Error setting canonical match to the default\n");
1373 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
1375 if (U_FAILURE(status
) ||
1376 usearch_getAttribute(strsrch
, USEARCH_CANONICAL_MATCH
) !=
1378 log_err("Error setting canonical match true\n");
1380 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_OFF
,
1382 if (U_FAILURE(status
) ||
1383 usearch_getAttribute(strsrch
, USEARCH_CANONICAL_MATCH
) !=
1385 log_err("Error setting canonical match false\n");
1387 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
,
1388 USEARCH_ATTRIBUTE_VALUE_COUNT
, &status
);
1389 if (U_SUCCESS(status
)) {
1390 log_err("Error setting canonical match to illegal value\n");
1392 status
= U_ZERO_ERROR
;
1393 usearch_setAttribute(strsrch
, USEARCH_ATTRIBUTE_COUNT
, USEARCH_DEFAULT
,
1395 if (U_SUCCESS(status
)) {
1396 log_err("Error setting illegal attribute success\n");
1399 usearch_close(strsrch
);
1403 static void TestGetMatch(void)
1406 UErrorCode status
= U_ZERO_ERROR
;
1409 SearchData search
= MATCH
[0];
1410 int32_t matchindex
= search
.offset
[count
];
1411 UStringSearch
*strsrch
;
1413 UChar matchtext
[128];
1416 if (U_FAILURE(status
)) {
1417 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1421 if (usearch_getMatchedStart(NULL
) != USEARCH_DONE
||
1422 usearch_getMatchedLength(NULL
) != USEARCH_DONE
) {
1424 "Expected start and length of NULL string search should be USEARCH_DONE\n");
1427 u_unescape(search
.text
, text
, 128);
1428 u_unescape(search
.pattern
, pattern
, 32);
1429 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, EN_US_
,
1431 if (U_FAILURE(status
)) {
1432 log_err("Error opening string search %s\n", u_errorName(status
));
1433 if (strsrch
!= NULL
) {
1434 usearch_close(strsrch
);
1439 while (U_SUCCESS(status
) && matchindex
>= 0) {
1440 int32_t matchlength
= search
.size
[count
];
1441 usearch_next(strsrch
, &status
);
1442 if (matchindex
!= usearch_getMatchedStart(strsrch
) ||
1443 matchlength
!= usearch_getMatchedLength(strsrch
)) {
1444 char *str
= toCharString(usearch_getText(strsrch
, &textlength
));
1445 log_err("Text: %s\n", str
);
1446 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
1447 log_err("Pattern: %s\n", str
);
1448 log_err("Error match found at %d %d\n",
1449 usearch_getMatchedStart(strsrch
),
1450 usearch_getMatchedLength(strsrch
));
1455 status
= U_ZERO_ERROR
;
1456 if (usearch_getMatchedText(NULL
, matchtext
, 128, &status
) !=
1457 USEARCH_DONE
|| U_SUCCESS(status
)){
1458 log_err("Error expecting errors with NULL string search\n");
1460 status
= U_ZERO_ERROR
;
1461 if (usearch_getMatchedText(strsrch
, NULL
, 0, &status
) !=
1462 (int32_t)matchlength
|| U_SUCCESS(status
)){
1463 log_err("Error pre-flighting match length\n");
1465 status
= U_ZERO_ERROR
;
1466 if (usearch_getMatchedText(strsrch
, matchtext
, 0, &status
) !=
1467 (int32_t)matchlength
|| U_SUCCESS(status
)){
1468 log_err("Error getting match text with buffer size 0\n");
1470 status
= U_ZERO_ERROR
;
1471 if (usearch_getMatchedText(strsrch
, matchtext
, matchlength
, &status
)
1472 != (int32_t)matchlength
|| matchtext
[matchlength
- 1] == 0 ||
1474 log_err("Error getting match text with exact size\n");
1476 status
= U_ZERO_ERROR
;
1477 if (usearch_getMatchedText(strsrch
, matchtext
, 128, &status
) !=
1478 (int32_t) matchlength
|| U_FAILURE(status
) ||
1480 usearch_getText(strsrch
, &textlength
) + matchindex
,
1481 matchlength
* sizeof(UChar
)) != 0 ||
1482 matchtext
[matchlength
] != 0) {
1483 log_err("Error getting matched text\n");
1486 matchindex
= search
.offset
[count
];
1488 status
= U_ZERO_ERROR
;
1489 usearch_next(strsrch
, &status
);
1490 if (usearch_getMatchedStart(strsrch
) != USEARCH_DONE
||
1491 usearch_getMatchedLength(strsrch
) != 0) {
1492 log_err("Error end of match not found\n");
1494 status
= U_ZERO_ERROR
;
1495 if (usearch_getMatchedText(strsrch
, matchtext
, 128, &status
) !=
1497 log_err("Error getting null matches\n");
1499 usearch_close(strsrch
);
1503 static void TestSetMatch(void)
1506 UErrorCode status
= U_ZERO_ERROR
;
1508 if (U_FAILURE(status
)) {
1509 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1512 while (MATCH
[count
].text
!= NULL
) {
1513 SearchData search
= MATCH
[count
];
1515 int offsetIndex
= 0;
1518 UStringSearch
*strsrch
;
1519 status
= U_ZERO_ERROR
;
1521 if (usearch_first(NULL
, &status
) != USEARCH_DONE
||
1522 usearch_last(NULL
, &status
) != USEARCH_DONE
) {
1523 log_err("Error getting the first and last match of a NULL string search\n");
1525 u_unescape(search
.text
, text
, 128);
1526 u_unescape(search
.pattern
, pattern
, 32);
1527 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, EN_US_
,
1529 if (U_FAILURE(status
)) {
1530 log_err("Error opening string search %s\n", u_errorName(status
));
1531 if (strsrch
!= NULL
) {
1532 usearch_close(strsrch
);
1538 while (search
.offset
[size
] != -1) {
1542 if (usearch_first(strsrch
, &status
) != search
.offset
[0] ||
1543 U_FAILURE(status
)) {
1544 log_err("Error getting first match\n");
1546 if (usearch_last(strsrch
, &status
) != search
.offset
[size
-1] ||
1547 U_FAILURE(status
)) {
1548 log_err("Error getting last match\n");
1551 while (offsetIndex
< size
) {
1552 if (offsetIndex
+ 2 < size
) {
1553 if (usearch_following(strsrch
, search
.offset
[offsetIndex
+ 2] - 1,
1554 &status
) != search
.offset
[offsetIndex
+ 2] ||
1555 U_FAILURE(status
)) {
1556 log_err("Error getting following match at index %d\n",
1557 search
.offset
[offsetIndex
+ 2] - 1);
1560 if (offsetIndex
+ 1 < size
) {
1561 if (usearch_preceding(strsrch
, search
.offset
[offsetIndex
+ 1] +
1562 search
.size
[offsetIndex
+ 1] + 1,
1563 &status
) != search
.offset
[offsetIndex
+ 1] ||
1564 U_FAILURE(status
)) {
1565 log_err("Error getting preceeding match at index %d\n",
1566 search
.offset
[offsetIndex
+ 1] + 1);
1571 status
= U_ZERO_ERROR
;
1572 if (usearch_following(strsrch
, u_strlen(text
), &status
) !=
1574 log_err("Error expecting out of bounds match\n");
1576 if (usearch_preceding(strsrch
, 0, &status
) != USEARCH_DONE
) {
1577 log_err("Error expecting out of bounds match\n");
1580 usearch_close(strsrch
);
1585 static void TestReset(void)
1587 UErrorCode status
= U_ZERO_ERROR
;
1588 UChar text
[] = {0x66, 0x69, 0x73, 0x68, 0x20,
1589 0x66, 0x69, 0x73, 0x68};
1590 UChar pattern
[] = {0x73};
1591 UStringSearch
*strsrch
;
1594 if (U_FAILURE(status
)) {
1595 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1598 strsrch
= usearch_openFromCollator(pattern
, 1, text
, 9,
1599 EN_US_
, NULL
, &status
);
1600 if (U_FAILURE(status
)) {
1601 log_err("Error opening string search %s\n", u_errorName(status
));
1602 if (strsrch
!= NULL
) {
1603 usearch_close(strsrch
);
1607 usearch_setAttribute(strsrch
, USEARCH_OVERLAP
, USEARCH_ON
, &status
);
1608 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
1610 usearch_setOffset(strsrch
, 9, &status
);
1611 if (U_FAILURE(status
)) {
1612 log_err("Error setting attributes and offsets\n");
1615 usearch_reset(strsrch
);
1616 if (usearch_getAttribute(strsrch
, USEARCH_OVERLAP
) != USEARCH_OFF
||
1617 usearch_getAttribute(strsrch
, USEARCH_CANONICAL_MATCH
) !=
1619 usearch_getOffset(strsrch
) != 0 ||
1620 usearch_getMatchedLength(strsrch
) != 0 ||
1621 usearch_getMatchedStart(strsrch
) != USEARCH_DONE
) {
1622 log_err("Error resetting string search\n");
1624 usearch_previous(strsrch
, &status
);
1625 if (usearch_getMatchedStart(strsrch
) != 7 ||
1626 usearch_getMatchedLength(strsrch
) != 1) {
1627 log_err("Error resetting string search\n");
1630 usearch_close(strsrch
);
1634 static void TestSupplementary(void)
1637 UErrorCode status
= U_ZERO_ERROR
;
1639 if (U_FAILURE(status
)) {
1640 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1643 while (SUPPLEMENTARY
[count
].text
!= NULL
) {
1644 if (!assertEqual(SUPPLEMENTARY
[count
])) {
1645 log_err("Error at test number %d\n", count
);
1652 static void TestContraction(void)
1657 UCollator
*collator
;
1658 UErrorCode status
= U_ZERO_ERROR
;
1660 UStringSearch
*strsrch
;
1661 memset(rules
, 0, 128*sizeof(UChar
));
1662 memset(pattern
, 0, 128*sizeof(UChar
));
1663 memset(text
, 0, 128*sizeof(UChar
));
1665 u_unescape(CONTRACTIONRULE
, rules
, 128);
1666 collator
= ucol_openRules(rules
, u_strlen(rules
), UCOL_ON
,
1667 UCOL_TERTIARY
, NULL
, &status
);
1668 if(status
== U_FILE_ACCESS_ERROR
) {
1669 log_data_err("Is your data around?\n");
1671 } else if(U_FAILURE(status
)) {
1672 log_err("Error opening collator %s\n", u_errorName(status
));
1675 strsrch
= usearch_openFromCollator(pattern
, 1, text
, 1, collator
, NULL
,
1677 if (U_FAILURE(status
)) {
1678 log_err("Error opening string search %s\n", u_errorName(status
));
1681 while (CONTRACTION
[count
].text
!= NULL
) {
1682 u_unescape(CONTRACTION
[count
].text
, text
, 128);
1683 u_unescape(CONTRACTION
[count
].pattern
, pattern
, 128);
1684 usearch_setText(strsrch
, text
, -1, &status
);
1685 usearch_setPattern(strsrch
, pattern
, -1, &status
);
1686 if (!assertEqualWithUStringSearch(strsrch
, CONTRACTION
[count
])) {
1687 log_err("Error at test number %d\n", count
);
1691 usearch_close(strsrch
);
1692 ucol_close(collator
);
1695 static void TestIgnorable(void)
1700 UCollator
*collator
;
1701 UErrorCode status
= U_ZERO_ERROR
;
1702 UStringSearch
*strsrch
;
1705 memset(rules
, 0, 128*sizeof(UChar
));
1706 memset(pattern
, 0, 128*sizeof(UChar
));
1707 memset(text
, 0, 128*sizeof(UChar
));
1709 u_unescape(IGNORABLERULE
, rules
, 128);
1710 collator
= ucol_openRules(rules
, u_strlen(rules
), UCOL_ON
,
1711 IGNORABLE
[count
].strength
, NULL
, &status
);
1712 if(status
== U_FILE_ACCESS_ERROR
) {
1713 log_data_err("Is your data around?\n");
1715 } else if(U_FAILURE(status
)) {
1716 log_err("Error opening collator %s\n", u_errorName(status
));
1719 strsrch
= usearch_openFromCollator(pattern
, 1, text
, 1, collator
, NULL
,
1721 if (U_FAILURE(status
)) {
1722 log_err("Error opening string search %s\n", u_errorName(status
));
1725 while (IGNORABLE
[count
].text
!= NULL
) {
1726 u_unescape(IGNORABLE
[count
].text
, text
, 128);
1727 u_unescape(IGNORABLE
[count
].pattern
, pattern
, 128);
1728 usearch_setText(strsrch
, text
, -1, &status
);
1729 usearch_setPattern(strsrch
, pattern
, -1, &status
);
1730 if (!assertEqualWithUStringSearch(strsrch
, IGNORABLE
[count
])) {
1731 log_err("Error at test number %d\n", count
);
1735 usearch_close(strsrch
);
1736 ucol_close(collator
);
1739 static void TestDiacriticMatch(void)
1743 UErrorCode status
= U_ZERO_ERROR
;
1744 UStringSearch
*strsrch
= NULL
;
1745 UCollator
*coll
= NULL
;
1749 memset(pattern
, 0, 128*sizeof(UChar
));
1750 memset(text
, 0, 128*sizeof(UChar
));
1752 strsrch
= usearch_open(pattern
, 1, text
, 1, uloc_getDefault(), NULL
, &status
);
1753 if (U_FAILURE(status
)) {
1754 log_err_status(status
, "Error opening string search %s\n", u_errorName(status
));
1758 search
= DIACRITICMATCH
[count
];
1759 while (search
.text
!= NULL
) {
1760 if (search
.collator
!= NULL
) {
1761 coll
= ucol_openFromShortString(search
.collator
, FALSE
, NULL
, &status
);
1763 /* Always use "en_US" because some of these tests fail in Danish locales. */
1764 coll
= ucol_open("en_US"/*uloc_getDefault()*/, &status
);
1765 ucol_setStrength(coll
, search
.strength
);
1767 if (U_FAILURE(status
)) {
1768 log_err("Error opening string search collator(\"%s\") %s\n", search
.collator
, u_errorName(status
));
1772 usearch_setCollator(strsrch
, coll
, &status
);
1773 if (U_FAILURE(status
)) {
1774 log_err("Error setting string search collator %s\n", u_errorName(status
));
1778 u_unescape(search
.text
, text
, 128);
1779 u_unescape(search
.pattern
, pattern
, 128);
1780 usearch_setText(strsrch
, text
, -1, &status
);
1781 usearch_setPattern(strsrch
, pattern
, -1, &status
);
1782 if (!assertEqualWithUStringSearch(strsrch
, search
)) {
1783 log_err("Error at test number %d\n", count
);
1787 search
= DIACRITICMATCH
[++count
];
1789 usearch_close(strsrch
);
1792 static void TestCanonical(void)
1795 UErrorCode status
= U_ZERO_ERROR
;
1797 if (U_FAILURE(status
)) {
1798 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1801 while (BASICCANONICAL
[count
].text
!= NULL
) {
1802 if (!assertCanonicalEqual(BASICCANONICAL
[count
])) {
1803 log_err("Error at test number %d\n", count
);
1810 static void TestNormCanonical(void)
1813 UErrorCode status
= U_ZERO_ERROR
;
1815 if (U_FAILURE(status
)) {
1816 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1819 ucol_setAttribute(EN_US_
, UCOL_NORMALIZATION_MODE
, UCOL_ON
, &status
);
1821 while (NORMCANONICAL
[count
].text
!= NULL
) {
1822 if (!assertCanonicalEqual(NORMCANONICAL
[count
])) {
1823 log_err("Error at test number %d\n", count
);
1827 ucol_setAttribute(EN_US_
, UCOL_NORMALIZATION_MODE
, UCOL_OFF
, &status
);
1831 static void TestStrengthCanonical(void)
1834 UErrorCode status
= U_ZERO_ERROR
;
1836 if (U_FAILURE(status
)) {
1837 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1840 while (STRENGTHCANONICAL
[count
].text
!= NULL
) {
1841 if (!assertCanonicalEqual(STRENGTHCANONICAL
[count
])) {
1842 log_err("Error at test number %d\n", count
);
1849 static void TestBreakIteratorCanonical(void) {
1850 UErrorCode status
= U_ZERO_ERROR
;
1855 #if !UCONFIG_NO_BREAK_ITERATION
1858 if (U_FAILURE(status
)) {
1859 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1863 /* 0-3 test are fixed */
1866 const SearchData
*search
= &(BREAKITERATORCANONICAL
[count
]);
1867 UCollator
*collator
= getCollator(search
->collator
);
1868 UBreakIterator
*breaker
= getBreakIterator(search
->breaker
);
1869 UStringSearch
*strsrch
;
1871 u_unescape(search
->text
, text
, 128);
1872 u_unescape(search
->pattern
, pattern
, 32);
1873 ucol_setStrength(collator
, search
->strength
);
1875 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, collator
,
1877 if(status
== U_FILE_ACCESS_ERROR
) {
1878 log_data_err("Is your data around?\n");
1879 goto ENDTESTBREAKITERATOR
;
1880 } else if(U_FAILURE(status
)) {
1881 log_err("Error opening searcher\n");
1882 goto ENDTESTBREAKITERATOR
;
1884 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
1886 if (U_FAILURE(status
) ||
1887 usearch_getBreakIterator(strsrch
) != breaker
) {
1888 log_err("Error setting break iterator\n");
1889 usearch_close(strsrch
);
1890 goto ENDTESTBREAKITERATOR
;
1892 if (!assertEqualWithUStringSearch(strsrch
, *search
)) {
1893 ucol_setStrength(collator
, UCOL_TERTIARY
);
1894 usearch_close(strsrch
);
1895 goto ENDTESTBREAKITERATOR
;
1897 search
= &(BREAKITERATOREXACT
[count
+ 1]);
1898 breaker
= getBreakIterator(search
->breaker
);
1899 usearch_setBreakIterator(strsrch
, breaker
, &status
);
1900 if (U_FAILURE(status
) || usearch_getBreakIterator(strsrch
) != breaker
) {
1901 log_err("Error setting break iterator\n");
1902 usearch_close(strsrch
);
1903 goto ENDTESTBREAKITERATOR
;
1905 usearch_reset(strsrch
);
1906 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
1908 if (!assertEqualWithUStringSearch(strsrch
, *search
)) {
1909 log_err("Error at test number %d\n", count
);
1910 usearch_close(strsrch
);
1911 goto ENDTESTBREAKITERATOR
;
1913 usearch_close(strsrch
);
1917 while (BREAKITERATORCANONICAL
[count
].text
!= NULL
) {
1918 if (!assertEqual(BREAKITERATORCANONICAL
[count
])) {
1919 log_err("Error at test number %d\n", count
);
1920 goto ENDTESTBREAKITERATOR
;
1925 ENDTESTBREAKITERATOR
:
1930 static void TestVariableCanonical(void)
1933 UErrorCode status
= U_ZERO_ERROR
;
1935 if (U_FAILURE(status
)) {
1936 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1939 ucol_setAttribute(EN_US_
, UCOL_ALTERNATE_HANDLING
, UCOL_SHIFTED
, &status
);
1940 if (U_FAILURE(status
)) {
1941 log_err("Error setting collation alternate attribute %s\n",
1942 u_errorName(status
));
1944 while (VARIABLE
[count
].text
!= NULL
) {
1945 log_verbose("variable %d\n", count
);
1946 if (!assertCanonicalEqual(VARIABLE
[count
])) {
1947 log_err("Error at test number %d\n", count
);
1951 ucol_setAttribute(EN_US_
, UCOL_ALTERNATE_HANDLING
,
1952 UCOL_NON_IGNORABLE
, &status
);
1956 static void TestOverlapCanonical(void)
1959 UErrorCode status
= U_ZERO_ERROR
;
1961 if (U_FAILURE(status
)) {
1962 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
1965 while (OVERLAPCANONICAL
[count
].text
!= NULL
) {
1966 if (!assertEqualWithAttribute(OVERLAPCANONICAL
[count
], USEARCH_ON
,
1968 log_err("Error at overlap test number %d\n", count
);
1973 while (NONOVERLAP
[count
].text
!= NULL
) {
1974 if (!assertCanonicalEqual(NONOVERLAPCANONICAL
[count
])) {
1975 log_err("Error at non overlap test number %d\n", count
);
1984 const SearchData
*search
= &(OVERLAPCANONICAL
[count
]);
1985 UCollator
*collator
= getCollator(search
->collator
);
1986 UStringSearch
*strsrch
;
1987 status
= U_ZERO_ERROR
;
1989 u_unescape(search
->text
, text
, 128);
1990 u_unescape(search
->pattern
, pattern
, 32);
1991 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, collator
,
1993 if(status
== U_FILE_ACCESS_ERROR
) {
1994 log_data_err("Is your data around?\n");
1996 } else if(U_FAILURE(status
)) {
1997 log_err("Error opening searcher\n");
2000 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
2002 usearch_setAttribute(strsrch
, USEARCH_OVERLAP
, USEARCH_ON
, &status
);
2003 if (U_FAILURE(status
) ||
2004 usearch_getAttribute(strsrch
, USEARCH_OVERLAP
) != USEARCH_ON
) {
2005 log_err("Error setting overlap option\n");
2007 if (!assertEqualWithUStringSearch(strsrch
, *search
)) {
2008 usearch_close(strsrch
);
2011 search
= &(NONOVERLAPCANONICAL
[count
]);
2012 usearch_setAttribute(strsrch
, USEARCH_OVERLAP
, USEARCH_OFF
, &status
);
2013 if (U_FAILURE(status
) ||
2014 usearch_getAttribute(strsrch
, USEARCH_OVERLAP
) != USEARCH_OFF
) {
2015 log_err("Error setting overlap option\n");
2017 usearch_reset(strsrch
);
2018 if (!assertEqualWithUStringSearch(strsrch
, *search
)) {
2019 usearch_close(strsrch
);
2020 log_err("Error at test number %d\n", count
);
2024 usearch_close(strsrch
);
2029 static void TestCollatorCanonical(void)
2031 /* test collator that thinks "o" and "p" are the same thing */
2033 UCollator
*tailored
= NULL
;
2034 UErrorCode status
= U_ZERO_ERROR
;
2037 UStringSearch
*strsrch
;
2040 if (U_FAILURE(status
)) {
2041 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
2044 u_unescape(COLLATORCANONICAL
[0].text
, text
, 128);
2045 u_unescape(COLLATORCANONICAL
[0].pattern
, pattern
, 32);
2047 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, EN_US_
,
2049 if(status
== U_FILE_ACCESS_ERROR
) {
2050 log_data_err("Is your data around?\n");
2052 } else if(U_FAILURE(status
)) {
2053 log_err("Error opening searcher\n");
2056 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
2058 if (U_FAILURE(status
)) {
2059 log_err("Error opening string search %s\n", u_errorName(status
));
2061 if (!assertEqualWithUStringSearch(strsrch
, COLLATORCANONICAL
[0])) {
2062 goto ENDTESTCOLLATOR
;
2065 u_unescape(TESTCOLLATORRULE
, rules
, 32);
2066 tailored
= ucol_openRules(rules
, -1, UCOL_ON
,
2067 COLLATORCANONICAL
[1].strength
, NULL
, &status
);
2068 if (U_FAILURE(status
)) {
2069 log_err("Error opening rule based collator %s\n", u_errorName(status
));
2072 usearch_setCollator(strsrch
, tailored
, &status
);
2073 if (U_FAILURE(status
) || usearch_getCollator(strsrch
) != tailored
) {
2074 log_err("Error setting rule based collator\n");
2076 usearch_reset(strsrch
);
2077 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
2079 if (!assertEqualWithUStringSearch(strsrch
, COLLATORCANONICAL
[1])) {
2080 goto ENDTESTCOLLATOR
;
2083 usearch_setCollator(strsrch
, EN_US_
, &status
);
2084 usearch_reset(strsrch
);
2085 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
2087 if (U_FAILURE(status
) || usearch_getCollator(strsrch
) != EN_US_
) {
2088 log_err("Error setting rule based collator\n");
2090 if (!assertEqualWithUStringSearch(strsrch
, COLLATORCANONICAL
[0])) {
2091 goto ENDTESTCOLLATOR
;
2095 usearch_close(strsrch
);
2096 if (tailored
!= NULL
) {
2097 ucol_close(tailored
);
2102 static void TestPatternCanonical(void)
2104 UStringSearch
*strsrch
;
2109 UErrorCode status
= U_ZERO_ERROR
;
2112 if (U_FAILURE(status
)) {
2113 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
2116 u_unescape(PATTERNCANONICAL
[0].text
, text
, 128);
2117 u_unescape(PATTERNCANONICAL
[0].pattern
, pattern
, 32);
2119 ucol_setStrength(EN_US_
, PATTERNCANONICAL
[0].strength
);
2120 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, EN_US_
,
2122 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
2124 if (U_FAILURE(status
)) {
2125 log_err("Error opening string search %s\n", u_errorName(status
));
2126 goto ENDTESTPATTERN
;
2128 temp
= usearch_getPattern(strsrch
, &templength
);
2129 if (u_strcmp(pattern
, temp
) != 0) {
2130 log_err("Error setting pattern\n");
2132 if (!assertEqualWithUStringSearch(strsrch
, PATTERNCANONICAL
[0])) {
2133 goto ENDTESTPATTERN
;
2136 u_unescape(PATTERNCANONICAL
[1].pattern
, pattern
, 32);
2137 usearch_setPattern(strsrch
, pattern
, -1, &status
);
2138 temp
= usearch_getPattern(strsrch
, &templength
);
2139 if (u_strcmp(pattern
, temp
) != 0) {
2140 log_err("Error setting pattern\n");
2141 goto ENDTESTPATTERN
;
2143 usearch_reset(strsrch
);
2144 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
2146 if (U_FAILURE(status
)) {
2147 log_err("Error setting pattern %s\n", u_errorName(status
));
2149 if (!assertEqualWithUStringSearch(strsrch
, PATTERNCANONICAL
[1])) {
2150 goto ENDTESTPATTERN
;
2153 u_unescape(PATTERNCANONICAL
[0].pattern
, pattern
, 32);
2154 usearch_setPattern(strsrch
, pattern
, -1, &status
);
2155 temp
= usearch_getPattern(strsrch
, &templength
);
2156 if (u_strcmp(pattern
, temp
) != 0) {
2157 log_err("Error setting pattern\n");
2158 goto ENDTESTPATTERN
;
2160 usearch_reset(strsrch
);
2161 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
2163 if (U_FAILURE(status
)) {
2164 log_err("Error setting pattern %s\n", u_errorName(status
));
2166 if (!assertEqualWithUStringSearch(strsrch
, PATTERNCANONICAL
[0])) {
2167 goto ENDTESTPATTERN
;
2170 ucol_setStrength(EN_US_
, UCOL_TERTIARY
);
2171 if (strsrch
!= NULL
) {
2172 usearch_close(strsrch
);
2177 static void TestTextCanonical(void)
2179 UStringSearch
*strsrch
;
2184 UErrorCode status
= U_ZERO_ERROR
;
2186 u_unescape(TEXTCANONICAL
[0].text
, text
, 128);
2187 u_unescape(TEXTCANONICAL
[0].pattern
, pattern
, 32);
2190 if (U_FAILURE(status
)) {
2191 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
2194 strsrch
= usearch_openFromCollator(pattern
, -1, text
, -1, EN_US_
,
2196 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
2199 if (U_FAILURE(status
)) {
2200 log_err("Error opening string search %s\n", u_errorName(status
));
2201 goto ENDTESTPATTERN
;
2203 temp
= usearch_getText(strsrch
, &templength
);
2204 if (u_strcmp(text
, temp
) != 0) {
2205 log_err("Error setting text\n");
2207 if (!assertEqualWithUStringSearch(strsrch
, TEXTCANONICAL
[0])) {
2208 goto ENDTESTPATTERN
;
2211 u_unescape(TEXTCANONICAL
[1].text
, text
, 32);
2212 usearch_setText(strsrch
, text
, -1, &status
);
2213 temp
= usearch_getText(strsrch
, &templength
);
2214 if (u_strcmp(text
, temp
) != 0) {
2215 log_err("Error setting text\n");
2216 goto ENDTESTPATTERN
;
2218 if (U_FAILURE(status
)) {
2219 log_err("Error setting text %s\n", u_errorName(status
));
2221 if (!assertEqualWithUStringSearch(strsrch
, TEXTCANONICAL
[1])) {
2222 goto ENDTESTPATTERN
;
2225 u_unescape(TEXTCANONICAL
[0].text
, text
, 32);
2226 usearch_setText(strsrch
, text
, -1, &status
);
2227 temp
= usearch_getText(strsrch
, &templength
);
2228 if (u_strcmp(text
, temp
) != 0) {
2229 log_err("Error setting text\n");
2230 goto ENDTESTPATTERN
;
2232 if (U_FAILURE(status
)) {
2233 log_err("Error setting pattern %s\n", u_errorName(status
));
2235 if (!assertEqualWithUStringSearch(strsrch
, TEXTCANONICAL
[0])) {
2236 goto ENDTESTPATTERN
;
2239 if (strsrch
!= NULL
) {
2240 usearch_close(strsrch
);
2245 static void TestCompositeBoundariesCanonical(void)
2248 UErrorCode status
= U_ZERO_ERROR
;
2250 if (U_FAILURE(status
)) {
2251 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
2254 while (COMPOSITEBOUNDARIESCANONICAL
[count
].text
!= NULL
) {
2255 log_verbose("composite %d\n", count
);
2256 if (!assertCanonicalEqual(COMPOSITEBOUNDARIESCANONICAL
[count
])) {
2257 log_err("Error at test number %d\n", count
);
2264 static void TestGetSetOffsetCanonical(void)
2266 int searchDataIndex
= 0;
2269 UErrorCode status
= U_ZERO_ERROR
;
2270 UStringSearch
*strsrch
;
2271 UCollator
*collator
;
2273 memset(pattern
, 0, 32*sizeof(UChar
));
2274 memset(text
, 0, 128*sizeof(UChar
));
2277 if (U_FAILURE(status
)) {
2278 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
2281 strsrch
= usearch_openFromCollator(pattern
, 16, text
, 32, EN_US_
, NULL
,
2284 collator
= usearch_getCollator(strsrch
);
2285 ucol_setAttribute(collator
, UCOL_NORMALIZATION_MODE
, UCOL_ON
, &status
);
2287 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
2290 /* testing out of bounds error */
2291 usearch_setOffset(strsrch
, -1, &status
);
2292 if (U_SUCCESS(status
)) {
2293 log_err("Error expecting set offset error\n");
2295 usearch_setOffset(strsrch
, 128, &status
);
2296 if (U_SUCCESS(status
)) {
2297 log_err("Error expecting set offset error\n");
2299 while (BASICCANONICAL
[searchDataIndex
].text
!= NULL
) {
2301 SearchData search
= BASICCANONICAL
[searchDataIndex
++];
2302 int32_t matchindex
= search
.offset
[count
];
2305 if (BASICCANONICAL
[searchDataIndex
].text
== NULL
) {
2306 /* skip the last one */
2310 u_unescape(search
.text
, text
, 128);
2311 u_unescape(search
.pattern
, pattern
, 32);
2312 status
= U_ZERO_ERROR
;
2313 usearch_setText(strsrch
, text
, -1, &status
);
2314 usearch_setPattern(strsrch
, pattern
, -1, &status
);
2315 while (U_SUCCESS(status
) && matchindex
>= 0) {
2316 uint32_t matchlength
= search
.size
[count
];
2317 usearch_next(strsrch
, &status
);
2318 if (matchindex
!= usearch_getMatchedStart(strsrch
) ||
2319 matchlength
!= (uint32_t)usearch_getMatchedLength(strsrch
)) {
2320 char *str
= toCharString(usearch_getText(strsrch
,
2322 log_err("Text: %s\n", str
);
2323 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
2324 log_err("Pattern: %s\n", str
);
2325 log_err("Error match found at %d %d\n",
2326 usearch_getMatchedStart(strsrch
),
2327 usearch_getMatchedLength(strsrch
));
2330 matchindex
= search
.offset
[count
+ 1] == -1 ? -1 :
2331 search
.offset
[count
+ 2];
2332 if (search
.offset
[count
+ 1] != -1) {
2333 usearch_setOffset(strsrch
, search
.offset
[count
+ 1] + 1,
2335 if (usearch_getOffset(strsrch
) != search
.offset
[count
+ 1] + 1) {
2336 log_err("Error setting offset\n");
2343 usearch_next(strsrch
, &status
);
2344 if (usearch_getMatchedStart(strsrch
) != USEARCH_DONE
) {
2345 char *str
= toCharString(usearch_getText(strsrch
, &textlength
));
2346 log_err("Text: %s\n", str
);
2347 str
= toCharString(usearch_getPattern(strsrch
, &textlength
));
2348 log_err("Pattern: %s\n", str
);
2349 log_err("Error match found at %d %d\n",
2350 usearch_getMatchedStart(strsrch
),
2351 usearch_getMatchedLength(strsrch
));
2357 ucol_setAttribute(collator
, UCOL_NORMALIZATION_MODE
, UCOL_OFF
, &status
);
2358 usearch_close(strsrch
);
2362 static void TestSupplementaryCanonical(void)
2365 UErrorCode status
= U_ZERO_ERROR
;
2367 if (U_FAILURE(status
)) {
2368 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
2371 while (SUPPLEMENTARYCANONICAL
[count
].text
!= NULL
) {
2372 if (!assertCanonicalEqual(SUPPLEMENTARYCANONICAL
[count
])) {
2373 log_err("Error at test number %d\n", count
);
2380 static void TestContractionCanonical(void)
2385 UCollator
*collator
= NULL
;
2386 UErrorCode status
= U_ZERO_ERROR
;
2388 UStringSearch
*strsrch
= NULL
;
2389 memset(rules
, 0, 128*sizeof(UChar
));
2390 memset(pattern
, 0, 128*sizeof(UChar
));
2391 memset(text
, 0, 128*sizeof(UChar
));
2393 u_unescape(CONTRACTIONRULE
, rules
, 128);
2394 collator
= ucol_openRules(rules
, u_strlen(rules
), UCOL_ON
,
2395 UCOL_TERTIARY
, NULL
, &status
);
2396 if(status
== U_FILE_ACCESS_ERROR
) {
2397 log_data_err("Is your data around?\n");
2399 } else if(U_FAILURE(status
)) {
2400 log_err("Error opening collator %s\n", u_errorName(status
));
2403 strsrch
= usearch_openFromCollator(pattern
, 1, text
, 1, collator
, NULL
,
2405 usearch_setAttribute(strsrch
, USEARCH_CANONICAL_MATCH
, USEARCH_ON
,
2407 if (U_FAILURE(status
)) {
2408 log_err("Error opening string search %s\n", u_errorName(status
));
2411 while (CONTRACTIONCANONICAL
[count
].text
!= NULL
) {
2412 u_unescape(CONTRACTIONCANONICAL
[count
].text
, text
, 128);
2413 u_unescape(CONTRACTIONCANONICAL
[count
].pattern
, pattern
, 128);
2414 usearch_setText(strsrch
, text
, -1, &status
);
2415 usearch_setPattern(strsrch
, pattern
, -1, &status
);
2416 if (!assertEqualWithUStringSearch(strsrch
,
2417 CONTRACTIONCANONICAL
[count
])) {
2418 log_err("Error at test number %d\n", count
);
2422 usearch_close(strsrch
);
2423 ucol_close(collator
);
2426 static void TestNumeric(void) {
2427 UCollator
*coll
= NULL
;
2428 UStringSearch
*strsrch
= NULL
;
2429 UErrorCode status
= U_ZERO_ERROR
;
2433 memset(pattern
, 0, 128*sizeof(UChar
));
2434 memset(text
, 0, 128*sizeof(UChar
));
2436 coll
= ucol_open("", &status
);
2437 if(U_FAILURE(status
)) {
2438 log_data_err("Could not open UCA. Is your data around?\n");
2442 ucol_setAttribute(coll
, UCOL_NUMERIC_COLLATION
, UCOL_ON
, &status
);
2444 strsrch
= usearch_openFromCollator(pattern
, 1, text
, 1, coll
, NULL
, &status
);
2446 if(status
!= U_UNSUPPORTED_ERROR
|| U_SUCCESS(status
)) {
2447 log_err("Expected U_UNSUPPORTED_ERROR when trying to instantiate a search object from a CODAN collator, got %s instead\n", u_errorName(status
));
2449 usearch_close(strsrch
);
2457 /* This test is for ticket 4038 due to incorrect backward searching when certain patterns have a length > 1 */
2458 static void TestForwardBackward(void) {
2459 UErrorCode status
= U_ZERO_ERROR
;
2460 UCollator
*coll
= NULL
;
2461 UStringSearch
*search
= NULL
;
2462 UChar usrcstr
[32], value
[4];
2464 int32_t expectedPos
= 9;
2466 coll
= ucol_open("en_GB", &status
);
2467 if (U_FAILURE(status
)) {
2468 log_err_status(status
, "ucol_open failed: %s\n", u_errorName(status
));
2469 goto exitTestForwardBackward
;
2471 ucol_setAttribute(coll
, UCOL_STRENGTH
, UCOL_PRIMARY
, &status
);
2472 ucol_setAttribute(coll
, UCOL_CASE_LEVEL
, UCOL_ON
, &status
);
2473 ucol_setAttribute(coll
, UCOL_ALTERNATE_HANDLING
, UCOL_NON_IGNORABLE
, &status
);
2475 u_uastrcpy(usrcstr
, "QBitArray::bitarr_data"); /* text */
2476 u_uastrcpy(value
, "::"); /* pattern */
2478 search
= usearch_openFromCollator(value
, 2, usrcstr
, 22, coll
, NULL
, &status
);
2479 if (U_FAILURE(status
)) {
2480 log_err("usearch_openFromCollator failed: %s\n", u_errorName(status
));
2481 goto exitTestForwardBackward
;
2484 usearch_reset(search
);
2485 /* forward search */
2486 pos
= usearch_first(search
, &status
);
2487 if (pos
!= expectedPos
) {
2488 log_err("Expected search result: %d; Got instead: %d\n", expectedPos
, pos
);
2489 goto exitTestForwardBackward
;
2493 usearch_reset(search
);
2494 /* backward search */
2495 pos
= usearch_last(search
, &status
);
2496 if (pos
!= expectedPos
) {
2497 log_err("Expected search result: %d; Got instead: %d\n", expectedPos
, pos
);
2500 exitTestForwardBackward
:
2504 if (search
!= NULL
) {
2505 usearch_close(search
);
2509 #define TEST_ASSERT(x) \
2510 {if (U_FAILURE(x)) {log_err_status(x, "%s:%d: FAIL: test assertion failure \n", __FILE__, __LINE__);\
2513 static void TestSearchForNull(void) {
2516 UStringSearch
*search
;
2523 const UChar zerodigit
= 0x0030; /* 0 */
2524 const UChar nulldigit
= 0x0000; /* null */
2526 /* static const UChar var[(length)+1]=U_DECLARE_UTF16(cs) */
2527 #define PATTERN_LEN 4
2530 U_STRING_DECL(_pattern
, "IS 0", PATTERN_LEN
);
2531 U_STRING_DECL(_text
, "_0IS 0 OK?", TEXT_LEN
);
2532 UChar pattern
[PATTERN_LEN
+ 1], text
[TEXT_LEN
+ 1];
2534 U_STRING_INIT(_pattern
, "IS 0", PATTERN_LEN
);
2535 U_STRING_INIT(_text
, "_0IS 0 OK?", TEXT_LEN
);
2540 for (pos
= 0; pos
< PATTERN_LEN
; pos
++) {
2541 if (_pattern
[pos
] == zerodigit
) {
2542 pattern
[pos
] = nulldigit
;
2544 pattern
[pos
] = _pattern
[pos
];
2547 pattern
[PATTERN_LEN
] = 0x0000;
2549 for (pos
= 0; pos
< TEXT_LEN
; pos
++) {
2550 if (_text
[pos
] == zerodigit
) {
2551 text
[pos
] = nulldigit
;
2553 text
[pos
] = _text
[pos
];
2556 text
[TEXT_LEN
] = 0x0000;
2560 /* create a US-English collator */
2561 coll
= ucol_open("en_US", &ec
);
2563 /* make sure we didn't fail. */
2566 ucol_setStrength(coll
, UCOL_IDENTICAL
);
2568 /* open a search looking for 0 */
2569 search
= usearch_openFromCollator(pattern
, PATTERN_LEN
, text
,
2570 TEXT_LEN
, coll
, NULL
, &ec
);
2573 if (coll
!= NULL
&& search
!= NULL
) {
2574 pos
= usearch_first(search
, &ec
);
2575 len
= usearch_getMatchedLength(search
);
2576 if (pos
!= expectedPos
) {
2577 log_err("Expected search result: %d; Got instead: %d\n", expectedPos
,
2581 if (len
!= expectedLen
) {
2582 log_err("Expected search result length: %d; Got instead: %d\n",
2586 for (pos
= usearch_first(search
, &ec
); pos
!= USEARCH_DONE
; pos
2587 = usearch_next(search
, &ec
)) {
2588 log_verbose("Match at %d\n", pos
);
2592 if (count
!= expectedNum
) {
2593 log_err("Expected %d search hits, found %d\n", expectedNum
, count
);
2598 usearch_close(search
);
2601 static void TestStrengthIdentical(void)
2604 UErrorCode ec
= U_ZERO_ERROR
;
2605 UStringSearch
*search
;
2607 UChar pattern
[] = {0x05E9, 0x0591, 0x05E9};
2608 UChar text
[] = {0x05E9, 0x0592, 0x05E9};
2609 int32_t pLen
= UPRV_LENGTHOF(pattern
);
2610 int32_t tLen
= UPRV_LENGTHOF(text
);
2611 int32_t expectedPos
= 0;
2612 int32_t expectedLen
= 3;
2617 /* create a US-English collator */
2618 coll
= ucol_open ("en_US", &ec
);
2620 /* make sure we didn't fail. */
2623 ucol_setStrength( coll
, UCOL_TERTIARY
);
2625 /* open a search looking for 0 */
2626 search
= usearch_openFromCollator (pattern
, pLen
, text
, tLen
, coll
, NULL
, &ec
);
2629 if (coll
!= NULL
&& search
!= NULL
) {
2630 pos
= usearch_first(search
, &ec
);
2631 len
= usearch_getMatchedLength(search
);
2633 if(pos
!= expectedPos
) {
2634 log_err("Expected search result: %d; Got instead: %d\n", expectedPos
, pos
);
2637 if(len
!= expectedLen
) {
2638 log_err("Expected search result length: %d; Got instead: %d\n", expectedLen
, len
);
2641 /* Now try it at strength == UCOL_IDENTICAL */
2642 ucol_setStrength(coll
, UCOL_IDENTICAL
);
2643 usearch_reset(search
);
2645 pos
= usearch_first(search
, &ec
);
2646 len
= usearch_getMatchedLength(search
);
2649 log_err("Expected failure for strentgh = UCOL_IDENTICAL: got %d instead.\n", pos
);
2653 usearch_close(search
);
2658 * TestUsingSearchCollator
2662 const UChar
* pattern
;
2663 const int32_t * offsets
;
2665 const int32_t * matchLens
;
2666 } PatternAndOffsets
;
2668 static const UChar scKoText
[] = {
2670 /*01*/ 0xAC00, 0x0020, /* simple LV Hangul */
2671 /*03*/ 0xAC01, 0x0020, /* simple LVT Hangul */
2672 /*05*/ 0xAC0F, 0x0020, /* LVTT, last jamo expands for search */
2673 /*07*/ 0xAFFF, 0x0020, /* LLVVVTT, every jamo expands for search */
2674 /*09*/ 0x1100, 0x1161, 0x11A8, 0x0020, /* 0xAC01 as conjoining jamo */
2675 /*13*/ 0x1100, 0x1161, 0x1100, 0x0020, /* 0xAC01 as basic conjoining jamo (per search rules) */
2676 /*17*/ 0x3131, 0x314F, 0x3131, 0x0020, /* 0xAC01 as compatibility jamo */
2677 /*21*/ 0x1100, 0x1161, 0x11B6, 0x0020, /* 0xAC0F as conjoining jamo; last expands for search */
2678 /*25*/ 0x1100, 0x1161, 0x1105, 0x1112, 0x0020, /* 0xAC0F as basic conjoining jamo; last expands for search */
2679 /*30*/ 0x1101, 0x1170, 0x11B6, 0x0020, /* 0xAFFF as conjoining jamo; all expand for search */
2680 /*34*/ 0x00E6, 0x0020, /* small letter ae, expands */
2681 /*36*/ 0x1E4D, 0x0020, /* small letter o with tilde and acute, decomposes */
2685 static const UChar scKoPat0
[] = { 0xAC01, 0 };
2686 static const UChar scKoPat1
[] = { 0x1100, 0x1161, 0x11A8, 0 }; /* 0xAC01 as conjoining jamo */
2687 static const UChar scKoPat2
[] = { 0xAC0F, 0 };
2688 static const UChar scKoPat3
[] = { 0x1100, 0x1161, 0x1105, 0x1112, 0 }; /* 0xAC0F as basic conjoining jamo */
2689 static const UChar scKoPat4
[] = { 0xAFFF, 0 };
2690 static const UChar scKoPat5
[] = { 0x1101, 0x1170, 0x11B6, 0 }; /* 0xAFFF as conjoining jamo */
2692 static const int32_t scKoSrchOff01
[] = { 3, 9, 13 };
2693 static const int32_t scKoSrchOff23
[] = { 5, 21, 25 };
2694 static const int32_t scKoSrchOff45
[] = { 7, 30 };
2696 static const PatternAndOffsets scKoSrchPatternsOffsets
[] = {
2697 { scKoPat0
, scKoSrchOff01
, UPRV_LENGTHOF(scKoSrchOff01
), NULL
},
2698 { scKoPat1
, scKoSrchOff01
, UPRV_LENGTHOF(scKoSrchOff01
), NULL
},
2699 { scKoPat2
, scKoSrchOff23
, UPRV_LENGTHOF(scKoSrchOff23
), NULL
},
2700 { scKoPat3
, scKoSrchOff23
, UPRV_LENGTHOF(scKoSrchOff23
), NULL
},
2701 { scKoPat4
, scKoSrchOff45
, UPRV_LENGTHOF(scKoSrchOff45
), NULL
},
2702 { scKoPat5
, scKoSrchOff45
, UPRV_LENGTHOF(scKoSrchOff45
), NULL
},
2703 { NULL
, NULL
, 0, NULL
}
2706 static const int32_t scKoStndOff01
[] = { 3, 9 };
2707 static const int32_t scKoStndOff2
[] = { 5, 21 };
2708 static const int32_t scKoStndOff3
[] = { 25 };
2709 static const int32_t scKoStndOff45
[] = { 7, 30 };
2711 static const PatternAndOffsets scKoStndPatternsOffsets
[] = {
2712 { scKoPat0
, scKoStndOff01
, UPRV_LENGTHOF(scKoStndOff01
), NULL
},
2713 { scKoPat1
, scKoStndOff01
, UPRV_LENGTHOF(scKoStndOff01
), NULL
},
2714 { scKoPat2
, scKoStndOff2
, UPRV_LENGTHOF(scKoStndOff2
), NULL
},
2715 { scKoPat3
, scKoStndOff3
, UPRV_LENGTHOF(scKoStndOff3
), NULL
},
2716 { scKoPat4
, scKoStndOff45
, UPRV_LENGTHOF(scKoStndOff45
), NULL
},
2717 { scKoPat5
, scKoStndOff45
, UPRV_LENGTHOF(scKoStndOff45
), NULL
},
2718 { NULL
, NULL
, 0, NULL
}
2721 static const UChar scJaText
[] = {
2722 /*00*/ 0x304D,0x305F,0x0020,0x30AD,0x30BF,0x0020, /* kita, hiragana and katakana */
2723 /*06*/ 0x304D,0x3060,0x0020,0x30AD,0x30C0,0x0020, /* kida, hiragana and katakana */
2724 /*12*/ 0x306F,0x306D,0x0020,0x30CF,0x30CD,0x0020, /* hane, hiragana and katakana */
2725 /*18*/ 0x3070,0x306D,0x0020,0x30D0,0x30CD,0x0020, /* bane, hiragana and katakana */
2726 /*24*/ 0x3071,0x306D,0x0020,0x30D1,0x30CD,0x0020, /* pane, hiragana and katakana */
2730 static const UChar scJaPatH0
[] = { 0x304D,0x305F,0 }; /* kita, hiragana */
2731 static const UChar scJaPatK0
[] = { 0x30AD,0x30BF,0 }; /* kita, katakana */
2732 static const UChar scJaPatH1
[] = { 0x304D,0x3060,0 }; /* kida, hiragana */
2733 static const UChar scJaPatK1
[] = { 0x30AD,0x30C0,0 }; /* kida, katakana */
2734 static const UChar scJaPatH2
[] = { 0x306F,0x306D,0 }; /* hane, hiragana */
2735 static const UChar scJaPatK2
[] = { 0x30CF,0x30CD,0 }; /* hane, katakana */
2736 static const UChar scJaPatH3
[] = { 0x3070,0x306D,0 }; /* bane, hiragana */
2737 static const UChar scJaPatK3
[] = { 0x30D0,0x30CD,0 }; /* bane, katakana */
2738 static const UChar scJaPatH4
[] = { 0x3071,0x306D,0 }; /* pane, hiragana */
2739 static const UChar scJaPatK4
[] = { 0x30D1,0x30CD,0 }; /* pane, katakana */
2741 static const int32_t scJaStndOff01
[] = { 0, 3, 6, 9 };
2742 static const int32_t scJaStndOff234
[] = { 12, 15, 18, 21, 24, 27 };
2744 static const int32_t scJaSrchOff0
[] = { 0, 3 };
2745 static const int32_t scJaSrchOff1
[] = { 6, 9 };
2746 static const int32_t scJaSrchOff2
[] = { 12, 15 };
2747 static const int32_t scJaSrchOff3
[] = { 18, 21 };
2748 static const int32_t scJaSrchOff4
[] = { 24, 27 };
2750 static const PatternAndOffsets scJaStndPatternsOffsets
[] = {
2751 { scJaPatH0
, scJaStndOff01
, UPRV_LENGTHOF(scJaStndOff01
), NULL
},
2752 { scJaPatK0
, scJaStndOff01
, UPRV_LENGTHOF(scJaStndOff01
), NULL
},
2753 { scJaPatH1
, scJaStndOff01
, UPRV_LENGTHOF(scJaStndOff01
), NULL
},
2754 { scJaPatK1
, scJaStndOff01
, UPRV_LENGTHOF(scJaStndOff01
), NULL
},
2755 { scJaPatH2
, scJaStndOff234
, UPRV_LENGTHOF(scJaStndOff234
), NULL
},
2756 { scJaPatK2
, scJaStndOff234
, UPRV_LENGTHOF(scJaStndOff234
), NULL
},
2757 { scJaPatH3
, scJaStndOff234
, UPRV_LENGTHOF(scJaStndOff234
), NULL
},
2758 { scJaPatK3
, scJaStndOff234
, UPRV_LENGTHOF(scJaStndOff234
), NULL
},
2759 { scJaPatH4
, scJaStndOff234
, UPRV_LENGTHOF(scJaStndOff234
), NULL
},
2760 { scJaPatK4
, scJaStndOff234
, UPRV_LENGTHOF(scJaStndOff234
), NULL
},
2761 { NULL
, NULL
, 0, NULL
}
2764 static const PatternAndOffsets scJaSrchPatternsOffsets
[] = {
2765 { scJaPatH0
, scJaSrchOff0
, UPRV_LENGTHOF(scJaSrchOff0
), NULL
},
2766 { scJaPatK0
, scJaSrchOff0
, UPRV_LENGTHOF(scJaSrchOff0
), NULL
},
2767 { scJaPatH1
, scJaSrchOff1
, UPRV_LENGTHOF(scJaSrchOff1
), NULL
},
2768 { scJaPatK1
, scJaSrchOff1
, UPRV_LENGTHOF(scJaSrchOff1
), NULL
},
2769 { scJaPatH2
, scJaSrchOff2
, UPRV_LENGTHOF(scJaSrchOff2
), NULL
},
2770 { scJaPatK2
, scJaSrchOff2
, UPRV_LENGTHOF(scJaSrchOff2
), NULL
},
2771 { scJaPatH3
, scJaSrchOff3
, UPRV_LENGTHOF(scJaSrchOff3
), NULL
},
2772 { scJaPatK3
, scJaSrchOff3
, UPRV_LENGTHOF(scJaSrchOff3
), NULL
},
2773 { scJaPatH4
, scJaSrchOff4
, UPRV_LENGTHOF(scJaSrchOff4
), NULL
},
2774 { scJaPatK4
, scJaSrchOff4
, UPRV_LENGTHOF(scJaSrchOff4
), NULL
},
2775 { NULL
, NULL
, 0, NULL
}
2778 static const UChar scModsText
[] = {
2779 /*00*/ 0x0020,0xD83D,0xDC4D,
2780 /*03*/ 0x0020,0xD83D,0xDC4D,0xD83C,0xDFFC,
2781 /*08*/ 0x0020,0xD83D,0xDC4D,0xD83C,0xDFFF,
2782 /*13*/ 0x0020,0xD83D,0xDC4D,0x0300,
2786 static const UChar scMods0
[] = { 0xD83D,0xDC4D,0 }; /* hand with no mods */
2787 static const UChar scMods1
[] = { 0xD83D,0xDC4D,0xD83C,0xDFFC,0 }; /* hand with fitz 3 */
2788 static const UChar scMods2
[] = { 0xD83D,0xDC4D,0xD83C,0xDFFF,0 }; /* hand with fitz 6 */
2789 static const UChar scMods3
[] = { 0xD83D,0xDC4D,0x0300,0 }; /* hand with grave */
2791 static const int32_t scMods012
[] = { 1, 4, 9, 14 };
2792 static const int32_t scModsLens012
[] = { 2, 4, 4, 3 };
2794 static const PatternAndOffsets scModsPatternsOffsets
[] = {
2795 { scMods0
, scMods012
, UPRV_LENGTHOF(scMods012
), scModsLens012
},
2796 { scMods1
, scMods012
, UPRV_LENGTHOF(scMods012
), scModsLens012
},
2797 { scMods2
, scMods012
, UPRV_LENGTHOF(scMods012
), scModsLens012
},
2798 { scMods3
, scMods012
, UPRV_LENGTHOF(scMods012
), scModsLens012
},
2799 { NULL
, NULL
, 0, NULL
}
2803 const char * locale
;
2805 const PatternAndOffsets
* patternsAndOffsets
;
2808 static const TUSCItem tuscItems
[] = {
2809 { "root", scKoText
, scKoStndPatternsOffsets
},
2810 { "root@collation=search", scKoText
, scKoSrchPatternsOffsets
},
2811 { "ko@collation=search", scKoText
, scKoSrchPatternsOffsets
},
2812 { "root@colStrength=primary", scJaText
, scJaStndPatternsOffsets
},
2813 { "root@collation=search;colStrength=primary", scJaText
, scJaSrchPatternsOffsets
},
2814 { "ja@colStrength=primary", scJaText
, scJaStndPatternsOffsets
},
2815 { "ja@collation=search;colStrength=primary", scJaText
, scJaSrchPatternsOffsets
},
2816 { "root@collation=search;colStrength=primary", scModsText
, scModsPatternsOffsets
},
2817 { NULL
, NULL
, NULL
}
2820 static const UChar dummyPat
[] = { 0x0061, 0 };
2822 static void TestUsingSearchCollator(void)
2824 const TUSCItem
* tuscItemPtr
;
2825 for (tuscItemPtr
= tuscItems
; tuscItemPtr
->locale
!= NULL
; tuscItemPtr
++) {
2826 UErrorCode status
= U_ZERO_ERROR
;
2827 UCollator
* ucol
= ucol_open(tuscItemPtr
->locale
, &status
);
2828 if ( U_SUCCESS(status
) ) {
2829 UStringSearch
* usrch
= usearch_openFromCollator(dummyPat
, -1, tuscItemPtr
->text
, -1, ucol
, NULL
, &status
);
2830 if ( U_SUCCESS(status
) ) {
2831 const PatternAndOffsets
* patternsOffsetsPtr
;
2832 for ( patternsOffsetsPtr
= tuscItemPtr
->patternsAndOffsets
; patternsOffsetsPtr
->pattern
!= NULL
; patternsOffsetsPtr
++) {
2833 int32_t patLen
= u_strlen(patternsOffsetsPtr
->pattern
);
2834 usearch_setPattern(usrch
, patternsOffsetsPtr
->pattern
, patLen
, &status
);
2835 if ( U_SUCCESS(status
) ) {
2837 const int32_t * nextOffsetPtr
;
2838 const int32_t * limitOffsetPtr
;
2839 const int32_t * nextMatchLenPtr
;
2841 usearch_reset(usrch
);
2842 nextOffsetPtr
= patternsOffsetsPtr
->offsets
;
2843 limitOffsetPtr
= patternsOffsetsPtr
->offsets
+ patternsOffsetsPtr
->offsetsLen
;
2844 nextMatchLenPtr
= patternsOffsetsPtr
->matchLens
;
2846 offset
= usearch_next(usrch
, &status
);
2847 if ( U_FAILURE(status
) || offset
== USEARCH_DONE
) {
2850 if ( nextOffsetPtr
< limitOffsetPtr
) {
2851 if (offset
!= *nextOffsetPtr
) {
2852 log_err("error, locale %s, patn (%d) %04X %04X..., expected usearch_next %d, got %d\n",
2853 tuscItemPtr
->locale
, patLen
, patternsOffsetsPtr
->pattern
[0], patternsOffsetsPtr
->pattern
[1], *nextOffsetPtr
, offset
);
2854 nextOffsetPtr
= limitOffsetPtr
;
2856 } else if (nextMatchLenPtr
!= NULL
) {
2857 int32_t matchLen
= usearch_getMatchedLength(usrch
);
2858 if (matchLen
!= *nextMatchLenPtr
) {
2859 log_err("error, locale %s, patn (%d) %04X %04X..., offset %d, expected matchLen %d, got %d\n",
2860 tuscItemPtr
->locale
, patLen
, patternsOffsetsPtr
->pattern
[0], patternsOffsetsPtr
->pattern
[1], offset
, *nextMatchLenPtr
, matchLen
);
2866 log_err("error, locale %s, patn (%d) %04X %04X..., usearch_next returned more matches than expected\n",
2867 tuscItemPtr
->locale
, patLen
, patternsOffsetsPtr
->pattern
[0], patternsOffsetsPtr
->pattern
[1] );
2870 if ( U_FAILURE(status
) ) {
2871 log_err("error, locale %s, patn (%d) %04X %04X..., usearch_next failed: %s\n",
2872 tuscItemPtr
->locale
, patLen
, patternsOffsetsPtr
->pattern
[0], patternsOffsetsPtr
->pattern
[1], u_errorName(status
) );
2873 } else if ( nextOffsetPtr
< limitOffsetPtr
) {
2874 log_err("error, locale %s, patn (%d) %04X %04X..., usearch_next returned fewer matches than expected\n",
2875 tuscItemPtr
->locale
, patLen
, patternsOffsetsPtr
->pattern
[0], patternsOffsetsPtr
->pattern
[1] );
2878 status
= U_ZERO_ERROR
;
2879 usearch_reset(usrch
);
2880 nextOffsetPtr
= patternsOffsetsPtr
->offsets
+ patternsOffsetsPtr
->offsetsLen
;
2881 limitOffsetPtr
= patternsOffsetsPtr
->offsets
;
2883 offset
= usearch_previous(usrch
, &status
);
2884 if ( U_FAILURE(status
) || offset
== USEARCH_DONE
) {
2887 if ( nextOffsetPtr
> limitOffsetPtr
) {
2889 if (offset
!= *nextOffsetPtr
) {
2890 log_err("error, locale %s, patn (%d) %04X %04X..., expected usearch_previous %d, got %d\n",
2891 tuscItemPtr
->locale
, patLen
, patternsOffsetsPtr
->pattern
[0], patternsOffsetsPtr
->pattern
[1], *nextOffsetPtr
, offset
);
2892 nextOffsetPtr
= limitOffsetPtr
;
2896 log_err("error, locale %s, patn (%d) %04X %04X..., usearch_previous returned more matches than expected\n",
2897 tuscItemPtr
->locale
, patLen
, patternsOffsetsPtr
->pattern
[0], patternsOffsetsPtr
->pattern
[1] );
2900 if ( U_FAILURE(status
) ) {
2901 log_err("error, locale %s, patn (%d) %04X %04X..., usearch_previous failed: %s\n",
2902 tuscItemPtr
->locale
, patLen
, patternsOffsetsPtr
->pattern
[0], patternsOffsetsPtr
->pattern
[1], u_errorName(status
) );
2903 } else if ( nextOffsetPtr
> limitOffsetPtr
) {
2904 log_err("error, locale %s, patn (%d) %04X %04X..., usearch_previous returned fewer matches than expected\n",
2905 tuscItemPtr
->locale
, patLen
, patternsOffsetsPtr
->pattern
[0], patternsOffsetsPtr
->pattern
[1] );
2909 log_err("error, locale %s, usearch_setPattern failed: %s\n",
2910 tuscItemPtr
->locale
, u_errorName(status
) );
2913 usearch_close(usrch
);
2915 log_err("error, locale %s, usearch_openFromCollator failed: %s\n", tuscItemPtr
->locale
, u_errorName(status
) );
2919 log_data_err("error, locale %s, ucol_open failed: %s\n", tuscItemPtr
->locale
, u_errorName(status
) );
2925 static void TestPCEBuffer_with(const UChar
*search
, uint32_t searchLen
, const UChar
*source
, uint32_t sourceLen
) {
2926 UErrorCode icuStatus
= U_ZERO_ERROR
;
2929 UBreakIterator
*ubrk
;
2930 UStringSearch
*usearch
;
2934 coll
= ucol_openFromShortString( "LSK_AS_CX_EX_FX_HX_NX_S4",
2938 if ( U_FAILURE(icuStatus
) )
2940 log_data_err( "ucol_openFromShortString error %s\n" , u_errorName(icuStatus
));
2944 locale
= ucol_getLocaleByType( coll
,
2947 if ( U_FAILURE(icuStatus
) )
2949 log_err( "ucol_getLocaleByType error %s\n", u_errorName(icuStatus
) );
2953 log_verbose("locale=%s\n", locale
);
2955 ubrk
= ubrk_open( UBRK_CHARACTER
,
2960 if ( U_FAILURE(icuStatus
) )
2962 log_err( "ubrk_open error %s\n", u_errorName(icuStatus
) );
2966 usearch
= usearch_openFromCollator( search
,
2973 if ( U_FAILURE(icuStatus
) )
2975 log_err( "usearch_openFromCollator error %s\n", u_errorName(icuStatus
) );
2979 match
= usearch_first( usearch
,
2981 if ( U_FAILURE(icuStatus
) )
2983 log_err( "usearch_first error %s\n", u_errorName(icuStatus
) );
2988 log_verbose("OK: match=%d\n", match
);
2990 log_err("Err: match expected 0 got %d\n", match
);
2993 usearch_close(usearch
);
3002 static void TestPCEBuffer_100df(void) {
3004 { 0x0020, 0x0020, 0x00df, 0x0020, 0x0041, 0x00df, 0x0020, 0x0061, 0x00df, 0x0020, 0x00c5, 0x00df, 0x0020, 0x212b, 0x00df, 0x0020, 0x0041, 0x030a, 0x00df, 0x0020, 0x00e5, 0x00df, 0x0020, 0x0061, 0x02da, 0x00df, 0x0020, 0x0061, 0x030a, 0x00df, 0x0020, 0xd8fa, 0xdeae, 0x00df, 0x0020, 0x2027, 0x00df }; /* 38 cp, 9 of them unpaired surrogates */
3006 { 0x0020, 0x0020, 0x00df, 0x0020, 0x0041, 0x00df, 0x0020, 0x0061, 0x00df, 0x0020, 0x00c5, 0x00df, 0x0020, 0x212b, 0x00df, 0x0020, 0x0041, 0x030a, 0x00df, 0x0020, 0x00e5, 0x00df, 0x0020, 0x0061, 0x02da, 0x00df, 0x0020, 0x0061, 0x030a, 0x00df, 0x0020, 0xd8fa, 0xdeae, 0x00df, 0x0020, 0x2027, 0x00df };
3007 uint32_t searchLen
= UPRV_LENGTHOF(search
);
3008 uint32_t sourceLen
= UPRV_LENGTHOF(source
);
3009 TestPCEBuffer_with(search
,searchLen
,source
,sourceLen
);
3013 static void TestPCEBuffer_2surr(void) {
3015 { 0x0020, 0x0020, 0xdfff, 0x0020, 0x0041, 0xdfff, 0x0020, 0x0061, 0xdfff, 0x0020, 0x00c5, 0xdfff, 0x0020, 0x212b, 0xdfff, 0x0020, 0x0041, 0x030a, 0xdfff, 0x0020, 0x00e5, 0xdfff, 0x0020, 0x0061, 0x02da, 0xdfff, 0x0020, 0x0061, 0x030a, 0xdfff, 0x0020, 0xd8fa, 0xdeae, 0xdfff, 0x0020, 0x2027, 0xdfff }; /* 38 cp, 9 of them unpaired surrogates */
3017 { 0x0020, 0x0020, 0xdfff, 0x0020, 0x0041, 0xdfff, 0x0020, 0x0061, 0xdfff, 0x0020, 0x00c5, 0xdfff, 0x0020, 0x212b, 0xdfff, 0x0020, 0x0041, 0x030a, 0xdfff, 0x0020, 0x00e5, 0xdfff, 0x0020, 0x0061, 0x02da, 0xdfff, 0x0020, 0x0061, 0x030a, 0xdfff, 0x0020, 0xd8fa, 0xdeae, 0xdfff, 0x0020, 0x2027, 0xdfff };
3018 uint32_t searchLen
= UPRV_LENGTHOF(search
);
3019 uint32_t sourceLen
= UPRV_LENGTHOF(source
);
3020 TestPCEBuffer_with(search
,searchLen
,source
,sourceLen
);
3023 static void TestMatchFollowedByIgnorables(void) {
3024 /* test case for ticket#8482 */
3025 UChar search
[] = { 0x00c9 };
3026 UChar source
[] = { 0x00c9, 0x0000, 0x0041 };
3029 UErrorCode icuStatus
= U_ZERO_ERROR
;
3032 UBreakIterator
*ubrk
;
3033 UStringSearch
*usearch
;
3035 int32_t matchLength
= 0;
3036 const int32_t expectedMatchLength
= 1;
3038 searchLen
= UPRV_LENGTHOF(search
);
3039 sourceLen
= UPRV_LENGTHOF(source
);
3041 coll
= ucol_openFromShortString("LHR_AN_CX_EX_FX_HX_NX_S3",
3045 if (U_FAILURE(icuStatus
)) {
3046 log_data_err("ucol_openFromShortString error - %s\n", u_errorName(icuStatus
));
3049 locale
= ucol_getLocaleByType(coll
,
3052 if (U_FAILURE(icuStatus
)) {
3053 log_data_err("ucol_getLocaleByType error - %s\n", u_errorName(icuStatus
));
3056 ubrk
= ubrk_open(UBRK_CHARACTER
,
3061 if (U_FAILURE(icuStatus
)) {
3062 log_data_err("ubrk_open error - %s\n", u_errorName(icuStatus
));
3065 usearch
= usearch_openFromCollator(search
,
3072 if (U_FAILURE(icuStatus
)) {
3073 log_data_err("usearch_openFromCollator error - %s\n", u_errorName(icuStatus
));
3076 match
= usearch_first(usearch
,
3078 if (U_FAILURE(icuStatus
)) {
3079 log_data_err("usearch_first error - %s\n", u_errorName(icuStatus
));
3082 log_verbose("match=%d\n", match
);
3084 matchLength
= usearch_getMatchedLength(usearch
);
3086 if (matchLength
!= expectedMatchLength
) {
3087 log_err("Error: matchLength=%d, expected=%d\n", matchLength
, expectedMatchLength
);
3091 usearch_close(usearch
);
3096 static void TestIndicPrefixMatch(void)
3099 UErrorCode status
= U_ZERO_ERROR
;
3101 if (U_FAILURE(status
)) {
3102 log_err_status(status
, "Unable to open static collators %s\n", u_errorName(status
));
3105 while (INDICPREFIXMATCH
[count
].text
!= NULL
) {
3106 if (!assertEqual(INDICPREFIXMATCH
[count
])) {
3107 log_err("Error at test number %d\n", count
);
3118 void addSearchTest(TestNode
** root
)
3120 addTest(root
, &TestStart
, "tscoll/usrchtst/TestStart");
3121 addTest(root
, &TestOpenClose
, "tscoll/usrchtst/TestOpenClose");
3122 addTest(root
, &TestInitialization
, "tscoll/usrchtst/TestInitialization");
3123 addTest(root
, &TestBasic
, "tscoll/usrchtst/TestBasic");
3124 addTest(root
, &TestNormExact
, "tscoll/usrchtst/TestNormExact");
3125 addTest(root
, &TestStrength
, "tscoll/usrchtst/TestStrength");
3126 addTest(root
, &TestBreakIterator
, "tscoll/usrchtst/TestBreakIterator");
3127 addTest(root
, &TestVariable
, "tscoll/usrchtst/TestVariable");
3128 addTest(root
, &TestOverlap
, "tscoll/usrchtst/TestOverlap");
3129 addTest(root
, &TestCollator
, "tscoll/usrchtst/TestCollator");
3130 addTest(root
, &TestPattern
, "tscoll/usrchtst/TestPattern");
3131 addTest(root
, &TestText
, "tscoll/usrchtst/TestText");
3132 addTest(root
, &TestCompositeBoundaries
,
3133 "tscoll/usrchtst/TestCompositeBoundaries");
3134 addTest(root
, &TestGetSetOffset
, "tscoll/usrchtst/TestGetSetOffset");
3135 addTest(root
, &TestGetSetAttribute
,
3136 "tscoll/usrchtst/TestGetSetAttribute");
3137 addTest(root
, &TestGetMatch
, "tscoll/usrchtst/TestGetMatch");
3138 addTest(root
, &TestSetMatch
, "tscoll/usrchtst/TestSetMatch");
3139 addTest(root
, &TestReset
, "tscoll/usrchtst/TestReset");
3140 addTest(root
, &TestSupplementary
, "tscoll/usrchtst/TestSupplementary");
3141 addTest(root
, &TestContraction
, "tscoll/usrchtst/TestContraction");
3142 addTest(root
, &TestIgnorable
, "tscoll/usrchtst/TestIgnorable");
3143 addTest(root
, &TestCanonical
, "tscoll/usrchtst/TestCanonical");
3144 addTest(root
, &TestNormCanonical
, "tscoll/usrchtst/TestNormCanonical");
3145 addTest(root
, &TestStrengthCanonical
,
3146 "tscoll/usrchtst/TestStrengthCanonical");
3147 addTest(root
, &TestBreakIteratorCanonical
,
3148 "tscoll/usrchtst/TestBreakIteratorCanonical");
3149 addTest(root
, &TestVariableCanonical
,
3150 "tscoll/usrchtst/TestVariableCanonical");
3151 addTest(root
, &TestOverlapCanonical
,
3152 "tscoll/usrchtst/TestOverlapCanonical");
3153 addTest(root
, &TestCollatorCanonical
,
3154 "tscoll/usrchtst/TestCollatorCanonical");
3155 addTest(root
, &TestPatternCanonical
,
3156 "tscoll/usrchtst/TestPatternCanonical");
3157 addTest(root
, &TestTextCanonical
, "tscoll/usrchtst/TestTextCanonical");
3158 addTest(root
, &TestCompositeBoundariesCanonical
,
3159 "tscoll/usrchtst/TestCompositeBoundariesCanonical");
3160 addTest(root
, &TestGetSetOffsetCanonical
,
3161 "tscoll/usrchtst/TestGetSetOffsetCanonical");
3162 addTest(root
, &TestSupplementaryCanonical
,
3163 "tscoll/usrchtst/TestSupplementaryCanonical");
3164 addTest(root
, &TestContractionCanonical
,
3165 "tscoll/usrchtst/TestContractionCanonical");
3166 addTest(root
, &TestEnd
, "tscoll/usrchtst/TestEnd");
3167 addTest(root
, &TestNumeric
, "tscoll/usrchtst/TestNumeric");
3168 addTest(root
, &TestDiacriticMatch
, "tscoll/usrchtst/TestDiacriticMatch");
3169 addTest(root
, &TestForwardBackward
, "tscoll/usrchtst/TestForwardBackward");
3170 addTest(root
, &TestSearchForNull
, "tscoll/usrchtst/TestSearchForNull");
3171 addTest(root
, &TestStrengthIdentical
, "tscoll/usrchtst/TestStrengthIdentical");
3172 addTest(root
, &TestUsingSearchCollator
, "tscoll/usrchtst/TestUsingSearchCollator");
3173 addTest(root
, &TestPCEBuffer_100df
, "tscoll/usrchtst/TestPCEBuffer/1_00df");
3174 addTest(root
, &TestPCEBuffer_2surr
, "tscoll/usrchtst/TestPCEBuffer/2_dfff");
3175 addTest(root
, &TestMatchFollowedByIgnorables
, "tscoll/usrchtst/TestMatchFollowedByIgnorables");
3176 addTest(root
, &TestIndicPrefixMatch
, "tscoll/usrchtst/TestIndicPrefixMatch");
3179 #endif /* #if !UCONFIG_NO_COLLATION */