1 /********************************************************************
3 * Copyright (c) 2004-2008, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6 /********************************************************************************
10 *********************************************************************************/
11 /*C API TEST FOR Regular Expressions */
13 * This is an API test for ICU regular expressions in C. It doesn't test very many cases, and doesn't
14 * try to test the full functionality. It just calls each function and verifies that it
15 * works on a basic level.
17 * More complete testing of regular expression functionality is done with the C++ tests.
20 #include "unicode/utypes.h"
22 #if !UCONFIG_NO_REGULAR_EXPRESSIONS
26 #include "unicode/uloc.h"
27 #include "unicode/uregex.h"
28 #include "unicode/ustring.h"
31 #define TEST_ASSERT_SUCCESS(status) {if (U_FAILURE(status)) { \
32 log_err("Failure at file %s, line %d, error = %s\n", __FILE__, __LINE__, u_errorName(status));}}
34 #define TEST_ASSERT(expr) {if ((expr)==FALSE) { \
35 log_err("Test Failure at file %s, line %d\n", __FILE__, __LINE__);}}
38 * TEST_SETUP and TEST_TEARDOWN
39 * macros to handle the boilerplate around setting up regex test cases.
40 * parameteres to setup:
41 * pattern: The regex pattern, a (char *) null terminated C string.
42 * testString: The string data, also a (char *) C string.
43 * flags: Regex flags to set when compiling the pattern
45 * Put arbitrary test code between SETUP and TEARDOWN.
46 * 're" is the compiled, ready-to-go regular expression.
48 #define TEST_SETUP(pattern, testString, flags) { \
49 UChar *srcString = NULL; \
50 status = U_ZERO_ERROR; \
51 re = uregex_openC(pattern, flags, NULL, &status); \
52 TEST_ASSERT_SUCCESS(status); \
53 srcString = (UChar *)malloc((strlen(testString)+2)*sizeof(UChar)); \
54 u_uastrncpy(srcString, testString, strlen(testString)+1); \
55 uregex_setText(re, srcString, -1, &status); \
56 TEST_ASSERT_SUCCESS(status); \
57 if (U_SUCCESS(status)) {
59 #define TEST_TEARDOWN \
61 TEST_ASSERT_SUCCESS(status); \
67 static void test_assert_string(const char *expected
, const UChar
*actual
, UBool nulTerm
, const char *file
, int line
) {
68 char buf_inside_macro
[120];
69 int32_t len
= (int32_t)strlen(expected
);
72 u_austrncpy(buf_inside_macro
, (actual
), len
+1);
73 buf_inside_macro
[len
+2] = 0;
74 success
= (strcmp((expected
), buf_inside_macro
) == 0);
76 u_austrncpy(buf_inside_macro
, (actual
), len
);
77 buf_inside_macro
[len
+1] = 0;
78 success
= (strncmp((expected
), buf_inside_macro
, len
) == 0);
80 if (success
== FALSE
) {
81 log_err("Failure at file %s, line %d, expected \"%s\", got \"%s\"\n",
82 file
, line
, (expected
), buf_inside_macro
);
86 #define TEST_ASSERT_STRING(expected, actual, nulTerm) test_assert_string(expected, actual, nulTerm, __FILE__, __LINE__)
92 static void TestRegexCAPI(void);
93 static void TestBug4315(void);
95 void addURegexTest(TestNode
** root
);
97 void addURegexTest(TestNode
** root
)
99 addTest(root
, &TestRegexCAPI
, "regex/TestRegexCAPI");
100 addTest(root
, &TestBug4315
, "regex/TestBug4315");
104 * Call back function and context struct used for testing
105 * regular expression user callbacks. This test is mostly the same as
106 * the corresponding C++ test in intltest.
108 typedef struct callBackContext
{
114 static UBool U_EXPORT2 U_CALLCONV
115 TestCallbackFn(const void *context
, int32_t steps
) {
116 callBackContext
*info
= (callBackContext
*)context
;
117 if (info
->lastSteps
+1 != steps
) {
118 log_err("incorrect steps in callback. Expected %d, got %d\n", info
->lastSteps
+1, steps
);
120 info
->lastSteps
= steps
;
122 return (info
->numCalls
< info
->maxCalls
);
126 * Regular Expression C API Tests
128 static void TestRegexCAPI(void) {
129 UErrorCode status
= U_ZERO_ERROR
;
130 URegularExpression
*re
;
134 memset(&minus1
, -1, sizeof(minus1
));
136 /* Mimimalist open/close */
137 u_uastrncpy(pat
, "abc*", sizeof(pat
)/2);
138 re
= uregex_open(pat
, -1, 0, 0, &status
);
139 if (U_FAILURE(status
)) {
140 log_err("Failed to open regular expression, line %d, error is \"%s\"\n", __LINE__
, u_errorName(status
));
145 /* Open with all flag values set */
146 status
= U_ZERO_ERROR
;
147 re
= uregex_open(pat
, -1,
148 UREGEX_CASE_INSENSITIVE
| UREGEX_COMMENTS
| UREGEX_DOTALL
| UREGEX_MULTILINE
| UREGEX_UWORD
,
150 TEST_ASSERT_SUCCESS(status
);
153 /* Open with an invalid flag */
154 status
= U_ZERO_ERROR
;
155 re
= uregex_open(pat
, -1, 0x40000000, 0, &status
);
156 TEST_ASSERT(status
== U_REGEX_INVALID_FLAG
);
159 /* openC with an invalid parameter */
160 status
= U_ZERO_ERROR
;
161 re
= uregex_openC(NULL
,
162 UREGEX_CASE_INSENSITIVE
| UREGEX_COMMENTS
| UREGEX_DOTALL
| UREGEX_MULTILINE
| UREGEX_UWORD
, 0, &status
);
163 TEST_ASSERT(status
== U_ILLEGAL_ARGUMENT_ERROR
&& re
== NULL
);
165 /* openC with an invalid parameter */
166 status
= U_USELESS_COLLATOR_ERROR
;
167 re
= uregex_openC(NULL
,
168 UREGEX_CASE_INSENSITIVE
| UREGEX_COMMENTS
| UREGEX_DOTALL
| UREGEX_MULTILINE
| UREGEX_UWORD
, 0, &status
);
169 TEST_ASSERT(status
== U_USELESS_COLLATOR_ERROR
&& re
== NULL
);
171 /* openC open from a C string */
175 status
= U_ZERO_ERROR
;
176 re
= uregex_openC("abc*", 0, 0, &status
);
177 TEST_ASSERT_SUCCESS(status
);
178 p
= uregex_pattern(re
, &len
, &status
);
179 TEST_ASSERT_SUCCESS(status
);
181 /* The TEST_ASSERT_SUCCESS above should change too... */
182 if(U_SUCCESS(status
)) {
183 u_uastrncpy(pat
, "abc*", sizeof(pat
)/2);
184 TEST_ASSERT(u_strcmp(pat
, p
) == 0);
185 TEST_ASSERT(len
==(int32_t)strlen("abc*"));
190 /* TODO: Open with ParseError parameter */
197 URegularExpression
*clone1
;
198 URegularExpression
*clone2
;
199 URegularExpression
*clone3
;
200 UChar testString1
[30];
201 UChar testString2
[30];
205 status
= U_ZERO_ERROR
;
206 re
= uregex_openC("abc*", 0, 0, &status
);
207 TEST_ASSERT_SUCCESS(status
);
208 clone1
= uregex_clone(re
, &status
);
209 TEST_ASSERT_SUCCESS(status
);
210 TEST_ASSERT(clone1
!= NULL
);
212 status
= U_ZERO_ERROR
;
213 clone2
= uregex_clone(re
, &status
);
214 TEST_ASSERT_SUCCESS(status
);
215 TEST_ASSERT(clone2
!= NULL
);
218 status
= U_ZERO_ERROR
;
219 clone3
= uregex_clone(clone2
, &status
);
220 TEST_ASSERT_SUCCESS(status
);
221 TEST_ASSERT(clone3
!= NULL
);
223 u_uastrncpy(testString1
, "abcccd", sizeof(pat
)/2);
224 u_uastrncpy(testString2
, "xxxabcccd", sizeof(pat
)/2);
226 status
= U_ZERO_ERROR
;
227 uregex_setText(clone1
, testString1
, -1, &status
);
228 TEST_ASSERT_SUCCESS(status
);
229 result
= uregex_lookingAt(clone1
, 0, &status
);
230 TEST_ASSERT_SUCCESS(status
);
231 TEST_ASSERT(result
==TRUE
);
233 status
= U_ZERO_ERROR
;
234 uregex_setText(clone2
, testString2
, -1, &status
);
235 TEST_ASSERT_SUCCESS(status
);
236 result
= uregex_lookingAt(clone2
, 0, &status
);
237 TEST_ASSERT_SUCCESS(status
);
238 TEST_ASSERT(result
==FALSE
);
239 result
= uregex_find(clone2
, 0, &status
);
240 TEST_ASSERT_SUCCESS(status
);
241 TEST_ASSERT(result
==TRUE
);
243 uregex_close(clone1
);
244 uregex_close(clone2
);
245 uregex_close(clone3
);
253 const UChar
*resultPat
;
255 u_uastrncpy(pat
, "hello", sizeof(pat
)/2);
256 status
= U_ZERO_ERROR
;
257 re
= uregex_open(pat
, -1, 0, NULL
, &status
);
258 resultPat
= uregex_pattern(re
, &resultLen
, &status
);
259 TEST_ASSERT_SUCCESS(status
);
261 /* The TEST_ASSERT_SUCCESS above should change too... */
262 if (U_SUCCESS(status
)) {
263 TEST_ASSERT(resultLen
== -1);
264 TEST_ASSERT(u_strcmp(resultPat
, pat
) == 0);
269 status
= U_ZERO_ERROR
;
270 re
= uregex_open(pat
, 3, 0, NULL
, &status
);
271 resultPat
= uregex_pattern(re
, &resultLen
, &status
);
272 TEST_ASSERT_SUCCESS(status
);
273 TEST_ASSERT_SUCCESS(status
);
275 /* The TEST_ASSERT_SUCCESS above should change too... */
276 if (U_SUCCESS(status
)) {
277 TEST_ASSERT(resultLen
== 3);
278 TEST_ASSERT(u_strncmp(resultPat
, pat
, 3) == 0);
279 TEST_ASSERT(u_strlen(resultPat
) == 3);
291 status
= U_ZERO_ERROR
;
292 re
= uregex_open(pat
, -1, 0, NULL
, &status
);
293 t
= uregex_flags(re
, &status
);
294 TEST_ASSERT_SUCCESS(status
);
298 status
= U_ZERO_ERROR
;
299 re
= uregex_open(pat
, -1, 0, NULL
, &status
);
300 t
= uregex_flags(re
, &status
);
301 TEST_ASSERT_SUCCESS(status
);
305 status
= U_ZERO_ERROR
;
306 re
= uregex_open(pat
, -1, UREGEX_CASE_INSENSITIVE
| UREGEX_DOTALL
, NULL
, &status
);
307 t
= uregex_flags(re
, &status
);
308 TEST_ASSERT_SUCCESS(status
);
309 TEST_ASSERT(t
== (UREGEX_CASE_INSENSITIVE
| UREGEX_DOTALL
));
314 * setText() and lookingAt()
321 u_uastrncpy(text1
, "abcccd", sizeof(text1
)/2);
322 u_uastrncpy(text2
, "abcccxd", sizeof(text2
)/2);
323 status
= U_ZERO_ERROR
;
324 u_uastrncpy(pat
, "abc*d", sizeof(pat
)/2);
325 re
= uregex_open(pat
, -1, 0, NULL
, &status
);
326 TEST_ASSERT_SUCCESS(status
);
328 /* Operation before doing a setText should fail... */
329 status
= U_ZERO_ERROR
;
330 uregex_lookingAt(re
, 0, &status
);
331 TEST_ASSERT( status
== U_REGEX_INVALID_STATE
);
333 status
= U_ZERO_ERROR
;
334 uregex_setText(re
, text1
, -1, &status
);
335 result
= uregex_lookingAt(re
, 0, &status
);
336 TEST_ASSERT(result
== TRUE
);
337 TEST_ASSERT_SUCCESS(status
);
339 status
= U_ZERO_ERROR
;
340 uregex_setText(re
, text2
, -1, &status
);
341 result
= uregex_lookingAt(re
, 0, &status
);
342 TEST_ASSERT(result
== FALSE
);
343 TEST_ASSERT_SUCCESS(status
);
345 status
= U_ZERO_ERROR
;
346 uregex_setText(re
, text1
, -1, &status
);
347 result
= uregex_lookingAt(re
, 0, &status
);
348 TEST_ASSERT(result
== TRUE
);
349 TEST_ASSERT_SUCCESS(status
);
351 status
= U_ZERO_ERROR
;
352 uregex_setText(re
, text1
, 5, &status
);
353 result
= uregex_lookingAt(re
, 0, &status
);
354 TEST_ASSERT(result
== FALSE
);
355 TEST_ASSERT_SUCCESS(status
);
357 status
= U_ZERO_ERROR
;
358 uregex_setText(re
, text1
, 6, &status
);
359 result
= uregex_lookingAt(re
, 0, &status
);
360 TEST_ASSERT(result
== TRUE
);
361 TEST_ASSERT_SUCCESS(status
);
376 u_uastrncpy(text1
, "abcccd", sizeof(text1
)/2);
377 u_uastrncpy(text2
, "abcccxd", sizeof(text2
)/2);
378 status
= U_ZERO_ERROR
;
379 u_uastrncpy(pat
, "abc*d", sizeof(pat
)/2);
380 re
= uregex_open(pat
, -1, 0, NULL
, &status
);
382 uregex_setText(re
, text1
, -1, &status
);
383 result
= uregex_getText(re
, &textLength
, &status
);
384 TEST_ASSERT(result
== text1
);
385 TEST_ASSERT(textLength
== -1);
386 TEST_ASSERT_SUCCESS(status
);
388 status
= U_ZERO_ERROR
;
389 uregex_setText(re
, text2
, 7, &status
);
390 result
= uregex_getText(re
, &textLength
, &status
);
391 TEST_ASSERT(result
== text2
);
392 TEST_ASSERT(textLength
== 7);
393 TEST_ASSERT_SUCCESS(status
);
395 status
= U_ZERO_ERROR
;
396 uregex_setText(re
, text2
, 4, &status
);
397 result
= uregex_getText(re
, &textLength
, &status
);
398 TEST_ASSERT(result
== text2
);
399 TEST_ASSERT(textLength
== 4);
400 TEST_ASSERT_SUCCESS(status
);
411 UChar nullString
[] = {0,0,0};
413 u_uastrncpy(text1
, "abcccde", sizeof(text1
)/2);
414 status
= U_ZERO_ERROR
;
415 u_uastrncpy(pat
, "abc*d", sizeof(pat
)/2);
416 re
= uregex_open(pat
, -1, 0, NULL
, &status
);
418 uregex_setText(re
, text1
, -1, &status
);
419 result
= uregex_matches(re
, 0, &status
);
420 TEST_ASSERT(result
== FALSE
);
421 TEST_ASSERT_SUCCESS(status
);
423 status
= U_ZERO_ERROR
;
424 uregex_setText(re
, text1
, 6, &status
);
425 result
= uregex_matches(re
, 0, &status
);
426 TEST_ASSERT(result
== TRUE
);
427 TEST_ASSERT_SUCCESS(status
);
429 status
= U_ZERO_ERROR
;
430 uregex_setText(re
, text1
, 6, &status
);
431 result
= uregex_matches(re
, 1, &status
);
432 TEST_ASSERT(result
== FALSE
);
433 TEST_ASSERT_SUCCESS(status
);
436 status
= U_ZERO_ERROR
;
437 re
= uregex_openC(".?", 0, NULL
, &status
);
438 uregex_setText(re
, text1
, -1, &status
);
439 len
= u_strlen(text1
);
440 result
= uregex_matches(re
, len
, &status
);
441 TEST_ASSERT(result
== TRUE
);
442 TEST_ASSERT_SUCCESS(status
);
444 status
= U_ZERO_ERROR
;
445 uregex_setText(re
, nullString
, -1, &status
);
446 TEST_ASSERT_SUCCESS(status
);
447 result
= uregex_matches(re
, 0, &status
);
448 TEST_ASSERT(result
== TRUE
);
449 TEST_ASSERT_SUCCESS(status
);
455 * lookingAt() Used in setText test.
460 * find(), findNext, start, end, reset
465 u_uastrncpy(text1
, "012rx5rx890rxrx...", sizeof(text1
)/2);
466 status
= U_ZERO_ERROR
;
467 re
= uregex_openC("rx", 0, NULL
, &status
);
469 uregex_setText(re
, text1
, -1, &status
);
470 result
= uregex_find(re
, 0, &status
);
471 TEST_ASSERT(result
== TRUE
);
472 TEST_ASSERT(uregex_start(re
, 0, &status
) == 3);
473 TEST_ASSERT(uregex_end(re
, 0, &status
) == 5);
474 TEST_ASSERT_SUCCESS(status
);
476 result
= uregex_find(re
, 9, &status
);
477 TEST_ASSERT(result
== TRUE
);
478 TEST_ASSERT(uregex_start(re
, 0, &status
) == 11);
479 TEST_ASSERT(uregex_end(re
, 0, &status
) == 13);
480 TEST_ASSERT_SUCCESS(status
);
482 result
= uregex_find(re
, 14, &status
);
483 TEST_ASSERT(result
== FALSE
);
484 TEST_ASSERT_SUCCESS(status
);
486 status
= U_ZERO_ERROR
;
487 uregex_reset(re
, 0, &status
);
489 result
= uregex_findNext(re
, &status
);
490 TEST_ASSERT(result
== TRUE
);
491 TEST_ASSERT(uregex_start(re
, 0, &status
) == 3);
492 TEST_ASSERT(uregex_end(re
, 0, &status
) == 5);
493 TEST_ASSERT_SUCCESS(status
);
495 result
= uregex_findNext(re
, &status
);
496 TEST_ASSERT(result
== TRUE
);
497 TEST_ASSERT(uregex_start(re
, 0, &status
) == 6);
498 TEST_ASSERT(uregex_end(re
, 0, &status
) == 8);
499 TEST_ASSERT_SUCCESS(status
);
501 status
= U_ZERO_ERROR
;
502 uregex_reset(re
, 12, &status
);
504 result
= uregex_findNext(re
, &status
);
505 TEST_ASSERT(result
== TRUE
);
506 TEST_ASSERT(uregex_start(re
, 0, &status
) == 13);
507 TEST_ASSERT(uregex_end(re
, 0, &status
) == 15);
508 TEST_ASSERT_SUCCESS(status
);
510 result
= uregex_findNext(re
, &status
);
511 TEST_ASSERT(result
== FALSE
);
512 TEST_ASSERT_SUCCESS(status
);
523 status
= U_ZERO_ERROR
;
524 re
= uregex_openC("abc", 0, NULL
, &status
);
525 result
= uregex_groupCount(re
, &status
);
526 TEST_ASSERT_SUCCESS(status
);
527 TEST_ASSERT(result
== 0);
530 status
= U_ZERO_ERROR
;
531 re
= uregex_openC("abc(def)(ghi(j))", 0, NULL
, &status
);
532 result
= uregex_groupCount(re
, &status
);
533 TEST_ASSERT_SUCCESS(status
);
534 TEST_ASSERT(result
== 3);
548 u_uastrncpy(text1
, "noise abc interior def, and this is off the end", sizeof(text1
)/2);
550 status
= U_ZERO_ERROR
;
551 re
= uregex_openC("abc(.*?)def", 0, NULL
, &status
);
552 TEST_ASSERT_SUCCESS(status
);
555 uregex_setText(re
, text1
, -1, &status
);
556 result
= uregex_find(re
, 0, &status
);
557 TEST_ASSERT(result
==TRUE
);
559 /* Capture Group 0, the full match. Should succeed. */
560 status
= U_ZERO_ERROR
;
561 resultSz
= uregex_group(re
, 0, buf
, sizeof(buf
)/2, &status
);
562 TEST_ASSERT_SUCCESS(status
);
563 TEST_ASSERT_STRING("abc interior def", buf
, TRUE
);
564 TEST_ASSERT(resultSz
== (int32_t)strlen("abc interior def"));
566 /* Capture group #1. Should succeed. */
567 status
= U_ZERO_ERROR
;
568 resultSz
= uregex_group(re
, 1, buf
, sizeof(buf
)/2, &status
);
569 TEST_ASSERT_SUCCESS(status
);
570 TEST_ASSERT_STRING(" interior ", buf
, TRUE
);
571 TEST_ASSERT(resultSz
== (int32_t)strlen(" interior "));
573 /* Capture group out of range. Error. */
574 status
= U_ZERO_ERROR
;
575 uregex_group(re
, 2, buf
, sizeof(buf
)/2, &status
);
576 TEST_ASSERT(status
== U_INDEX_OUTOFBOUNDS_ERROR
);
578 /* NULL buffer, pure pre-flight */
579 status
= U_ZERO_ERROR
;
580 resultSz
= uregex_group(re
, 0, NULL
, 0, &status
);
581 TEST_ASSERT(status
== U_BUFFER_OVERFLOW_ERROR
);
582 TEST_ASSERT(resultSz
== (int32_t)strlen("abc interior def"));
584 /* Too small buffer, truncated string */
585 status
= U_ZERO_ERROR
;
586 memset(buf
, -1, sizeof(buf
));
587 resultSz
= uregex_group(re
, 0, buf
, 5, &status
);
588 TEST_ASSERT(status
== U_BUFFER_OVERFLOW_ERROR
);
589 TEST_ASSERT_STRING("abc i", buf
, FALSE
);
590 TEST_ASSERT(buf
[5] == (UChar
)0xffff);
591 TEST_ASSERT(resultSz
== (int32_t)strlen("abc interior def"));
593 /* Output string just fits buffer, no NUL term. */
594 status
= U_ZERO_ERROR
;
595 resultSz
= uregex_group(re
, 0, buf
, (int32_t)strlen("abc interior def"), &status
);
596 TEST_ASSERT(status
== U_STRING_NOT_TERMINATED_WARNING
);
597 TEST_ASSERT_STRING("abc interior def", buf
, FALSE
);
598 TEST_ASSERT(resultSz
== (int32_t)strlen("abc interior def"));
599 TEST_ASSERT(buf
[strlen("abc interior def")] == (UChar
)0xffff);
610 /* SetRegion(), getRegion() do something */
611 TEST_SETUP(".*", "0123456789ABCDEF", 0)
612 UChar resultString
[40];
613 TEST_ASSERT(uregex_regionStart(re
, &status
) == 0);
614 TEST_ASSERT(uregex_regionEnd(re
, &status
) == 16);
615 uregex_setRegion(re
, 3, 6, &status
);
616 TEST_ASSERT(uregex_regionStart(re
, &status
) == 3);
617 TEST_ASSERT(uregex_regionEnd(re
, &status
) == 6);
618 TEST_ASSERT(uregex_findNext(re
, &status
));
619 TEST_ASSERT(uregex_group(re
, 0, resultString
, sizeof(resultString
)/2, &status
) == 3)
620 TEST_ASSERT_STRING("345", resultString
, TRUE
);
623 /* find(start=-1) uses regions */
624 TEST_SETUP(".*", "0123456789ABCDEF", 0);
625 uregex_setRegion(re
, 4, 6, &status
);
626 TEST_ASSERT(uregex_find(re
, -1, &status
) == TRUE
);
627 TEST_ASSERT(uregex_start(re
, 0, &status
) == 4);
628 TEST_ASSERT(uregex_end(re
, 0, &status
) == 6);
631 /* find (start >=0) does not use regions */
632 TEST_SETUP(".*", "0123456789ABCDEF", 0);
633 uregex_setRegion(re
, 4, 6, &status
);
634 TEST_ASSERT(uregex_find(re
, 0, &status
) == TRUE
);
635 TEST_ASSERT(uregex_start(re
, 0, &status
) == 0);
636 TEST_ASSERT(uregex_end(re
, 0, &status
) == 16);
639 /* findNext() obeys regions */
640 TEST_SETUP(".", "0123456789ABCDEF", 0);
641 uregex_setRegion(re
, 4, 6, &status
);
642 TEST_ASSERT(uregex_findNext(re
,&status
) == TRUE
);
643 TEST_ASSERT(uregex_start(re
, 0, &status
) == 4);
644 TEST_ASSERT(uregex_findNext(re
, &status
) == TRUE
);
645 TEST_ASSERT(uregex_start(re
, 0, &status
) == 5);
646 TEST_ASSERT(uregex_findNext(re
, &status
) == FALSE
);
649 /* matches(start=-1) uses regions */
650 /* Also, verify that non-greedy *? succeeds in finding the full match. */
651 TEST_SETUP(".*?", "0123456789ABCDEF", 0);
652 uregex_setRegion(re
, 4, 6, &status
);
653 TEST_ASSERT(uregex_matches(re
, -1, &status
) == TRUE
);
654 TEST_ASSERT(uregex_start(re
, 0, &status
) == 4);
655 TEST_ASSERT(uregex_end(re
, 0, &status
) == 6);
658 /* matches (start >=0) does not use regions */
659 TEST_SETUP(".*?", "0123456789ABCDEF", 0);
660 uregex_setRegion(re
, 4, 6, &status
);
661 TEST_ASSERT(uregex_matches(re
, 0, &status
) == TRUE
);
662 TEST_ASSERT(uregex_start(re
, 0, &status
) == 0);
663 TEST_ASSERT(uregex_end(re
, 0, &status
) == 16);
666 /* lookingAt(start=-1) uses regions */
667 /* Also, verify that non-greedy *? finds the first (shortest) match. */
668 TEST_SETUP(".*?", "0123456789ABCDEF", 0);
669 uregex_setRegion(re
, 4, 6, &status
);
670 TEST_ASSERT(uregex_lookingAt(re
, -1, &status
) == TRUE
);
671 TEST_ASSERT(uregex_start(re
, 0, &status
) == 4);
672 TEST_ASSERT(uregex_end(re
, 0, &status
) == 4);
675 /* lookingAt (start >=0) does not use regions */
676 TEST_SETUP(".*?", "0123456789ABCDEF", 0);
677 uregex_setRegion(re
, 4, 6, &status
);
678 TEST_ASSERT(uregex_lookingAt(re
, 0, &status
) == TRUE
);
679 TEST_ASSERT(uregex_start(re
, 0, &status
) == 0);
680 TEST_ASSERT(uregex_end(re
, 0, &status
) == 0);
684 TEST_SETUP("[a-f]*", "abcdefghij", 0);
685 TEST_ASSERT(uregex_find(re
, 0, &status
) == TRUE
);
686 TEST_ASSERT(uregex_hitEnd(re
, &status
) == FALSE
);
689 TEST_SETUP("[a-f]*", "abcdef", 0);
690 TEST_ASSERT(uregex_find(re
, 0, &status
) == TRUE
);
691 TEST_ASSERT(uregex_hitEnd(re
, &status
) == TRUE
);
695 TEST_SETUP("abcd", "abcd", 0);
696 TEST_ASSERT(uregex_find(re
, 0, &status
) == TRUE
);
697 TEST_ASSERT(uregex_requireEnd(re
, &status
) == FALSE
);
700 TEST_SETUP("abcd$", "abcd", 0);
701 TEST_ASSERT(uregex_find(re
, 0, &status
) == TRUE
);
702 TEST_ASSERT(uregex_requireEnd(re
, &status
) == TRUE
);
705 /* anchoringBounds */
706 TEST_SETUP("abc$", "abcdef", 0);
707 TEST_ASSERT(uregex_hasAnchoringBounds(re
, &status
) == TRUE
);
708 uregex_useAnchoringBounds(re
, FALSE
, &status
);
709 TEST_ASSERT(uregex_hasAnchoringBounds(re
, &status
) == FALSE
);
711 TEST_ASSERT(uregex_find(re
, -1, &status
) == FALSE
);
712 uregex_useAnchoringBounds(re
, TRUE
, &status
);
713 uregex_setRegion(re
, 0, 3, &status
);
714 TEST_ASSERT(uregex_find(re
, -1, &status
) == TRUE
);
715 TEST_ASSERT(uregex_end(re
, 0, &status
) == 3);
718 /* Transparent Bounds */
719 TEST_SETUP("abc(?=def)", "abcdef", 0);
720 TEST_ASSERT(uregex_hasTransparentBounds(re
, &status
) == FALSE
);
721 uregex_useTransparentBounds(re
, TRUE
, &status
);
722 TEST_ASSERT(uregex_hasTransparentBounds(re
, &status
) == TRUE
);
724 uregex_useTransparentBounds(re
, FALSE
, &status
);
725 TEST_ASSERT(uregex_find(re
, -1, &status
) == TRUE
); /* No Region */
726 uregex_setRegion(re
, 0, 3, &status
);
727 TEST_ASSERT(uregex_find(re
, -1, &status
) == FALSE
); /* with region, opaque bounds */
728 uregex_useTransparentBounds(re
, TRUE
, &status
);
729 TEST_ASSERT(uregex_find(re
, -1, &status
) == TRUE
); /* with region, transparent bounds */
730 TEST_ASSERT(uregex_end(re
, 0, &status
) == 3);
743 u_uastrncpy(text1
, "Replace xaax x1x x...x.", sizeof(text1
)/2);
744 u_uastrncpy(text2
, "No match here.", sizeof(text2
)/2);
745 u_uastrncpy(replText
, "<$1>", sizeof(replText
)/2);
747 status
= U_ZERO_ERROR
;
748 re
= uregex_openC("x(.*?)x", 0, NULL
, &status
);
749 TEST_ASSERT_SUCCESS(status
);
751 /* Normal case, with match */
752 uregex_setText(re
, text1
, -1, &status
);
753 resultSz
= uregex_replaceFirst(re
, replText
, -1, buf
, sizeof(buf
)/2, &status
);
754 TEST_ASSERT_SUCCESS(status
);
755 TEST_ASSERT_STRING("Replace <aa> x1x x...x.", buf
, TRUE
);
756 TEST_ASSERT(resultSz
== (int32_t)strlen("Replace xaax x1x x...x."));
758 /* No match. Text should copy to output with no changes. */
759 status
= U_ZERO_ERROR
;
760 uregex_setText(re
, text2
, -1, &status
);
761 resultSz
= uregex_replaceFirst(re
, replText
, -1, buf
, sizeof(buf
)/2, &status
);
762 TEST_ASSERT_SUCCESS(status
);
763 TEST_ASSERT_STRING("No match here.", buf
, TRUE
);
764 TEST_ASSERT(resultSz
== (int32_t)strlen("No match here."));
766 /* Match, output just fills buffer, no termination warning. */
767 status
= U_ZERO_ERROR
;
768 uregex_setText(re
, text1
, -1, &status
);
769 memset(buf
, -1, sizeof(buf
));
770 resultSz
= uregex_replaceFirst(re
, replText
, -1, buf
, strlen("Replace <aa> x1x x...x."), &status
);
771 TEST_ASSERT(status
== U_STRING_NOT_TERMINATED_WARNING
);
772 TEST_ASSERT_STRING("Replace <aa> x1x x...x.", buf
, FALSE
);
773 TEST_ASSERT(resultSz
== (int32_t)strlen("Replace xaax x1x x...x."));
774 TEST_ASSERT(buf
[resultSz
] == (UChar
)0xffff);
776 /* Do the replaceFirst again, without first resetting anything.
777 * Should give the same results.
779 status
= U_ZERO_ERROR
;
780 memset(buf
, -1, sizeof(buf
));
781 resultSz
= uregex_replaceFirst(re
, replText
, -1, buf
, strlen("Replace <aa> x1x x...x."), &status
);
782 TEST_ASSERT(status
== U_STRING_NOT_TERMINATED_WARNING
);
783 TEST_ASSERT_STRING("Replace <aa> x1x x...x.", buf
, FALSE
);
784 TEST_ASSERT(resultSz
== (int32_t)strlen("Replace xaax x1x x...x."));
785 TEST_ASSERT(buf
[resultSz
] == (UChar
)0xffff);
787 /* NULL buffer, zero buffer length */
788 status
= U_ZERO_ERROR
;
789 resultSz
= uregex_replaceFirst(re
, replText
, -1, NULL
, 0, &status
);
790 TEST_ASSERT(status
== U_BUFFER_OVERFLOW_ERROR
);
791 TEST_ASSERT(resultSz
== (int32_t)strlen("Replace xaax x1x x...x."));
793 /* Buffer too small by one */
794 status
= U_ZERO_ERROR
;
795 memset(buf
, -1, sizeof(buf
));
796 resultSz
= uregex_replaceFirst(re
, replText
, -1, buf
, strlen("Replace <aa> x1x x...x.")-1, &status
);
797 TEST_ASSERT(status
== U_BUFFER_OVERFLOW_ERROR
);
798 TEST_ASSERT_STRING("Replace <aa> x1x x...x", buf
, FALSE
);
799 TEST_ASSERT(resultSz
== (int32_t)strlen("Replace xaax x1x x...x."));
800 TEST_ASSERT(buf
[resultSz
] == (UChar
)0xffff);
815 int32_t expectedResultSize
;
818 u_uastrncpy(text1
, "Replace xaax x1x x...x.", sizeof(text1
)/2);
819 u_uastrncpy(text2
, "No match here.", sizeof(text2
)/2);
820 u_uastrncpy(replText
, "<$1>", sizeof(replText
)/2);
821 expectedResultSize
= u_strlen(text1
);
823 status
= U_ZERO_ERROR
;
824 re
= uregex_openC("x(.*?)x", 0, NULL
, &status
);
825 TEST_ASSERT_SUCCESS(status
);
827 /* Normal case, with match */
828 uregex_setText(re
, text1
, -1, &status
);
829 resultSz
= uregex_replaceAll(re
, replText
, -1, buf
, sizeof(buf
)/2, &status
);
830 TEST_ASSERT_SUCCESS(status
);
831 TEST_ASSERT_STRING("Replace <aa> <1> <...>.", buf
, TRUE
);
832 TEST_ASSERT(resultSz
== (int32_t)strlen("Replace xaax x1x x...x."));
834 /* No match. Text should copy to output with no changes. */
835 status
= U_ZERO_ERROR
;
836 uregex_setText(re
, text2
, -1, &status
);
837 resultSz
= uregex_replaceAll(re
, replText
, -1, buf
, sizeof(buf
)/2, &status
);
838 TEST_ASSERT_SUCCESS(status
);
839 TEST_ASSERT_STRING("No match here.", buf
, TRUE
);
840 TEST_ASSERT(resultSz
== (int32_t)strlen("No match here."));
842 /* Match, output just fills buffer, no termination warning. */
843 status
= U_ZERO_ERROR
;
844 uregex_setText(re
, text1
, -1, &status
);
845 memset(buf
, -1, sizeof(buf
));
846 resultSz
= uregex_replaceAll(re
, replText
, -1, buf
, strlen("Replace xaax x1x x...x."), &status
);
847 TEST_ASSERT(status
== U_STRING_NOT_TERMINATED_WARNING
);
848 TEST_ASSERT_STRING("Replace <aa> <1> <...>.", buf
, FALSE
);
849 TEST_ASSERT(resultSz
== (int32_t)strlen("Replace <aa> <1> <...>."));
850 TEST_ASSERT(buf
[resultSz
] == (UChar
)0xffff);
852 /* Do the replaceFirst again, without first resetting anything.
853 * Should give the same results.
855 status
= U_ZERO_ERROR
;
856 memset(buf
, -1, sizeof(buf
));
857 resultSz
= uregex_replaceAll(re
, replText
, -1, buf
, strlen("Replace xaax x1x x...x."), &status
);
858 TEST_ASSERT(status
== U_STRING_NOT_TERMINATED_WARNING
);
859 TEST_ASSERT_STRING("Replace <aa> <1> <...>.", buf
, FALSE
);
860 TEST_ASSERT(resultSz
== (int32_t)strlen("Replace <aa> <1> <...>."));
861 TEST_ASSERT(buf
[resultSz
] == (UChar
)0xffff);
863 /* NULL buffer, zero buffer length */
864 status
= U_ZERO_ERROR
;
865 resultSz
= uregex_replaceAll(re
, replText
, -1, NULL
, 0, &status
);
866 TEST_ASSERT(status
== U_BUFFER_OVERFLOW_ERROR
);
867 TEST_ASSERT(resultSz
== (int32_t)strlen("Replace <aa> <1> <...>."));
869 /* Buffer too small. Try every size, which will tickle edge cases
870 * in uregex_appendReplacement (used by replaceAll) */
871 for (i
=0; i
<expectedResultSize
; i
++) {
873 status
= U_ZERO_ERROR
;
874 memset(buf
, -1, sizeof(buf
));
875 resultSz
= uregex_replaceAll(re
, replText
, -1, buf
, i
, &status
);
876 TEST_ASSERT(status
== U_BUFFER_OVERFLOW_ERROR
);
877 strcpy(expected
, "Replace <aa> <1> <...>.");
879 TEST_ASSERT_STRING(expected
, buf
, FALSE
);
880 TEST_ASSERT(resultSz
== expectedResultSize
);
881 TEST_ASSERT(buf
[i
] == (UChar
)0xffff);
889 * appendReplacement()
899 status
= U_ZERO_ERROR
;
900 re
= uregex_openC(".*", 0, 0, &status
);
901 TEST_ASSERT_SUCCESS(status
);
903 u_uastrncpy(text
, "whatever", sizeof(text
)/2);
904 u_uastrncpy(repl
, "some other", sizeof(repl
)/2);
905 uregex_setText(re
, text
, -1, &status
);
907 /* match covers whole target string */
908 uregex_find(re
, 0, &status
);
909 TEST_ASSERT_SUCCESS(status
);
911 bufCap
= sizeof(buf
) / 2;
912 uregex_appendReplacement(re
, repl
, -1, &bufPtr
, &bufCap
, &status
);
913 TEST_ASSERT_SUCCESS(status
);
914 TEST_ASSERT_STRING("some other", buf
, TRUE
);
916 /* Match has \u \U escapes */
917 uregex_find(re
, 0, &status
);
918 TEST_ASSERT_SUCCESS(status
);
920 bufCap
= sizeof(buf
) / 2;
921 u_uastrncpy(repl
, "abc\\u0041\\U00000042 \\\\ $ \\abc", sizeof(repl
)/2);
922 uregex_appendReplacement(re
, repl
, -1, &bufPtr
, &bufCap
, &status
);
923 TEST_ASSERT_SUCCESS(status
);
924 TEST_ASSERT_STRING("abcAB \\ $ abc", buf
, TRUE
);
931 * appendTail(). Checked in ReplaceFirst(), replaceAll().
938 UChar textToSplit
[80];
943 int32_t requiredCapacity
;
947 u_uastrncpy(textToSplit
, "first : second: third", sizeof(textToSplit
)/2);
948 u_uastrncpy(text2
, "No match here.", sizeof(text2
)/2);
950 status
= U_ZERO_ERROR
;
951 re
= uregex_openC(":", 0, NULL
, &status
);
956 uregex_setText(re
, textToSplit
, -1, &status
);
957 TEST_ASSERT_SUCCESS(status
);
959 /* The TEST_ASSERT_SUCCESS call above should change too... */
960 if (U_SUCCESS(status
)) {
961 memset(fields
, -1, sizeof(fields
));
963 uregex_split(re
, buf
, sizeof(buf
)/2, &requiredCapacity
, fields
, 10, &status
);
964 TEST_ASSERT_SUCCESS(status
);
966 /* The TEST_ASSERT_SUCCESS call above should change too... */
967 if(U_SUCCESS(status
)) {
968 TEST_ASSERT(numFields
== 3);
969 TEST_ASSERT_STRING("first ", fields
[0], TRUE
);
970 TEST_ASSERT_STRING(" second", fields
[1], TRUE
);
971 TEST_ASSERT_STRING(" third", fields
[2], TRUE
);
972 TEST_ASSERT(fields
[3] == NULL
);
974 spaceNeeded
= u_strlen(textToSplit
) -
975 (numFields
- 1) + /* Field delimiters do not appear in output */
976 numFields
; /* Each field gets a NUL terminator */
978 TEST_ASSERT(spaceNeeded
== requiredCapacity
);
985 /* Split with too few output strings available */
986 status
= U_ZERO_ERROR
;
987 re
= uregex_openC(":", 0, NULL
, &status
);
988 uregex_setText(re
, textToSplit
, -1, &status
);
989 TEST_ASSERT_SUCCESS(status
);
991 /* The TEST_ASSERT_SUCCESS call above should change too... */
992 if(U_SUCCESS(status
)) {
993 memset(fields
, -1, sizeof(fields
));
995 uregex_split(re
, buf
, sizeof(buf
)/2, &requiredCapacity
, fields
, 2, &status
);
996 TEST_ASSERT_SUCCESS(status
);
998 /* The TEST_ASSERT_SUCCESS call above should change too... */
999 if(U_SUCCESS(status
)) {
1000 TEST_ASSERT(numFields
== 2);
1001 TEST_ASSERT_STRING("first ", fields
[0], TRUE
);
1002 TEST_ASSERT_STRING(" second: third", fields
[1], TRUE
);
1003 TEST_ASSERT(!memcmp(&fields
[2],&minus1
,sizeof(UChar
*)));
1005 spaceNeeded
= u_strlen(textToSplit
) -
1006 (numFields
- 1) + /* Field delimiters do not appear in output */
1007 numFields
; /* Each field gets a NUL terminator */
1009 TEST_ASSERT(spaceNeeded
== requiredCapacity
);
1011 /* Split with a range of output buffer sizes. */
1012 spaceNeeded
= u_strlen(textToSplit
) -
1013 (numFields
- 1) + /* Field delimiters do not appear in output */
1014 numFields
; /* Each field gets a NUL terminator */
1016 for (sz
=0; sz
< spaceNeeded
+1; sz
++) {
1017 memset(fields
, -1, sizeof(fields
));
1018 status
= U_ZERO_ERROR
;
1020 uregex_split(re
, buf
, sz
, &requiredCapacity
, fields
, 10, &status
);
1021 if (sz
>= spaceNeeded
) {
1022 TEST_ASSERT_SUCCESS(status
);
1023 TEST_ASSERT_STRING("first ", fields
[0], TRUE
);
1024 TEST_ASSERT_STRING(" second", fields
[1], TRUE
);
1025 TEST_ASSERT_STRING(" third", fields
[2], TRUE
);
1027 TEST_ASSERT(status
== U_BUFFER_OVERFLOW_ERROR
);
1029 TEST_ASSERT(numFields
== 3);
1030 TEST_ASSERT(fields
[3] == NULL
);
1031 TEST_ASSERT(spaceNeeded
== requiredCapacity
);
1042 /* Split(), part 2. Patterns with capture groups. The capture group text
1043 * comes out as additional fields. */
1045 UChar textToSplit
[80];
1049 int32_t requiredCapacity
;
1050 int32_t spaceNeeded
;
1053 u_uastrncpy(textToSplit
, "first <tag-a> second<tag-b> third", sizeof(textToSplit
)/2);
1055 status
= U_ZERO_ERROR
;
1056 re
= uregex_openC("<(.*?)>", 0, NULL
, &status
);
1058 uregex_setText(re
, textToSplit
, -1, &status
);
1059 TEST_ASSERT_SUCCESS(status
);
1061 /* The TEST_ASSERT_SUCCESS call above should change too... */
1062 if(U_SUCCESS(status
)) {
1063 memset(fields
, -1, sizeof(fields
));
1065 uregex_split(re
, buf
, sizeof(buf
)/2, &requiredCapacity
, fields
, 10, &status
);
1066 TEST_ASSERT_SUCCESS(status
);
1068 /* The TEST_ASSERT_SUCCESS call above should change too... */
1069 if(U_SUCCESS(status
)) {
1070 TEST_ASSERT(numFields
== 5);
1071 TEST_ASSERT_STRING("first ", fields
[0], TRUE
);
1072 TEST_ASSERT_STRING("tag-a", fields
[1], TRUE
);
1073 TEST_ASSERT_STRING(" second", fields
[2], TRUE
);
1074 TEST_ASSERT_STRING("tag-b", fields
[3], TRUE
);
1075 TEST_ASSERT_STRING(" third", fields
[4], TRUE
);
1076 TEST_ASSERT(fields
[5] == NULL
);
1077 spaceNeeded
= strlen("first .tag-a. second.tag-b. third."); /* "." at NUL positions */
1078 TEST_ASSERT(spaceNeeded
== requiredCapacity
);
1082 /* Split with too few output strings available (2) */
1083 status
= U_ZERO_ERROR
;
1084 memset(fields
, -1, sizeof(fields
));
1086 uregex_split(re
, buf
, sizeof(buf
)/2, &requiredCapacity
, fields
, 2, &status
);
1087 TEST_ASSERT_SUCCESS(status
);
1089 /* The TEST_ASSERT_SUCCESS call above should change too... */
1090 if(U_SUCCESS(status
)) {
1091 TEST_ASSERT(numFields
== 2);
1092 TEST_ASSERT_STRING("first ", fields
[0], TRUE
);
1093 TEST_ASSERT_STRING(" second<tag-b> third", fields
[1], TRUE
);
1094 TEST_ASSERT(!memcmp(&fields
[2],&minus1
,sizeof(UChar
*)));
1096 spaceNeeded
= strlen("first . second<tag-b> third."); /* "." at NUL positions */
1097 TEST_ASSERT(spaceNeeded
== requiredCapacity
);
1100 /* Split with too few output strings available (3) */
1101 status
= U_ZERO_ERROR
;
1102 memset(fields
, -1, sizeof(fields
));
1104 uregex_split(re
, buf
, sizeof(buf
)/2, &requiredCapacity
, fields
, 3, &status
);
1105 TEST_ASSERT_SUCCESS(status
);
1107 /* The TEST_ASSERT_SUCCESS call above should change too... */
1108 if(U_SUCCESS(status
)) {
1109 TEST_ASSERT(numFields
== 3);
1110 TEST_ASSERT_STRING("first ", fields
[0], TRUE
);
1111 TEST_ASSERT_STRING("tag-a", fields
[1], TRUE
);
1112 TEST_ASSERT_STRING(" second<tag-b> third", fields
[2], TRUE
);
1113 TEST_ASSERT(!memcmp(&fields
[3],&minus1
,sizeof(UChar
*)));
1115 spaceNeeded
= strlen("first .tag-a. second<tag-b> third."); /* "." at NUL positions */
1116 TEST_ASSERT(spaceNeeded
== requiredCapacity
);
1119 /* Split with just enough output strings available (5) */
1120 status
= U_ZERO_ERROR
;
1121 memset(fields
, -1, sizeof(fields
));
1123 uregex_split(re
, buf
, sizeof(buf
)/2, &requiredCapacity
, fields
, 5, &status
);
1124 TEST_ASSERT_SUCCESS(status
);
1126 /* The TEST_ASSERT_SUCCESS call above should change too... */
1127 if(U_SUCCESS(status
)) {
1128 TEST_ASSERT(numFields
== 5);
1129 TEST_ASSERT_STRING("first ", fields
[0], TRUE
);
1130 TEST_ASSERT_STRING("tag-a", fields
[1], TRUE
);
1131 TEST_ASSERT_STRING(" second", fields
[2], TRUE
);
1132 TEST_ASSERT_STRING("tag-b", fields
[3], TRUE
);
1133 TEST_ASSERT_STRING(" third", fields
[4], TRUE
);
1134 TEST_ASSERT(!memcmp(&fields
[5],&minus1
,sizeof(UChar
*)));
1136 spaceNeeded
= strlen("first .tag-a. second.tag-b. third."); /* "." at NUL positions */
1137 TEST_ASSERT(spaceNeeded
== requiredCapacity
);
1140 /* Split, end of text is a field delimiter. */
1141 status
= U_ZERO_ERROR
;
1142 sz
= strlen("first <tag-a> second<tag-b>");
1143 uregex_setText(re
, textToSplit
, sz
, &status
);
1144 TEST_ASSERT_SUCCESS(status
);
1146 /* The TEST_ASSERT_SUCCESS call above should change too... */
1147 if(U_SUCCESS(status
)) {
1148 memset(fields
, -1, sizeof(fields
));
1150 uregex_split(re
, buf
, sizeof(buf
)/2, &requiredCapacity
, fields
, 9, &status
);
1151 TEST_ASSERT_SUCCESS(status
);
1153 /* The TEST_ASSERT_SUCCESS call above should change too... */
1154 if(U_SUCCESS(status
)) {
1155 TEST_ASSERT(numFields
== 4);
1156 TEST_ASSERT_STRING("first ", fields
[0], TRUE
);
1157 TEST_ASSERT_STRING("tag-a", fields
[1], TRUE
);
1158 TEST_ASSERT_STRING(" second", fields
[2], TRUE
);
1159 TEST_ASSERT_STRING("tag-b", fields
[3], TRUE
);
1160 TEST_ASSERT(fields
[4] == NULL
);
1161 TEST_ASSERT(fields
[8] == NULL
);
1162 TEST_ASSERT(!memcmp(&fields
[9],&minus1
,sizeof(UChar
*)));
1163 spaceNeeded
= strlen("first .tag-a. second.tag-b."); /* "." at NUL positions */
1164 TEST_ASSERT(spaceNeeded
== requiredCapacity
);
1174 TEST_SETUP("abc$", "abcdef", 0);
1175 TEST_ASSERT(uregex_getTimeLimit(re
, &status
) == 0);
1176 uregex_setTimeLimit(re
, 1000, &status
);
1177 TEST_ASSERT(uregex_getTimeLimit(re
, &status
) == 1000);
1178 TEST_ASSERT_SUCCESS(status
);
1179 uregex_setTimeLimit(re
, -1, &status
);
1180 TEST_ASSERT(status
== U_ILLEGAL_ARGUMENT_ERROR
);
1181 status
= U_ZERO_ERROR
;
1182 TEST_ASSERT(uregex_getTimeLimit(re
, &status
) == 1000);
1186 * set/get Stack Limit
1188 TEST_SETUP("abc$", "abcdef", 0);
1189 TEST_ASSERT(uregex_getStackLimit(re
, &status
) == 8000000);
1190 uregex_setStackLimit(re
, 40000, &status
);
1191 TEST_ASSERT(uregex_getStackLimit(re
, &status
) == 40000);
1192 TEST_ASSERT_SUCCESS(status
);
1193 uregex_setStackLimit(re
, -1, &status
);
1194 TEST_ASSERT(status
== U_ILLEGAL_ARGUMENT_ERROR
);
1195 status
= U_ZERO_ERROR
;
1196 TEST_ASSERT(uregex_getStackLimit(re
, &status
) == 40000);
1201 * Get/Set callback functions
1202 * This test is copied from intltest regex/Callbacks
1203 * The pattern and test data will run long enough to cause the callback
1204 * to be invoked. The nested '+' operators give exponential time
1205 * behavior with increasing string length.
1207 TEST_SETUP("((.)+\\2)+x", "aaaaaaaaaaaaaaaaaaab", 0)
1208 callBackContext cbInfo
= {4, 0, 0};
1209 const void *pContext
= &cbInfo
;
1210 URegexMatchCallback
*returnedFn
= &TestCallbackFn
;
1212 /* Getting the callback fn when it hasn't been set must return NULL */
1213 uregex_getMatchCallback(re
, &returnedFn
, &pContext
, &status
);
1214 TEST_ASSERT_SUCCESS(status
);
1215 TEST_ASSERT(returnedFn
== NULL
);
1216 TEST_ASSERT(pContext
== NULL
);
1218 /* Set thecallback and do a match. */
1219 /* The callback function should record that it has been called. */
1220 uregex_setMatchCallback(re
, &TestCallbackFn
, &cbInfo
, &status
);
1221 TEST_ASSERT_SUCCESS(status
);
1222 TEST_ASSERT(cbInfo
.numCalls
== 0);
1223 TEST_ASSERT(uregex_matches(re
, -1, &status
) == FALSE
);
1224 TEST_ASSERT_SUCCESS(status
);
1225 TEST_ASSERT(cbInfo
.numCalls
> 0);
1227 /* Getting the callback should return the values that were set above. */
1228 uregex_getMatchCallback(re
, &returnedFn
, &pContext
, &status
);
1229 TEST_ASSERT(returnedFn
== &TestCallbackFn
);
1230 TEST_ASSERT(pContext
== &cbInfo
);
1237 static void TestBug4315(void) {
1238 UErrorCode theICUError
= U_ZERO_ERROR
;
1239 URegularExpression
*theRegEx
;
1241 const char *thePattern
;
1242 UChar theString
[100];
1243 UChar
*destFields
[24];
1244 int32_t neededLength1
;
1245 int32_t neededLength2
;
1247 int32_t wordCount
= 0;
1248 int32_t destFieldsSize
= 24;
1251 u_uastrcpy(theString
, "The quick brown fox jumped over the slow black turtle.");
1254 theRegEx
= uregex_openC(thePattern
, 0, NULL
, &theICUError
);
1255 TEST_ASSERT_SUCCESS(theICUError
);
1257 /* set the input string */
1258 uregex_setText(theRegEx
, theString
, u_strlen(theString
), &theICUError
);
1259 TEST_ASSERT_SUCCESS(theICUError
);
1262 /*explicitly pass NULL and 0 to force the overflow error -> this is where the
1264 wordCount
= uregex_split(theRegEx
, NULL
, 0, &neededLength1
, destFields
,
1265 destFieldsSize
, &theICUError
);
1267 TEST_ASSERT(theICUError
== U_BUFFER_OVERFLOW_ERROR
);
1268 TEST_ASSERT(wordCount
==3);
1270 if(theICUError
== U_BUFFER_OVERFLOW_ERROR
)
1272 theICUError
= U_ZERO_ERROR
;
1273 textBuff
= (UChar
*) malloc(sizeof(UChar
) * (neededLength1
+ 1));
1274 wordCount
= uregex_split(theRegEx
, textBuff
, neededLength1
+1, &neededLength2
,
1275 destFields
, destFieldsSize
, &theICUError
);
1276 TEST_ASSERT(wordCount
==3);
1277 TEST_ASSERT_SUCCESS(theICUError
);
1278 TEST_ASSERT(neededLength1
== neededLength2
);
1279 TEST_ASSERT_STRING("The qui", destFields
[0], TRUE
);
1280 TEST_ASSERT_STRING("brown fox jumped over the slow bla", destFields
[1], TRUE
);
1281 TEST_ASSERT_STRING("turtle.", destFields
[2], TRUE
);
1282 TEST_ASSERT(destFields
[3] == NULL
);
1285 uregex_close(theRegEx
);
1288 #endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS */