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