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