1 /********************************************************************
2 * Copyright (c) 2001-2011 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 UErrorCode status = U_ZERO_ERROR;
341 int32_t matchindex = search.offset[count];
342 int32_t textlength;
343 UChar matchtext[128];
344 int32_t matchlength;
345 int32_t nextStart;
346 UBool isOverlap;
347
348 usearch_setAttribute(strsrch, USEARCH_ELEMENT_COMPARISON, search.elemCompare, &status);
349 if (U_FAILURE(status)) {
350 log_err("Error setting USEARCH_ELEMENT_COMPARISON attribute %s\n", u_errorName(status));
351 return FALSE;
352 }
353
354 if (usearch_getMatchedStart(strsrch) != USEARCH_DONE ||
355 usearch_getMatchedLength(strsrch) != 0) {
356 log_err("Error with the initialization of match start and length\n");
357 }
358 /* start of next matches */
359 while (U_SUCCESS(status) && matchindex >= 0) {
360 matchlength = search.size[count];
361 usearch_next(strsrch, &status);
362 if (matchindex != usearch_getMatchedStart(strsrch) ||
363 matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
364 char *str = toCharString(usearch_getText(strsrch, &textlength));
365 log_err("Text: %s\n", str);
366 str = toCharString(usearch_getPattern(strsrch, &textlength));
367 log_err("Pattern: %s\n", str);
368 log_err("Error next match found at idx %d (len:%d); expected %d (len:%d)\n",
369 usearch_getMatchedStart(strsrch), usearch_getMatchedLength(strsrch),
370 matchindex, matchlength);
371 return FALSE;
372 }
373 count ++;
374
375 if (usearch_getMatchedText(strsrch, matchtext, 128, &status) !=
376 (int32_t) matchlength || U_FAILURE(status) ||
377 memcmp(matchtext,
378 usearch_getText(strsrch, &textlength) + matchindex,
379 matchlength * sizeof(UChar)) != 0) {
380 log_err("Error getting next matched text\n");
381 }
382
383 matchindex = search.offset[count];
384 }
385 usearch_next(strsrch, &status);
386 if (usearch_getMatchedStart(strsrch) != USEARCH_DONE ||
387 usearch_getMatchedLength(strsrch) != 0) {
388 char *str = toCharString(usearch_getText(strsrch, &textlength));
389 log_err("Text: %s\n", str);
390 str = toCharString(usearch_getPattern(strsrch, &textlength));
391 log_err("Pattern: %s\n", str);
392 log_err("Error next match found at %d (len:%d); expected <NO MATCH>\n",
393 usearch_getMatchedStart(strsrch),
394 usearch_getMatchedLength(strsrch));
395 return FALSE;
396 }
397 /* start of previous matches */
398 count = count == 0 ? 0 : count - 1;
399 matchindex = search.offset[count];
400
401 while (U_SUCCESS(status) && matchindex >= 0) {
402 matchlength = search.size[count];
403 usearch_previous(strsrch, &status);
404 if (matchindex != usearch_getMatchedStart(strsrch) ||
405 matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
406 char *str = toCharString(usearch_getText(strsrch, &textlength));
407 log_err("Text: %s\n", str);
408 str = toCharString(usearch_getPattern(strsrch, &textlength));
409 log_err("Pattern: %s\n", str);
410 log_err("Error previous match found at %d (len:%d); expected %d (len:%d)\n",
411 usearch_getMatchedStart(strsrch), usearch_getMatchedLength(strsrch),
412 matchindex, matchlength);
413 return FALSE;
414 }
415
416 if (usearch_getMatchedText(strsrch, matchtext, 128, &status) !=
417 (int32_t) matchlength || U_FAILURE(status) ||
418 memcmp(matchtext,
419 usearch_getText(strsrch, &textlength) + matchindex,
420 matchlength * sizeof(UChar)) != 0) {
421 log_err("Error getting previous matched text\n");
422 }
423
424 matchindex = count > 0 ? search.offset[count - 1] : -1;
425 count --;
426 }
427 usearch_previous(strsrch, &status);
428 if (usearch_getMatchedStart(strsrch) != USEARCH_DONE ||
429 usearch_getMatchedLength(strsrch) != 0) {
430 char *str = toCharString(usearch_getText(strsrch, &textlength));
431 log_err("Text: %s\n", str);
432 str = toCharString(usearch_getPattern(strsrch, &textlength));
433 log_err("Pattern: %s\n", str);
434 log_err("Error previous match found at %d (len:%d); expected <NO MATCH>\n",
435 usearch_getMatchedStart(strsrch),
436 usearch_getMatchedLength(strsrch));
437 return FALSE;
438 }
439
440
441 isOverlap = (usearch_getAttribute(strsrch, USEARCH_OVERLAP) == USEARCH_ON);
442
443 /* start of following matches */
444 count = 0;
445 matchindex = search.offset[count];
446 nextStart = 0;
447
448 while (TRUE) {
449 usearch_following(strsrch, nextStart, &status);
450
451 if (matchindex < 0) {
452 if (usearch_getMatchedStart(strsrch) != USEARCH_DONE || usearch_getMatchedLength(strsrch) != 0) {
453 char *str = toCharString(usearch_getText(strsrch, &textlength));
454 log_err("Text: %s\n", str);
455 str = toCharString(usearch_getPattern(strsrch, &textlength));
456 log_err("Pattern: %s\n", str);
457 log_err("Error following match starting at %d (overlap:%d) found at %d (len:%d); expected <NO MATCH>\n",
458 nextStart, isOverlap,
459 usearch_getMatchedStart(strsrch),
460 usearch_getMatchedLength(strsrch));
461 return FALSE;
462 }
463 /* no more matches */
464 break;
465 }
466
467 matchlength = search.size[count];
468 if (usearch_getMatchedStart(strsrch) != matchindex
469 || usearch_getMatchedLength(strsrch) != matchlength
470 || U_FAILURE(status)) {
471 char *str = toCharString(usearch_getText(strsrch, &textlength));
472 log_err("Text: %s\n", str);
473 str = toCharString(usearch_getPattern(strsrch, &textlength));
474 log_err("Pattern: %s\n", str);
475 log_err("Error following match starting at %d (overlap: %d) found at %d (len:%d); expected %d (len:%d)\n",
476 nextStart, isOverlap,
477 usearch_getMatchedStart(strsrch), usearch_getMatchedLength(strsrch),
478 matchindex, matchlength);
479 return FALSE;
480 }
481
482 if (isOverlap || usearch_getMatchedLength(strsrch) == 0) {
483 nextStart = usearch_getMatchedStart(strsrch) + 1;
484 } else {
485 nextStart = usearch_getMatchedStart(strsrch) + usearch_getMatchedLength(strsrch);
486 }
487
488 count++;
489 matchindex = search.offset[count];
490 }
491
492 /* start of preceding matches */
493 count = -1; /* last non-negative offset index, could be -1 if no match */
494 while (search.offset[count + 1] >= 0) {
495 count++;
496 }
497 usearch_getText(strsrch, &nextStart);
498
499 while (TRUE) {
500 usearch_preceding(strsrch, nextStart, &status);
501
502 if (count < 0) {
503 if (usearch_getMatchedStart(strsrch) != USEARCH_DONE || usearch_getMatchedLength(strsrch) != 0) {
504 char *str = toCharString(usearch_getText(strsrch, &textlength));
505 log_err("Text: %s\n", str);
506 str = toCharString(usearch_getPattern(strsrch, &textlength));
507 log_err("Pattern: %s\n", str);
508 log_err("Error preceding match starting at %d (overlap: %d) found at %d (len:%d); expected <NO MATCH>\n",
509 nextStart, isOverlap,
510 usearch_getMatchedStart(strsrch),
511 usearch_getMatchedLength(strsrch));
512 return FALSE;
513 }
514 /* no more matches */
515 break;
516 }
517
518 matchindex = search.offset[count];
519 matchlength = search.size[count];
520 if (usearch_getMatchedStart(strsrch) != matchindex
521 || usearch_getMatchedLength(strsrch) != matchlength
522 || U_FAILURE(status)) {
523 char *str = toCharString(usearch_getText(strsrch, &textlength));
524 log_err("Text: %s\n", str);
525 str = toCharString(usearch_getPattern(strsrch, &textlength));
526 log_err("Pattern: %s\n", str);
527 log_err("Error preceding match starting at %d (overlap: %d) found at %d (len:%d); expected %d (len:%d)\n",
528 nextStart, isOverlap,
529 usearch_getMatchedStart(strsrch), usearch_getMatchedLength(strsrch),
530 matchindex, matchlength);
531 return FALSE;
532 }
533
534 nextStart = matchindex;
535 count--;
536 }
537
538 usearch_setAttribute(strsrch, USEARCH_ELEMENT_COMPARISON, USEARCH_STANDARD_ELEMENT_COMPARISON, &status);
539 return TRUE;
540 }
541
assertEqual(const SearchData search)542 static UBool assertEqual(const SearchData search)
543 {
544 UErrorCode status = U_ZERO_ERROR;
545 UChar pattern[32];
546 UChar text[128];
547 UCollator *collator = getCollator(search.collator);
548 UBreakIterator *breaker = getBreakIterator(search.breaker);
549 UStringSearch *strsrch;
550
551 CHECK_BREAK_BOOL(search.breaker);
552
553 u_unescape(search.text, text, 128);
554 u_unescape(search.pattern, pattern, 32);
555 ucol_setStrength(collator, search.strength);
556 strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
557 breaker, &status);
558 if (U_FAILURE(status)) {
559 log_err("Error opening string search %s\n", u_errorName(status));
560 return FALSE;
561 }
562
563 if (!assertEqualWithUStringSearch(strsrch, search)) {
564 ucol_setStrength(collator, UCOL_TERTIARY);
565 usearch_close(strsrch);
566 return FALSE;
567 }
568 ucol_setStrength(collator, UCOL_TERTIARY);
569 usearch_close(strsrch);
570 return TRUE;
571 }
572
assertCanonicalEqual(const SearchData search)573 static UBool assertCanonicalEqual(const SearchData search)
574 {
575 UErrorCode status = U_ZERO_ERROR;
576 UChar pattern[32];
577 UChar text[128];
578 UCollator *collator = getCollator(search.collator);
579 UBreakIterator *breaker = getBreakIterator(search.breaker);
580 UStringSearch *strsrch;
581 UBool result = TRUE;
582
583 CHECK_BREAK_BOOL(search.breaker);
584 u_unescape(search.text, text, 128);
585 u_unescape(search.pattern, pattern, 32);
586 ucol_setStrength(collator, search.strength);
587 ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
588 strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
589 breaker, &status);
590 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
591 &status);
592 if (U_FAILURE(status)) {
593 log_err("Error opening string search %s\n", u_errorName(status));
594 result = FALSE;
595 goto bail;
596 }
597
598 if (!assertEqualWithUStringSearch(strsrch, search)) {
599 ucol_setStrength(collator, UCOL_TERTIARY);
600 usearch_close(strsrch);
601 result = FALSE;
602 goto bail;
603 }
604
605 bail:
606 ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
607 ucol_setStrength(collator, UCOL_TERTIARY);
608 usearch_close(strsrch);
609 return result;
610 }
611
assertEqualWithAttribute(const SearchData search,USearchAttributeValue canonical,USearchAttributeValue overlap)612 static UBool assertEqualWithAttribute(const SearchData search,
613 USearchAttributeValue canonical,
614 USearchAttributeValue overlap)
615 {
616 UErrorCode status = U_ZERO_ERROR;
617 UChar pattern[32];
618 UChar text[128];
619 UCollator *collator = getCollator(search.collator);
620 UBreakIterator *breaker = getBreakIterator(search.breaker);
621 UStringSearch *strsrch;
622
623 CHECK_BREAK_BOOL(search.breaker);
624 u_unescape(search.text, text, 128);
625 u_unescape(search.pattern, pattern, 32);
626 ucol_setStrength(collator, search.strength);
627 strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
628 breaker, &status);
629 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, canonical,
630 &status);
631 usearch_setAttribute(strsrch, USEARCH_OVERLAP, overlap, &status);
632
633 if (U_FAILURE(status)) {
634 log_err("Error opening string search %s\n", u_errorName(status));
635 return FALSE;
636 }
637
638 if (!assertEqualWithUStringSearch(strsrch, search)) {
639 ucol_setStrength(collator, UCOL_TERTIARY);
640 usearch_close(strsrch);
641 return FALSE;
642 }
643 ucol_setStrength(collator, UCOL_TERTIARY);
644 usearch_close(strsrch);
645 return TRUE;
646 }
647
TestBasic(void)648 static void TestBasic(void)
649 {
650 int count = 0;
651 UErrorCode status = U_ZERO_ERROR;
652 open(&status);
653 if (U_FAILURE(status)) {
654 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
655 return;
656 }
657 while (BASIC[count].text != NULL) {
658 if (!assertEqual(BASIC[count])) {
659 log_err("Error at test number %d\n", count);
660 }
661 count ++;
662 }
663 close();
664 }
665
TestNormExact(void)666 static void TestNormExact(void)
667 {
668 int count = 0;
669 UErrorCode status = U_ZERO_ERROR;
670 open(&status);
671 if (U_FAILURE(status)) {
672 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
673 return;
674 }
675 ucol_setAttribute(EN_US_, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
676 if (U_FAILURE(status)) {
677 log_err("Error setting collation normalization %s\n",
678 u_errorName(status));
679 }
680 while (BASIC[count].text != NULL) {
681 if (!assertEqual(BASIC[count])) {
682 log_err("Error at test number %d\n", count);
683 }
684 count ++;
685 }
686 count = 0;
687 while (NORMEXACT[count].text != NULL) {
688 if (!assertEqual(NORMEXACT[count])) {
689 log_err("Error at test number %d\n", count);
690 }
691 count ++;
692 }
693 ucol_setAttribute(EN_US_, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
694 count = 0;
695 while (NONNORMEXACT[count].text != NULL) {
696 if (!assertEqual(NONNORMEXACT[count])) {
697 log_err("Error at test number %d\n", count);
698 }
699 count ++;
700 }
701 close();
702 }
703
TestStrength(void)704 static void TestStrength(void)
705 {
706 int count = 0;
707 UErrorCode status = U_ZERO_ERROR;
708 open(&status);
709 if (U_FAILURE(status)) {
710 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
711 return;
712 }
713 while (STRENGTH[count].text != NULL) {
714 if (!assertEqual(STRENGTH[count])) {
715 log_err("Error at test number %d\n", count);
716 }
717 count ++;
718 }
719 close();
720 }
721
TestBreakIterator(void)722 static void TestBreakIterator(void) {
723 UErrorCode status = U_ZERO_ERROR;
724 UStringSearch *strsrch;
725 UChar text[128];
726 UChar pattern[32];
727 int count = 0;
728
729 CHECK_BREAK("x");
730
731 #if !UCONFIG_NO_BREAK_ITERATION
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 if (usearch_getBreakIterator(NULL) != NULL) {
738 log_err("Expected NULL breakiterator from NULL string search\n");
739 }
740 u_unescape(BREAKITERATOREXACT[0].text, text, 128);
741 u_unescape(BREAKITERATOREXACT[0].pattern, pattern, 32);
742 strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_, NULL,
743 &status);
744 if (U_FAILURE(status)) {
745 log_err("Error opening string search %s\n", u_errorName(status));
746 goto ENDTESTBREAKITERATOR;
747 }
748
749 usearch_setBreakIterator(strsrch, NULL, &status);
750 if (U_FAILURE(status) || usearch_getBreakIterator(strsrch) != NULL) {
751 log_err("Error usearch_getBreakIterator returned wrong object");
752 goto ENDTESTBREAKITERATOR;
753 }
754
755 usearch_setBreakIterator(strsrch, EN_CHARACTERBREAKER_, &status);
756 if (U_FAILURE(status) ||
757 usearch_getBreakIterator(strsrch) != EN_CHARACTERBREAKER_) {
758 log_err("Error usearch_getBreakIterator returned wrong object");
759 goto ENDTESTBREAKITERATOR;
760 }
761
762 usearch_setBreakIterator(strsrch, EN_WORDBREAKER_, &status);
763 if (U_FAILURE(status) ||
764 usearch_getBreakIterator(strsrch) != EN_WORDBREAKER_) {
765 log_err("Error usearch_getBreakIterator returned wrong object");
766 goto ENDTESTBREAKITERATOR;
767 }
768
769 usearch_close(strsrch);
770
771 count = 0;
772 while (count < 4) {
773 /* 0-3 test are fixed */
774 const SearchData *search = &(BREAKITERATOREXACT[count]);
775 UCollator *collator = getCollator(search->collator);
776 UBreakIterator *breaker = getBreakIterator(search->breaker);
777
778 u_unescape(search->text, text, 128);
779 u_unescape(search->pattern, pattern, 32);
780 ucol_setStrength(collator, search->strength);
781
782 strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
783 breaker, &status);
784 if (U_FAILURE(status) ||
785 usearch_getBreakIterator(strsrch) != breaker) {
786 log_err("Error setting break iterator\n");
787 if (strsrch != NULL) {
788 usearch_close(strsrch);
789 }
790 }
791 if (!assertEqualWithUStringSearch(strsrch, *search)) {
792 ucol_setStrength(collator, UCOL_TERTIARY);
793 usearch_close(strsrch);
794 goto ENDTESTBREAKITERATOR;
795 }
796 search = &(BREAKITERATOREXACT[count + 1]);
797 breaker = getBreakIterator(search->breaker);
798 usearch_setBreakIterator(strsrch, breaker, &status);
799 if (U_FAILURE(status) || usearch_getBreakIterator(strsrch) != breaker) {
800 log_err("Error setting break iterator\n");
801 usearch_close(strsrch);
802 goto ENDTESTBREAKITERATOR;
803 }
804 usearch_reset(strsrch);
805 if (!assertEqualWithUStringSearch(strsrch, *search)) {
806 log_err("Error at test number %d\n", count);
807 usearch_close(strsrch);
808 goto ENDTESTBREAKITERATOR;
809 }
810 usearch_close(strsrch);
811 count += 2;
812 }
813 count = 0;
814 while (BREAKITERATOREXACT[count].text != NULL) {
815 if (!assertEqual(BREAKITERATOREXACT[count])) {
816 log_err("Error at test number %d\n", count);
817 goto ENDTESTBREAKITERATOR;
818 }
819 count ++;
820 }
821
822 ENDTESTBREAKITERATOR:
823 close();
824 #endif
825 }
826
TestVariable(void)827 static void TestVariable(void)
828 {
829 int count = 0;
830 UErrorCode status = U_ZERO_ERROR;
831 open(&status);
832 if (U_FAILURE(status)) {
833 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
834 return;
835 }
836 ucol_setAttribute(EN_US_, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
837 if (U_FAILURE(status)) {
838 log_err("Error setting collation alternate attribute %s\n",
839 u_errorName(status));
840 }
841 while (VARIABLE[count].text != NULL) {
842 log_verbose("variable %d\n", count);
843 if (!assertEqual(VARIABLE[count])) {
844 log_err("Error at test number %d\n", count);
845 }
846 count ++;
847 }
848 ucol_setAttribute(EN_US_, UCOL_ALTERNATE_HANDLING,
849 UCOL_NON_IGNORABLE, &status);
850 close();
851 }
852
TestOverlap(void)853 static void TestOverlap(void)
854 {
855 int count = 0;
856 UErrorCode status = U_ZERO_ERROR;
857 open(&status);
858 if (U_FAILURE(status)) {
859 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
860 return;
861 }
862 while (OVERLAP[count].text != NULL) {
863 if (!assertEqualWithAttribute(OVERLAP[count], USEARCH_OFF,
864 USEARCH_ON)) {
865 log_err("Error at overlap test number %d\n", count);
866 }
867 count ++;
868 }
869 count = 0;
870 while (NONOVERLAP[count].text != NULL) {
871 if (!assertEqual(NONOVERLAP[count])) {
872 log_err("Error at non overlap test number %d\n", count);
873 }
874 count ++;
875 }
876
877 count = 0;
878 while (count < 1) {
879 UChar pattern[32];
880 UChar text[128];
881 const SearchData *search = &(OVERLAP[count]);
882 UCollator *collator = getCollator(search->collator);
883 UStringSearch *strsrch;
884 status = U_ZERO_ERROR;
885
886 u_unescape(search->text, text, 128);
887 u_unescape(search->pattern, pattern, 32);
888 strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
889 NULL, &status);
890 if(status == U_FILE_ACCESS_ERROR) {
891 log_data_err("Is your data around?\n");
892 return;
893 } else if(U_FAILURE(status)) {
894 log_err("Error opening searcher\n");
895 return;
896 }
897 usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_ON, &status);
898 if (U_FAILURE(status) ||
899 usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_ON) {
900 log_err("Error setting overlap option\n");
901 }
902 if (!assertEqualWithUStringSearch(strsrch, *search)) {
903 usearch_close(strsrch);
904 return;
905 }
906 search = &(NONOVERLAP[count]);
907 usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_OFF, &status);
908 if (U_FAILURE(status) ||
909 usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF) {
910 log_err("Error setting overlap option\n");
911 }
912 usearch_reset(strsrch);
913 if (!assertEqualWithUStringSearch(strsrch, *search)) {
914 usearch_close(strsrch);
915 log_err("Error at test number %d\n", count);
916 }
917
918 count ++;
919 usearch_close(strsrch);
920 }
921 close();
922 }
923
TestCollator(void)924 static void TestCollator(void)
925 {
926 /* test collator that thinks "o" and "p" are the same thing */
927 UChar rules[32];
928 UCollator *tailored = NULL;
929 UErrorCode status = U_ZERO_ERROR;
930 UChar pattern[32];
931 UChar text[128];
932 UStringSearch *strsrch;
933
934 text[0] = 0x41;
935 text[1] = 0x42;
936 text[2] = 0x43;
937 text[3] = 0x44;
938 text[4] = 0x45;
939 pattern[0] = 0x62;
940 pattern[1] = 0x63;
941 strsrch = usearch_open(pattern, 2, text, 5, "en_US", NULL, &status);
942 if(status == U_FILE_ACCESS_ERROR) {
943 log_data_err("Is your data around?\n");
944 return;
945 } else if(U_FAILURE(status)) {
946 log_err("Error opening searcher\n");
947 return;
948 }
949 tailored = usearch_getCollator(strsrch);
950 if (usearch_next(strsrch, &status) != -1) {
951 log_err("Error: Found case insensitive match, when we shouldn't\n");
952 }
953 ucol_setStrength(tailored, UCOL_PRIMARY);
954 usearch_reset(strsrch);
955 if (usearch_next(strsrch, &status) != 1) {
956 log_err("Error: Found case insensitive match not found\n");
957 }
958 usearch_close(strsrch);
959
960 open(&status);
961
962 if (usearch_getCollator(NULL) != NULL) {
963 log_err("Expected NULL collator from NULL string search\n");
964 }
965 u_unescape(COLLATOR[0].text, text, 128);
966 u_unescape(COLLATOR[0].pattern, pattern, 32);
967
968 strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
969 NULL, &status);
970 if (U_FAILURE(status)) {
971 log_err("Error opening string search %s\n", u_errorName(status));
972 }
973 if (!assertEqualWithUStringSearch(strsrch, COLLATOR[0])) {
974 goto ENDTESTCOLLATOR;
975 }
976
977 u_unescape(TESTCOLLATORRULE, rules, 32);
978 tailored = ucol_openRules(rules, -1, UCOL_ON, COLLATOR[1].strength,
979 NULL, &status);
980 if (U_FAILURE(status)) {
981 log_err("Error opening rule based collator %s\n", u_errorName(status));
982 }
983
984 usearch_setCollator(strsrch, tailored, &status);
985 if (U_FAILURE(status) || usearch_getCollator(strsrch) != tailored) {
986 log_err("Error setting rule based collator\n");
987 }
988 usearch_reset(strsrch);
989 if (!assertEqualWithUStringSearch(strsrch, COLLATOR[1])) {
990 goto ENDTESTCOLLATOR;
991 }
992
993 usearch_setCollator(strsrch, EN_US_, &status);
994 usearch_reset(strsrch);
995 if (U_FAILURE(status) || usearch_getCollator(strsrch) != EN_US_) {
996 log_err("Error setting rule based collator\n");
997 }
998 if (!assertEqualWithUStringSearch(strsrch, COLLATOR[0])) {
999 goto ENDTESTCOLLATOR;
1000 }
1001
1002 ENDTESTCOLLATOR:
1003 usearch_close(strsrch);
1004 if (tailored != NULL) {
1005 ucol_close(tailored);
1006 }
1007 close();
1008 }
1009
TestPattern(void)1010 static void TestPattern(void)
1011 {
1012 UStringSearch *strsrch;
1013 UChar pattern[32];
1014 UChar bigpattern[512];
1015 UChar text[128];
1016 const UChar *temp;
1017 int32_t templength;
1018 UErrorCode status = U_ZERO_ERROR;
1019
1020 open(&status);
1021 if (U_FAILURE(status)) {
1022 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1023 return;
1024 }
1025 if (usearch_getPattern(NULL, &templength) != NULL) {
1026 log_err("Error NULL string search expected returning NULL pattern\n");
1027 }
1028 usearch_setPattern(NULL, pattern, 3, &status);
1029 if (U_SUCCESS(status)) {
1030 log_err("Error expected setting pattern in NULL strings search\n");
1031 }
1032 status = U_ZERO_ERROR;
1033 u_unescape(PATTERN[0].text, text, 128);
1034 u_unescape(PATTERN[0].pattern, pattern, 32);
1035
1036 ucol_setStrength(EN_US_, PATTERN[0].strength);
1037 strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
1038 NULL, &status);
1039 if(status == U_FILE_ACCESS_ERROR) {
1040 log_data_err("Is your data around?\n");
1041 return;
1042 } else if(U_FAILURE(status)) {
1043 log_err("Error opening searcher\n");
1044 return;
1045 }
1046
1047 status = U_ZERO_ERROR;
1048 usearch_setPattern(strsrch, NULL, 3, &status);
1049 if (U_SUCCESS(status)) {
1050 log_err("Error expected setting NULL pattern in strings search\n");
1051 }
1052 status = U_ZERO_ERROR;
1053 usearch_setPattern(strsrch, pattern, 0, &status);
1054 if (U_SUCCESS(status)) {
1055 log_err("Error expected setting pattern with length 0 in strings search\n");
1056 }
1057 status = U_ZERO_ERROR;
1058 if (U_FAILURE(status)) {
1059 log_err("Error opening string search %s\n", u_errorName(status));
1060 goto ENDTESTPATTERN;
1061 }
1062 temp = usearch_getPattern(strsrch, &templength);
1063 if (u_strcmp(pattern, temp) != 0) {
1064 log_err("Error setting pattern\n");
1065 }
1066 if (!assertEqualWithUStringSearch(strsrch, PATTERN[0])) {
1067 goto ENDTESTPATTERN;
1068 }
1069
1070 u_unescape(PATTERN[1].pattern, pattern, 32);
1071 usearch_setPattern(strsrch, pattern, -1, &status);
1072 temp = usearch_getPattern(strsrch, &templength);
1073 if (u_strcmp(pattern, temp) != 0) {
1074 log_err("Error setting pattern\n");
1075 goto ENDTESTPATTERN;
1076 }
1077 usearch_reset(strsrch);
1078 if (U_FAILURE(status)) {
1079 log_err("Error setting pattern %s\n", u_errorName(status));
1080 }
1081 if (!assertEqualWithUStringSearch(strsrch, PATTERN[1])) {
1082 goto ENDTESTPATTERN;
1083 }
1084
1085 u_unescape(PATTERN[0].pattern, pattern, 32);
1086 usearch_setPattern(strsrch, pattern, -1, &status);
1087 temp = usearch_getPattern(strsrch, &templength);
1088 if (u_strcmp(pattern, temp) != 0) {
1089 log_err("Error setting pattern\n");
1090 goto ENDTESTPATTERN;
1091 }
1092 usearch_reset(strsrch);
1093 if (U_FAILURE(status)) {
1094 log_err("Error setting pattern %s\n", u_errorName(status));
1095 }
1096 if (!assertEqualWithUStringSearch(strsrch, PATTERN[0])) {
1097 goto ENDTESTPATTERN;
1098 }
1099 /* enormous pattern size to see if this crashes */
1100 for (templength = 0; templength != 512; templength ++) {
1101 bigpattern[templength] = 0x61;
1102 }
1103 bigpattern[511] = 0;
1104 usearch_setPattern(strsrch, bigpattern, -1, &status);
1105 if (U_FAILURE(status)) {
1106 log_err("Error setting pattern with size 512, %s \n",
1107 u_errorName(status));
1108 }
1109 ENDTESTPATTERN:
1110 ucol_setStrength(EN_US_, UCOL_TERTIARY);
1111 if (strsrch != NULL) {
1112 usearch_close(strsrch);
1113 }
1114 close();
1115 }
1116
TestText(void)1117 static void TestText(void)
1118 {
1119 UStringSearch *strsrch;
1120 UChar pattern[32];
1121 UChar text[128];
1122 const UChar *temp;
1123 int32_t templength;
1124 UErrorCode status = U_ZERO_ERROR;
1125
1126 u_unescape(TEXT[0].text, text, 128);
1127 u_unescape(TEXT[0].pattern, pattern, 32);
1128
1129 open(&status);
1130 if (U_FAILURE(status)) {
1131 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1132 return;
1133 }
1134
1135 if (usearch_getText(NULL, &templength) != NULL) {
1136 log_err("Error NULL string search should return NULL text\n");
1137 }
1138
1139 usearch_setText(NULL, text, 10, &status);
1140 if (U_SUCCESS(status)) {
1141 log_err("Error NULL string search should have an error when setting text\n");
1142 }
1143
1144 status = U_ZERO_ERROR;
1145 strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
1146 NULL, &status);
1147
1148 if (U_FAILURE(status)) {
1149 log_err("Error opening string search %s\n", u_errorName(status));
1150 goto ENDTESTPATTERN;
1151 }
1152 temp = usearch_getText(strsrch, &templength);
1153 if (u_strcmp(text, temp) != 0) {
1154 log_err("Error setting text\n");
1155 }
1156 if (!assertEqualWithUStringSearch(strsrch, TEXT[0])) {
1157 goto ENDTESTPATTERN;
1158 }
1159
1160 u_unescape(TEXT[1].text, text, 32);
1161 usearch_setText(strsrch, text, -1, &status);
1162 temp = usearch_getText(strsrch, &templength);
1163 if (u_strcmp(text, temp) != 0) {
1164 log_err("Error setting text\n");
1165 goto ENDTESTPATTERN;
1166 }
1167 if (U_FAILURE(status)) {
1168 log_err("Error setting text %s\n", u_errorName(status));
1169 }
1170 if (!assertEqualWithUStringSearch(strsrch, TEXT[1])) {
1171 goto ENDTESTPATTERN;
1172 }
1173
1174 u_unescape(TEXT[0].text, text, 32);
1175 usearch_setText(strsrch, text, -1, &status);
1176 temp = usearch_getText(strsrch, &templength);
1177 if (u_strcmp(text, temp) != 0) {
1178 log_err("Error setting text\n");
1179 goto ENDTESTPATTERN;
1180 }
1181 if (U_FAILURE(status)) {
1182 log_err("Error setting pattern %s\n", u_errorName(status));
1183 }
1184 if (!assertEqualWithUStringSearch(strsrch, TEXT[0])) {
1185 goto ENDTESTPATTERN;
1186 }
1187 ENDTESTPATTERN:
1188 if (strsrch != NULL) {
1189 usearch_close(strsrch);
1190 }
1191 close();
1192 }
1193
TestCompositeBoundaries(void)1194 static void TestCompositeBoundaries(void)
1195 {
1196 int count = 0;
1197 UErrorCode status = U_ZERO_ERROR;
1198 open(&status);
1199 if (U_FAILURE(status)) {
1200 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1201 return;
1202 }
1203 while (COMPOSITEBOUNDARIES[count].text != NULL) {
1204 log_verbose("composite %d\n", count);
1205 if (!assertEqual(COMPOSITEBOUNDARIES[count])) {
1206 log_err("Error at test number %d\n", count);
1207 }
1208 count ++;
1209 }
1210 close();
1211 }
1212
TestGetSetOffset(void)1213 static void TestGetSetOffset(void)
1214 {
1215 int searchDataIndex = 0;
1216 UChar pattern[32];
1217 UChar text[128];
1218 UErrorCode status = U_ZERO_ERROR;
1219 UStringSearch *strsrch;
1220 memset(pattern, 0, 32*sizeof(UChar));
1221 memset(text, 0, 128*sizeof(UChar));
1222
1223 open(&status);
1224 if (U_FAILURE(status)) {
1225 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1226 return;
1227 }
1228 if (usearch_getOffset(NULL) != USEARCH_DONE) {
1229 log_err("usearch_getOffset(NULL) expected USEARCH_DONE\n");
1230 }
1231 strsrch = usearch_openFromCollator(pattern, 16, text, 32, EN_US_, NULL,
1232 &status);
1233 /* testing out of bounds error */
1234 usearch_setOffset(strsrch, -1, &status);
1235 if (U_SUCCESS(status)) {
1236 log_err("Error expecting set offset error\n");
1237 }
1238 usearch_setOffset(strsrch, 128, &status);
1239 if (U_SUCCESS(status)) {
1240 log_err("Error expecting set offset error\n");
1241 }
1242 while (BASIC[searchDataIndex].text != NULL) {
1243 int count = 0;
1244 SearchData search = BASIC[searchDataIndex ++];
1245 int32_t matchindex = search.offset[count];
1246 int32_t textlength;
1247
1248 u_unescape(search.text, text, 128);
1249 u_unescape(search.pattern, pattern, 32);
1250 status = U_ZERO_ERROR;
1251 usearch_setText(strsrch, text, -1, &status);
1252 usearch_setPattern(strsrch, pattern, -1, &status);
1253 ucol_setStrength(usearch_getCollator(strsrch), search.strength);
1254 usearch_reset(strsrch);
1255 while (U_SUCCESS(status) && matchindex >= 0) {
1256 uint32_t matchlength = search.size[count];
1257 usearch_next(strsrch, &status);
1258 if (matchindex != usearch_getMatchedStart(strsrch) ||
1259 matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
1260 char *str = toCharString(usearch_getText(strsrch,
1261 &textlength));
1262 log_err("Text: %s\n", str);
1263 str = toCharString(usearch_getPattern(strsrch, &textlength));
1264 log_err("Pattern: %s\n", str);
1265 log_err("Error match found at %d %d\n",
1266 usearch_getMatchedStart(strsrch),
1267 usearch_getMatchedLength(strsrch));
1268 return;
1269 }
1270 usearch_setOffset(strsrch, matchindex + matchlength, &status);
1271 usearch_previous(strsrch, &status);
1272 if (matchindex != usearch_getMatchedStart(strsrch) ||
1273 matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
1274 char *str = toCharString(usearch_getText(strsrch,
1275 &textlength));
1276 log_err("Text: %s\n", str);
1277 str = toCharString(usearch_getPattern(strsrch, &textlength));
1278 log_err("Pattern: %s\n", str);
1279 log_err("Error match found at %d %d\n",
1280 usearch_getMatchedStart(strsrch),
1281 usearch_getMatchedLength(strsrch));
1282 return;
1283 }
1284 usearch_setOffset(strsrch, matchindex + matchlength, &status);
1285 matchindex = search.offset[count + 1] == -1 ? -1 :
1286 search.offset[count + 2];
1287 if (search.offset[count + 1] != -1) {
1288 usearch_setOffset(strsrch, search.offset[count + 1] + 1,
1289 &status);
1290 if (usearch_getOffset(strsrch) != search.offset[count + 1] + 1) {
1291 log_err("Error setting offset\n");
1292 return;
1293 }
1294 }
1295
1296 count += 2;
1297 }
1298 usearch_next(strsrch, &status);
1299 if (usearch_getMatchedStart(strsrch) != USEARCH_DONE) {
1300 char *str = toCharString(usearch_getText(strsrch, &textlength));
1301 log_err("Text: %s\n", str);
1302 str = toCharString(usearch_getPattern(strsrch, &textlength));
1303 log_err("Pattern: %s\n", str);
1304 log_err("Error match found at %d %d\n",
1305 usearch_getMatchedStart(strsrch),
1306 usearch_getMatchedLength(strsrch));
1307 return;
1308 }
1309 }
1310 ucol_setStrength(usearch_getCollator(strsrch), UCOL_TERTIARY);
1311 usearch_close(strsrch);
1312 close();
1313 }
1314
TestGetSetAttribute(void)1315 static void TestGetSetAttribute(void)
1316 {
1317 UErrorCode status = U_ZERO_ERROR;
1318 UChar pattern[32];
1319 UChar text[128];
1320 UStringSearch *strsrch;
1321
1322 memset(pattern, 0, 32*sizeof(UChar));
1323 memset(text, 0, 128*sizeof(UChar));
1324
1325 open(&status);
1326 if (U_FAILURE(status)) {
1327 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1328 return;
1329 }
1330 if (usearch_getAttribute(NULL, USEARCH_OVERLAP) != USEARCH_DEFAULT ||
1331 usearch_getAttribute(NULL, USEARCH_CANONICAL_MATCH) !=
1332 USEARCH_DEFAULT) {
1333 log_err(
1334 "Attributes for NULL string search should be USEARCH_DEFAULT\n");
1335 }
1336 strsrch = usearch_openFromCollator(pattern, 16, text, 32, EN_US_, NULL,
1337 &status);
1338 if (U_FAILURE(status)) {
1339 log_err("Error opening search %s\n", u_errorName(status));
1340 return;
1341 }
1342
1343 usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_DEFAULT, &status);
1344 if (U_FAILURE(status) ||
1345 usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF) {
1346 log_err("Error setting overlap to the default\n");
1347 }
1348 usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_ON, &status);
1349 if (U_FAILURE(status) ||
1350 usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_ON) {
1351 log_err("Error setting overlap true\n");
1352 }
1353 usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_OFF, &status);
1354 if (U_FAILURE(status) ||
1355 usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF) {
1356 log_err("Error setting overlap false\n");
1357 }
1358 usearch_setAttribute(strsrch, USEARCH_OVERLAP,
1359 USEARCH_ATTRIBUTE_VALUE_COUNT, &status);
1360 if (U_SUCCESS(status)) {
1361 log_err("Error setting overlap to illegal value\n");
1362 }
1363 status = U_ZERO_ERROR;
1364 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_DEFAULT,
1365 &status);
1366 if (U_FAILURE(status) ||
1367 usearch_getAttribute(strsrch, USEARCH_CANONICAL_MATCH) !=
1368 USEARCH_OFF) {
1369 log_err("Error setting canonical match to the default\n");
1370 }
1371 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1372 &status);
1373 if (U_FAILURE(status) ||
1374 usearch_getAttribute(strsrch, USEARCH_CANONICAL_MATCH) !=
1375 USEARCH_ON) {
1376 log_err("Error setting canonical match true\n");
1377 }
1378 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_OFF,
1379 &status);
1380 if (U_FAILURE(status) ||
1381 usearch_getAttribute(strsrch, USEARCH_CANONICAL_MATCH) !=
1382 USEARCH_OFF) {
1383 log_err("Error setting canonical match false\n");
1384 }
1385 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH,
1386 USEARCH_ATTRIBUTE_VALUE_COUNT, &status);
1387 if (U_SUCCESS(status)) {
1388 log_err("Error setting canonical match to illegal value\n");
1389 }
1390 status = U_ZERO_ERROR;
1391 usearch_setAttribute(strsrch, USEARCH_ATTRIBUTE_COUNT, USEARCH_DEFAULT,
1392 &status);
1393 if (U_SUCCESS(status)) {
1394 log_err("Error setting illegal attribute success\n");
1395 }
1396
1397 usearch_close(strsrch);
1398 close();
1399 }
1400
TestGetMatch(void)1401 static void TestGetMatch(void)
1402 {
1403 int count = 0;
1404 UErrorCode status = U_ZERO_ERROR;
1405 UChar text[128];
1406 UChar pattern[32];
1407 SearchData search = MATCH[0];
1408 int32_t matchindex = search.offset[count];
1409 UStringSearch *strsrch;
1410 int32_t textlength;
1411 UChar matchtext[128];
1412
1413 open(&status);
1414 if (U_FAILURE(status)) {
1415 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1416 return;
1417 }
1418
1419 if (usearch_getMatchedStart(NULL) != USEARCH_DONE ||
1420 usearch_getMatchedLength(NULL) != USEARCH_DONE) {
1421 log_err(
1422 "Expected start and length of NULL string search should be USEARCH_DONE\n");
1423 }
1424
1425 u_unescape(search.text, text, 128);
1426 u_unescape(search.pattern, pattern, 32);
1427 strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
1428 NULL, &status);
1429 if (U_FAILURE(status)) {
1430 log_err("Error opening string search %s\n", u_errorName(status));
1431 if (strsrch != NULL) {
1432 usearch_close(strsrch);
1433 }
1434 return;
1435 }
1436
1437 while (U_SUCCESS(status) && matchindex >= 0) {
1438 int32_t matchlength = search.size[count];
1439 usearch_next(strsrch, &status);
1440 if (matchindex != usearch_getMatchedStart(strsrch) ||
1441 matchlength != usearch_getMatchedLength(strsrch)) {
1442 char *str = toCharString(usearch_getText(strsrch, &textlength));
1443 log_err("Text: %s\n", str);
1444 str = toCharString(usearch_getPattern(strsrch, &textlength));
1445 log_err("Pattern: %s\n", str);
1446 log_err("Error match found at %d %d\n",
1447 usearch_getMatchedStart(strsrch),
1448 usearch_getMatchedLength(strsrch));
1449 return;
1450 }
1451 count ++;
1452
1453 status = U_ZERO_ERROR;
1454 if (usearch_getMatchedText(NULL, matchtext, 128, &status) !=
1455 USEARCH_DONE || U_SUCCESS(status)){
1456 log_err("Error expecting errors with NULL string search\n");
1457 }
1458 status = U_ZERO_ERROR;
1459 if (usearch_getMatchedText(strsrch, NULL, 0, &status) !=
1460 (int32_t)matchlength || U_SUCCESS(status)){
1461 log_err("Error pre-flighting match length\n");
1462 }
1463 status = U_ZERO_ERROR;
1464 if (usearch_getMatchedText(strsrch, matchtext, 0, &status) !=
1465 (int32_t)matchlength || U_SUCCESS(status)){
1466 log_err("Error getting match text with buffer size 0\n");
1467 }
1468 status = U_ZERO_ERROR;
1469 if (usearch_getMatchedText(strsrch, matchtext, matchlength, &status)
1470 != (int32_t)matchlength || matchtext[matchlength - 1] == 0 ||
1471 U_FAILURE(status)){
1472 log_err("Error getting match text with exact size\n");
1473 }
1474 status = U_ZERO_ERROR;
1475 if (usearch_getMatchedText(strsrch, matchtext, 128, &status) !=
1476 (int32_t) matchlength || U_FAILURE(status) ||
1477 memcmp(matchtext,
1478 usearch_getText(strsrch, &textlength) + matchindex,
1479 matchlength * sizeof(UChar)) != 0 ||
1480 matchtext[matchlength] != 0) {
1481 log_err("Error getting matched text\n");
1482 }
1483
1484 matchindex = search.offset[count];
1485 }
1486 status = U_ZERO_ERROR;
1487 usearch_next(strsrch, &status);
1488 if (usearch_getMatchedStart(strsrch) != USEARCH_DONE ||
1489 usearch_getMatchedLength(strsrch) != 0) {
1490 log_err("Error end of match not found\n");
1491 }
1492 status = U_ZERO_ERROR;
1493 if (usearch_getMatchedText(strsrch, matchtext, 128, &status) !=
1494 USEARCH_DONE) {
1495 log_err("Error getting null matches\n");
1496 }
1497 usearch_close(strsrch);
1498 close();
1499 }
1500
TestSetMatch(void)1501 static void TestSetMatch(void)
1502 {
1503 int count = 0;
1504 UErrorCode status = U_ZERO_ERROR;
1505 open(&status);
1506 if (U_FAILURE(status)) {
1507 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1508 return;
1509 }
1510 while (MATCH[count].text != NULL) {
1511 SearchData search = MATCH[count];
1512 int size = 0;
1513 int offsetIndex = 0;
1514 UChar text[128];
1515 UChar pattern[32];
1516 UStringSearch *strsrch;
1517 status = U_ZERO_ERROR;
1518
1519 if (usearch_first(NULL, &status) != USEARCH_DONE ||
1520 usearch_last(NULL, &status) != USEARCH_DONE) {
1521 log_err("Error getting the first and last match of a NULL string search\n");
1522 }
1523 u_unescape(search.text, text, 128);
1524 u_unescape(search.pattern, pattern, 32);
1525 strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
1526 NULL, &status);
1527 if (U_FAILURE(status)) {
1528 log_err("Error opening string search %s\n", u_errorName(status));
1529 if (strsrch != NULL) {
1530 usearch_close(strsrch);
1531 }
1532 return;
1533 }
1534
1535 size = 0;
1536 while (search.offset[size] != -1) {
1537 size ++;
1538 }
1539
1540 if (usearch_first(strsrch, &status) != search.offset[0] ||
1541 U_FAILURE(status)) {
1542 log_err("Error getting first match\n");
1543 }
1544 if (usearch_last(strsrch, &status) != search.offset[size -1] ||
1545 U_FAILURE(status)) {
1546 log_err("Error getting last match\n");
1547 }
1548
1549 while (offsetIndex < size) {
1550 if (offsetIndex + 2 < size) {
1551 if (usearch_following(strsrch, search.offset[offsetIndex + 2] - 1,
1552 &status) != search.offset[offsetIndex + 2] ||
1553 U_FAILURE(status)) {
1554 log_err("Error getting following match at index %d\n",
1555 search.offset[offsetIndex + 2] - 1);
1556 }
1557 }
1558 if (offsetIndex + 1 < size) {
1559 if (usearch_preceding(strsrch, search.offset[offsetIndex + 1] +
1560 search.size[offsetIndex + 1] + 1,
1561 &status) != search.offset[offsetIndex + 1] ||
1562 U_FAILURE(status)) {
1563 log_err("Error getting preceeding match at index %d\n",
1564 search.offset[offsetIndex + 1] + 1);
1565 }
1566 }
1567 offsetIndex += 2;
1568 }
1569 status = U_ZERO_ERROR;
1570 if (usearch_following(strsrch, u_strlen(text), &status) !=
1571 USEARCH_DONE) {
1572 log_err("Error expecting out of bounds match\n");
1573 }
1574 if (usearch_preceding(strsrch, 0, &status) != USEARCH_DONE) {
1575 log_err("Error expecting out of bounds match\n");
1576 }
1577 count ++;
1578 usearch_close(strsrch);
1579 }
1580 close();
1581 }
1582
TestReset(void)1583 static void TestReset(void)
1584 {
1585 UErrorCode status = U_ZERO_ERROR;
1586 UChar text[] = {0x66, 0x69, 0x73, 0x68, 0x20,
1587 0x66, 0x69, 0x73, 0x68};
1588 UChar pattern[] = {0x73};
1589 UStringSearch *strsrch;
1590
1591 open(&status);
1592 if (U_FAILURE(status)) {
1593 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1594 return;
1595 }
1596 strsrch = usearch_openFromCollator(pattern, 1, text, 9,
1597 EN_US_, NULL, &status);
1598 if (U_FAILURE(status)) {
1599 log_err("Error opening string search %s\n", u_errorName(status));
1600 if (strsrch != NULL) {
1601 usearch_close(strsrch);
1602 }
1603 return;
1604 }
1605 usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_ON, &status);
1606 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1607 &status);
1608 usearch_setOffset(strsrch, 9, &status);
1609 if (U_FAILURE(status)) {
1610 log_err("Error setting attributes and offsets\n");
1611 }
1612 else {
1613 usearch_reset(strsrch);
1614 if (usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF ||
1615 usearch_getAttribute(strsrch, USEARCH_CANONICAL_MATCH) !=
1616 USEARCH_OFF ||
1617 usearch_getOffset(strsrch) != 0 ||
1618 usearch_getMatchedLength(strsrch) != 0 ||
1619 usearch_getMatchedStart(strsrch) != USEARCH_DONE) {
1620 log_err("Error resetting string search\n");
1621 }
1622 usearch_previous(strsrch, &status);
1623 if (usearch_getMatchedStart(strsrch) != 7 ||
1624 usearch_getMatchedLength(strsrch) != 1) {
1625 log_err("Error resetting string search\n");
1626 }
1627 }
1628 usearch_close(strsrch);
1629 close();
1630 }
1631
TestSupplementary(void)1632 static void TestSupplementary(void)
1633 {
1634 int count = 0;
1635 UErrorCode status = U_ZERO_ERROR;
1636 open(&status);
1637 if (U_FAILURE(status)) {
1638 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1639 return;
1640 }
1641 while (SUPPLEMENTARY[count].text != NULL) {
1642 if (!assertEqual(SUPPLEMENTARY[count])) {
1643 log_err("Error at test number %d\n", count);
1644 }
1645 count ++;
1646 }
1647 close();
1648 }
1649
TestContraction(void)1650 static void TestContraction(void)
1651 {
1652 UChar rules[128];
1653 UChar pattern[128];
1654 UChar text[128];
1655 UCollator *collator;
1656 UErrorCode status = U_ZERO_ERROR;
1657 int count = 0;
1658 UStringSearch *strsrch;
1659 memset(rules, 0, 128*sizeof(UChar));
1660 memset(pattern, 0, 128*sizeof(UChar));
1661 memset(text, 0, 128*sizeof(UChar));
1662
1663 u_unescape(CONTRACTIONRULE, rules, 128);
1664 collator = ucol_openRules(rules, u_strlen(rules), UCOL_ON,
1665 UCOL_TERTIARY, NULL, &status);
1666 if(status == U_FILE_ACCESS_ERROR) {
1667 log_data_err("Is your data around?\n");
1668 return;
1669 } else if(U_FAILURE(status)) {
1670 log_err("Error opening collator %s\n", u_errorName(status));
1671 return;
1672 }
1673 strsrch = usearch_openFromCollator(pattern, 1, text, 1, collator, NULL,
1674 &status);
1675 if (U_FAILURE(status)) {
1676 log_err("Error opening string search %s\n", u_errorName(status));
1677 }
1678
1679 while (CONTRACTION[count].text != NULL) {
1680 u_unescape(CONTRACTION[count].text, text, 128);
1681 u_unescape(CONTRACTION[count].pattern, pattern, 128);
1682 usearch_setText(strsrch, text, -1, &status);
1683 usearch_setPattern(strsrch, pattern, -1, &status);
1684 if (!assertEqualWithUStringSearch(strsrch, CONTRACTION[count])) {
1685 log_err("Error at test number %d\n", count);
1686 }
1687 count ++;
1688 }
1689 usearch_close(strsrch);
1690 ucol_close(collator);
1691 }
1692
TestIgnorable(void)1693 static void TestIgnorable(void)
1694 {
1695 UChar rules[128];
1696 UChar pattern[128];
1697 UChar text[128];
1698 UCollator *collator;
1699 UErrorCode status = U_ZERO_ERROR;
1700 UStringSearch *strsrch;
1701 uint32_t count = 0;
1702
1703 memset(rules, 0, 128*sizeof(UChar));
1704 memset(pattern, 0, 128*sizeof(UChar));
1705 memset(text, 0, 128*sizeof(UChar));
1706
1707 u_unescape(IGNORABLERULE, rules, 128);
1708 collator = ucol_openRules(rules, u_strlen(rules), UCOL_ON,
1709 IGNORABLE[count].strength, NULL, &status);
1710 if(status == U_FILE_ACCESS_ERROR) {
1711 log_data_err("Is your data around?\n");
1712 return;
1713 } else if(U_FAILURE(status)) {
1714 log_err("Error opening collator %s\n", u_errorName(status));
1715 return;
1716 }
1717 strsrch = usearch_openFromCollator(pattern, 1, text, 1, collator, NULL,
1718 &status);
1719 if (U_FAILURE(status)) {
1720 log_err("Error opening string search %s\n", u_errorName(status));
1721 }
1722
1723 while (IGNORABLE[count].text != NULL) {
1724 u_unescape(IGNORABLE[count].text, text, 128);
1725 u_unescape(IGNORABLE[count].pattern, pattern, 128);
1726 usearch_setText(strsrch, text, -1, &status);
1727 usearch_setPattern(strsrch, pattern, -1, &status);
1728 if (!assertEqualWithUStringSearch(strsrch, IGNORABLE[count])) {
1729 log_err("Error at test number %d\n", count);
1730 }
1731 count ++;
1732 }
1733 usearch_close(strsrch);
1734 ucol_close(collator);
1735 }
1736
TestDiacriticMatch(void)1737 static void TestDiacriticMatch(void)
1738 {
1739 UChar pattern[128];
1740 UChar text[128];
1741 UErrorCode status = U_ZERO_ERROR;
1742 UStringSearch *strsrch = NULL;
1743 UCollator *coll = NULL;
1744 uint32_t count = 0;
1745 SearchData search;
1746
1747 memset(pattern, 0, 128*sizeof(UChar));
1748 memset(text, 0, 128*sizeof(UChar));
1749
1750 strsrch = usearch_open(pattern, 1, text, 1, uloc_getDefault(), NULL, &status);
1751 if (U_FAILURE(status)) {
1752 log_err_status(status, "Error opening string search %s\n", u_errorName(status));
1753 return;
1754 }
1755
1756 search = DIACRITICMATCH[count];
1757 while (search.text != NULL) {
1758 if (search.collator != NULL) {
1759 coll = ucol_openFromShortString(search.collator, FALSE, NULL, &status);
1760 } else {
1761 /* Always use "en_US" because some of these tests fail in Danish locales. */
1762 coll = ucol_open("en_US"/*uloc_getDefault()*/, &status);
1763 ucol_setStrength(coll, search.strength);
1764 }
1765 if (U_FAILURE(status)) {
1766 log_err("Error opening string search collator(\"%s\") %s\n", search.collator, u_errorName(status));
1767 return;
1768 }
1769
1770 usearch_setCollator(strsrch, coll, &status);
1771 if (U_FAILURE(status)) {
1772 log_err("Error setting string search collator %s\n", u_errorName(status));
1773 return;
1774 }
1775
1776 u_unescape(search.text, text, 128);
1777 u_unescape(search.pattern, pattern, 128);
1778 usearch_setText(strsrch, text, -1, &status);
1779 usearch_setPattern(strsrch, pattern, -1, &status);
1780 if (!assertEqualWithUStringSearch(strsrch, search)) {
1781 log_err("Error at test number %d\n", count);
1782 }
1783 ucol_close(coll);
1784
1785 search = DIACRITICMATCH[++count];
1786 }
1787 usearch_close(strsrch);
1788 }
1789
TestCanonical(void)1790 static void TestCanonical(void)
1791 {
1792 int count = 0;
1793 UErrorCode status = U_ZERO_ERROR;
1794 open(&status);
1795 if (U_FAILURE(status)) {
1796 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1797 return;
1798 }
1799 while (BASICCANONICAL[count].text != NULL) {
1800 if (!assertCanonicalEqual(BASICCANONICAL[count])) {
1801 log_err("Error at test number %d\n", count);
1802 }
1803 count ++;
1804 }
1805 close();
1806 }
1807
TestNormCanonical(void)1808 static void TestNormCanonical(void)
1809 {
1810 int count = 0;
1811 UErrorCode status = U_ZERO_ERROR;
1812 open(&status);
1813 if (U_FAILURE(status)) {
1814 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1815 return;
1816 }
1817 ucol_setAttribute(EN_US_, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
1818 count = 0;
1819 while (NORMCANONICAL[count].text != NULL) {
1820 if (!assertCanonicalEqual(NORMCANONICAL[count])) {
1821 log_err("Error at test number %d\n", count);
1822 }
1823 count ++;
1824 }
1825 ucol_setAttribute(EN_US_, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
1826 close();
1827 }
1828
TestStrengthCanonical(void)1829 static void TestStrengthCanonical(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 while (STRENGTHCANONICAL[count].text != NULL) {
1839 if (!assertCanonicalEqual(STRENGTHCANONICAL[count])) {
1840 log_err("Error at test number %d\n", count);
1841 }
1842 count ++;
1843 }
1844 close();
1845 }
1846
TestBreakIteratorCanonical(void)1847 static void TestBreakIteratorCanonical(void) {
1848 UErrorCode status = U_ZERO_ERROR;
1849 int count = 0;
1850
1851 CHECK_BREAK("x");
1852
1853 #if !UCONFIG_NO_BREAK_ITERATION
1854
1855 open(&status);
1856 if (U_FAILURE(status)) {
1857 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1858 return;
1859 }
1860 while (count < 4) {
1861 /* 0-3 test are fixed */
1862 UChar pattern[32];
1863 UChar text[128];
1864 const SearchData *search = &(BREAKITERATORCANONICAL[count]);
1865 UCollator *collator = getCollator(search->collator);
1866 UBreakIterator *breaker = getBreakIterator(search->breaker);
1867 UStringSearch *strsrch;
1868
1869 u_unescape(search->text, text, 128);
1870 u_unescape(search->pattern, pattern, 32);
1871 ucol_setStrength(collator, search->strength);
1872
1873 strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
1874 breaker, &status);
1875 if(status == U_FILE_ACCESS_ERROR) {
1876 log_data_err("Is your data around?\n");
1877 goto ENDTESTBREAKITERATOR;
1878 } else if(U_FAILURE(status)) {
1879 log_err("Error opening searcher\n");
1880 goto ENDTESTBREAKITERATOR;
1881 }
1882 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1883 &status);
1884 if (U_FAILURE(status) ||
1885 usearch_getBreakIterator(strsrch) != breaker) {
1886 log_err("Error setting break iterator\n");
1887 usearch_close(strsrch);
1888 goto ENDTESTBREAKITERATOR;
1889 }
1890 if (!assertEqualWithUStringSearch(strsrch, *search)) {
1891 ucol_setStrength(collator, UCOL_TERTIARY);
1892 usearch_close(strsrch);
1893 goto ENDTESTBREAKITERATOR;
1894 }
1895 search = &(BREAKITERATOREXACT[count + 1]);
1896 breaker = getBreakIterator(search->breaker);
1897 usearch_setBreakIterator(strsrch, breaker, &status);
1898 if (U_FAILURE(status) || usearch_getBreakIterator(strsrch) != breaker) {
1899 log_err("Error setting break iterator\n");
1900 usearch_close(strsrch);
1901 goto ENDTESTBREAKITERATOR;
1902 }
1903 usearch_reset(strsrch);
1904 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1905 &status);
1906 if (!assertEqualWithUStringSearch(strsrch, *search)) {
1907 log_err("Error at test number %d\n", count);
1908 usearch_close(strsrch);
1909 goto ENDTESTBREAKITERATOR;
1910 }
1911 usearch_close(strsrch);
1912 count += 2;
1913 }
1914 count = 0;
1915 while (BREAKITERATORCANONICAL[count].text != NULL) {
1916 if (!assertEqual(BREAKITERATORCANONICAL[count])) {
1917 log_err("Error at test number %d\n", count);
1918 goto ENDTESTBREAKITERATOR;
1919 }
1920 count ++;
1921 }
1922
1923 ENDTESTBREAKITERATOR:
1924 close();
1925 #endif
1926 }
1927
TestVariableCanonical(void)1928 static void TestVariableCanonical(void)
1929 {
1930 int count = 0;
1931 UErrorCode status = U_ZERO_ERROR;
1932 open(&status);
1933 if (U_FAILURE(status)) {
1934 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1935 return;
1936 }
1937 ucol_setAttribute(EN_US_, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
1938 if (U_FAILURE(status)) {
1939 log_err("Error setting collation alternate attribute %s\n",
1940 u_errorName(status));
1941 }
1942 while (VARIABLE[count].text != NULL) {
1943 log_verbose("variable %d\n", count);
1944 if (!assertCanonicalEqual(VARIABLE[count])) {
1945 log_err("Error at test number %d\n", count);
1946 }
1947 count ++;
1948 }
1949 ucol_setAttribute(EN_US_, UCOL_ALTERNATE_HANDLING,
1950 UCOL_NON_IGNORABLE, &status);
1951 close();
1952 }
1953
TestOverlapCanonical(void)1954 static void TestOverlapCanonical(void)
1955 {
1956 int count = 0;
1957 UErrorCode status = U_ZERO_ERROR;
1958 open(&status);
1959 if (U_FAILURE(status)) {
1960 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
1961 return;
1962 }
1963 while (OVERLAPCANONICAL[count].text != NULL) {
1964 if (!assertEqualWithAttribute(OVERLAPCANONICAL[count], USEARCH_ON,
1965 USEARCH_ON)) {
1966 log_err("Error at overlap test number %d\n", count);
1967 }
1968 count ++;
1969 }
1970 count = 0;
1971 while (NONOVERLAP[count].text != NULL) {
1972 if (!assertCanonicalEqual(NONOVERLAPCANONICAL[count])) {
1973 log_err("Error at non overlap test number %d\n", count);
1974 }
1975 count ++;
1976 }
1977
1978 count = 0;
1979 while (count < 1) {
1980 UChar pattern[32];
1981 UChar text[128];
1982 const SearchData *search = &(OVERLAPCANONICAL[count]);
1983 UCollator *collator = getCollator(search->collator);
1984 UStringSearch *strsrch;
1985 status = U_ZERO_ERROR;
1986
1987 u_unescape(search->text, text, 128);
1988 u_unescape(search->pattern, pattern, 32);
1989 strsrch = usearch_openFromCollator(pattern, -1, text, -1, collator,
1990 NULL, &status);
1991 if(status == U_FILE_ACCESS_ERROR) {
1992 log_data_err("Is your data around?\n");
1993 return;
1994 } else if(U_FAILURE(status)) {
1995 log_err("Error opening searcher\n");
1996 return;
1997 }
1998 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
1999 &status);
2000 usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_ON, &status);
2001 if (U_FAILURE(status) ||
2002 usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_ON) {
2003 log_err("Error setting overlap option\n");
2004 }
2005 if (!assertEqualWithUStringSearch(strsrch, *search)) {
2006 usearch_close(strsrch);
2007 return;
2008 }
2009 search = &(NONOVERLAPCANONICAL[count]);
2010 usearch_setAttribute(strsrch, USEARCH_OVERLAP, USEARCH_OFF, &status);
2011 if (U_FAILURE(status) ||
2012 usearch_getAttribute(strsrch, USEARCH_OVERLAP) != USEARCH_OFF) {
2013 log_err("Error setting overlap option\n");
2014 }
2015 usearch_reset(strsrch);
2016 if (!assertEqualWithUStringSearch(strsrch, *search)) {
2017 usearch_close(strsrch);
2018 log_err("Error at test number %d\n", count);
2019 }
2020
2021 count ++;
2022 usearch_close(strsrch);
2023 }
2024 close();
2025 }
2026
TestCollatorCanonical(void)2027 static void TestCollatorCanonical(void)
2028 {
2029 /* test collator that thinks "o" and "p" are the same thing */
2030 UChar rules[32];
2031 UCollator *tailored = NULL;
2032 UErrorCode status = U_ZERO_ERROR;
2033 UChar pattern[32];
2034 UChar text[128];
2035 UStringSearch *strsrch;
2036
2037 open(&status);
2038 if (U_FAILURE(status)) {
2039 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
2040 return;
2041 }
2042 u_unescape(COLLATORCANONICAL[0].text, text, 128);
2043 u_unescape(COLLATORCANONICAL[0].pattern, pattern, 32);
2044
2045 strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
2046 NULL, &status);
2047 if(status == U_FILE_ACCESS_ERROR) {
2048 log_data_err("Is your data around?\n");
2049 return;
2050 } else if(U_FAILURE(status)) {
2051 log_err("Error opening searcher\n");
2052 return;
2053 }
2054 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2055 &status);
2056 if (U_FAILURE(status)) {
2057 log_err("Error opening string search %s\n", u_errorName(status));
2058 }
2059 if (!assertEqualWithUStringSearch(strsrch, COLLATORCANONICAL[0])) {
2060 goto ENDTESTCOLLATOR;
2061 }
2062
2063 u_unescape(TESTCOLLATORRULE, rules, 32);
2064 tailored = ucol_openRules(rules, -1, UCOL_ON,
2065 COLLATORCANONICAL[1].strength, NULL, &status);
2066 if (U_FAILURE(status)) {
2067 log_err("Error opening rule based collator %s\n", u_errorName(status));
2068 }
2069
2070 usearch_setCollator(strsrch, tailored, &status);
2071 if (U_FAILURE(status) || usearch_getCollator(strsrch) != tailored) {
2072 log_err("Error setting rule based collator\n");
2073 }
2074 usearch_reset(strsrch);
2075 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2076 &status);
2077 if (!assertEqualWithUStringSearch(strsrch, COLLATORCANONICAL[1])) {
2078 goto ENDTESTCOLLATOR;
2079 }
2080
2081 usearch_setCollator(strsrch, EN_US_, &status);
2082 usearch_reset(strsrch);
2083 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2084 &status);
2085 if (U_FAILURE(status) || usearch_getCollator(strsrch) != EN_US_) {
2086 log_err("Error setting rule based collator\n");
2087 }
2088 if (!assertEqualWithUStringSearch(strsrch, COLLATORCANONICAL[0])) {
2089 goto ENDTESTCOLLATOR;
2090 }
2091
2092 ENDTESTCOLLATOR:
2093 usearch_close(strsrch);
2094 if (tailored != NULL) {
2095 ucol_close(tailored);
2096 }
2097 close();
2098 }
2099
TestPatternCanonical(void)2100 static void TestPatternCanonical(void)
2101 {
2102 UStringSearch *strsrch;
2103 UChar pattern[32];
2104 UChar text[128];
2105 const UChar *temp;
2106 int32_t templength;
2107 UErrorCode status = U_ZERO_ERROR;
2108
2109 open(&status);
2110 if (U_FAILURE(status)) {
2111 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
2112 return;
2113 }
2114 u_unescape(PATTERNCANONICAL[0].text, text, 128);
2115 u_unescape(PATTERNCANONICAL[0].pattern, pattern, 32);
2116
2117 ucol_setStrength(EN_US_, PATTERNCANONICAL[0].strength);
2118 strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
2119 NULL, &status);
2120 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2121 &status);
2122 if (U_FAILURE(status)) {
2123 log_err("Error opening string search %s\n", u_errorName(status));
2124 goto ENDTESTPATTERN;
2125 }
2126 temp = usearch_getPattern(strsrch, &templength);
2127 if (u_strcmp(pattern, temp) != 0) {
2128 log_err("Error setting pattern\n");
2129 }
2130 if (!assertEqualWithUStringSearch(strsrch, PATTERNCANONICAL[0])) {
2131 goto ENDTESTPATTERN;
2132 }
2133
2134 u_unescape(PATTERNCANONICAL[1].pattern, pattern, 32);
2135 usearch_setPattern(strsrch, pattern, -1, &status);
2136 temp = usearch_getPattern(strsrch, &templength);
2137 if (u_strcmp(pattern, temp) != 0) {
2138 log_err("Error setting pattern\n");
2139 goto ENDTESTPATTERN;
2140 }
2141 usearch_reset(strsrch);
2142 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2143 &status);
2144 if (U_FAILURE(status)) {
2145 log_err("Error setting pattern %s\n", u_errorName(status));
2146 }
2147 if (!assertEqualWithUStringSearch(strsrch, PATTERNCANONICAL[1])) {
2148 goto ENDTESTPATTERN;
2149 }
2150
2151 u_unescape(PATTERNCANONICAL[0].pattern, pattern, 32);
2152 usearch_setPattern(strsrch, pattern, -1, &status);
2153 temp = usearch_getPattern(strsrch, &templength);
2154 if (u_strcmp(pattern, temp) != 0) {
2155 log_err("Error setting pattern\n");
2156 goto ENDTESTPATTERN;
2157 }
2158 usearch_reset(strsrch);
2159 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2160 &status);
2161 if (U_FAILURE(status)) {
2162 log_err("Error setting pattern %s\n", u_errorName(status));
2163 }
2164 if (!assertEqualWithUStringSearch(strsrch, PATTERNCANONICAL[0])) {
2165 goto ENDTESTPATTERN;
2166 }
2167 ENDTESTPATTERN:
2168 ucol_setStrength(EN_US_, UCOL_TERTIARY);
2169 if (strsrch != NULL) {
2170 usearch_close(strsrch);
2171 }
2172 close();
2173 }
2174
TestTextCanonical(void)2175 static void TestTextCanonical(void)
2176 {
2177 UStringSearch *strsrch;
2178 UChar pattern[32];
2179 UChar text[128];
2180 const UChar *temp;
2181 int32_t templength;
2182 UErrorCode status = U_ZERO_ERROR;
2183
2184 u_unescape(TEXTCANONICAL[0].text, text, 128);
2185 u_unescape(TEXTCANONICAL[0].pattern, pattern, 32);
2186
2187 open(&status);
2188 if (U_FAILURE(status)) {
2189 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
2190 return;
2191 }
2192 strsrch = usearch_openFromCollator(pattern, -1, text, -1, EN_US_,
2193 NULL, &status);
2194 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2195 &status);
2196
2197 if (U_FAILURE(status)) {
2198 log_err("Error opening string search %s\n", u_errorName(status));
2199 goto ENDTESTPATTERN;
2200 }
2201 temp = usearch_getText(strsrch, &templength);
2202 if (u_strcmp(text, temp) != 0) {
2203 log_err("Error setting text\n");
2204 }
2205 if (!assertEqualWithUStringSearch(strsrch, TEXTCANONICAL[0])) {
2206 goto ENDTESTPATTERN;
2207 }
2208
2209 u_unescape(TEXTCANONICAL[1].text, text, 32);
2210 usearch_setText(strsrch, text, -1, &status);
2211 temp = usearch_getText(strsrch, &templength);
2212 if (u_strcmp(text, temp) != 0) {
2213 log_err("Error setting text\n");
2214 goto ENDTESTPATTERN;
2215 }
2216 if (U_FAILURE(status)) {
2217 log_err("Error setting text %s\n", u_errorName(status));
2218 }
2219 if (!assertEqualWithUStringSearch(strsrch, TEXTCANONICAL[1])) {
2220 goto ENDTESTPATTERN;
2221 }
2222
2223 u_unescape(TEXTCANONICAL[0].text, text, 32);
2224 usearch_setText(strsrch, text, -1, &status);
2225 temp = usearch_getText(strsrch, &templength);
2226 if (u_strcmp(text, temp) != 0) {
2227 log_err("Error setting text\n");
2228 goto ENDTESTPATTERN;
2229 }
2230 if (U_FAILURE(status)) {
2231 log_err("Error setting pattern %s\n", u_errorName(status));
2232 }
2233 if (!assertEqualWithUStringSearch(strsrch, TEXTCANONICAL[0])) {
2234 goto ENDTESTPATTERN;
2235 }
2236 ENDTESTPATTERN:
2237 if (strsrch != NULL) {
2238 usearch_close(strsrch);
2239 }
2240 close();
2241 }
2242
TestCompositeBoundariesCanonical(void)2243 static void TestCompositeBoundariesCanonical(void)
2244 {
2245 int count = 0;
2246 UErrorCode status = U_ZERO_ERROR;
2247 open(&status);
2248 if (U_FAILURE(status)) {
2249 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
2250 return;
2251 }
2252 while (COMPOSITEBOUNDARIESCANONICAL[count].text != NULL) {
2253 log_verbose("composite %d\n", count);
2254 if (!assertCanonicalEqual(COMPOSITEBOUNDARIESCANONICAL[count])) {
2255 log_err("Error at test number %d\n", count);
2256 }
2257 count ++;
2258 }
2259 close();
2260 }
2261
TestGetSetOffsetCanonical(void)2262 static void TestGetSetOffsetCanonical(void)
2263 {
2264 int searchDataIndex = 0;
2265 UChar pattern[32];
2266 UChar text[128];
2267 UErrorCode status = U_ZERO_ERROR;
2268 UStringSearch *strsrch;
2269 UCollator *collator;
2270
2271 memset(pattern, 0, 32*sizeof(UChar));
2272 memset(text, 0, 128*sizeof(UChar));
2273
2274 open(&status);
2275 if (U_FAILURE(status)) {
2276 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
2277 return;
2278 }
2279 strsrch = usearch_openFromCollator(pattern, 16, text, 32, EN_US_, NULL,
2280 &status);
2281
2282 collator = usearch_getCollator(strsrch);
2283 ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
2284
2285 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2286 &status);
2287
2288 /* testing out of bounds error */
2289 usearch_setOffset(strsrch, -1, &status);
2290 if (U_SUCCESS(status)) {
2291 log_err("Error expecting set offset error\n");
2292 }
2293 usearch_setOffset(strsrch, 128, &status);
2294 if (U_SUCCESS(status)) {
2295 log_err("Error expecting set offset error\n");
2296 }
2297 while (BASICCANONICAL[searchDataIndex].text != NULL) {
2298 int count = 0;
2299 SearchData search = BASICCANONICAL[searchDataIndex ++];
2300 int32_t matchindex = search.offset[count];
2301 int32_t textlength;
2302
2303 if (BASICCANONICAL[searchDataIndex].text == NULL) {
2304 /* skip the last one */
2305 break;
2306 }
2307
2308 u_unescape(search.text, text, 128);
2309 u_unescape(search.pattern, pattern, 32);
2310 status = U_ZERO_ERROR;
2311 usearch_setText(strsrch, text, -1, &status);
2312 usearch_setPattern(strsrch, pattern, -1, &status);
2313 while (U_SUCCESS(status) && matchindex >= 0) {
2314 uint32_t matchlength = search.size[count];
2315 usearch_next(strsrch, &status);
2316 if (matchindex != usearch_getMatchedStart(strsrch) ||
2317 matchlength != (uint32_t)usearch_getMatchedLength(strsrch)) {
2318 char *str = toCharString(usearch_getText(strsrch,
2319 &textlength));
2320 log_err("Text: %s\n", str);
2321 str = toCharString(usearch_getPattern(strsrch, &textlength));
2322 log_err("Pattern: %s\n", str);
2323 log_err("Error match found at %d %d\n",
2324 usearch_getMatchedStart(strsrch),
2325 usearch_getMatchedLength(strsrch));
2326 goto bail;
2327 }
2328 matchindex = search.offset[count + 1] == -1 ? -1 :
2329 search.offset[count + 2];
2330 if (search.offset[count + 1] != -1) {
2331 usearch_setOffset(strsrch, search.offset[count + 1] + 1,
2332 &status);
2333 if (usearch_getOffset(strsrch) != search.offset[count + 1] + 1) {
2334 log_err("Error setting offset\n");
2335 goto bail;
2336 }
2337 }
2338
2339 count += 2;
2340 }
2341 usearch_next(strsrch, &status);
2342 if (usearch_getMatchedStart(strsrch) != USEARCH_DONE) {
2343 char *str = toCharString(usearch_getText(strsrch, &textlength));
2344 log_err("Text: %s\n", str);
2345 str = toCharString(usearch_getPattern(strsrch, &textlength));
2346 log_err("Pattern: %s\n", str);
2347 log_err("Error match found at %d %d\n",
2348 usearch_getMatchedStart(strsrch),
2349 usearch_getMatchedLength(strsrch));
2350 goto bail;
2351 }
2352 }
2353
2354 bail:
2355 ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
2356 usearch_close(strsrch);
2357 close();
2358 }
2359
TestSupplementaryCanonical(void)2360 static void TestSupplementaryCanonical(void)
2361 {
2362 int count = 0;
2363 UErrorCode status = U_ZERO_ERROR;
2364 open(&status);
2365 if (U_FAILURE(status)) {
2366 log_err_status(status, "Unable to open static collators %s\n", u_errorName(status));
2367 return;
2368 }
2369 while (SUPPLEMENTARYCANONICAL[count].text != NULL) {
2370 if (!assertCanonicalEqual(SUPPLEMENTARYCANONICAL[count])) {
2371 log_err("Error at test number %d\n", count);
2372 }
2373 count ++;
2374 }
2375 close();
2376 }
2377
TestContractionCanonical(void)2378 static void TestContractionCanonical(void)
2379 {
2380 UChar rules[128];
2381 UChar pattern[128];
2382 UChar text[128];
2383 UCollator *collator = NULL;
2384 UErrorCode status = U_ZERO_ERROR;
2385 int count = 0;
2386 UStringSearch *strsrch = NULL;
2387 memset(rules, 0, 128*sizeof(UChar));
2388 memset(pattern, 0, 128*sizeof(UChar));
2389 memset(text, 0, 128*sizeof(UChar));
2390
2391 u_unescape(CONTRACTIONRULE, rules, 128);
2392 collator = ucol_openRules(rules, u_strlen(rules), UCOL_ON,
2393 UCOL_TERTIARY, NULL, &status);
2394 if(status == U_FILE_ACCESS_ERROR) {
2395 log_data_err("Is your data around?\n");
2396 return;
2397 } else if(U_FAILURE(status)) {
2398 log_err("Error opening collator %s\n", u_errorName(status));
2399 return;
2400 }
2401 strsrch = usearch_openFromCollator(pattern, 1, text, 1, collator, NULL,
2402 &status);
2403 usearch_setAttribute(strsrch, USEARCH_CANONICAL_MATCH, USEARCH_ON,
2404 &status);
2405 if (U_FAILURE(status)) {
2406 log_err("Error opening string search %s\n", u_errorName(status));
2407 }
2408
2409 while (CONTRACTIONCANONICAL[count].text != NULL) {
2410 u_unescape(CONTRACTIONCANONICAL[count].text, text, 128);
2411 u_unescape(CONTRACTIONCANONICAL[count].pattern, pattern, 128);
2412 usearch_setText(strsrch, text, -1, &status);
2413 usearch_setPattern(strsrch, pattern, -1, &status);
2414 if (!assertEqualWithUStringSearch(strsrch,
2415 CONTRACTIONCANONICAL[count])) {
2416 log_err("Error at test number %d\n", count);
2417 }
2418 count ++;
2419 }
2420 usearch_close(strsrch);
2421 ucol_close(collator);
2422 }
2423
TestNumeric(void)2424 static void TestNumeric(void) {
2425 UCollator *coll = NULL;
2426 UStringSearch *strsrch = NULL;
2427 UErrorCode status = U_ZERO_ERROR;
2428
2429 UChar pattern[128];
2430 UChar text[128];
2431 memset(pattern, 0, 128*sizeof(UChar));
2432 memset(text, 0, 128*sizeof(UChar));
2433
2434 coll = ucol_open("", &status);
2435 if(U_FAILURE(status)) {
2436 log_data_err("Could not open UCA. Is your data around?\n");
2437 return;
2438 }
2439
2440 ucol_setAttribute(coll, UCOL_NUMERIC_COLLATION, UCOL_ON, &status);
2441
2442 strsrch = usearch_openFromCollator(pattern, 1, text, 1, coll, NULL, &status);
2443
2444 if(status != U_UNSUPPORTED_ERROR || U_SUCCESS(status)) {
2445 log_err("Expected U_UNSUPPORTED_ERROR when trying to instantiate a search object from a CODAN collator, got %s instead\n", u_errorName(status));
2446 if(strsrch) {
2447 usearch_close(strsrch);
2448 }
2449 }
2450
2451 ucol_close(coll);
2452
2453 }
2454
2455 /* This test is for ticket 4038 due to incorrect backward searching when certain patterns have a length > 1 */
TestForwardBackward(void)2456 static void TestForwardBackward(void) {
2457 UErrorCode status = U_ZERO_ERROR;
2458 UCollator *coll = NULL;
2459 UStringSearch *search = NULL;
2460 UChar usrcstr[32], value[4];
2461 int32_t pos= -1;
2462 int32_t expectedPos = 9;
2463
2464 coll = ucol_open("en_GB", &status);
2465 if (U_FAILURE(status)) {
2466 log_err_status(status, "ucol_open failed: %s\n", u_errorName(status));
2467 goto exitTestForwardBackward;
2468 }
2469 ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_PRIMARY, &status);
2470 ucol_setAttribute(coll, UCOL_CASE_LEVEL, UCOL_ON, &status);
2471 ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status);
2472
2473 u_uastrcpy(usrcstr, "QBitArray::bitarr_data"); /* text */
2474 u_uastrcpy(value, "::"); /* pattern */
2475
2476 search = usearch_openFromCollator(value, 2, usrcstr, 22, coll, NULL, &status);
2477 if (U_FAILURE(status)) {
2478 log_err("usearch_openFromCollator failed: %s\n", u_errorName(status));
2479 goto exitTestForwardBackward;
2480 }
2481
2482 usearch_reset(search);
2483 /* forward search */
2484 pos = usearch_first(search, &status);
2485 if (pos != expectedPos) {
2486 log_err("Expected search result: %d; Got instead: %d\n", expectedPos, pos);
2487 goto exitTestForwardBackward;
2488 }
2489
2490 pos = -1;
2491 usearch_reset(search);
2492 /* backward search */
2493 pos = usearch_last(search, &status);
2494 if (pos != expectedPos) {
2495 log_err("Expected search result: %d; Got instead: %d\n", expectedPos, pos);
2496 }
2497
2498 exitTestForwardBackward :
2499 if (coll != NULL) {
2500 ucol_close(coll);
2501 }
2502 if (search != NULL) {
2503 usearch_close(search);
2504 }
2505 }
2506
2507 #define TEST_ASSERT(x) \
2508 {if (U_FAILURE(x)) {log_err_status(x, "%s:%d: FAIL: test assertion failure \n", __FILE__, __LINE__);\
2509 }}
2510
TestSearchForNull(void)2511 static void TestSearchForNull(void) {
2512 UCollator *coll;
2513 UErrorCode ec;
2514 UStringSearch *search;
2515 int pos;
2516 int len;
2517 int expectedPos;
2518 int expectedLen;
2519 int expectedNum;
2520 int count = 0;
2521 const UChar zerodigit = 0x0030; /* 0 */
2522 const UChar nulldigit = 0x0000; /* null */
2523
2524 /* static const UChar var[(length)+1]=U_DECLARE_UTF16(cs) */
2525 #define PATTERN_LEN 4
2526 #define TEXT_LEN 10
2527
2528 U_STRING_DECL(_pattern, "IS 0", PATTERN_LEN);
2529 U_STRING_DECL(_text, "_0IS 0 OK?", TEXT_LEN);
2530 UChar pattern[PATTERN_LEN + 1], text[TEXT_LEN + 1];
2531
2532 U_STRING_INIT(_pattern, "IS 0", PATTERN_LEN);
2533 U_STRING_INIT(_text, "_0IS 0 OK?", TEXT_LEN);
2534 expectedPos = 2;
2535 expectedLen = 4;
2536 expectedNum = 1;
2537
2538 for (pos = 0; pos < PATTERN_LEN; pos++) {
2539 if (_pattern[pos] == zerodigit) {
2540 pattern[pos] = nulldigit;
2541 } else {
2542 pattern[pos] = _pattern[pos];
2543 }
2544 }
2545 pattern[PATTERN_LEN] = 0x0000;
2546
2547 for (pos = 0; pos < TEXT_LEN; pos++) {
2548 if (_text[pos] == zerodigit) {
2549 text[pos] = nulldigit;
2550 } else {
2551 text[pos] = _text[pos];
2552 }
2553 }
2554 text[TEXT_LEN] = 0x0000;
2555
2556 ec = U_ZERO_ERROR;
2557
2558 /* create a US-English collator */
2559 coll = ucol_open("en_US", &ec);
2560
2561 /* make sure we didn't fail. */
2562 TEST_ASSERT (ec);
2563
2564 ucol_setStrength(coll, UCOL_IDENTICAL);
2565
2566 /* open a search looking for 0 */
2567 search = usearch_openFromCollator(pattern, PATTERN_LEN, text,
2568 TEXT_LEN, coll, NULL, &ec);
2569 TEST_ASSERT (ec);
2570
2571 if (coll != NULL && search != NULL) {
2572 pos = usearch_first(search, &ec);
2573 len = usearch_getMatchedLength(search);
2574 if (pos != expectedPos) {
2575 log_err("Expected search result: %d; Got instead: %d\n", expectedPos,
2576 pos);
2577 }
2578
2579 if (len != expectedLen) {
2580 log_err("Expected search result length: %d; Got instead: %d\n",
2581 expectedLen, len);
2582 }
2583
2584 for (pos = usearch_first(search, &ec); pos != USEARCH_DONE; pos
2585 = usearch_next(search, &ec)) {
2586 log_verbose("Match at %d\n", pos);
2587 count += 1;
2588 }
2589
2590 if (count != expectedNum) {
2591 log_err("Expected %d search hits, found %d\n", expectedNum, count);
2592 }
2593 }
2594
2595 ucol_close(coll);
2596 usearch_close(search);
2597 }
2598
TestStrengthIdentical(void)2599 static void TestStrengthIdentical(void)
2600 {
2601 UCollator *coll;
2602 UErrorCode ec = U_ZERO_ERROR;
2603 UStringSearch *search;
2604
2605 UChar pattern[] = {0x05E9, 0x0591, 0x05E9};
2606 UChar text[] = {0x05E9, 0x0592, 0x05E9};
2607 int32_t pLen = sizeof (pattern) / sizeof(pattern[0]);
2608 int32_t tLen = sizeof(text) / sizeof (text[0]);
2609 int32_t expectedPos = 0;
2610 int32_t expectedLen = 3;
2611
2612 int32_t pos;
2613 int32_t len;
2614
2615 /* create a US-English collator */
2616 coll = ucol_open ("en_US", &ec);
2617
2618 /* make sure we didn't fail. */
2619 TEST_ASSERT (ec);
2620
2621 ucol_setStrength( coll, UCOL_TERTIARY);
2622
2623 /* open a search looking for 0 */
2624 search = usearch_openFromCollator (pattern, pLen, text, tLen, coll, NULL, &ec);
2625 TEST_ASSERT (ec);
2626
2627 if (coll != NULL && search != NULL) {
2628 pos = usearch_first(search, &ec);
2629 len = usearch_getMatchedLength(search);
2630
2631 if(pos != expectedPos) {
2632 log_err("Expected search result: %d; Got instead: %d\n", expectedPos, pos);
2633 }
2634
2635 if(len != expectedLen) {
2636 log_err("Expected search result length: %d; Got instead: %d\n", expectedLen, len);
2637 }
2638
2639 /* Now try it at strength == UCOL_IDENTICAL */
2640 ucol_setStrength(coll, UCOL_IDENTICAL);
2641 usearch_reset(search);
2642
2643 pos = usearch_first(search, &ec);
2644 len = usearch_getMatchedLength(search);
2645
2646 if(pos != -1) {
2647 log_err("Expected failure for strentgh = UCOL_IDENTICAL: got %d instead.\n", pos);
2648 }
2649 }
2650
2651 usearch_close(search);
2652 ucol_close(coll);
2653 }
2654
2655 /**
2656 * TestUsingSearchCollator
2657 */
2658
2659 #define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
2660
2661 typedef struct {
2662 const UChar * pattern;
2663 const int32_t * offsets;
2664 int32_t offsetsLen;
2665 } PatternAndOffsets;
2666
2667 static const UChar scKoText[] = {
2668 0x0020,
2669 /*01*/ 0xAC00, 0x0020, /* simple LV Hangul */
2670 /*03*/ 0xAC01, 0x0020, /* simple LVT Hangul */
2671 /*05*/ 0xAC0F, 0x0020, /* LVTT, last jamo expands for search */
2672 /*07*/ 0xAFFF, 0x0020, /* LLVVVTT, every jamo expands for search */
2673 /*09*/ 0x1100, 0x1161, 0x11A8, 0x0020, /* 0xAC01 as conjoining jamo */
2674 /*13*/ 0x1100, 0x1161, 0x1100, 0x0020, /* 0xAC01 as basic conjoining jamo (per search rules) */
2675 /*17*/ 0x3131, 0x314F, 0x3131, 0x0020, /* 0xAC01 as compatibility jamo */
2676 /*21*/ 0x1100, 0x1161, 0x11B6, 0x0020, /* 0xAC0F as conjoining jamo; last expands for search */
2677 /*25*/ 0x1100, 0x1161, 0x1105, 0x1112, 0x0020, /* 0xAC0F as basic conjoining jamo; last expands for search */
2678 /*30*/ 0x1101, 0x1170, 0x11B6, 0x0020, /* 0xAFFF as conjoining jamo; all expand for search */
2679 /*34*/ 0x00E6, 0x0020, /* small letter ae, expands */
2680 /*36*/ 0x1E4D, 0x0020, /* small letter o with tilde and acute, decomposes */
2681 0
2682 };
2683
2684 static const UChar scKoPat0[] = { 0xAC01, 0 };
2685 static const UChar scKoPat1[] = { 0x1100, 0x1161, 0x11A8, 0 }; /* 0xAC01 as conjoining jamo */
2686 static const UChar scKoPat2[] = { 0xAC0F, 0 };
2687 static const UChar scKoPat3[] = { 0x1100, 0x1161, 0x1105, 0x1112, 0 }; /* 0xAC0F as basic conjoining jamo */
2688 static const UChar scKoPat4[] = { 0xAFFF, 0 };
2689 static const UChar scKoPat5[] = { 0x1101, 0x1170, 0x11B6, 0 }; /* 0xAFFF as conjoining jamo */
2690
2691 static const int32_t scKoSrchOff01[] = { 3, 9, 13 };
2692 static const int32_t scKoSrchOff23[] = { 5, 21, 25 };
2693 static const int32_t scKoSrchOff45[] = { 7, 30 };
2694
2695 static const PatternAndOffsets scKoSrchPatternsOffsets[] = {
2696 { scKoPat0, scKoSrchOff01, ARRAY_LENGTH(scKoSrchOff01) },
2697 { scKoPat1, scKoSrchOff01, ARRAY_LENGTH(scKoSrchOff01) },
2698 { scKoPat2, scKoSrchOff23, ARRAY_LENGTH(scKoSrchOff23) },
2699 { scKoPat3, scKoSrchOff23, ARRAY_LENGTH(scKoSrchOff23) },
2700 { scKoPat4, scKoSrchOff45, ARRAY_LENGTH(scKoSrchOff45) },
2701 { scKoPat5, scKoSrchOff45, ARRAY_LENGTH(scKoSrchOff45) },
2702 { NULL, NULL, 0 }
2703 };
2704
2705 static const int32_t scKoStndOff01[] = { 3, 9 };
2706 static const int32_t scKoStndOff2[] = { 5, 21 };
2707 static const int32_t scKoStndOff3[] = { 25 };
2708 static const int32_t scKoStndOff45[] = { 7, 30 };
2709
2710 static const PatternAndOffsets scKoStndPatternsOffsets[] = {
2711 { scKoPat0, scKoStndOff01, ARRAY_LENGTH(scKoStndOff01) },
2712 { scKoPat1, scKoStndOff01, ARRAY_LENGTH(scKoStndOff01) },
2713 { scKoPat2, scKoStndOff2, ARRAY_LENGTH(scKoStndOff2) },
2714 { scKoPat3, scKoStndOff3, ARRAY_LENGTH(scKoStndOff3) },
2715 { scKoPat4, scKoStndOff45, ARRAY_LENGTH(scKoStndOff45) },
2716 { scKoPat5, scKoStndOff45, ARRAY_LENGTH(scKoStndOff45) },
2717 { NULL, NULL, 0 }
2718 };
2719
2720 typedef struct {
2721 const char * locale;
2722 const UChar * text;
2723 const PatternAndOffsets * patternsAndOffsets;
2724 } TUSCItem;
2725
2726 static const TUSCItem tuscItems[] = {
2727 { "root", scKoText, scKoStndPatternsOffsets },
2728 { "root@collation=search", scKoText, scKoSrchPatternsOffsets },
2729 { "ko@collation=search", scKoText, scKoSrchPatternsOffsets },
2730 { NULL, NULL, NULL }
2731 };
2732
2733 static const UChar dummyPat[] = { 0x0061, 0 };
2734
TestUsingSearchCollator(void)2735 static void TestUsingSearchCollator(void)
2736 {
2737 const TUSCItem * tuscItemPtr;
2738 for (tuscItemPtr = tuscItems; tuscItemPtr->locale != NULL; tuscItemPtr++) {
2739 UErrorCode status = U_ZERO_ERROR;
2740 UCollator* ucol = ucol_open(tuscItemPtr->locale, &status);
2741 if ( U_SUCCESS(status) ) {
2742 UStringSearch* usrch = usearch_openFromCollator(dummyPat, -1, tuscItemPtr->text, -1, ucol, NULL, &status);
2743 if ( U_SUCCESS(status) ) {
2744 const PatternAndOffsets * patternsOffsetsPtr;
2745 for ( patternsOffsetsPtr = tuscItemPtr->patternsAndOffsets; patternsOffsetsPtr->pattern != NULL; patternsOffsetsPtr++) {
2746 usearch_setPattern(usrch, patternsOffsetsPtr->pattern, -1, &status);
2747 if ( U_SUCCESS(status) ) {
2748 int32_t offset;
2749 const int32_t * nextOffsetPtr;
2750 const int32_t * limitOffsetPtr;
2751
2752 usearch_reset(usrch);
2753 nextOffsetPtr = patternsOffsetsPtr->offsets;
2754 limitOffsetPtr = patternsOffsetsPtr->offsets + patternsOffsetsPtr->offsetsLen;
2755 while (TRUE) {
2756 offset = usearch_next(usrch, &status);
2757 if ( U_FAILURE(status) || offset == USEARCH_DONE ) {
2758 break;
2759 }
2760 if ( nextOffsetPtr < limitOffsetPtr ) {
2761 if (offset != *nextOffsetPtr) {
2762 log_err("error, locale %s, expected usearch_next %d, got %d\n", tuscItemPtr->locale, *nextOffsetPtr, offset);
2763 nextOffsetPtr = limitOffsetPtr;
2764 break;
2765 }
2766 nextOffsetPtr++;
2767 } else {
2768 log_err("error, locale %s, usearch_next returned more matches than expected\n", tuscItemPtr->locale );
2769 }
2770 }
2771 if ( U_FAILURE(status) ) {
2772 log_err("error, locale %s, usearch_next failed: %s\n", tuscItemPtr->locale, u_errorName(status) );
2773 } else if ( nextOffsetPtr < limitOffsetPtr ) {
2774 log_err("error, locale %s, usearch_next returned fewer matches than expected\n", tuscItemPtr->locale );
2775 }
2776
2777 status = U_ZERO_ERROR;
2778 usearch_reset(usrch);
2779 nextOffsetPtr = patternsOffsetsPtr->offsets + patternsOffsetsPtr->offsetsLen;
2780 limitOffsetPtr = patternsOffsetsPtr->offsets;
2781 while (TRUE) {
2782 offset = usearch_previous(usrch, &status);
2783 if ( U_FAILURE(status) || offset == USEARCH_DONE ) {
2784 break;
2785 }
2786 if ( nextOffsetPtr > limitOffsetPtr ) {
2787 nextOffsetPtr--;
2788 if (offset != *nextOffsetPtr) {
2789 log_err("error, locale %s, expected usearch_previous %d, got %d\n", tuscItemPtr->locale, *nextOffsetPtr, offset);
2790 nextOffsetPtr = limitOffsetPtr;
2791 break;
2792 }
2793 } else {
2794 log_err("error, locale %s, usearch_previous returned more matches than expected\n", tuscItemPtr->locale );
2795 }
2796 }
2797 if ( U_FAILURE(status) ) {
2798 log_err("error, locale %s, usearch_previous failed: %s\n", tuscItemPtr->locale, u_errorName(status) );
2799 } else if ( nextOffsetPtr > limitOffsetPtr ) {
2800 log_err("error, locale %s, usearch_previous returned fewer matches than expected\n", tuscItemPtr->locale );
2801 }
2802
2803 } else {
2804 log_err("error, locale %s, usearch_setPattern failed: %s\n", tuscItemPtr->locale, u_errorName(status) );
2805 }
2806 }
2807 usearch_close(usrch);
2808 } else {
2809 log_err("error, locale %s, usearch_openFromCollator failed: %s\n", tuscItemPtr->locale, u_errorName(status) );
2810 }
2811 ucol_close(ucol);
2812 } else {
2813 log_data_err("error, locale %s, ucol_open failed: %s\n", tuscItemPtr->locale, u_errorName(status) );
2814 }
2815 }
2816 }
2817
2818
TestPCEBuffer_with(const UChar * search,uint32_t searchLen,const UChar * source,uint32_t sourceLen)2819 static void TestPCEBuffer_with(const UChar *search, uint32_t searchLen, const UChar *source, uint32_t sourceLen) {
2820 UErrorCode icuStatus = U_ZERO_ERROR;
2821 UCollator *coll;
2822 const char *locale;
2823 UBreakIterator *ubrk;
2824 UStringSearch *usearch;
2825 int32_t match = 0;
2826
2827
2828 coll = ucol_openFromShortString( "LSK_AS_CX_EX_FX_HX_NX_S4",
2829 FALSE,
2830 NULL,
2831 &icuStatus );
2832 if ( U_FAILURE(icuStatus) )
2833 {
2834 log_data_err( "ucol_openFromShortString error %s\n" , u_errorName(icuStatus));
2835 goto exit;
2836 }
2837
2838 locale = ucol_getLocaleByType( coll,
2839 ULOC_VALID_LOCALE,
2840 &icuStatus );
2841 if ( U_FAILURE(icuStatus) )
2842 {
2843 log_err( "ucol_getLocaleByType error %s\n", u_errorName(icuStatus) );
2844 goto exit;
2845 }
2846
2847 log_verbose("locale=%s\n", locale);
2848
2849 ubrk = ubrk_open( UBRK_CHARACTER,
2850 locale,
2851 source,
2852 sourceLen,
2853 &icuStatus );
2854 if ( U_FAILURE(icuStatus) )
2855 {
2856 log_err( "ubrk_open error %s\n", u_errorName(icuStatus) );
2857 goto exit;
2858 }
2859
2860 usearch = usearch_openFromCollator( search,
2861 searchLen,
2862 source,
2863 sourceLen,
2864 coll,
2865 ubrk,
2866 &icuStatus );
2867 if ( U_FAILURE(icuStatus) )
2868 {
2869 log_err( "usearch_openFromCollator error %s\n", u_errorName(icuStatus) );
2870 goto exit;
2871 }
2872
2873 match = usearch_first( usearch,
2874 &icuStatus );
2875 if ( U_FAILURE(icuStatus) )
2876 {
2877 log_err( "usearch_first error %s\n", u_errorName(icuStatus) );
2878 goto exit;
2879 }
2880
2881 if(match==0) {
2882 log_verbose("OK: match=%d\n", match);
2883 } else {
2884 log_err("Err: match expected 0 got %d\n", match);
2885 }
2886
2887 usearch_close(usearch);
2888 ubrk_close(ubrk);
2889 ucol_close(coll);
2890
2891 exit:
2892 return;
2893 }
2894
2895
TestPCEBuffer_100df(void)2896 static void TestPCEBuffer_100df(void) {
2897 UChar search[] =
2898 { 0x0020, 0x0020, 0x00df, 0x0020, 0x0041, 0x00df, 0x0020, 0x0061, 0x00df, 0x0020, 0x00c5, 0x00df, 0x0020, 0x212b, 0x00df, 0x0020, 0x0041, 0x030a, 0x00df, 0x0020, 0x00e5, 0x00df, 0x0020, 0x0061, 0x02da, 0x00df, 0x0020, 0x0061, 0x030a, 0x00df, 0x0020, 0xd8fa, 0xdeae, 0x00df, 0x0020, 0x2027, 0x00df }; /* 38 cp, 9 of them unpaired surrogates */
2899 UChar source[] =
2900 { 0x0020, 0x0020, 0x00df, 0x0020, 0x0041, 0x00df, 0x0020, 0x0061, 0x00df, 0x0020, 0x00c5, 0x00df, 0x0020, 0x212b, 0x00df, 0x0020, 0x0041, 0x030a, 0x00df, 0x0020, 0x00e5, 0x00df, 0x0020, 0x0061, 0x02da, 0x00df, 0x0020, 0x0061, 0x030a, 0x00df, 0x0020, 0xd8fa, 0xdeae, 0x00df, 0x0020, 0x2027, 0x00df };
2901 uint32_t searchLen = sizeof(search)/sizeof(UChar);
2902 uint32_t sourceLen = sizeof(source)/sizeof(UChar);
2903 TestPCEBuffer_with(search,searchLen,source,sourceLen);
2904 }
2905
2906
TestPCEBuffer_2surr(void)2907 static void TestPCEBuffer_2surr(void) {
2908 UChar search[] =
2909 { 0x0020, 0x0020, 0xdfff, 0x0020, 0x0041, 0xdfff, 0x0020, 0x0061, 0xdfff, 0x0020, 0x00c5, 0xdfff, 0x0020, 0x212b, 0xdfff, 0x0020, 0x0041, 0x030a, 0xdfff, 0x0020, 0x00e5, 0xdfff, 0x0020, 0x0061, 0x02da, 0xdfff, 0x0020, 0x0061, 0x030a, 0xdfff, 0x0020, 0xd8fa, 0xdeae, 0xdfff, 0x0020, 0x2027, 0xdfff }; /* 38 cp, 9 of them unpaired surrogates */
2910 UChar source[] =
2911 { 0x0020, 0x0020, 0xdfff, 0x0020, 0x0041, 0xdfff, 0x0020, 0x0061, 0xdfff, 0x0020, 0x00c5, 0xdfff, 0x0020, 0x212b, 0xdfff, 0x0020, 0x0041, 0x030a, 0xdfff, 0x0020, 0x00e5, 0xdfff, 0x0020, 0x0061, 0x02da, 0xdfff, 0x0020, 0x0061, 0x030a, 0xdfff, 0x0020, 0xd8fa, 0xdeae, 0xdfff, 0x0020, 0x2027, 0xdfff };
2912 uint32_t searchLen = sizeof(search)/sizeof(UChar);
2913 uint32_t sourceLen = sizeof(source)/sizeof(UChar);
2914 TestPCEBuffer_with(search,searchLen,source,sourceLen);
2915 }
2916
TestMatchFollowedByIgnorables(void)2917 static void TestMatchFollowedByIgnorables(void) {
2918 /* test case for ticket#8482 */
2919 UChar search[] = { 0x00c9 };
2920 UChar source[] = { 0x00c9, 0x0000, 0x0041 };
2921 int32_t searchLen;
2922 int32_t sourceLen;
2923 UErrorCode icuStatus = U_ZERO_ERROR;
2924 UCollator *coll;
2925 const char *locale;
2926 UBreakIterator *ubrk;
2927 UStringSearch *usearch;
2928 int32_t match = 0;
2929 int32_t matchLength = 0;
2930 const int32_t expectedMatchLength = 1;
2931
2932 searchLen = sizeof(search)/sizeof(UChar);
2933 sourceLen = sizeof(source)/sizeof(UChar);
2934
2935 coll = ucol_openFromShortString("LHR_AN_CX_EX_FX_HX_NX_S3",
2936 FALSE,
2937 NULL,
2938 &icuStatus);
2939 if (U_FAILURE(icuStatus)) {
2940 log_data_err("ucol_openFromShortString error - %s\n", u_errorName(icuStatus));
2941 }
2942
2943 locale = ucol_getLocaleByType(coll,
2944 ULOC_VALID_LOCALE,
2945 &icuStatus);
2946 if (U_FAILURE(icuStatus)) {
2947 log_data_err("ucol_getLocaleByType error - %s\n", u_errorName(icuStatus));
2948 }
2949
2950 ubrk = ubrk_open(UBRK_CHARACTER,
2951 locale,
2952 source,
2953 sourceLen,
2954 &icuStatus);
2955 if (U_FAILURE(icuStatus)) {
2956 log_data_err("ubrk_open error - %s\n", u_errorName(icuStatus));
2957 }
2958
2959 usearch = usearch_openFromCollator(search,
2960 searchLen,
2961 source,
2962 sourceLen,
2963 coll,
2964 ubrk,
2965 &icuStatus);
2966 if (U_FAILURE(icuStatus)) {
2967 log_data_err("usearch_openFromCollator error - %s\n", u_errorName(icuStatus));
2968 }
2969
2970 match = usearch_first(usearch,
2971 &icuStatus);
2972 if (U_FAILURE(icuStatus)) {
2973 log_data_err("usearch_first error - %s\n", u_errorName(icuStatus));
2974 } else {
2975
2976 log_verbose("match=%d\n", match);
2977
2978 matchLength = usearch_getMatchedLength(usearch);
2979
2980 if (matchLength != expectedMatchLength) {
2981 log_err("Error: matchLength=%d, expected=%d\n", matchLength, expectedMatchLength);
2982 }
2983 }
2984
2985 usearch_close(usearch);
2986 ubrk_close(ubrk);
2987 ucol_close(coll);
2988 }
2989
2990 /**
2991 * addSearchTest
2992 */
2993
addSearchTest(TestNode ** root)2994 void addSearchTest(TestNode** root)
2995 {
2996 addTest(root, &TestStart, "tscoll/usrchtst/TestStart");
2997 addTest(root, &TestOpenClose, "tscoll/usrchtst/TestOpenClose");
2998 addTest(root, &TestInitialization, "tscoll/usrchtst/TestInitialization");
2999 addTest(root, &TestBasic, "tscoll/usrchtst/TestBasic");
3000 addTest(root, &TestNormExact, "tscoll/usrchtst/TestNormExact");
3001 addTest(root, &TestStrength, "tscoll/usrchtst/TestStrength");
3002 addTest(root, &TestBreakIterator, "tscoll/usrchtst/TestBreakIterator");
3003 addTest(root, &TestVariable, "tscoll/usrchtst/TestVariable");
3004 addTest(root, &TestOverlap, "tscoll/usrchtst/TestOverlap");
3005 addTest(root, &TestCollator, "tscoll/usrchtst/TestCollator");
3006 addTest(root, &TestPattern, "tscoll/usrchtst/TestPattern");
3007 addTest(root, &TestText, "tscoll/usrchtst/TestText");
3008 addTest(root, &TestCompositeBoundaries,
3009 "tscoll/usrchtst/TestCompositeBoundaries");
3010 addTest(root, &TestGetSetOffset, "tscoll/usrchtst/TestGetSetOffset");
3011 addTest(root, &TestGetSetAttribute,
3012 "tscoll/usrchtst/TestGetSetAttribute");
3013 addTest(root, &TestGetMatch, "tscoll/usrchtst/TestGetMatch");
3014 addTest(root, &TestSetMatch, "tscoll/usrchtst/TestSetMatch");
3015 addTest(root, &TestReset, "tscoll/usrchtst/TestReset");
3016 addTest(root, &TestSupplementary, "tscoll/usrchtst/TestSupplementary");
3017 addTest(root, &TestContraction, "tscoll/usrchtst/TestContraction");
3018 addTest(root, &TestIgnorable, "tscoll/usrchtst/TestIgnorable");
3019 addTest(root, &TestCanonical, "tscoll/usrchtst/TestCanonical");
3020 addTest(root, &TestNormCanonical, "tscoll/usrchtst/TestNormCanonical");
3021 addTest(root, &TestStrengthCanonical,
3022 "tscoll/usrchtst/TestStrengthCanonical");
3023 addTest(root, &TestBreakIteratorCanonical,
3024 "tscoll/usrchtst/TestBreakIteratorCanonical");
3025 addTest(root, &TestVariableCanonical,
3026 "tscoll/usrchtst/TestVariableCanonical");
3027 addTest(root, &TestOverlapCanonical,
3028 "tscoll/usrchtst/TestOverlapCanonical");
3029 addTest(root, &TestCollatorCanonical,
3030 "tscoll/usrchtst/TestCollatorCanonical");
3031 addTest(root, &TestPatternCanonical,
3032 "tscoll/usrchtst/TestPatternCanonical");
3033 addTest(root, &TestTextCanonical, "tscoll/usrchtst/TestTextCanonical");
3034 addTest(root, &TestCompositeBoundariesCanonical,
3035 "tscoll/usrchtst/TestCompositeBoundariesCanonical");
3036 addTest(root, &TestGetSetOffsetCanonical,
3037 "tscoll/usrchtst/TestGetSetOffsetCanonical");
3038 addTest(root, &TestSupplementaryCanonical,
3039 "tscoll/usrchtst/TestSupplementaryCanonical");
3040 addTest(root, &TestContractionCanonical,
3041 "tscoll/usrchtst/TestContractionCanonical");
3042 addTest(root, &TestEnd, "tscoll/usrchtst/TestEnd");
3043 addTest(root, &TestNumeric, "tscoll/usrchtst/TestNumeric");
3044 addTest(root, &TestDiacriticMatch, "tscoll/usrchtst/TestDiacriticMatch");
3045 addTest(root, &TestForwardBackward, "tscoll/usrchtst/TestForwardBackward");
3046 addTest(root, &TestSearchForNull, "tscoll/usrchtst/TestSearchForNull");
3047 addTest(root, &TestStrengthIdentical, "tscoll/usrchtst/TestStrengthIdentical");
3048 addTest(root, &TestUsingSearchCollator, "tscoll/usrchtst/TestUsingSearchCollator");
3049 addTest(root, &TestPCEBuffer_100df, "tscoll/usrchtst/TestPCEBuffer/1_00df");
3050 addTest(root, &TestPCEBuffer_2surr, "tscoll/usrchtst/TestPCEBuffer/2_dfff");
3051 addTest(root, &TestMatchFollowedByIgnorables, "tscoll/usrchtst/TestMatchFollowedByIgnorables");
3052 }
3053
3054 #endif /* #if !UCONFIG_NO_COLLATION */
3055