1 // Copyright (C) 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 } PatternAndOffsets;
2667 static const UChar scKoText[] = {
2669 /*01*/ 0xAC00, 0x0020, /* simple LV Hangul */
2670 /*03*/ 0xAC01, 0x0020, /* simple LVT Hangul */
2671 /*05*/ 0xAC0F, 0x0020, /* LVTT, last jamo expands for search */
2672 /*07*/ 0xAFFF, 0x0020, /* LLVVVTT, every jamo expands for search */
2673 /*09*/ 0x1100, 0x1161, 0x11A8, 0x0020, /* 0xAC01 as conjoining jamo */
2674 /*13*/ 0x1100, 0x1161, 0x1100, 0x0020, /* 0xAC01 as basic conjoining jamo (per search rules) */
2675 /*17*/ 0x3131, 0x314F, 0x3131, 0x0020, /* 0xAC01 as compatibility jamo */
2676 /*21*/ 0x1100, 0x1161, 0x11B6, 0x0020, /* 0xAC0F as conjoining jamo; last expands for search */
2677 /*25*/ 0x1100, 0x1161, 0x1105, 0x1112, 0x0020, /* 0xAC0F as basic conjoining jamo; last expands for search */
2678 /*30*/ 0x1101, 0x1170, 0x11B6, 0x0020, /* 0xAFFF as conjoining jamo; all expand for search */
2679 /*34*/ 0x00E6, 0x0020, /* small letter ae, expands */
2680 /*36*/ 0x1E4D, 0x0020, /* small letter o with tilde and acute, decomposes */
2684 static const UChar scKoPat0[] = { 0xAC01, 0 };
2685 static const UChar scKoPat1[] = { 0x1100, 0x1161, 0x11A8, 0 }; /* 0xAC01 as conjoining jamo */
2686 static const UChar scKoPat2[] = { 0xAC0F, 0 };
2687 static const UChar scKoPat3[] = { 0x1100, 0x1161, 0x1105, 0x1112, 0 }; /* 0xAC0F as basic conjoining jamo */
2688 static const UChar scKoPat4[] = { 0xAFFF, 0 };
2689 static const UChar scKoPat5[] = { 0x1101, 0x1170, 0x11B6, 0 }; /* 0xAFFF as conjoining jamo */
2691 static const int32_t scKoSrchOff01[] = { 3, 9, 13 };
2692 static const int32_t scKoSrchOff23[] = { 5, 21, 25 };
2693 static const int32_t scKoSrchOff45[] = { 7, 30 };
2695 static const PatternAndOffsets scKoSrchPatternsOffsets[] = {
2696 { scKoPat0, scKoSrchOff01, UPRV_LENGTHOF(scKoSrchOff01) },
2697 { scKoPat1, scKoSrchOff01, UPRV_LENGTHOF(scKoSrchOff01) },
2698 { scKoPat2, scKoSrchOff23, UPRV_LENGTHOF(scKoSrchOff23) },
2699 { scKoPat3, scKoSrchOff23, UPRV_LENGTHOF(scKoSrchOff23) },
2700 { scKoPat4, scKoSrchOff45, UPRV_LENGTHOF(scKoSrchOff45) },
2701 { scKoPat5, scKoSrchOff45, UPRV_LENGTHOF(scKoSrchOff45) },
2705 static const int32_t scKoStndOff01[] = { 3, 9 };
2706 static const int32_t scKoStndOff2[] = { 5, 21 };
2707 static const int32_t scKoStndOff3[] = { 25 };
2708 static const int32_t scKoStndOff45[] = { 7, 30 };
2710 static const PatternAndOffsets scKoStndPatternsOffsets[] = {
2711 { scKoPat0, scKoStndOff01, UPRV_LENGTHOF(scKoStndOff01) },
2712 { scKoPat1, scKoStndOff01, UPRV_LENGTHOF(scKoStndOff01) },
2713 { scKoPat2, scKoStndOff2, UPRV_LENGTHOF(scKoStndOff2) },
2714 { scKoPat3, scKoStndOff3, UPRV_LENGTHOF(scKoStndOff3) },
2715 { scKoPat4, scKoStndOff45, UPRV_LENGTHOF(scKoStndOff45) },
2716 { scKoPat5, scKoStndOff45, UPRV_LENGTHOF(scKoStndOff45) },
2721 const char * locale;
2723 const PatternAndOffsets * patternsAndOffsets;
2726 static const TUSCItem tuscItems[] = {
2727 { "root", scKoText, scKoStndPatternsOffsets },
2728 { "root@collation=search", scKoText, scKoSrchPatternsOffsets },
2729 { "ko@collation=search", scKoText, scKoSrchPatternsOffsets },
2730 { NULL, NULL, NULL }
2733 static const UChar dummyPat[] = { 0x0061, 0 };
2735 static void TestUsingSearchCollator(void)
2737 const TUSCItem * tuscItemPtr;
2738 for (tuscItemPtr = tuscItems; tuscItemPtr->locale != NULL; tuscItemPtr++) {
2739 UErrorCode status = U_ZERO_ERROR;
2740 UCollator* ucol = ucol_open(tuscItemPtr->locale, &status);
2741 if ( U_SUCCESS(status) ) {
2742 UStringSearch* usrch = usearch_openFromCollator(dummyPat, -1, tuscItemPtr->text, -1, ucol, NULL, &status);
2743 if ( U_SUCCESS(status) ) {
2744 const PatternAndOffsets * patternsOffsetsPtr;
2745 for ( patternsOffsetsPtr = tuscItemPtr->patternsAndOffsets; patternsOffsetsPtr->pattern != NULL; patternsOffsetsPtr++) {
2746 usearch_setPattern(usrch, patternsOffsetsPtr->pattern, -1, &status);
2747 if ( U_SUCCESS(status) ) {
2749 const int32_t * nextOffsetPtr;
2750 const int32_t * limitOffsetPtr;
2752 usearch_reset(usrch);
2753 nextOffsetPtr = patternsOffsetsPtr->offsets;
2754 limitOffsetPtr = patternsOffsetsPtr->offsets + patternsOffsetsPtr->offsetsLen;
2756 offset = usearch_next(usrch, &status);
2757 if ( U_FAILURE(status) || offset == USEARCH_DONE ) {
2760 if ( nextOffsetPtr < limitOffsetPtr ) {
2761 if (offset != *nextOffsetPtr) {
2762 log_err("error, locale %s, expected usearch_next %d, got %d\n", tuscItemPtr->locale, *nextOffsetPtr, offset);
2763 nextOffsetPtr = limitOffsetPtr;
2768 log_err("error, locale %s, usearch_next returned more matches than expected\n", tuscItemPtr->locale );
2771 if ( U_FAILURE(status) ) {
2772 log_err("error, locale %s, usearch_next failed: %s\n", tuscItemPtr->locale, u_errorName(status) );
2773 } else if ( nextOffsetPtr < limitOffsetPtr ) {
2774 log_err("error, locale %s, usearch_next returned fewer matches than expected\n", tuscItemPtr->locale );
2777 status = U_ZERO_ERROR;
2778 usearch_reset(usrch);
2779 nextOffsetPtr = patternsOffsetsPtr->offsets + patternsOffsetsPtr->offsetsLen;
2780 limitOffsetPtr = patternsOffsetsPtr->offsets;
2782 offset = usearch_previous(usrch, &status);
2783 if ( U_FAILURE(status) || offset == USEARCH_DONE ) {
2786 if ( nextOffsetPtr > limitOffsetPtr ) {
2788 if (offset != *nextOffsetPtr) {
2789 log_err("error, locale %s, expected usearch_previous %d, got %d\n", tuscItemPtr->locale, *nextOffsetPtr, offset);
2790 nextOffsetPtr = limitOffsetPtr;
2794 log_err("error, locale %s, usearch_previous returned more matches than expected\n", tuscItemPtr->locale );
2797 if ( U_FAILURE(status) ) {
2798 log_err("error, locale %s, usearch_previous failed: %s\n", tuscItemPtr->locale, u_errorName(status) );
2799 } else if ( nextOffsetPtr > limitOffsetPtr ) {
2800 log_err("error, locale %s, usearch_previous returned fewer matches than expected\n", tuscItemPtr->locale );
2804 log_err("error, locale %s, usearch_setPattern failed: %s\n", tuscItemPtr->locale, u_errorName(status) );
2807 usearch_close(usrch);
2809 log_err("error, locale %s, usearch_openFromCollator failed: %s\n", tuscItemPtr->locale, u_errorName(status) );
2813 log_data_err("error, locale %s, ucol_open failed: %s\n", tuscItemPtr->locale, u_errorName(status) );
2819 static void TestPCEBuffer_with(const UChar *search, uint32_t searchLen, const UChar *source, uint32_t sourceLen) {
2820 UErrorCode icuStatus = U_ZERO_ERROR;
2823 UBreakIterator *ubrk;
2824 UStringSearch *usearch;
2828 coll = ucol_openFromShortString( "LSK_AS_CX_EX_FX_HX_NX_S4",
2832 if ( U_FAILURE(icuStatus) )
2834 log_data_err( "ucol_openFromShortString error %s\n" , u_errorName(icuStatus));
2838 locale = ucol_getLocaleByType( coll,
2841 if ( U_FAILURE(icuStatus) )
2843 log_err( "ucol_getLocaleByType error %s\n", u_errorName(icuStatus) );
2847 log_verbose("locale=%s\n", locale);
2849 ubrk = ubrk_open( UBRK_CHARACTER,
2854 if ( U_FAILURE(icuStatus) )
2856 log_err( "ubrk_open error %s\n", u_errorName(icuStatus) );
2860 usearch = usearch_openFromCollator( search,
2867 if ( U_FAILURE(icuStatus) )
2869 log_err( "usearch_openFromCollator error %s\n", u_errorName(icuStatus) );
2873 match = usearch_first( usearch,
2875 if ( U_FAILURE(icuStatus) )
2877 log_err( "usearch_first error %s\n", u_errorName(icuStatus) );
2882 log_verbose("OK: match=%d\n", match);
2884 log_err("Err: match expected 0 got %d\n", match);
2887 usearch_close(usearch);
2896 static void TestPCEBuffer_100df(void) {
2898 { 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 */
2900 { 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 };
2901 uint32_t searchLen = UPRV_LENGTHOF(search);
2902 uint32_t sourceLen = UPRV_LENGTHOF(source);
2903 TestPCEBuffer_with(search,searchLen,source,sourceLen);
2907 static void TestPCEBuffer_2surr(void) {
2909 { 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 */
2911 { 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 };
2912 uint32_t searchLen = UPRV_LENGTHOF(search);
2913 uint32_t sourceLen = UPRV_LENGTHOF(source);
2914 TestPCEBuffer_with(search,searchLen,source,sourceLen);
2917 static void TestMatchFollowedByIgnorables(void) {
2918 /* test case for ticket#8482 */
2919 UChar search[] = { 0x00c9 };
2920 UChar source[] = { 0x00c9, 0x0000, 0x0041 };
2923 UErrorCode icuStatus = U_ZERO_ERROR;
2926 UBreakIterator *ubrk;
2927 UStringSearch *usearch;
2929 int32_t matchLength = 0;
2930 const int32_t expectedMatchLength = 1;
2932 searchLen = UPRV_LENGTHOF(search);
2933 sourceLen = UPRV_LENGTHOF(source);
2935 coll = ucol_openFromShortString("LHR_AN_CX_EX_FX_HX_NX_S3",
2939 if (U_FAILURE(icuStatus)) {
2940 log_data_err("ucol_openFromShortString error - %s\n", u_errorName(icuStatus));
2943 locale = ucol_getLocaleByType(coll,
2946 if (U_FAILURE(icuStatus)) {
2947 log_data_err("ucol_getLocaleByType error - %s\n", u_errorName(icuStatus));
2950 ubrk = ubrk_open(UBRK_CHARACTER,
2955 if (U_FAILURE(icuStatus)) {
2956 log_data_err("ubrk_open error - %s\n", u_errorName(icuStatus));
2959 usearch = usearch_openFromCollator(search,
2966 if (U_FAILURE(icuStatus)) {
2967 log_data_err("usearch_openFromCollator error - %s\n", u_errorName(icuStatus));
2970 match = usearch_first(usearch,
2972 if (U_FAILURE(icuStatus)) {
2973 log_data_err("usearch_first error - %s\n", u_errorName(icuStatus));
2976 log_verbose("match=%d\n", match);
2978 matchLength = usearch_getMatchedLength(usearch);
2980 if (matchLength != expectedMatchLength) {
2981 log_err("Error: matchLength=%d, expected=%d\n", matchLength, expectedMatchLength);
2985 usearch_close(usearch);
2990 static void TestIndicPrefixMatch(void)
2993 UErrorCode status = U_ZERO_ERROR;
2995 if (U_FAILURE(status)) {
2996 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
2999 while (INDICPREFIXMATCH[count].text != NULL) {
3000 if (!assertEqual(INDICPREFIXMATCH[count])) {
3001 log_err("Error at test number %d\n", count);
3012 void addSearchTest(TestNode** root)
3014 addTest(root, &TestStart, "tscoll/usrchtst/TestStart");
3015 addTest(root, &TestOpenClose, "tscoll/usrchtst/TestOpenClose");
3016 addTest(root, &TestInitialization, "tscoll/usrchtst/TestInitialization");
3017 addTest(root, &TestBasic, "tscoll/usrchtst/TestBasic");
3018 addTest(root, &TestNormExact, "tscoll/usrchtst/TestNormExact");
3019 addTest(root, &TestStrength, "tscoll/usrchtst/TestStrength");
3020 addTest(root, &TestBreakIterator, "tscoll/usrchtst/TestBreakIterator");
3021 addTest(root, &TestVariable, "tscoll/usrchtst/TestVariable");
3022 addTest(root, &TestOverlap, "tscoll/usrchtst/TestOverlap");
3023 addTest(root, &TestCollator, "tscoll/usrchtst/TestCollator");
3024 addTest(root, &TestPattern, "tscoll/usrchtst/TestPattern");
3025 addTest(root, &TestText, "tscoll/usrchtst/TestText");
3026 addTest(root, &TestCompositeBoundaries,
3027 "tscoll/usrchtst/TestCompositeBoundaries");
3028 addTest(root, &TestGetSetOffset, "tscoll/usrchtst/TestGetSetOffset");
3029 addTest(root, &TestGetSetAttribute,
3030 "tscoll/usrchtst/TestGetSetAttribute");
3031 addTest(root, &TestGetMatch, "tscoll/usrchtst/TestGetMatch");
3032 addTest(root, &TestSetMatch, "tscoll/usrchtst/TestSetMatch");
3033 addTest(root, &TestReset, "tscoll/usrchtst/TestReset");
3034 addTest(root, &TestSupplementary, "tscoll/usrchtst/TestSupplementary");
3035 addTest(root, &TestContraction, "tscoll/usrchtst/TestContraction");
3036 addTest(root, &TestIgnorable, "tscoll/usrchtst/TestIgnorable");
3037 addTest(root, &TestCanonical, "tscoll/usrchtst/TestCanonical");
3038 addTest(root, &TestNormCanonical, "tscoll/usrchtst/TestNormCanonical");
3039 addTest(root, &TestStrengthCanonical,
3040 "tscoll/usrchtst/TestStrengthCanonical");
3041 addTest(root, &TestBreakIteratorCanonical,
3042 "tscoll/usrchtst/TestBreakIteratorCanonical");
3043 addTest(root, &TestVariableCanonical,
3044 "tscoll/usrchtst/TestVariableCanonical");
3045 addTest(root, &TestOverlapCanonical,
3046 "tscoll/usrchtst/TestOverlapCanonical");
3047 addTest(root, &TestCollatorCanonical,
3048 "tscoll/usrchtst/TestCollatorCanonical");
3049 addTest(root, &TestPatternCanonical,
3050 "tscoll/usrchtst/TestPatternCanonical");
3051 addTest(root, &TestTextCanonical, "tscoll/usrchtst/TestTextCanonical");
3052 addTest(root, &TestCompositeBoundariesCanonical,
3053 "tscoll/usrchtst/TestCompositeBoundariesCanonical");
3054 addTest(root, &TestGetSetOffsetCanonical,
3055 "tscoll/usrchtst/TestGetSetOffsetCanonical");
3056 addTest(root, &TestSupplementaryCanonical,
3057 "tscoll/usrchtst/TestSupplementaryCanonical");
3058 addTest(root, &TestContractionCanonical,
3059 "tscoll/usrchtst/TestContractionCanonical");
3060 addTest(root, &TestEnd, "tscoll/usrchtst/TestEnd");
3061 addTest(root, &TestNumeric, "tscoll/usrchtst/TestNumeric");
3062 addTest(root, &TestDiacriticMatch, "tscoll/usrchtst/TestDiacriticMatch");
3063 addTest(root, &TestForwardBackward, "tscoll/usrchtst/TestForwardBackward");
3064 addTest(root, &TestSearchForNull, "tscoll/usrchtst/TestSearchForNull");
3065 addTest(root, &TestStrengthIdentical, "tscoll/usrchtst/TestStrengthIdentical");
3066 addTest(root, &TestUsingSearchCollator, "tscoll/usrchtst/TestUsingSearchCollator");
3067 addTest(root, &TestPCEBuffer_100df, "tscoll/usrchtst/TestPCEBuffer/1_00df");
3068 addTest(root, &TestPCEBuffer_2surr, "tscoll/usrchtst/TestPCEBuffer/2_dfff");
3069 addTest(root, &TestMatchFollowedByIgnorables, "tscoll/usrchtst/TestMatchFollowedByIgnorables");
3070 addTest(root, &TestIndicPrefixMatch, "tscoll/usrchtst/TestIndicPrefixMatch");
3073 #endif /* #if !UCONFIG_NO_COLLATION */