• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /********************************************************************
2  * Copyright (c) 2001-2010 International Business Machines
3  * Corporation and others. All Rights Reserved.
4  ********************************************************************
5  * File usrchtst.c
6  * Modification History:
7  * Name           Date             Description
8  * synwee         July 19 2001     creation
9  ********************************************************************/
10 
11 #include "unicode/utypes.h"
12 
13 #if !UCONFIG_NO_COLLATION && !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_FILE_IO
14 
15 #include "unicode/usearch.h"
16 #include "unicode/ustring.h"
17 #include "ccolltst.h"
18 #include "cmemory.h"
19 #include <stdio.h>
20 #include "usrchdat.c"
21 #include "unicode/ubrk.h"
22 #include <assert.h>
23 
24 static UBool      TOCLOSE_ = TRUE;
25 static UCollator *EN_US_;
26 static UCollator *FR_FR_;
27 static UCollator *DE_;
28 static UCollator *ES_;
29 
30 /**
31  * CHECK_BREAK(char *brk)
32  *     Test if a break iterator is passed in AND break iteration is disabled.
33  *     Skip the test if so.
34  * CHECK_BREAK_BOOL(char *brk)
35  *     Same as above, but returns 'TRUE' as a passing result
36  */
37 
38 #if !UCONFIG_NO_BREAK_ITERATION
39 static UBreakIterator *EN_WORDBREAKER_;
40 static UBreakIterator *EN_CHARACTERBREAKER_;
41 #define CHECK_BREAK(x)
42 #define CHECK_BREAK_BOOL(x)
43 #else
44 #define CHECK_BREAK(x)  if(x) { log_info("Skipping test on %s:%d because UCONFIG_NO_BREAK_ITERATION is on\n", __FILE__, __LINE__); return; }
45 #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; }
46 #endif
47 
48 /**
49 * Opening all static collators and break iterators
50 */
open(UErrorCode * status)51 static void open(UErrorCode* status)
52 {
53     if (TOCLOSE_) {
54         UChar      rules[1024];
55         int32_t    rulelength = 0;
56         *status = U_ZERO_ERROR;
57 
58         EN_US_ = ucol_open("en_US", status);
59         if(U_FAILURE(*status)) {
60           log_err_status(*status, "Error opening collator\n");
61           return;
62         }
63         FR_FR_ = ucol_open("fr_FR", status);
64         DE_ = ucol_open("de_DE", status);
65         ES_ = ucol_open("es_ES", status);
66 
67         u_strcpy(rules, ucol_getRules(DE_, &rulelength));
68         u_unescape(EXTRACOLLATIONRULE, rules + rulelength, 1024 - rulelength);
69 
70         ucol_close(DE_);
71 
72         DE_ = ucol_openRules(rules, u_strlen(rules), UCOL_ON, UCOL_TERTIARY,
73                              (UParseError *)NULL, status);
74         u_strcpy(rules, ucol_getRules(ES_, &rulelength));
75         u_unescape(EXTRACOLLATIONRULE, rules + rulelength, 1024 - rulelength);
76 
77         ucol_close(ES_);
78         ES_ = ucol_openRules(rules, u_strlen(rules), UCOL_ON, UCOL_TERTIARY,
79                              NULL, status);
80 #if !UCONFIG_NO_BREAK_ITERATION
81         EN_WORDBREAKER_     = ubrk_open(UBRK_WORD, "en_US", NULL, 0, status);
82         EN_CHARACTERBREAKER_ = ubrk_open(UBRK_CHARACTER, "en_US", NULL, 0,
83                                         status);
84 #endif
85         TOCLOSE_ = TRUE;
86     }
87 }
88 
89 /**
90 * Start opening all static collators and break iterators
91 */
TestStart(void)92 static void TestStart(void)
93 {
94     UErrorCode status = U_ZERO_ERROR;
95     open(&status);
96     if (U_FAILURE(status)) {
97         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
98         return;
99     }
100     TOCLOSE_ = FALSE;
101 }
102 
103 /**
104 * Closing all static collators and break iterators
105 */
close(void)106 static void close(void)
107 {
108     if (TOCLOSE_) {
109         ucol_close(EN_US_);
110         ucol_close(FR_FR_);
111         ucol_close(DE_);
112         ucol_close(ES_);
113 #if !UCONFIG_NO_BREAK_ITERATION
114         ubrk_close(EN_WORDBREAKER_);
115         ubrk_close(EN_CHARACTERBREAKER_);
116 #endif
117     }
118     TOCLOSE_ = FALSE;
119 }
120 
121 /**
122 * End closing all static collators and break iterators
123 */
TestEnd(void)124 static void TestEnd(void)
125 {
126     TOCLOSE_ = TRUE;
127     close();
128     TOCLOSE_ = TRUE;
129 }
130 
131 /**
132 * output UChar strings for printing.
133 */
toCharString(const UChar * unichars)134 static char *toCharString(const UChar* unichars)
135 {
136     static char result[1024];
137     char *temp   = result;
138     int   count  = 0;
139     int   length = u_strlen(unichars);
140 
141     for (; count < length; count ++) {
142         UChar ch = unichars[count];
143         if (ch >= 0x20 && ch <= 0x7e) {
144             *temp ++ = (char)ch;
145         }
146         else {
147             sprintf(temp, "\\u%04x", ch);
148             temp += 6; /* \uxxxx */
149         }
150     }
151     *temp = 0;
152 
153     return result;
154 }
155 
156 /**
157 * Getting the collator
158 */
getCollator(const char * collator)159 static UCollator *getCollator(const char *collator)
160 {
161     if (collator == NULL) {
162         return EN_US_;
163     }
164     if (strcmp(collator, "fr") == 0) {
165         return FR_FR_;
166     }
167     else if (strcmp(collator, "de") == 0) {
168         return DE_;
169     }
170     else if (strcmp(collator, "es") == 0) {
171         return ES_;
172     }
173     else {
174         return EN_US_;
175     }
176 }
177 
178 /**
179 * Getting the breakiterator
180 */
getBreakIterator(const char * breaker)181 static UBreakIterator *getBreakIterator(const char *breaker)
182 {
183     if (breaker == NULL) {
184         return NULL;
185     }
186 #if !UCONFIG_NO_BREAK_ITERATION
187     if (strcmp(breaker, "wordbreaker") == 0) {
188         return EN_WORDBREAKER_;
189     }
190     else {
191         return EN_CHARACTERBREAKER_;
192     }
193 #else
194     return NULL;
195 #endif
196 }
197 
TestOpenClose(void)198 static void TestOpenClose(void)
199 {
200           UErrorCode      status    = U_ZERO_ERROR;
201           UStringSearch  *result;
202     const UChar           pattern[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
203     const UChar           text[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67};
204 #if !UCONFIG_NO_BREAK_ITERATION
205           UBreakIterator *breakiter = ubrk_open(UBRK_WORD, "en_US",
206                                                 text, 6, &status);
207 #endif
208     /* testing null arguments */
209     result = usearch_open(NULL, 0, NULL, 0, NULL, NULL, &status);
210     if (U_SUCCESS(status) || result != NULL) {
211         log_err("Error: NULL arguments should produce an error and a NULL result\n");
212     }
213     status = U_ZERO_ERROR;
214     result = usearch_openFromCollator(NULL, 0, NULL, 0, NULL, NULL, &status);
215     if (U_SUCCESS(status) || result != NULL) {
216         log_err("Error: NULL arguments should produce an error and a NULL result\n");
217     }
218 
219     status = U_ZERO_ERROR;
220     result = usearch_open(pattern, 3, NULL, 0, NULL, NULL, &status);
221     if (U_SUCCESS(status) || result != NULL) {
222         log_err("Error: NULL arguments should produce an error and a NULL result\n");
223     }
224     status = U_ZERO_ERROR;
225     result = usearch_openFromCollator(pattern, 3, NULL, 0, NULL, NULL,
226                                       &status);
227     if (U_SUCCESS(status) || result != NULL) {
228         log_err("Error: NULL arguments should produce an error and a NULL result\n");
229     }
230 
231     status = U_ZERO_ERROR;
232     result = usearch_open(pattern, 3, text, 6, NULL, NULL, &status);
233     if (U_SUCCESS(status) || result != NULL) {
234         log_err("Error: NULL arguments should produce an error and a NULL result\n");
235     }
236     status = U_ZERO_ERROR;
237     result = usearch_openFromCollator(pattern, 3, text, 6, NULL, NULL,
238                                       &status);
239     if (U_SUCCESS(status) || result != NULL) {
240         log_err("Error: NULL arguments should produce an error and a NULL result\n");
241     }
242 
243     status = U_ZERO_ERROR;
244     result = usearch_open(pattern, 3, text, 6, "en_US", NULL, &status);
245     if (U_FAILURE(status) || result == NULL) {
246         log_err_status(status, "Error: NULL break iterator is valid for opening search\n");
247     }
248     else {
249         usearch_close(result);
250     }
251     open(&status);
252     if (U_FAILURE(status)) {
253         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
254         return;
255     }
256     status = U_ZERO_ERROR;
257     result = usearch_openFromCollator(pattern, 3, text, 6, EN_US_, NULL,
258                                       &status);
259     if (U_FAILURE(status) || result == NULL) {
260         if (EN_US_ == NULL) {
261             log_data_err("Opening collator failed.\n");
262         } else {
263             log_err("Error: NULL break iterator is valid for opening search\n");
264         }
265     }
266     else {
267         usearch_close(result);
268     }
269 
270 
271     status = U_ZERO_ERROR;
272 #if !UCONFIG_NO_BREAK_ITERATION
273 
274     result = usearch_open(pattern, 3, text, 6, "en_US", breakiter, &status);
275     if (U_FAILURE(status) || result == NULL) {
276         log_err_status(status, "Error: Break iterator is valid for opening search\n");
277     }
278     else {
279         usearch_close(result);
280     }
281     status = U_ZERO_ERROR;
282     result = usearch_openFromCollator(pattern, 3, text, 6, EN_US_, breakiter,
283                                       &status);
284     if (U_FAILURE(status) || result == NULL) {
285         if (EN_US_ == NULL) {
286             log_data_err("Opening collator failed.\n");
287         } else {
288             log_err("Error: Break iterator is valid for opening search\n");
289         }
290     }
291     else {
292         usearch_close(result);
293     }
294     ubrk_close(breakiter);
295 #endif
296     close();
297 }
298 
TestInitialization(void)299 static void TestInitialization(void)
300 {
301           UErrorCode      status = U_ZERO_ERROR;
302           UChar           pattern[512];
303     const UChar           text[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
304     int32_t i = 0;
305     UStringSearch  *result;
306 
307     /* simple test on the pattern ce construction */
308     pattern[0] = 0x41;
309     pattern[1] = 0x42;
310     open(&status);
311     if (U_FAILURE(status)) {
312         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
313         return;
314     }
315     result = usearch_openFromCollator(pattern, 2, text, 3, EN_US_, NULL,
316                                       &status);
317     if (U_FAILURE(status)) {
318         log_err("Error opening search %s\n", u_errorName(status));
319     }
320     usearch_close(result);
321 
322     /* testing if an extremely large pattern will fail the initialization */
323     for(i = 0; i < 512; i++) {
324       pattern[i] = 0x41;
325     }
326     /*uprv_memset(pattern, 0x41, 512);*/
327     result = usearch_openFromCollator(pattern, 512, text, 3, EN_US_, NULL,
328                                       &status);
329     if (U_FAILURE(status)) {
330         log_err("Error opening search %s\n", u_errorName(status));
331     }
332     usearch_close(result);
333     close();
334 }
335 
assertEqualWithUStringSearch(UStringSearch * strsrch,const SearchData search)336 static UBool assertEqualWithUStringSearch(      UStringSearch *strsrch,
337                                           const SearchData     search)
338 {
339     int         count       = 0;
340     int         matchlimit  = 0;
341     UErrorCode  status      = U_ZERO_ERROR;
342     int32_t matchindex  = search.offset[count];
343     int32_t     textlength;
344     UChar       matchtext[128];
345 
346     usearch_setAttribute(strsrch, USEARCH_ELEMENT_COMPARISON, search.elemCompare, &status);
347     if (U_FAILURE(status)) {
348         log_err("Error setting USEARCH_ELEMENT_COMPARISON attribute %s\n", u_errorName(status));
349         return FALSE;
350     }
351 
352     if (usearch_getMatchedStart(strsrch) != USEARCH_DONE ||
353         usearch_getMatchedLength(strsrch) != 0) {
354         log_err("Error with the initialization of match start and length\n");
355     }
356     /* start of following matches */
357     while (U_SUCCESS(status) && matchindex >= 0) {
358         uint32_t matchlength = search.size[count];
359         usearch_next(strsrch, &status);
360         if (matchindex != usearch_getMatchedStart(strsrch) ||
361             matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
362             char *str = toCharString(usearch_getText(strsrch, &textlength));
363             log_err("Text: %s\n", str);
364             str = toCharString(usearch_getPattern(strsrch, &textlength));
365             log_err("Pattern: %s\n", str);
366             log_err("Error following match found at idx,len %d,%d; expected %d,%d\n",
367                     usearch_getMatchedStart(strsrch), usearch_getMatchedLength(strsrch),
368                     matchindex, matchlength);
369             return FALSE;
370         }
371         count ++;
372 
373         if (usearch_getMatchedText(strsrch, matchtext, 128, &status) !=
374             (int32_t) matchlength || U_FAILURE(status) ||
375             memcmp(matchtext,
376                    usearch_getText(strsrch, &textlength) + matchindex,
377                    matchlength * sizeof(UChar)) != 0) {
378             log_err("Error getting following matched text\n");
379         }
380 
381         matchindex = search.offset[count];
382     }
383     usearch_next(strsrch, &status);
384     if (usearch_getMatchedStart(strsrch) != USEARCH_DONE ||
385         usearch_getMatchedLength(strsrch) != 0) {
386         char *str = toCharString(usearch_getText(strsrch, &textlength));
387         log_err("Text: %s\n", str);
388         str = toCharString(usearch_getPattern(strsrch, &textlength));
389         log_err("Pattern: %s\n", str);
390         log_err("Error following match found at %d %d\n",
391                     usearch_getMatchedStart(strsrch),
392                     usearch_getMatchedLength(strsrch));
393         return FALSE;
394     }
395     /* start of preceding matches */
396     count = count == 0 ? 0 : count - 1;
397     matchlimit = count;
398     matchindex = search.offset[count];
399 
400     while (U_SUCCESS(status) && matchindex >= 0) {
401         uint32_t matchlength = search.size[count];
402         usearch_previous(strsrch, &status);
403         if (matchindex != usearch_getMatchedStart(strsrch) ||
404             matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
405             char *str = toCharString(usearch_getText(strsrch, &textlength));
406             log_err("Text: %s\n", str);
407             str = toCharString(usearch_getPattern(strsrch, &textlength));
408             log_err("Pattern: %s\n", str);
409             log_err("Error preceding match found at %d %d\n",
410                     usearch_getMatchedStart(strsrch),
411                     usearch_getMatchedLength(strsrch));
412             return FALSE;
413         }
414 
415         if (usearch_getMatchedText(strsrch, matchtext, 128, &status) !=
416             (int32_t) matchlength || U_FAILURE(status) ||
417             memcmp(matchtext,
418                    usearch_getText(strsrch, &textlength) + matchindex,
419                    matchlength * sizeof(UChar)) != 0) {
420             log_err("Error getting preceding matched text\n");
421         }
422 
423         matchindex = count > 0 ? search.offset[count - 1] : -1;
424         count --;
425     }
426     usearch_previous(strsrch, &status);
427     if (usearch_getMatchedStart(strsrch) != USEARCH_DONE ||
428         usearch_getMatchedLength(strsrch) != 0) {
429         char *str = toCharString(usearch_getText(strsrch, &textlength));
430         log_err("Text: %s\n", str);
431         str = toCharString(usearch_getPattern(strsrch, &textlength));
432         log_err("Pattern: %s\n", str);
433         log_err("Error preceding match found at %d %d\n",
434                     usearch_getMatchedStart(strsrch),
435                     usearch_getMatchedLength(strsrch));
436         return FALSE;
437     }
438 
439     usearch_setAttribute(strsrch, USEARCH_ELEMENT_COMPARISON, USEARCH_STANDARD_ELEMENT_COMPARISON, &status);
440     return TRUE;
441 }
442 
assertEqual(const SearchData search)443 static UBool assertEqual(const SearchData search)
444 {
445     UErrorCode      status      = U_ZERO_ERROR;
446     UChar           pattern[32];
447     UChar           text[128];
448     UCollator      *collator = getCollator(search.collator);
449     UBreakIterator *breaker  = getBreakIterator(search.breaker);
450     UStringSearch  *strsrch;
451 
452     CHECK_BREAK_BOOL(search.breaker);
453 
454     u_unescape(search.text, text, 128);
455     u_unescape(search.pattern, pattern, 32);
456     ucol_setStrength(collator, search.strength);
457     strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
458                                        breaker, &status);
459     if (U_FAILURE(status)) {
460         log_err("Error opening string search %s\n", u_errorName(status));
461         return FALSE;
462     }
463 
464     if (!assertEqualWithUStringSearch(strsrch, search)) {
465         ucol_setStrength(collator, UCOL_TERTIARY);
466         usearch_close(strsrch);
467         return FALSE;
468     }
469     ucol_setStrength(collator, UCOL_TERTIARY);
470     usearch_close(strsrch);
471     return TRUE;
472 }
473 
assertCanonicalEqual(const SearchData search)474 static UBool assertCanonicalEqual(const SearchData search)
475 {
476     UErrorCode      status      = U_ZERO_ERROR;
477     UChar           pattern[32];
478     UChar           text[128];
479     UCollator      *collator = getCollator(search.collator);
480     UBreakIterator *breaker  = getBreakIterator(search.breaker);
481     UStringSearch  *strsrch;
482     UBool           result = TRUE;
483 
484     CHECK_BREAK_BOOL(search.breaker);
485     u_unescape(search.text, text, 128);
486     u_unescape(search.pattern, pattern, 32);
487     ucol_setStrength(collator, search.strength);
488     ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
489     strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
490                                        breaker, &status);
491     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
492                          &status);
493     if (U_FAILURE(status)) {
494         log_err("Error opening string search %s\n", u_errorName(status));
495         result = FALSE;
496         goto bail;
497     }
498 
499     if (!assertEqualWithUStringSearch(strsrch, search)) {
500         ucol_setStrength(collator, UCOL_TERTIARY);
501         usearch_close(strsrch);
502         result = FALSE;
503         goto bail;
504     }
505 
506 bail:
507     ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
508     ucol_setStrength(collator, UCOL_TERTIARY);
509     usearch_close(strsrch);
510     return result;
511 }
512 
assertEqualWithAttribute(const SearchData search,USearchAttributeValue canonical,USearchAttributeValue overlap)513 static UBool assertEqualWithAttribute(const SearchData            search,
514                                             USearchAttributeValue canonical,
515                                             USearchAttributeValue overlap)
516 {
517     UErrorCode      status      = U_ZERO_ERROR;
518     UChar           pattern[32];
519     UChar           text[128];
520     UCollator      *collator = getCollator(search.collator);
521     UBreakIterator *breaker  = getBreakIterator(search.breaker);
522     UStringSearch  *strsrch;
523 
524     CHECK_BREAK_BOOL(search.breaker);
525     u_unescape(search.text, text, 128);
526     u_unescape(search.pattern, pattern, 32);
527     ucol_setStrength(collator, search.strength);
528     strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
529                                        breaker, &status);
530     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, canonical,
531                          &status);
532     usearch_setAttribute(strsrch, USEARCH_OVERLAP, overlap, &status);
533 
534     if (U_FAILURE(status)) {
535         log_err("Error opening string search %s\n", u_errorName(status));
536         return FALSE;
537     }
538 
539     if (!assertEqualWithUStringSearch(strsrch, search)) {
540             ucol_setStrength(collator, UCOL_TERTIARY);
541             usearch_close(strsrch);
542             return FALSE;
543     }
544     ucol_setStrength(collator, UCOL_TERTIARY);
545     usearch_close(strsrch);
546     return TRUE;
547 }
548 
TestBasic(void)549 static void TestBasic(void)
550 {
551     int count = 0;
552     UErrorCode status = U_ZERO_ERROR;
553     open(&status);
554     if (U_FAILURE(status)) {
555         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
556         return;
557     }
558     while (BASIC[count].text != NULL) {
559         if (!assertEqual(BASIC[count])) {
560             log_err("Error at test number %d\n", count);
561         }
562         count ++;
563     }
564     close();
565 }
566 
TestNormExact(void)567 static void TestNormExact(void)
568 {
569     int count = 0;
570     UErrorCode status = U_ZERO_ERROR;
571     open(&status);
572     if (U_FAILURE(status)) {
573         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
574         return;
575     }
576     ucol_setAttribute(EN_US_, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
577     if (U_FAILURE(status)) {
578         log_err("Error setting collation normalization %s\n",
579             u_errorName(status));
580     }
581     while (BASIC[count].text != NULL) {
582         if (!assertEqual(BASIC[count])) {
583             log_err("Error at test number %d\n", count);
584         }
585         count ++;
586     }
587     count = 0;
588     while (NORMEXACT[count].text != NULL) {
589         if (!assertEqual(NORMEXACT[count])) {
590             log_err("Error at test number %d\n", count);
591         }
592         count ++;
593     }
594     ucol_setAttribute(EN_US_, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
595     count = 0;
596     while (NONNORMEXACT[count].text != NULL) {
597         if (!assertEqual(NONNORMEXACT[count])) {
598             log_err("Error at test number %d\n", count);
599         }
600         count ++;
601     }
602     close();
603 }
604 
TestStrength(void)605 static void TestStrength(void)
606 {
607     int count = 0;
608     UErrorCode status = U_ZERO_ERROR;
609     open(&status);
610     if (U_FAILURE(status)) {
611         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
612         return;
613     }
614     while (STRENGTH[count].text != NULL) {
615         if (!assertEqual(STRENGTH[count])) {
616             log_err("Error at test number %d\n", count);
617         }
618         count ++;
619     }
620     close();
621 }
622 
TestBreakIterator(void)623 static void TestBreakIterator(void) {
624     UErrorCode      status      = U_ZERO_ERROR;
625     UStringSearch  *strsrch;
626     UChar           text[128];
627     UChar           pattern[32];
628     int             count = 0;
629 
630     CHECK_BREAK("x");
631 
632 #if !UCONFIG_NO_BREAK_ITERATION
633     open(&status);
634     if (U_FAILURE(status)) {
635         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
636         return;
637     }
638     if (usearch_getBreakIterator(NULL) != NULL) {
639         log_err("Expected NULL breakiterator from NULL string search\n");
640     }
641     u_unescape(BREAKITERATOREXACT[0].text, text, 128);
642     u_unescape(BREAKITERATOREXACT[0].pattern, pattern, 32);
643     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_, NULL,
644                                        &status);
645     if (U_FAILURE(status)) {
646         log_err("Error opening string search %s\n", u_errorName(status));
647         goto ENDTESTBREAKITERATOR;
648     }
649 
650     usearch_setBreakIterator(strsrch, NULL, &status);
651     if (U_FAILURE(status) || usearch_getBreakIterator(strsrch) != NULL) {
652         log_err("Error usearch_getBreakIterator returned wrong object");
653         goto ENDTESTBREAKITERATOR;
654     }
655 
656     usearch_setBreakIterator(strsrch, EN_CHARACTERBREAKER_, &status);
657     if (U_FAILURE(status) ||
658         usearch_getBreakIterator(strsrch) != EN_CHARACTERBREAKER_) {
659         log_err("Error usearch_getBreakIterator returned wrong object");
660         goto ENDTESTBREAKITERATOR;
661     }
662 
663     usearch_setBreakIterator(strsrch, EN_WORDBREAKER_, &status);
664     if (U_FAILURE(status) ||
665         usearch_getBreakIterator(strsrch) != EN_WORDBREAKER_) {
666         log_err("Error usearch_getBreakIterator returned wrong object");
667         goto ENDTESTBREAKITERATOR;
668     }
669 
670     usearch_close(strsrch);
671 
672     count = 0;
673     while (count < 4) {
674         /* 0-3 test are fixed */
675         const SearchData     *search   = &(BREAKITERATOREXACT[count]);
676               UCollator      *collator = getCollator(search->collator);
677               UBreakIterator *breaker  = getBreakIterator(search->breaker);
678 
679         u_unescape(search->text, text, 128);
680         u_unescape(search->pattern, pattern, 32);
681         ucol_setStrength(collator, search->strength);
682 
683         strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
684                                            breaker, &status);
685         if (U_FAILURE(status) ||
686             usearch_getBreakIterator(strsrch) != breaker) {
687             log_err("Error setting break iterator\n");
688             if (strsrch != NULL) {
689                 usearch_close(strsrch);
690             }
691         }
692         if (!assertEqualWithUStringSearch(strsrch, *search)) {
693             ucol_setStrength(collator, UCOL_TERTIARY);
694             usearch_close(strsrch);
695             goto ENDTESTBREAKITERATOR;
696         }
697         search   = &(BREAKITERATOREXACT[count + 1]);
698         breaker  = getBreakIterator(search->breaker);
699         usearch_setBreakIterator(strsrch, breaker, &status);
700         if (U_FAILURE(status) || usearch_getBreakIterator(strsrch) != breaker) {
701             log_err("Error setting break iterator\n");
702             usearch_close(strsrch);
703             goto ENDTESTBREAKITERATOR;
704         }
705         usearch_reset(strsrch);
706         if (!assertEqualWithUStringSearch(strsrch, *search)) {
707             log_err("Error at test number %d\n", count);
708             usearch_close(strsrch);
709             goto ENDTESTBREAKITERATOR;
710         }
711         usearch_close(strsrch);
712         count += 2;
713     }
714     count = 0;
715     while (BREAKITERATOREXACT[count].text != NULL) {
716          if (!assertEqual(BREAKITERATOREXACT[count])) {
717              log_err("Error at test number %d\n", count);
718              goto ENDTESTBREAKITERATOR;
719          }
720          count ++;
721     }
722 
723 ENDTESTBREAKITERATOR:
724     close();
725 #endif
726 }
727 
TestVariable(void)728 static void TestVariable(void)
729 {
730     int count = 0;
731     UErrorCode status = U_ZERO_ERROR;
732     open(&status);
733     if (U_FAILURE(status)) {
734         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
735         return;
736     }
737     ucol_setAttribute(EN_US_, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
738     if (U_FAILURE(status)) {
739         log_err("Error setting collation alternate attribute %s\n",
740             u_errorName(status));
741     }
742     while (VARIABLE[count].text != NULL) {
743         log_verbose("variable %d\n", count);
744         if (!assertEqual(VARIABLE[count])) {
745             log_err("Error at test number %d\n", count);
746         }
747         count ++;
748     }
749     ucol_setAttribute(EN_US_, UCOL_ALTERNATE_HANDLING,
750                       UCOL_NON_IGNORABLE, &status);
751     close();
752 }
753 
TestOverlap(void)754 static void TestOverlap(void)
755 {
756     int count = 0;
757     UErrorCode status = U_ZERO_ERROR;
758     open(&status);
759     if (U_FAILURE(status)) {
760         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
761         return;
762     }
763     while (OVERLAP[count].text != NULL) {
764         if (!assertEqualWithAttribute(OVERLAP[count], USEARCH_OFF,
765                                       USEARCH_ON)) {
766             log_err("Error at overlap test number %d\n", count);
767         }
768         count ++;
769     }
770     count = 0;
771     while (NONOVERLAP[count].text != NULL) {
772         if (!assertEqual(NONOVERLAP[count])) {
773             log_err("Error at non overlap test number %d\n", count);
774         }
775         count ++;
776     }
777 
778     count = 0;
779     while (count < 1) {
780               UChar           pattern[32];
781               UChar           text[128];
782         const SearchData     *search   = &(OVERLAP[count]);
783               UCollator      *collator = getCollator(search->collator);
784               UStringSearch  *strsrch;
785               status   = U_ZERO_ERROR;
786 
787         u_unescape(search->text, text, 128);
788         u_unescape(search->pattern, pattern, 32);
789         strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
790                                            NULL, &status);
791         if(status == U_FILE_ACCESS_ERROR) {
792           log_data_err("Is your data around?\n");
793           return;
794         } else if(U_FAILURE(status)) {
795           log_err("Error opening searcher\n");
796           return;
797         }
798         usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_ON, &status);
799         if (U_FAILURE(status) ||
800             usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_ON) {
801             log_err("Error setting overlap option\n");
802         }
803         if (!assertEqualWithUStringSearch(strsrch, *search)) {
804             usearch_close(strsrch);
805             return;
806         }
807         search   = &(NONOVERLAP[count]);
808         usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_OFF, &status);
809         if (U_FAILURE(status) ||
810             usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF) {
811             log_err("Error setting overlap option\n");
812         }
813         usearch_reset(strsrch);
814         if (!assertEqualWithUStringSearch(strsrch, *search)) {
815             usearch_close(strsrch);
816             log_err("Error at test number %d\n", count);
817          }
818 
819         count ++;
820         usearch_close(strsrch);
821     }
822     close();
823 }
824 
TestCollator(void)825 static void TestCollator(void)
826 {
827     /* test collator that thinks "o" and "p" are the same thing */
828           UChar          rules[32];
829           UCollator     *tailored = NULL;
830           UErrorCode     status   = U_ZERO_ERROR;
831           UChar          pattern[32];
832           UChar          text[128];
833           UStringSearch *strsrch;
834 
835     text[0] = 0x41;
836     text[1] = 0x42;
837     text[2] = 0x43;
838     text[3] = 0x44;
839     text[4] = 0x45;
840     pattern[0] = 0x62;
841     pattern[1] = 0x63;
842     strsrch  = usearch_open(pattern, 2, text, 5, "en_US",  NULL,  &status);
843     if(status == U_FILE_ACCESS_ERROR) {
844       log_data_err("Is your data around?\n");
845       return;
846     } else if(U_FAILURE(status)) {
847       log_err("Error opening searcher\n");
848       return;
849     }
850     tailored = usearch_getCollator(strsrch);
851     if (usearch_next(strsrch, &status) != -1) {
852         log_err("Error: Found case insensitive match, when we shouldn't\n");
853     }
854     ucol_setStrength(tailored, UCOL_PRIMARY);
855     usearch_reset(strsrch);
856     if (usearch_next(strsrch, &status) != 1) {
857         log_err("Error: Found case insensitive match not found\n");
858     }
859     usearch_close(strsrch);
860 
861     open(&status);
862 
863     if (usearch_getCollator(NULL) != NULL) {
864         log_err("Expected NULL collator from NULL string search\n");
865     }
866     u_unescape(COLLATOR[0].text, text, 128);
867     u_unescape(COLLATOR[0].pattern, pattern, 32);
868 
869     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
870                                        NULL, &status);
871     if (U_FAILURE(status)) {
872         log_err("Error opening string search %s\n", u_errorName(status));
873     }
874     if (!assertEqualWithUStringSearch(strsrch, COLLATOR[0])) {
875         goto ENDTESTCOLLATOR;
876     }
877 
878     u_unescape(TESTCOLLATORRULE, rules, 32);
879     tailored = ucol_openRules(rules, -1, UCOL_ON, COLLATOR[1].strength,
880                               NULL, &status);
881     if (U_FAILURE(status)) {
882         log_err("Error opening rule based collator %s\n", u_errorName(status));
883     }
884 
885     usearch_setCollator(strsrch, tailored, &status);
886     if (U_FAILURE(status) || usearch_getCollator(strsrch) != tailored) {
887         log_err("Error setting rule based collator\n");
888     }
889     usearch_reset(strsrch);
890     if (!assertEqualWithUStringSearch(strsrch, COLLATOR[1])) {
891         goto ENDTESTCOLLATOR;
892     }
893 
894     usearch_setCollator(strsrch, EN_US_, &status);
895     usearch_reset(strsrch);
896     if (U_FAILURE(status) || usearch_getCollator(strsrch) != EN_US_) {
897         log_err("Error setting rule based collator\n");
898     }
899     if (!assertEqualWithUStringSearch(strsrch, COLLATOR[0])) {
900         goto ENDTESTCOLLATOR;
901     }
902 
903 ENDTESTCOLLATOR:
904     usearch_close(strsrch);
905     if (tailored != NULL) {
906         ucol_close(tailored);
907     }
908     close();
909 }
910 
TestPattern(void)911 static void TestPattern(void)
912 {
913           UStringSearch *strsrch;
914           UChar          pattern[32];
915           UChar          bigpattern[512];
916           UChar          text[128];
917     const UChar         *temp;
918           int32_t        templength;
919           UErrorCode     status = U_ZERO_ERROR;
920 
921     open(&status);
922     if (U_FAILURE(status)) {
923         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
924         return;
925     }
926     if (usearch_getPattern(NULL, &templength) != NULL) {
927         log_err("Error NULL string search expected returning NULL pattern\n");
928     }
929     usearch_setPattern(NULL, pattern, 3, &status);
930     if (U_SUCCESS(status)) {
931         log_err("Error expected setting pattern in NULL strings search\n");
932     }
933     status = U_ZERO_ERROR;
934     u_unescape(PATTERN[0].text, text, 128);
935     u_unescape(PATTERN[0].pattern, pattern, 32);
936 
937     ucol_setStrength(EN_US_, PATTERN[0].strength);
938     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
939                                        NULL, &status);
940     if(status == U_FILE_ACCESS_ERROR) {
941       log_data_err("Is your data around?\n");
942       return;
943     } else if(U_FAILURE(status)) {
944       log_err("Error opening searcher\n");
945       return;
946     }
947 
948     status = U_ZERO_ERROR;
949     usearch_setPattern(strsrch, NULL, 3, &status);
950     if (U_SUCCESS(status)) {
951         log_err("Error expected setting NULL pattern in strings search\n");
952     }
953     status = U_ZERO_ERROR;
954     usearch_setPattern(strsrch, pattern, 0, &status);
955     if (U_SUCCESS(status)) {
956         log_err("Error expected setting pattern with length 0 in strings search\n");
957     }
958     status = U_ZERO_ERROR;
959     if (U_FAILURE(status)) {
960         log_err("Error opening string search %s\n", u_errorName(status));
961         goto ENDTESTPATTERN;
962     }
963     temp = usearch_getPattern(strsrch, &templength);
964     if (u_strcmp(pattern, temp) != 0) {
965         log_err("Error setting pattern\n");
966     }
967     if (!assertEqualWithUStringSearch(strsrch, PATTERN[0])) {
968         goto ENDTESTPATTERN;
969     }
970 
971     u_unescape(PATTERN[1].pattern, pattern, 32);
972     usearch_setPattern(strsrch, pattern, -1, &status);
973     temp = usearch_getPattern(strsrch, &templength);
974     if (u_strcmp(pattern, temp) != 0) {
975         log_err("Error setting pattern\n");
976         goto ENDTESTPATTERN;
977     }
978     usearch_reset(strsrch);
979     if (U_FAILURE(status)) {
980         log_err("Error setting pattern %s\n", u_errorName(status));
981     }
982     if (!assertEqualWithUStringSearch(strsrch, PATTERN[1])) {
983         goto ENDTESTPATTERN;
984     }
985 
986     u_unescape(PATTERN[0].pattern, pattern, 32);
987     usearch_setPattern(strsrch, pattern, -1, &status);
988     temp = usearch_getPattern(strsrch, &templength);
989     if (u_strcmp(pattern, temp) != 0) {
990         log_err("Error setting pattern\n");
991         goto ENDTESTPATTERN;
992     }
993     usearch_reset(strsrch);
994     if (U_FAILURE(status)) {
995         log_err("Error setting pattern %s\n", u_errorName(status));
996     }
997     if (!assertEqualWithUStringSearch(strsrch, PATTERN[0])) {
998         goto ENDTESTPATTERN;
999     }
1000     /* enormous pattern size to see if this crashes */
1001     for (templength = 0; templength != 512; templength ++) {
1002         bigpattern[templength] = 0x61;
1003     }
1004     bigpattern[511] = 0;
1005     usearch_setPattern(strsrch, bigpattern, -1, &status);
1006     if (U_FAILURE(status)) {
1007         log_err("Error setting pattern with size 512, %s \n",
1008             u_errorName(status));
1009     }
1010 ENDTESTPATTERN:
1011     ucol_setStrength(EN_US_, UCOL_TERTIARY);
1012     if (strsrch != NULL) {
1013         usearch_close(strsrch);
1014     }
1015     close();
1016 }
1017 
TestText(void)1018 static void TestText(void)
1019 {
1020           UStringSearch *strsrch;
1021           UChar          pattern[32];
1022           UChar          text[128];
1023     const UChar         *temp;
1024           int32_t        templength;
1025           UErrorCode     status = U_ZERO_ERROR;
1026 
1027     u_unescape(TEXT[0].text, text, 128);
1028     u_unescape(TEXT[0].pattern, pattern, 32);
1029 
1030     open(&status);
1031     if (U_FAILURE(status)) {
1032         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1033         return;
1034     }
1035 
1036     if (usearch_getText(NULL, &templength) != NULL) {
1037         log_err("Error NULL string search should return NULL text\n");
1038     }
1039 
1040     usearch_setText(NULL, text, 10, &status);
1041     if (U_SUCCESS(status)) {
1042         log_err("Error NULL string search should have an error when setting text\n");
1043     }
1044 
1045     status = U_ZERO_ERROR;
1046     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
1047                                        NULL, &status);
1048 
1049     if (U_FAILURE(status)) {
1050         log_err("Error opening string search %s\n", u_errorName(status));
1051         goto ENDTESTPATTERN;
1052     }
1053     temp = usearch_getText(strsrch, &templength);
1054     if (u_strcmp(text, temp) != 0) {
1055         log_err("Error setting text\n");
1056     }
1057     if (!assertEqualWithUStringSearch(strsrch, TEXT[0])) {
1058         goto ENDTESTPATTERN;
1059     }
1060 
1061     u_unescape(TEXT[1].text, text, 32);
1062     usearch_setText(strsrch, text, -1, &status);
1063     temp = usearch_getText(strsrch, &templength);
1064     if (u_strcmp(text, temp) != 0) {
1065         log_err("Error setting text\n");
1066         goto ENDTESTPATTERN;
1067     }
1068     if (U_FAILURE(status)) {
1069         log_err("Error setting text %s\n", u_errorName(status));
1070     }
1071     if (!assertEqualWithUStringSearch(strsrch, TEXT[1])) {
1072         goto ENDTESTPATTERN;
1073     }
1074 
1075     u_unescape(TEXT[0].text, text, 32);
1076     usearch_setText(strsrch, text, -1, &status);
1077     temp = usearch_getText(strsrch, &templength);
1078     if (u_strcmp(text, temp) != 0) {
1079         log_err("Error setting text\n");
1080         goto ENDTESTPATTERN;
1081     }
1082     if (U_FAILURE(status)) {
1083         log_err("Error setting pattern %s\n", u_errorName(status));
1084     }
1085     if (!assertEqualWithUStringSearch(strsrch, TEXT[0])) {
1086         goto ENDTESTPATTERN;
1087     }
1088 ENDTESTPATTERN:
1089     if (strsrch != NULL) {
1090         usearch_close(strsrch);
1091     }
1092     close();
1093 }
1094 
TestCompositeBoundaries(void)1095 static void TestCompositeBoundaries(void)
1096 {
1097     int count = 0;
1098     UErrorCode status = U_ZERO_ERROR;
1099     open(&status);
1100     if (U_FAILURE(status)) {
1101         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1102         return;
1103     }
1104     while (COMPOSITEBOUNDARIES[count].text != NULL) {
1105         log_verbose("composite %d\n", count);
1106         if (!assertEqual(COMPOSITEBOUNDARIES[count])) {
1107             log_err("Error at test number %d\n", count);
1108         }
1109         count ++;
1110     }
1111     close();
1112 }
1113 
TestGetSetOffset(void)1114 static void TestGetSetOffset(void)
1115 {
1116     int            searchDataIndex   = 0;
1117     UChar          pattern[32];
1118     UChar          text[128];
1119     UErrorCode     status  = U_ZERO_ERROR;
1120     UStringSearch *strsrch;
1121     memset(pattern, 0, 32*sizeof(UChar));
1122     memset(text, 0, 128*sizeof(UChar));
1123 
1124     open(&status);
1125     if (U_FAILURE(status)) {
1126         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1127         return;
1128     }
1129     if (usearch_getOffset(NULL) != USEARCH_DONE) {
1130         log_err("usearch_getOffset(NULL) expected USEARCH_DONE\n");
1131     }
1132     strsrch = usearch_openFromCollator(pattern, 16, text, 32, EN_US_, NULL,
1133                                        &status);
1134     /* testing out of bounds error */
1135     usearch_setOffset(strsrch, -1, &status);
1136     if (U_SUCCESS(status)) {
1137         log_err("Error expecting set offset error\n");
1138     }
1139     usearch_setOffset(strsrch, 128, &status);
1140     if (U_SUCCESS(status)) {
1141         log_err("Error expecting set offset error\n");
1142     }
1143     while (BASIC[searchDataIndex].text != NULL) {
1144         int         count       = 0;
1145         SearchData  search      = BASIC[searchDataIndex ++];
1146         int32_t matchindex  = search.offset[count];
1147         int32_t     textlength;
1148 
1149         u_unescape(search.text, text, 128);
1150         u_unescape(search.pattern, pattern, 32);
1151         status = U_ZERO_ERROR;
1152         usearch_setText(strsrch, text, -1, &status);
1153         usearch_setPattern(strsrch, pattern, -1, &status);
1154         ucol_setStrength(usearch_getCollator(strsrch), search.strength);
1155         usearch_reset(strsrch);
1156         while (U_SUCCESS(status) && matchindex >= 0) {
1157             uint32_t matchlength = search.size[count];
1158             usearch_next(strsrch, &status);
1159             if (matchindex != usearch_getMatchedStart(strsrch) ||
1160                 matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
1161                 char *str = toCharString(usearch_getText(strsrch,
1162                                                          &textlength));
1163                 log_err("Text: %s\n", str);
1164                 str = toCharString(usearch_getPattern(strsrch, &textlength));
1165                 log_err("Pattern: %s\n", str);
1166                 log_err("Error match found at %d %d\n",
1167                         usearch_getMatchedStart(strsrch),
1168                         usearch_getMatchedLength(strsrch));
1169                 return;
1170             }
1171             usearch_setOffset(strsrch, matchindex + matchlength, &status);
1172             usearch_previous(strsrch, &status);
1173             if (matchindex != usearch_getMatchedStart(strsrch) ||
1174                 matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
1175                 char *str = toCharString(usearch_getText(strsrch,
1176                                                          &textlength));
1177                 log_err("Text: %s\n", str);
1178                 str = toCharString(usearch_getPattern(strsrch, &textlength));
1179                 log_err("Pattern: %s\n", str);
1180                 log_err("Error match found at %d %d\n",
1181                         usearch_getMatchedStart(strsrch),
1182                         usearch_getMatchedLength(strsrch));
1183                 return;
1184             }
1185             usearch_setOffset(strsrch, matchindex + matchlength, &status);
1186             matchindex = search.offset[count + 1] == -1 ? -1 :
1187                          search.offset[count + 2];
1188             if (search.offset[count + 1] != -1) {
1189                 usearch_setOffset(strsrch, search.offset[count + 1] + 1,
1190                                   &status);
1191                 if (usearch_getOffset(strsrch) != search.offset[count + 1] + 1) {
1192                     log_err("Error setting offset\n");
1193                     return;
1194                 }
1195             }
1196 
1197             count += 2;
1198         }
1199         usearch_next(strsrch, &status);
1200         if (usearch_getMatchedStart(strsrch) != USEARCH_DONE) {
1201             char *str = toCharString(usearch_getText(strsrch, &textlength));
1202             log_err("Text: %s\n", str);
1203             str = toCharString(usearch_getPattern(strsrch, &textlength));
1204             log_err("Pattern: %s\n", str);
1205             log_err("Error match found at %d %d\n",
1206                         usearch_getMatchedStart(strsrch),
1207                         usearch_getMatchedLength(strsrch));
1208             return;
1209         }
1210     }
1211     ucol_setStrength(usearch_getCollator(strsrch), UCOL_TERTIARY);
1212     usearch_close(strsrch);
1213     close();
1214 }
1215 
TestGetSetAttribute(void)1216 static void TestGetSetAttribute(void)
1217 {
1218     UErrorCode      status    = U_ZERO_ERROR;
1219     UChar           pattern[32];
1220     UChar           text[128];
1221     UStringSearch  *strsrch;
1222 
1223     memset(pattern, 0, 32*sizeof(UChar));
1224     memset(text, 0, 128*sizeof(UChar));
1225 
1226     open(&status);
1227     if (U_FAILURE(status)) {
1228         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1229         return;
1230     }
1231     if (usearch_getAttribute(NULL, USEARCH_OVERLAP) != USEARCH_DEFAULT ||
1232         usearch_getAttribute(NULL, USEARCH_CANONICAL_MATCH) !=
1233                                                          USEARCH_DEFAULT) {
1234         log_err(
1235             "Attributes for NULL string search should be USEARCH_DEFAULT\n");
1236     }
1237     strsrch = usearch_openFromCollator(pattern, 16, text, 32, EN_US_, NULL,
1238                                        &status);
1239     if (U_FAILURE(status)) {
1240         log_err("Error opening search %s\n", u_errorName(status));
1241         return;
1242     }
1243 
1244     usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_DEFAULT, &status);
1245     if (U_FAILURE(status) ||
1246         usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF) {
1247         log_err("Error setting overlap to the default\n");
1248     }
1249     usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_ON, &status);
1250     if (U_FAILURE(status) ||
1251         usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_ON) {
1252         log_err("Error setting overlap true\n");
1253     }
1254     usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_OFF, &status);
1255     if (U_FAILURE(status) ||
1256         usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF) {
1257         log_err("Error setting overlap false\n");
1258     }
1259     usearch_setAttribute(strsrch, USEARCH_OVERLAP,
1260                          USEARCH_ATTRIBUTE_VALUE_COUNT, &status);
1261     if (U_SUCCESS(status)) {
1262         log_err("Error setting overlap to illegal value\n");
1263     }
1264     status = U_ZERO_ERROR;
1265     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_DEFAULT,
1266                          &status);
1267     if (U_FAILURE(status) ||
1268         usearch_getAttribute(strsrch, USEARCH_CANONICAL_MATCH) !=
1269                                                         USEARCH_OFF) {
1270         log_err("Error setting canonical match to the default\n");
1271     }
1272     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1273                          &status);
1274     if (U_FAILURE(status) ||
1275         usearch_getAttribute(strsrch, USEARCH_CANONICAL_MATCH) !=
1276                                                          USEARCH_ON) {
1277         log_err("Error setting canonical match true\n");
1278     }
1279     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_OFF,
1280                          &status);
1281     if (U_FAILURE(status) ||
1282         usearch_getAttribute(strsrch, USEARCH_CANONICAL_MATCH) !=
1283                                                         USEARCH_OFF) {
1284         log_err("Error setting canonical match false\n");
1285     }
1286     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH,
1287                          USEARCH_ATTRIBUTE_VALUE_COUNT, &status);
1288     if (U_SUCCESS(status)) {
1289         log_err("Error setting canonical match to illegal value\n");
1290     }
1291     status = U_ZERO_ERROR;
1292     usearch_setAttribute(strsrch, USEARCH_ATTRIBUTE_COUNT, USEARCH_DEFAULT,
1293                          &status);
1294     if (U_SUCCESS(status)) {
1295         log_err("Error setting illegal attribute success\n");
1296     }
1297 
1298     usearch_close(strsrch);
1299     close();
1300 }
1301 
TestGetMatch(void)1302 static void TestGetMatch(void)
1303 {
1304     int            count       = 0;
1305     UErrorCode     status      = U_ZERO_ERROR;
1306     UChar          text[128];
1307     UChar          pattern[32];
1308     SearchData     search      = MATCH[0];
1309     int32_t    matchindex  = search.offset[count];
1310     UStringSearch *strsrch;
1311     int32_t        textlength;
1312     UChar          matchtext[128];
1313 
1314     open(&status);
1315     if (U_FAILURE(status)) {
1316         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1317         return;
1318     }
1319 
1320     if (usearch_getMatchedStart(NULL) != USEARCH_DONE ||
1321         usearch_getMatchedLength(NULL) != USEARCH_DONE) {
1322         log_err(
1323    "Expected start and length of NULL string search should be USEARCH_DONE\n");
1324     }
1325 
1326     u_unescape(search.text, text, 128);
1327     u_unescape(search.pattern, pattern, 32);
1328     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
1329                                        NULL, &status);
1330     if (U_FAILURE(status)) {
1331         log_err("Error opening string search %s\n", u_errorName(status));
1332         if (strsrch != NULL) {
1333             usearch_close(strsrch);
1334         }
1335         return;
1336     }
1337 
1338     while (U_SUCCESS(status) && matchindex >= 0) {
1339         int32_t matchlength = search.size[count];
1340         usearch_next(strsrch, &status);
1341         if (matchindex != usearch_getMatchedStart(strsrch) ||
1342             matchlength != usearch_getMatchedLength(strsrch)) {
1343             char *str = toCharString(usearch_getText(strsrch, &textlength));
1344             log_err("Text: %s\n", str);
1345             str = toCharString(usearch_getPattern(strsrch, &textlength));
1346             log_err("Pattern: %s\n", str);
1347             log_err("Error match found at %d %d\n",
1348                     usearch_getMatchedStart(strsrch),
1349                     usearch_getMatchedLength(strsrch));
1350             return;
1351         }
1352         count ++;
1353 
1354         status = U_ZERO_ERROR;
1355         if (usearch_getMatchedText(NULL, matchtext, 128, &status) !=
1356             USEARCH_DONE || U_SUCCESS(status)){
1357             log_err("Error expecting errors with NULL string search\n");
1358         }
1359         status = U_ZERO_ERROR;
1360         if (usearch_getMatchedText(strsrch, NULL, 0, &status) !=
1361             (int32_t)matchlength || U_SUCCESS(status)){
1362             log_err("Error pre-flighting match length\n");
1363         }
1364         status = U_ZERO_ERROR;
1365         if (usearch_getMatchedText(strsrch, matchtext, 0, &status) !=
1366             (int32_t)matchlength || U_SUCCESS(status)){
1367             log_err("Error getting match text with buffer size 0\n");
1368         }
1369         status = U_ZERO_ERROR;
1370         if (usearch_getMatchedText(strsrch, matchtext, matchlength, &status)
1371             != (int32_t)matchlength || matchtext[matchlength - 1] == 0 ||
1372             U_FAILURE(status)){
1373             log_err("Error getting match text with exact size\n");
1374         }
1375         status = U_ZERO_ERROR;
1376         if (usearch_getMatchedText(strsrch, matchtext, 128, &status) !=
1377             (int32_t) matchlength || U_FAILURE(status) ||
1378             memcmp(matchtext,
1379                    usearch_getText(strsrch, &textlength) + matchindex,
1380                    matchlength * sizeof(UChar)) != 0 ||
1381             matchtext[matchlength] != 0) {
1382             log_err("Error getting matched text\n");
1383         }
1384 
1385         matchindex = search.offset[count];
1386     }
1387     status = U_ZERO_ERROR;
1388     usearch_next(strsrch, &status);
1389     if (usearch_getMatchedStart(strsrch)  != USEARCH_DONE ||
1390         usearch_getMatchedLength(strsrch) != 0) {
1391         log_err("Error end of match not found\n");
1392     }
1393     status = U_ZERO_ERROR;
1394     if (usearch_getMatchedText(strsrch, matchtext, 128, &status) !=
1395         USEARCH_DONE) {
1396         log_err("Error getting null matches\n");
1397     }
1398     usearch_close(strsrch);
1399     close();
1400 }
1401 
TestSetMatch(void)1402 static void TestSetMatch(void)
1403 {
1404     int            count       = 0;
1405     UErrorCode status = U_ZERO_ERROR;
1406     open(&status);
1407     if (U_FAILURE(status)) {
1408         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1409         return;
1410     }
1411     while (MATCH[count].text != NULL) {
1412         SearchData     search = MATCH[count];
1413         int            size   = 0;
1414         int            offsetIndex = 0;
1415         UChar          text[128];
1416         UChar          pattern[32];
1417         UStringSearch *strsrch;
1418         status = U_ZERO_ERROR;
1419 
1420         if (usearch_first(NULL, &status) != USEARCH_DONE ||
1421             usearch_last(NULL, &status) != USEARCH_DONE) {
1422             log_err("Error getting the first and last match of a NULL string search\n");
1423         }
1424         u_unescape(search.text, text, 128);
1425         u_unescape(search.pattern, pattern, 32);
1426         strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
1427                                            NULL, &status);
1428         if (U_FAILURE(status)) {
1429             log_err("Error opening string search %s\n", u_errorName(status));
1430             if (strsrch != NULL) {
1431                 usearch_close(strsrch);
1432             }
1433             return;
1434         }
1435 
1436         size = 0;
1437         while (search.offset[size] != -1) {
1438             size ++;
1439         }
1440 
1441         if (usearch_first(strsrch, &status) != search.offset[0] ||
1442             U_FAILURE(status)) {
1443             log_err("Error getting first match\n");
1444         }
1445         if (usearch_last(strsrch, &status) != search.offset[size -1] ||
1446             U_FAILURE(status)) {
1447             log_err("Error getting last match\n");
1448         }
1449 
1450         while (offsetIndex < size) {
1451             if (offsetIndex + 2 < size) {
1452                 if (usearch_following(strsrch, search.offset[offsetIndex + 2] - 1,
1453                                       &status) != search.offset[offsetIndex + 2] ||
1454                     U_FAILURE(status)) {
1455                     log_err("Error getting following match at index %d\n",
1456                             search.offset[offsetIndex + 2] - 1);
1457                 }
1458             }
1459             if (offsetIndex + 1 < size) {
1460                 if (usearch_preceding(strsrch, search.offset[offsetIndex + 1] +
1461                                                search.size[offsetIndex + 1] + 1,
1462                                       &status) != search.offset[offsetIndex + 1] ||
1463                     U_FAILURE(status)) {
1464                     log_err("Error getting preceeding match at index %d\n",
1465                             search.offset[offsetIndex + 1] + 1);
1466                 }
1467             }
1468             offsetIndex += 2;
1469         }
1470         status = U_ZERO_ERROR;
1471         if (usearch_following(strsrch, u_strlen(text), &status) !=
1472             USEARCH_DONE) {
1473             log_err("Error expecting out of bounds match\n");
1474         }
1475         if (usearch_preceding(strsrch, 0, &status) != USEARCH_DONE) {
1476             log_err("Error expecting out of bounds match\n");
1477         }
1478         count ++;
1479         usearch_close(strsrch);
1480     }
1481     close();
1482 }
1483 
TestReset(void)1484 static void TestReset(void)
1485 {
1486     UErrorCode     status    = U_ZERO_ERROR;
1487     UChar          text[]    = {0x66, 0x69, 0x73, 0x68, 0x20,
1488                                 0x66, 0x69, 0x73, 0x68};
1489     UChar          pattern[] = {0x73};
1490     UStringSearch *strsrch;
1491 
1492     open(&status);
1493     if (U_FAILURE(status)) {
1494         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1495         return;
1496     }
1497     strsrch = usearch_openFromCollator(pattern, 1, text, 9,
1498                                                       EN_US_, NULL, &status);
1499     if (U_FAILURE(status)) {
1500         log_err("Error opening string search %s\n", u_errorName(status));
1501         if (strsrch != NULL) {
1502             usearch_close(strsrch);
1503         }
1504         return;
1505     }
1506     usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_ON, &status);
1507     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1508                          &status);
1509     usearch_setOffset(strsrch, 9, &status);
1510     if (U_FAILURE(status)) {
1511         log_err("Error setting attributes and offsets\n");
1512     }
1513     else {
1514         usearch_reset(strsrch);
1515         if (usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF ||
1516             usearch_getAttribute(strsrch, USEARCH_CANONICAL_MATCH) !=
1517                                  USEARCH_OFF ||
1518             usearch_getOffset(strsrch) != 0 ||
1519             usearch_getMatchedLength(strsrch) != 0 ||
1520             usearch_getMatchedStart(strsrch) != USEARCH_DONE) {
1521             log_err("Error resetting string search\n");
1522         }
1523         usearch_previous(strsrch, &status);
1524         if (usearch_getMatchedStart(strsrch) != 7 ||
1525             usearch_getMatchedLength(strsrch) != 1) {
1526             log_err("Error resetting string search\n");
1527         }
1528     }
1529     usearch_close(strsrch);
1530     close();
1531 }
1532 
TestSupplementary(void)1533 static void TestSupplementary(void)
1534 {
1535     int count = 0;
1536     UErrorCode status = U_ZERO_ERROR;
1537     open(&status);
1538     if (U_FAILURE(status)) {
1539         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1540         return;
1541     }
1542     while (SUPPLEMENTARY[count].text != NULL) {
1543         if (!assertEqual(SUPPLEMENTARY[count])) {
1544             log_err("Error at test number %d\n", count);
1545         }
1546         count ++;
1547     }
1548     close();
1549 }
1550 
TestContraction(void)1551 static void TestContraction(void)
1552 {
1553     UChar          rules[128];
1554     UChar          pattern[128];
1555     UChar          text[128];
1556     UCollator     *collator;
1557     UErrorCode     status = U_ZERO_ERROR;
1558     int            count = 0;
1559     UStringSearch *strsrch;
1560     memset(rules, 0, 128*sizeof(UChar));
1561     memset(pattern, 0, 128*sizeof(UChar));
1562     memset(text, 0, 128*sizeof(UChar));
1563 
1564     u_unescape(CONTRACTIONRULE, rules, 128);
1565     collator = ucol_openRules(rules, u_strlen(rules), UCOL_ON,
1566                               UCOL_TERTIARY, NULL, &status);
1567     if(status == U_FILE_ACCESS_ERROR) {
1568       log_data_err("Is your data around?\n");
1569       return;
1570     } else if(U_FAILURE(status)) {
1571       log_err("Error opening collator %s\n", u_errorName(status));
1572       return;
1573     }
1574     strsrch = usearch_openFromCollator(pattern, 1, text, 1, collator, NULL,
1575                                        &status);
1576     if (U_FAILURE(status)) {
1577         log_err("Error opening string search %s\n", u_errorName(status));
1578     }
1579 
1580     while (CONTRACTION[count].text != NULL) {
1581         u_unescape(CONTRACTION[count].text, text, 128);
1582         u_unescape(CONTRACTION[count].pattern, pattern, 128);
1583         usearch_setText(strsrch, text, -1, &status);
1584         usearch_setPattern(strsrch, pattern, -1, &status);
1585         if (!assertEqualWithUStringSearch(strsrch, CONTRACTION[count])) {
1586             log_err("Error at test number %d\n", count);
1587         }
1588         count ++;
1589     }
1590     usearch_close(strsrch);
1591     ucol_close(collator);
1592 }
1593 
TestIgnorable(void)1594 static void TestIgnorable(void)
1595 {
1596     UChar          rules[128];
1597     UChar          pattern[128];
1598     UChar          text[128];
1599     UCollator     *collator;
1600     UErrorCode     status = U_ZERO_ERROR;
1601     UStringSearch *strsrch;
1602     uint32_t       count = 0;
1603 
1604     memset(rules, 0, 128*sizeof(UChar));
1605     memset(pattern, 0, 128*sizeof(UChar));
1606     memset(text, 0, 128*sizeof(UChar));
1607 
1608     u_unescape(IGNORABLERULE, rules, 128);
1609     collator = ucol_openRules(rules, u_strlen(rules), UCOL_ON,
1610                               IGNORABLE[count].strength, NULL, &status);
1611     if(status == U_FILE_ACCESS_ERROR) {
1612       log_data_err("Is your data around?\n");
1613       return;
1614     } else if(U_FAILURE(status)) {
1615         log_err("Error opening collator %s\n", u_errorName(status));
1616         return;
1617     }
1618     strsrch = usearch_openFromCollator(pattern, 1, text, 1, collator, NULL,
1619                                        &status);
1620     if (U_FAILURE(status)) {
1621         log_err("Error opening string search %s\n", u_errorName(status));
1622     }
1623 
1624     while (IGNORABLE[count].text != NULL) {
1625         u_unescape(IGNORABLE[count].text, text, 128);
1626         u_unescape(IGNORABLE[count].pattern, pattern, 128);
1627         usearch_setText(strsrch, text, -1, &status);
1628         usearch_setPattern(strsrch, pattern, -1, &status);
1629         if (!assertEqualWithUStringSearch(strsrch, IGNORABLE[count])) {
1630             log_err("Error at test number %d\n", count);
1631         }
1632         count ++;
1633     }
1634     usearch_close(strsrch);
1635     ucol_close(collator);
1636 }
1637 
TestDiacriticMatch(void)1638 static void TestDiacriticMatch(void)
1639 {
1640     UChar          pattern[128];
1641     UChar          text[128];
1642     UErrorCode     status = U_ZERO_ERROR;
1643     UStringSearch *strsrch = NULL;
1644     UCollator *coll = NULL;
1645     uint32_t       count = 0;
1646     SearchData search;
1647 
1648     memset(pattern, 0, 128*sizeof(UChar));
1649     memset(text, 0, 128*sizeof(UChar));
1650 
1651     strsrch = usearch_open(pattern, 1, text, 1, uloc_getDefault(), NULL, &status);
1652 	if (U_FAILURE(status)) {
1653         log_err_status(status, "Error opening string search %s\n", u_errorName(status));
1654         return;
1655     }
1656 
1657     search = DIACRITICMATCH[count];
1658     while (search.text != NULL) {
1659     	if (search.collator != NULL) {
1660     		coll = ucol_openFromShortString(search.collator, FALSE, NULL, &status);
1661     	} else {
1662             /* Always use "en_US" because some of these tests fail in Danish locales. */
1663     		coll = ucol_open("en_US"/*uloc_getDefault()*/, &status);
1664     		ucol_setStrength(coll, search.strength);
1665     	}
1666     	if (U_FAILURE(status)) {
1667 	        log_err("Error opening string search collator(\"%s\") %s\n", search.collator, u_errorName(status));
1668 	        return;
1669 	    }
1670 
1671     	usearch_setCollator(strsrch, coll, &status);
1672     	if (U_FAILURE(status)) {
1673 	        log_err("Error setting string search collator %s\n", u_errorName(status));
1674 	        return;
1675 	    }
1676 
1677         u_unescape(search.text, text, 128);
1678         u_unescape(search.pattern, pattern, 128);
1679         usearch_setText(strsrch, text, -1, &status);
1680         usearch_setPattern(strsrch, pattern, -1, &status);
1681         if (!assertEqualWithUStringSearch(strsrch, search)) {
1682             log_err("Error at test number %d\n", count);
1683         }
1684         ucol_close(coll);
1685 
1686         search = DIACRITICMATCH[++count];
1687     }
1688     usearch_close(strsrch);
1689 }
1690 
TestCanonical(void)1691 static void TestCanonical(void)
1692 {
1693     int count = 0;
1694     UErrorCode status = U_ZERO_ERROR;
1695     open(&status);
1696     if (U_FAILURE(status)) {
1697         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1698         return;
1699     }
1700     while (BASICCANONICAL[count].text != NULL) {
1701         if (!assertCanonicalEqual(BASICCANONICAL[count])) {
1702             log_err("Error at test number %d\n", count);
1703         }
1704         count ++;
1705     }
1706     close();
1707 }
1708 
TestNormCanonical(void)1709 static void TestNormCanonical(void)
1710 {
1711     int count = 0;
1712     UErrorCode status = U_ZERO_ERROR;
1713     open(&status);
1714     if (U_FAILURE(status)) {
1715         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1716         return;
1717     }
1718     ucol_setAttribute(EN_US_, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
1719     count = 0;
1720     while (NORMCANONICAL[count].text != NULL) {
1721         if (!assertCanonicalEqual(NORMCANONICAL[count])) {
1722             log_err("Error at test number %d\n", count);
1723         }
1724         count ++;
1725     }
1726     ucol_setAttribute(EN_US_, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
1727     close();
1728 }
1729 
TestStrengthCanonical(void)1730 static void TestStrengthCanonical(void)
1731 {
1732     int count = 0;
1733     UErrorCode status = U_ZERO_ERROR;
1734     open(&status);
1735     if (U_FAILURE(status)) {
1736         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1737         return;
1738     }
1739     while (STRENGTHCANONICAL[count].text != NULL) {
1740         if (!assertCanonicalEqual(STRENGTHCANONICAL[count])) {
1741             log_err("Error at test number %d\n", count);
1742         }
1743         count ++;
1744     }
1745     close();
1746 }
1747 
TestBreakIteratorCanonical(void)1748 static void TestBreakIteratorCanonical(void) {
1749     UErrorCode      status      = U_ZERO_ERROR;
1750     int             count = 0;
1751 
1752     CHECK_BREAK("x");
1753 
1754 #if !UCONFIG_NO_BREAK_ITERATION
1755 
1756     open(&status);
1757     if (U_FAILURE(status)) {
1758         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1759         return;
1760     }
1761     while (count < 4) {
1762         /* 0-3 test are fixed */
1763               UChar           pattern[32];
1764               UChar           text[128];
1765         const SearchData     *search   = &(BREAKITERATORCANONICAL[count]);
1766               UCollator      *collator = getCollator(search->collator);
1767               UBreakIterator *breaker  = getBreakIterator(search->breaker);
1768               UStringSearch  *strsrch;
1769 
1770         u_unescape(search->text, text, 128);
1771         u_unescape(search->pattern, pattern, 32);
1772         ucol_setStrength(collator, search->strength);
1773 
1774         strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
1775                                            breaker, &status);
1776         if(status == U_FILE_ACCESS_ERROR) {
1777             log_data_err("Is your data around?\n");
1778             goto ENDTESTBREAKITERATOR;
1779         } else if(U_FAILURE(status)) {
1780             log_err("Error opening searcher\n");
1781             goto ENDTESTBREAKITERATOR;
1782         }
1783         usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1784                              &status);
1785         if (U_FAILURE(status) ||
1786             usearch_getBreakIterator(strsrch) != breaker) {
1787             log_err("Error setting break iterator\n");
1788             usearch_close(strsrch);
1789             goto ENDTESTBREAKITERATOR;
1790         }
1791         if (!assertEqualWithUStringSearch(strsrch, *search)) {
1792             ucol_setStrength(collator, UCOL_TERTIARY);
1793             usearch_close(strsrch);
1794             goto ENDTESTBREAKITERATOR;
1795         }
1796         search   = &(BREAKITERATOREXACT[count + 1]);
1797         breaker  = getBreakIterator(search->breaker);
1798         usearch_setBreakIterator(strsrch, breaker, &status);
1799         if (U_FAILURE(status) || usearch_getBreakIterator(strsrch) != breaker) {
1800             log_err("Error setting break iterator\n");
1801             usearch_close(strsrch);
1802             goto ENDTESTBREAKITERATOR;
1803         }
1804         usearch_reset(strsrch);
1805         usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1806                              &status);
1807         if (!assertEqualWithUStringSearch(strsrch, *search)) {
1808             log_err("Error at test number %d\n", count);
1809             usearch_close(strsrch);
1810             goto ENDTESTBREAKITERATOR;
1811         }
1812         usearch_close(strsrch);
1813         count += 2;
1814     }
1815     count = 0;
1816     while (BREAKITERATORCANONICAL[count].text != NULL) {
1817          if (!assertEqual(BREAKITERATORCANONICAL[count])) {
1818              log_err("Error at test number %d\n", count);
1819              goto ENDTESTBREAKITERATOR;
1820          }
1821          count ++;
1822     }
1823 
1824 ENDTESTBREAKITERATOR:
1825     close();
1826 #endif
1827 }
1828 
TestVariableCanonical(void)1829 static void TestVariableCanonical(void)
1830 {
1831     int count = 0;
1832     UErrorCode status = U_ZERO_ERROR;
1833     open(&status);
1834     if (U_FAILURE(status)) {
1835         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1836         return;
1837     }
1838     ucol_setAttribute(EN_US_, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
1839     if (U_FAILURE(status)) {
1840         log_err("Error setting collation alternate attribute %s\n",
1841             u_errorName(status));
1842     }
1843     while (VARIABLE[count].text != NULL) {
1844         log_verbose("variable %d\n", count);
1845         if (!assertCanonicalEqual(VARIABLE[count])) {
1846             log_err("Error at test number %d\n", count);
1847         }
1848         count ++;
1849     }
1850     ucol_setAttribute(EN_US_, UCOL_ALTERNATE_HANDLING,
1851                       UCOL_NON_IGNORABLE, &status);
1852     close();
1853 }
1854 
TestOverlapCanonical(void)1855 static void TestOverlapCanonical(void)
1856 {
1857     int count = 0;
1858     UErrorCode status = U_ZERO_ERROR;
1859     open(&status);
1860     if (U_FAILURE(status)) {
1861         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1862         return;
1863     }
1864     while (OVERLAPCANONICAL[count].text != NULL) {
1865         if (!assertEqualWithAttribute(OVERLAPCANONICAL[count], USEARCH_ON,
1866                                       USEARCH_ON)) {
1867             log_err("Error at overlap test number %d\n", count);
1868         }
1869         count ++;
1870     }
1871     count = 0;
1872     while (NONOVERLAP[count].text != NULL) {
1873         if (!assertCanonicalEqual(NONOVERLAPCANONICAL[count])) {
1874             log_err("Error at non overlap test number %d\n", count);
1875         }
1876         count ++;
1877     }
1878 
1879     count = 0;
1880     while (count < 1) {
1881               UChar           pattern[32];
1882               UChar           text[128];
1883         const SearchData     *search   = &(OVERLAPCANONICAL[count]);
1884               UCollator      *collator = getCollator(search->collator);
1885               UStringSearch  *strsrch;
1886               status   = U_ZERO_ERROR;
1887 
1888         u_unescape(search->text, text, 128);
1889         u_unescape(search->pattern, pattern, 32);
1890         strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
1891                                            NULL, &status);
1892         if(status == U_FILE_ACCESS_ERROR) {
1893           log_data_err("Is your data around?\n");
1894           return;
1895         } else if(U_FAILURE(status)) {
1896           log_err("Error opening searcher\n");
1897           return;
1898         }
1899         usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1900                              &status);
1901         usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_ON, &status);
1902         if (U_FAILURE(status) ||
1903             usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_ON) {
1904             log_err("Error setting overlap option\n");
1905         }
1906         if (!assertEqualWithUStringSearch(strsrch, *search)) {
1907             usearch_close(strsrch);
1908             return;
1909         }
1910         search   = &(NONOVERLAPCANONICAL[count]);
1911         usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_OFF, &status);
1912         if (U_FAILURE(status) ||
1913             usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF) {
1914             log_err("Error setting overlap option\n");
1915         }
1916         usearch_reset(strsrch);
1917         if (!assertEqualWithUStringSearch(strsrch, *search)) {
1918             usearch_close(strsrch);
1919             log_err("Error at test number %d\n", count);
1920          }
1921 
1922         count ++;
1923         usearch_close(strsrch);
1924     }
1925     close();
1926 }
1927 
TestCollatorCanonical(void)1928 static void TestCollatorCanonical(void)
1929 {
1930     /* test collator that thinks "o" and "p" are the same thing */
1931           UChar          rules[32];
1932           UCollator     *tailored = NULL;
1933           UErrorCode     status = U_ZERO_ERROR;
1934           UChar          pattern[32];
1935           UChar          text[128];
1936           UStringSearch *strsrch;
1937 
1938     open(&status);
1939     if (U_FAILURE(status)) {
1940         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1941         return;
1942     }
1943     u_unescape(COLLATORCANONICAL[0].text, text, 128);
1944     u_unescape(COLLATORCANONICAL[0].pattern, pattern, 32);
1945 
1946     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
1947                                        NULL, &status);
1948     if(status == U_FILE_ACCESS_ERROR) {
1949       log_data_err("Is your data around?\n");
1950       return;
1951     } else if(U_FAILURE(status)) {
1952       log_err("Error opening searcher\n");
1953       return;
1954     }
1955     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1956                          &status);
1957     if (U_FAILURE(status)) {
1958         log_err("Error opening string search %s\n", u_errorName(status));
1959     }
1960     if (!assertEqualWithUStringSearch(strsrch, COLLATORCANONICAL[0])) {
1961         goto ENDTESTCOLLATOR;
1962     }
1963 
1964     u_unescape(TESTCOLLATORRULE, rules, 32);
1965     tailored = ucol_openRules(rules, -1, UCOL_ON,
1966                               COLLATORCANONICAL[1].strength, NULL, &status);
1967     if (U_FAILURE(status)) {
1968         log_err("Error opening rule based collator %s\n", u_errorName(status));
1969     }
1970 
1971     usearch_setCollator(strsrch, tailored, &status);
1972     if (U_FAILURE(status) || usearch_getCollator(strsrch) != tailored) {
1973         log_err("Error setting rule based collator\n");
1974     }
1975     usearch_reset(strsrch);
1976     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1977                          &status);
1978     if (!assertEqualWithUStringSearch(strsrch, COLLATORCANONICAL[1])) {
1979         goto ENDTESTCOLLATOR;
1980     }
1981 
1982     usearch_setCollator(strsrch, EN_US_, &status);
1983     usearch_reset(strsrch);
1984     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1985                          &status);
1986     if (U_FAILURE(status) || usearch_getCollator(strsrch) != EN_US_) {
1987         log_err("Error setting rule based collator\n");
1988     }
1989     if (!assertEqualWithUStringSearch(strsrch, COLLATORCANONICAL[0])) {
1990         goto ENDTESTCOLLATOR;
1991     }
1992 
1993 ENDTESTCOLLATOR:
1994     usearch_close(strsrch);
1995     if (tailored != NULL) {
1996         ucol_close(tailored);
1997     }
1998     close();
1999 }
2000 
TestPatternCanonical(void)2001 static void TestPatternCanonical(void)
2002 {
2003           UStringSearch *strsrch;
2004           UChar          pattern[32];
2005           UChar          text[128];
2006     const UChar         *temp;
2007           int32_t        templength;
2008           UErrorCode     status = U_ZERO_ERROR;
2009 
2010     open(&status);
2011     if (U_FAILURE(status)) {
2012         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
2013         return;
2014     }
2015     u_unescape(PATTERNCANONICAL[0].text, text, 128);
2016     u_unescape(PATTERNCANONICAL[0].pattern, pattern, 32);
2017 
2018     ucol_setStrength(EN_US_, PATTERNCANONICAL[0].strength);
2019     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
2020                                        NULL, &status);
2021     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2022                          &status);
2023     if (U_FAILURE(status)) {
2024         log_err("Error opening string search %s\n", u_errorName(status));
2025         goto ENDTESTPATTERN;
2026     }
2027     temp = usearch_getPattern(strsrch, &templength);
2028     if (u_strcmp(pattern, temp) != 0) {
2029         log_err("Error setting pattern\n");
2030     }
2031     if (!assertEqualWithUStringSearch(strsrch, PATTERNCANONICAL[0])) {
2032         goto ENDTESTPATTERN;
2033     }
2034 
2035     u_unescape(PATTERNCANONICAL[1].pattern, pattern, 32);
2036     usearch_setPattern(strsrch, pattern, -1, &status);
2037     temp = usearch_getPattern(strsrch, &templength);
2038     if (u_strcmp(pattern, temp) != 0) {
2039         log_err("Error setting pattern\n");
2040         goto ENDTESTPATTERN;
2041     }
2042     usearch_reset(strsrch);
2043     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2044                          &status);
2045     if (U_FAILURE(status)) {
2046         log_err("Error setting pattern %s\n", u_errorName(status));
2047     }
2048     if (!assertEqualWithUStringSearch(strsrch, PATTERNCANONICAL[1])) {
2049         goto ENDTESTPATTERN;
2050     }
2051 
2052     u_unescape(PATTERNCANONICAL[0].pattern, pattern, 32);
2053     usearch_setPattern(strsrch, pattern, -1, &status);
2054     temp = usearch_getPattern(strsrch, &templength);
2055     if (u_strcmp(pattern, temp) != 0) {
2056         log_err("Error setting pattern\n");
2057         goto ENDTESTPATTERN;
2058     }
2059     usearch_reset(strsrch);
2060     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2061                          &status);
2062     if (U_FAILURE(status)) {
2063         log_err("Error setting pattern %s\n", u_errorName(status));
2064     }
2065     if (!assertEqualWithUStringSearch(strsrch, PATTERNCANONICAL[0])) {
2066         goto ENDTESTPATTERN;
2067     }
2068 ENDTESTPATTERN:
2069     ucol_setStrength(EN_US_, UCOL_TERTIARY);
2070     if (strsrch != NULL) {
2071         usearch_close(strsrch);
2072     }
2073     close();
2074 }
2075 
TestTextCanonical(void)2076 static void TestTextCanonical(void)
2077 {
2078           UStringSearch *strsrch;
2079           UChar          pattern[32];
2080           UChar          text[128];
2081     const UChar         *temp;
2082           int32_t        templength;
2083           UErrorCode     status = U_ZERO_ERROR;
2084 
2085     u_unescape(TEXTCANONICAL[0].text, text, 128);
2086     u_unescape(TEXTCANONICAL[0].pattern, pattern, 32);
2087 
2088     open(&status);
2089     if (U_FAILURE(status)) {
2090         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
2091         return;
2092     }
2093     strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
2094                                        NULL, &status);
2095     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2096                          &status);
2097 
2098     if (U_FAILURE(status)) {
2099         log_err("Error opening string search %s\n", u_errorName(status));
2100         goto ENDTESTPATTERN;
2101     }
2102     temp = usearch_getText(strsrch, &templength);
2103     if (u_strcmp(text, temp) != 0) {
2104         log_err("Error setting text\n");
2105     }
2106     if (!assertEqualWithUStringSearch(strsrch, TEXTCANONICAL[0])) {
2107         goto ENDTESTPATTERN;
2108     }
2109 
2110     u_unescape(TEXTCANONICAL[1].text, text, 32);
2111     usearch_setText(strsrch, text, -1, &status);
2112     temp = usearch_getText(strsrch, &templength);
2113     if (u_strcmp(text, temp) != 0) {
2114         log_err("Error setting text\n");
2115         goto ENDTESTPATTERN;
2116     }
2117     if (U_FAILURE(status)) {
2118         log_err("Error setting text %s\n", u_errorName(status));
2119     }
2120     if (!assertEqualWithUStringSearch(strsrch, TEXTCANONICAL[1])) {
2121         goto ENDTESTPATTERN;
2122     }
2123 
2124     u_unescape(TEXTCANONICAL[0].text, text, 32);
2125     usearch_setText(strsrch, text, -1, &status);
2126     temp = usearch_getText(strsrch, &templength);
2127     if (u_strcmp(text, temp) != 0) {
2128         log_err("Error setting text\n");
2129         goto ENDTESTPATTERN;
2130     }
2131     if (U_FAILURE(status)) {
2132         log_err("Error setting pattern %s\n", u_errorName(status));
2133     }
2134     if (!assertEqualWithUStringSearch(strsrch, TEXTCANONICAL[0])) {
2135         goto ENDTESTPATTERN;
2136     }
2137 ENDTESTPATTERN:
2138     if (strsrch != NULL) {
2139         usearch_close(strsrch);
2140     }
2141     close();
2142 }
2143 
TestCompositeBoundariesCanonical(void)2144 static void TestCompositeBoundariesCanonical(void)
2145 {
2146     int count = 0;
2147     UErrorCode status = U_ZERO_ERROR;
2148     open(&status);
2149     if (U_FAILURE(status)) {
2150         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
2151         return;
2152     }
2153     while (COMPOSITEBOUNDARIESCANONICAL[count].text != NULL) {
2154         log_verbose("composite %d\n", count);
2155         if (!assertCanonicalEqual(COMPOSITEBOUNDARIESCANONICAL[count])) {
2156             log_err("Error at test number %d\n", count);
2157         }
2158         count ++;
2159     }
2160     close();
2161 }
2162 
TestGetSetOffsetCanonical(void)2163 static void TestGetSetOffsetCanonical(void)
2164 {
2165     int            searchDataIndex   = 0;
2166     UChar          pattern[32];
2167     UChar          text[128];
2168     UErrorCode     status  = U_ZERO_ERROR;
2169     UStringSearch *strsrch;
2170     UCollator     *collator;
2171 
2172     memset(pattern, 0, 32*sizeof(UChar));
2173     memset(text, 0, 128*sizeof(UChar));
2174 
2175     open(&status);
2176     if (U_FAILURE(status)) {
2177         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
2178         return;
2179     }
2180     strsrch = usearch_openFromCollator(pattern, 16, text, 32, EN_US_, NULL,
2181                                        &status);
2182 
2183     collator = usearch_getCollator(strsrch);
2184     ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
2185 
2186     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2187                          &status);
2188 
2189     /* testing out of bounds error */
2190     usearch_setOffset(strsrch, -1, &status);
2191     if (U_SUCCESS(status)) {
2192         log_err("Error expecting set offset error\n");
2193     }
2194     usearch_setOffset(strsrch, 128, &status);
2195     if (U_SUCCESS(status)) {
2196         log_err("Error expecting set offset error\n");
2197     }
2198     while (BASICCANONICAL[searchDataIndex].text != NULL) {
2199         int         count       = 0;
2200         SearchData  search      = BASICCANONICAL[searchDataIndex ++];
2201         int32_t matchindex  = search.offset[count];
2202         int32_t     textlength;
2203 
2204         if (BASICCANONICAL[searchDataIndex].text == NULL) {
2205             /* skip the last one */
2206             break;
2207         }
2208 
2209         u_unescape(search.text, text, 128);
2210         u_unescape(search.pattern, pattern, 32);
2211         status = U_ZERO_ERROR;
2212         usearch_setText(strsrch, text, -1, &status);
2213         usearch_setPattern(strsrch, pattern, -1, &status);
2214         while (U_SUCCESS(status) && matchindex >= 0) {
2215             uint32_t matchlength = search.size[count];
2216             usearch_next(strsrch, &status);
2217             if (matchindex != usearch_getMatchedStart(strsrch) ||
2218                 matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
2219                 char *str = toCharString(usearch_getText(strsrch,
2220                                                          &textlength));
2221                 log_err("Text: %s\n", str);
2222                 str = toCharString(usearch_getPattern(strsrch, &textlength));
2223                 log_err("Pattern: %s\n", str);
2224                 log_err("Error match found at %d %d\n",
2225                         usearch_getMatchedStart(strsrch),
2226                         usearch_getMatchedLength(strsrch));
2227                 goto bail;
2228             }
2229             matchindex = search.offset[count + 1] == -1 ? -1 :
2230                          search.offset[count + 2];
2231             if (search.offset[count + 1] != -1) {
2232                 usearch_setOffset(strsrch, search.offset[count + 1] + 1,
2233                                   &status);
2234                 if (usearch_getOffset(strsrch) != search.offset[count + 1] + 1) {
2235                     log_err("Error setting offset\n");
2236                     goto bail;
2237                 }
2238             }
2239 
2240             count += 2;
2241         }
2242         usearch_next(strsrch, &status);
2243         if (usearch_getMatchedStart(strsrch) != USEARCH_DONE) {
2244             char *str = toCharString(usearch_getText(strsrch, &textlength));
2245             log_err("Text: %s\n", str);
2246             str = toCharString(usearch_getPattern(strsrch, &textlength));
2247             log_err("Pattern: %s\n", str);
2248             log_err("Error match found at %d %d\n",
2249                         usearch_getMatchedStart(strsrch),
2250                         usearch_getMatchedLength(strsrch));
2251             goto bail;
2252         }
2253     }
2254 
2255 bail:
2256     ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
2257     usearch_close(strsrch);
2258     close();
2259 }
2260 
TestSupplementaryCanonical(void)2261 static void TestSupplementaryCanonical(void)
2262 {
2263     int count = 0;
2264     UErrorCode status = U_ZERO_ERROR;
2265     open(&status);
2266     if (U_FAILURE(status)) {
2267         log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
2268         return;
2269     }
2270     while (SUPPLEMENTARYCANONICAL[count].text != NULL) {
2271         if (!assertCanonicalEqual(SUPPLEMENTARYCANONICAL[count])) {
2272             log_err("Error at test number %d\n", count);
2273         }
2274         count ++;
2275     }
2276     close();
2277 }
2278 
TestContractionCanonical(void)2279 static void TestContractionCanonical(void)
2280 {
2281     UChar          rules[128];
2282     UChar          pattern[128];
2283     UChar          text[128];
2284     UCollator     *collator = NULL;
2285     UErrorCode     status = U_ZERO_ERROR;
2286     int            count = 0;
2287     UStringSearch *strsrch = NULL;
2288     memset(rules, 0, 128*sizeof(UChar));
2289     memset(pattern, 0, 128*sizeof(UChar));
2290     memset(text, 0, 128*sizeof(UChar));
2291 
2292     u_unescape(CONTRACTIONRULE, rules, 128);
2293     collator = ucol_openRules(rules, u_strlen(rules), UCOL_ON,
2294                               UCOL_TERTIARY, NULL, &status);
2295     if(status == U_FILE_ACCESS_ERROR) {
2296       log_data_err("Is your data around?\n");
2297       return;
2298     } else if(U_FAILURE(status)) {
2299       log_err("Error opening collator %s\n", u_errorName(status));
2300       return;
2301     }
2302     strsrch = usearch_openFromCollator(pattern, 1, text, 1, collator, NULL,
2303                                        &status);
2304     usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2305                          &status);
2306     if (U_FAILURE(status)) {
2307         log_err("Error opening string search %s\n", u_errorName(status));
2308     }
2309 
2310     while (CONTRACTIONCANONICAL[count].text != NULL) {
2311         u_unescape(CONTRACTIONCANONICAL[count].text, text, 128);
2312         u_unescape(CONTRACTIONCANONICAL[count].pattern, pattern, 128);
2313         usearch_setText(strsrch, text, -1, &status);
2314         usearch_setPattern(strsrch, pattern, -1, &status);
2315         if (!assertEqualWithUStringSearch(strsrch,
2316                                               CONTRACTIONCANONICAL[count])) {
2317             log_err("Error at test number %d\n", count);
2318         }
2319         count ++;
2320     }
2321     usearch_close(strsrch);
2322     ucol_close(collator);
2323 }
2324 
TestNumeric(void)2325 static void TestNumeric(void) {
2326     UCollator     *coll = NULL;
2327     UStringSearch *strsrch = NULL;
2328     UErrorCode     status = U_ZERO_ERROR;
2329 
2330     UChar          pattern[128];
2331     UChar          text[128];
2332     memset(pattern, 0, 128*sizeof(UChar));
2333     memset(text, 0, 128*sizeof(UChar));
2334 
2335     coll = ucol_open("", &status);
2336     if(U_FAILURE(status)) {
2337         log_data_err("Could not open UCA. Is your data around?\n");
2338         return;
2339     }
2340 
2341     ucol_setAttribute(coll, UCOL_NUMERIC_COLLATION, UCOL_ON, &status);
2342 
2343     strsrch = usearch_openFromCollator(pattern, 1, text, 1, coll, NULL, &status);
2344 
2345     if(status != U_UNSUPPORTED_ERROR || U_SUCCESS(status)) {
2346         log_err("Expected U_UNSUPPORTED_ERROR when trying to instantiate a search object from a CODAN collator, got %s instead\n", u_errorName(status));
2347         if(strsrch) {
2348             usearch_close(strsrch);
2349         }
2350     }
2351 
2352     ucol_close(coll);
2353 
2354 }
2355 
2356 /* This test is for ticket 4038 due to incorrect backward searching when certain patterns have a length > 1 */
TestForwardBackward(void)2357 static void TestForwardBackward(void) {
2358     UErrorCode status = U_ZERO_ERROR;
2359     UCollator *coll = NULL;
2360     UStringSearch *search = NULL;
2361     UChar usrcstr[32], value[4];
2362     int32_t pos= -1;
2363     int32_t expectedPos = 9;
2364 
2365     coll = ucol_open("en_GB", &status);
2366     if (U_FAILURE(status)) {
2367         log_err_status(status, "ucol_open failed: %s\n", u_errorName(status));
2368         goto exitTestForwardBackward;
2369     }
2370     ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_PRIMARY, &status);
2371     ucol_setAttribute(coll, UCOL_CASE_LEVEL, UCOL_ON, &status);
2372     ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status);
2373 
2374     u_uastrcpy(usrcstr, "QBitArray::bitarr_data"); /* text */
2375     u_uastrcpy(value, "::");                       /* pattern */
2376 
2377     search = usearch_openFromCollator(value, 2, usrcstr, 22, coll, NULL, &status);
2378     if (U_FAILURE(status)) {
2379         log_err("usearch_openFromCollator failed: %s\n", u_errorName(status));
2380         goto exitTestForwardBackward;
2381     }
2382 
2383     usearch_reset(search);
2384     /* forward search */
2385     pos = usearch_first(search, &status);
2386     if (pos != expectedPos) {
2387         log_err("Expected search result: %d; Got instead: %d\n", expectedPos, pos);
2388         goto exitTestForwardBackward;
2389     }
2390 
2391     pos = -1;
2392     usearch_reset(search);
2393     /* backward search */
2394     pos = usearch_last(search, &status);
2395     if (pos != expectedPos) {
2396         log_err("Expected search result: %d; Got instead: %d\n", expectedPos, pos);
2397     }
2398 
2399 exitTestForwardBackward :
2400     if (coll != NULL) {
2401         ucol_close(coll);
2402     }
2403     if (search != NULL) {
2404         usearch_close(search);
2405     }
2406 }
2407 
2408 #define TEST_ASSERT(x) \
2409    {if (U_FAILURE(x)) {log_err_status(x, "%s:%d: FAIL: test assertion failure \n", __FILE__, __LINE__);\
2410    }}
2411 
TestSearchForNull(void)2412 static void TestSearchForNull(void) {
2413     UCollator *coll;
2414     UErrorCode ec;
2415     UStringSearch *search;
2416     int pos;
2417     int len;
2418     int expectedPos;
2419     int expectedLen;
2420     int expectedNum;
2421     int count = 0;
2422     const UChar zerodigit = 0x0030; /* 0 */
2423     const UChar nulldigit = 0x0000; /* null */
2424 
2425     /* static const UChar var[(length)+1]=U_DECLARE_UTF16(cs) */
2426 #define PATTERN_LEN 4
2427 #define TEXT_LEN 10
2428 
2429     U_STRING_DECL(_pattern, "IS 0", PATTERN_LEN);
2430     U_STRING_DECL(_text, "_0IS 0 OK?", TEXT_LEN);
2431     UChar pattern[PATTERN_LEN + 1], text[TEXT_LEN + 1];
2432 
2433     U_STRING_INIT(_pattern, "IS 0", PATTERN_LEN);
2434     U_STRING_INIT(_text, "_0IS 0 OK?", TEXT_LEN);
2435     expectedPos = 2;
2436     expectedLen = 4;
2437     expectedNum = 1;
2438 
2439     for (pos = 0; pos < PATTERN_LEN; pos++) {
2440         if (_pattern[pos] == zerodigit) {
2441             pattern[pos] = nulldigit;
2442         } else {
2443             pattern[pos] = _pattern[pos];
2444         }
2445     }
2446     pattern[PATTERN_LEN] = 0x0000;
2447 
2448     for (pos = 0; pos < TEXT_LEN; pos++) {
2449         if (_text[pos] == zerodigit) {
2450             text[pos] = nulldigit;
2451         } else {
2452             text[pos] = _text[pos];
2453         }
2454     }
2455     text[TEXT_LEN] = 0x0000;
2456 
2457     ec = U_ZERO_ERROR;
2458 
2459     /* create a US-English collator */
2460     coll = ucol_open("en_US", &ec);
2461 
2462     /* make sure we didn't fail. */
2463      TEST_ASSERT (ec);
2464 
2465     ucol_setStrength(coll, UCOL_IDENTICAL);
2466 
2467     /* open a search looking for 0 */
2468     search = usearch_openFromCollator(pattern, PATTERN_LEN, text,
2469             TEXT_LEN, coll, NULL, &ec);
2470      TEST_ASSERT (ec);
2471 
2472     if (coll != NULL && search != NULL) {
2473         pos = usearch_first(search, &ec);
2474         len = usearch_getMatchedLength(search);
2475         if (pos != expectedPos) {
2476             log_err("Expected search result: %d; Got instead: %d\n", expectedPos,
2477                     pos);
2478         }
2479 
2480         if (len != expectedLen) {
2481             log_err("Expected search result length: %d; Got instead: %d\n",
2482                     expectedLen, len);
2483         }
2484 
2485         for (pos = usearch_first(search, &ec); pos != USEARCH_DONE; pos
2486                 = usearch_next(search, &ec)) {
2487             log_verbose("Match at %d\n", pos);
2488             count += 1;
2489         }
2490 
2491         if (count != expectedNum) {
2492             log_err("Expected %d search hits, found %d\n", expectedNum, count);
2493         }
2494     }
2495 
2496     ucol_close(coll);
2497     usearch_close(search);
2498 }
2499 
TestStrengthIdentical(void)2500 static void TestStrengthIdentical(void)
2501 {
2502 	UCollator *coll;
2503 	UErrorCode ec = U_ZERO_ERROR;
2504 	UStringSearch *search;
2505 
2506     UChar pattern[] = {0x05E9, 0x0591, 0x05E9};
2507     UChar text[]    = {0x05E9, 0x0592, 0x05E9};
2508     int32_t pLen = sizeof (pattern) / sizeof(pattern[0]);
2509     int32_t tLen = sizeof(text) / sizeof (text[0]);
2510 	int32_t expectedPos = 0;
2511 	int32_t expectedLen = 3;
2512 
2513 	int32_t pos;
2514 	int32_t len;
2515 
2516     /* create a US-English collator */
2517 	coll = ucol_open ("en_US", &ec);
2518 
2519 	/* make sure we didn't fail. */
2520 	TEST_ASSERT (ec);
2521 
2522     ucol_setStrength( coll, UCOL_TERTIARY);
2523 
2524 	/* open a search looking for 0 */
2525 	search = usearch_openFromCollator (pattern, pLen, text, tLen, coll, NULL, &ec);
2526 	TEST_ASSERT (ec);
2527 
2528     if (coll != NULL && search != NULL) {
2529 	    pos = usearch_first(search, &ec);
2530 	    len = usearch_getMatchedLength(search);
2531 
2532 	    if(pos != expectedPos) {
2533 		    log_err("Expected search result: %d; Got instead: %d\n", expectedPos, pos);
2534 	    }
2535 
2536 	    if(len != expectedLen) {
2537 		    log_err("Expected search result length: %d; Got instead: %d\n", expectedLen, len);
2538 	    }
2539 
2540         /* Now try it at strength == UCOL_IDENTICAL */
2541         ucol_setStrength(coll, UCOL_IDENTICAL);
2542 	    usearch_reset(search);
2543 
2544 	    pos = usearch_first(search, &ec);
2545 	    len = usearch_getMatchedLength(search);
2546 
2547 	    if(pos != -1) {
2548 		    log_err("Expected failure for strentgh = UCOL_IDENTICAL: got %d instead.\n", pos);
2549 	    }
2550     }
2551 
2552     usearch_close(search);
2553     ucol_close(coll);
2554 }
2555 
2556 
addSearchTest(TestNode ** root)2557 void addSearchTest(TestNode** root)
2558 {
2559     addTest(root, &TestStart, "tscoll/usrchtst/TestStart");
2560     addTest(root, &TestOpenClose, "tscoll/usrchtst/TestOpenClose");
2561     addTest(root, &TestInitialization, "tscoll/usrchtst/TestInitialization");
2562     addTest(root, &TestBasic, "tscoll/usrchtst/TestBasic");
2563     addTest(root, &TestNormExact, "tscoll/usrchtst/TestNormExact");
2564     addTest(root, &TestStrength, "tscoll/usrchtst/TestStrength");
2565     addTest(root, &TestBreakIterator, "tscoll/usrchtst/TestBreakIterator");
2566     addTest(root, &TestVariable, "tscoll/usrchtst/TestVariable");
2567     addTest(root, &TestOverlap, "tscoll/usrchtst/TestOverlap");
2568     addTest(root, &TestCollator, "tscoll/usrchtst/TestCollator");
2569     addTest(root, &TestPattern, "tscoll/usrchtst/TestPattern");
2570     addTest(root, &TestText, "tscoll/usrchtst/TestText");
2571     addTest(root, &TestCompositeBoundaries,
2572                                   "tscoll/usrchtst/TestCompositeBoundaries");
2573     addTest(root, &TestGetSetOffset, "tscoll/usrchtst/TestGetSetOffset");
2574     addTest(root, &TestGetSetAttribute,
2575                                       "tscoll/usrchtst/TestGetSetAttribute");
2576     addTest(root, &TestGetMatch, "tscoll/usrchtst/TestGetMatch");
2577     addTest(root, &TestSetMatch, "tscoll/usrchtst/TestSetMatch");
2578     addTest(root, &TestReset, "tscoll/usrchtst/TestReset");
2579     addTest(root, &TestSupplementary, "tscoll/usrchtst/TestSupplementary");
2580     addTest(root, &TestContraction, "tscoll/usrchtst/TestContraction");
2581     addTest(root, &TestIgnorable, "tscoll/usrchtst/TestIgnorable");
2582     addTest(root, &TestCanonical, "tscoll/usrchtst/TestCanonical");
2583     addTest(root, &TestNormCanonical, "tscoll/usrchtst/TestNormCanonical");
2584     addTest(root, &TestStrengthCanonical,
2585                                     "tscoll/usrchtst/TestStrengthCanonical");
2586     addTest(root, &TestBreakIteratorCanonical,
2587                                "tscoll/usrchtst/TestBreakIteratorCanonical");
2588     addTest(root, &TestVariableCanonical,
2589                                     "tscoll/usrchtst/TestVariableCanonical");
2590     addTest(root, &TestOverlapCanonical,
2591                                      "tscoll/usrchtst/TestOverlapCanonical");
2592     addTest(root, &TestCollatorCanonical,
2593                                     "tscoll/usrchtst/TestCollatorCanonical");
2594     addTest(root, &TestPatternCanonical,
2595                                      "tscoll/usrchtst/TestPatternCanonical");
2596     addTest(root, &TestTextCanonical, "tscoll/usrchtst/TestTextCanonical");
2597     addTest(root, &TestCompositeBoundariesCanonical,
2598                          "tscoll/usrchtst/TestCompositeBoundariesCanonical");
2599     addTest(root, &TestGetSetOffsetCanonical,
2600                                 "tscoll/usrchtst/TestGetSetOffsetCanonical");
2601     addTest(root, &TestSupplementaryCanonical,
2602                                "tscoll/usrchtst/TestSupplementaryCanonical");
2603     addTest(root, &TestContractionCanonical,
2604                                  "tscoll/usrchtst/TestContractionCanonical");
2605     addTest(root, &TestEnd, "tscoll/usrchtst/TestEnd");
2606     addTest(root, &TestNumeric, "tscoll/usrchtst/TestNumeric");
2607     addTest(root, &TestDiacriticMatch, "tscoll/usrchtst/TestDiacriticMatch");
2608     addTest(root, &TestForwardBackward, "tscoll/usrchtst/TestForwardBackward");
2609 	addTest(root, &TestSearchForNull, "tscoll/usrchtst/TestSearchForNull");
2610     addTest(root, &TestStrengthIdentical, "tscoll/usrchtst/TestStrengthIdentical");
2611 }
2612 
2613 #endif /* #if !UCONFIG_NO_COLLATION */
2614