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