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