~ubuntu-branches/ubuntu/maverick/icu/maverick-updates

« back to all changes in this revision

Viewing changes to source/test/cintltst/reapits.c

  • Committer: Package Import Robot
  • Author(s): Jay Berkenbilt
  • Date: 2009-09-04 11:56:06 UTC
  • mfrom: (10.1.6 sid)
  • Revision ID: package-import@ubuntu.com-20090904115606-sqxxuizelam5tozb
Tags: 4.2.1-3
Change install-doc target to not fail if there are subdirectories of
doc/html.  This is necessary to handle the doc/html/search directory
created by doxygen 3.6.1.  (Closes: #544799)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/********************************************************************
 
2
 * COPYRIGHT: 
 
3
 * Copyright (c) 2004-2009, International Business Machines Corporation and
 
4
 * others. All Rights Reserved.
 
5
 ********************************************************************/
 
6
/********************************************************************************
 
7
*
 
8
* File reapits.c
 
9
*
 
10
*********************************************************************************/
 
11
/*C API TEST FOR Regular Expressions */
 
12
/**
 
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.
 
16
*
 
17
*   More complete testing of regular expression functionality is done with the C++ tests.
 
18
**/
 
19
 
 
20
#include "unicode/utypes.h"
 
21
 
 
22
#if !UCONFIG_NO_REGULAR_EXPRESSIONS
 
23
 
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include "unicode/uloc.h"
 
27
#include "unicode/uregex.h"
 
28
#include "unicode/ustring.h"
 
29
#include "cintltst.h"
 
30
 
 
31
#define TEST_ASSERT_SUCCESS(status) {if (U_FAILURE(status)) { \
 
32
log_data_err("Failure at file %s, line %d, error = %s (Are you missing data?)\n", __FILE__, __LINE__, u_errorName(status));}}
 
33
 
 
34
#define TEST_ASSERT(expr) {if ((expr)==FALSE) { \
 
35
log_data_err("Test Failure at file %s, line %d (Are you missing data?)\n", __FILE__, __LINE__);}}
 
36
 
 
37
/*
 
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
 
44
 *
 
45
 *         Put arbitrary test code between SETUP and TEARDOWN.
 
46
 *         're" is the compiled, ready-to-go  regular expression.
 
47
 */
 
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)) {
 
58
    
 
59
#define TEST_TEARDOWN  \
 
60
    }  \
 
61
    TEST_ASSERT_SUCCESS(status);  \
 
62
    uregex_close(re);  \
 
63
    free(srcString);   \
 
64
    }
 
65
 
 
66
 
 
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);
 
70
     UBool    success;
 
71
     if (nulTerm) {
 
72
         u_austrncpy(buf_inside_macro, (actual), len+1);
 
73
         buf_inside_macro[len+2] = 0;
 
74
         success = (strcmp((expected), buf_inside_macro) == 0);
 
75
     } else {
 
76
         u_austrncpy(buf_inside_macro, (actual), len);
 
77
         buf_inside_macro[len+1] = 0;
 
78
         success = (strncmp((expected), buf_inside_macro, len) == 0);
 
79
     }
 
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);
 
83
     }
 
84
}
 
85
 
 
86
#define TEST_ASSERT_STRING(expected, actual, nulTerm) test_assert_string(expected, actual, nulTerm, __FILE__, __LINE__)
 
87
             
 
88
 
 
89
 
 
90
 
 
91
 
 
92
static void TestRegexCAPI(void);
 
93
static void TestBug4315(void);
 
94
 
 
95
void addURegexTest(TestNode** root);
 
96
 
 
97
void addURegexTest(TestNode** root)
 
98
{
 
99
    addTest(root, &TestRegexCAPI, "regex/TestRegexCAPI");
 
100
    addTest(root, &TestBug4315,   "regex/TestBug4315");
 
101
}
 
102
 
 
103
/*
 
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. 
 
107
 */
 
108
typedef struct callBackContext {
 
109
    int32_t          maxCalls;
 
110
    int32_t          numCalls;
 
111
    int32_t          lastSteps;
 
112
} callBackContext;
 
113
 
 
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);
 
119
  }
 
120
  info->lastSteps = steps;
 
121
  info->numCalls++;
 
122
  return (info->numCalls < info->maxCalls);
 
123
}
 
124
 
 
125
/*
 
126
 *   Regular Expression C API Tests
 
127
 */
 
128
static void TestRegexCAPI(void) {
 
129
    UErrorCode           status = U_ZERO_ERROR;
 
130
    URegularExpression  *re;
 
131
    UChar                pat[200];
 
132
    UChar               *minus1;
 
133
 
 
134
    memset(&minus1, -1, sizeof(minus1));
 
135
 
 
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_data_err("Failed to open regular expression, line %d, error is \"%s\" (Are you missing data?)\n", __LINE__, u_errorName(status));
 
141
         return;
 
142
    }
 
143
    uregex_close(re);
 
144
 
 
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,
 
149
        0, &status);
 
150
    TEST_ASSERT_SUCCESS(status);
 
151
    uregex_close(re);
 
152
 
 
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);
 
157
    uregex_close(re);
 
158
 
 
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);
 
164
 
 
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);
 
170
 
 
171
    /* openC   open from a C string */
 
172
    {
 
173
        const UChar   *p;
 
174
        int32_t  len;
 
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);
 
180
 
 
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*"));
 
186
        }
 
187
 
 
188
        uregex_close(re);
 
189
 
 
190
        /*  TODO:  Open with ParseError parameter */
 
191
    }
 
192
 
 
193
    /*
 
194
     *  clone
 
195
     */
 
196
    {
 
197
        URegularExpression *clone1;
 
198
        URegularExpression *clone2;
 
199
        URegularExpression *clone3;
 
200
        UChar  testString1[30];
 
201
        UChar  testString2[30];
 
202
        UBool  result;
 
203
 
 
204
 
 
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);
 
211
 
 
212
        status = U_ZERO_ERROR;
 
213
        clone2 = uregex_clone(re, &status);
 
214
        TEST_ASSERT_SUCCESS(status);
 
215
        TEST_ASSERT(clone2 != NULL);
 
216
        uregex_close(re);
 
217
 
 
218
        status = U_ZERO_ERROR;
 
219
        clone3 = uregex_clone(clone2, &status);
 
220
        TEST_ASSERT_SUCCESS(status);
 
221
        TEST_ASSERT(clone3 != NULL);
 
222
 
 
223
        u_uastrncpy(testString1, "abcccd", sizeof(pat)/2);
 
224
        u_uastrncpy(testString2, "xxxabcccd", sizeof(pat)/2);
 
225
 
 
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);
 
232
        
 
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);
 
242
 
 
243
        uregex_close(clone1);
 
244
        uregex_close(clone2);
 
245
        uregex_close(clone3);
 
246
 
 
247
    }
 
248
 
 
249
    /*
 
250
     *  pattern()
 
251
    */
 
252
    {
 
253
        const UChar  *resultPat;
 
254
        int32_t       resultLen;
 
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);
 
260
 
 
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);
 
265
        }
 
266
 
 
267
        uregex_close(re);
 
268
 
 
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);
 
274
 
 
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);
 
280
        }
 
281
 
 
282
        uregex_close(re);
 
283
    }
 
284
 
 
285
    /*
 
286
     *  flags()
 
287
     */
 
288
    {
 
289
        int32_t  t;
 
290
 
 
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);
 
295
        TEST_ASSERT(t == 0);
 
296
        uregex_close(re);
 
297
 
 
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);
 
302
        TEST_ASSERT(t == 0);
 
303
        uregex_close(re);
 
304
 
 
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));
 
310
        uregex_close(re);
 
311
    }
 
312
 
 
313
    /*
 
314
     *  setText() and lookingAt()
 
315
     */
 
316
    {
 
317
        UChar  text1[50];
 
318
        UChar  text2[50];
 
319
        UBool  result;
 
320
 
 
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);
 
327
 
 
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);
 
332
 
 
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);
 
338
 
 
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);
 
344
 
 
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);
 
350
 
 
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);
 
356
 
 
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);
 
362
 
 
363
        uregex_close(re);
 
364
    }
 
365
 
 
366
 
 
367
    /*
 
368
     *  getText() 
 
369
     */
 
370
    {
 
371
        UChar    text1[50];
 
372
        UChar    text2[50];
 
373
        const UChar   *result;
 
374
        int32_t  textLength;
 
375
 
 
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);
 
381
 
 
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);
 
387
 
 
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);
 
394
 
 
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);
 
401
        uregex_close(re);
 
402
    }
 
403
 
 
404
    /*
 
405
     *  matches()
 
406
     */
 
407
    {
 
408
        UChar   text1[50];
 
409
        UBool   result;
 
410
        int     len;
 
411
        UChar   nullString[] = {0,0,0};
 
412
 
 
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);
 
417
 
 
418
        uregex_setText(re, text1, -1, &status);
 
419
        result = uregex_matches(re, 0, &status);
 
420
        TEST_ASSERT(result == FALSE);
 
421
        TEST_ASSERT_SUCCESS(status);
 
422
 
 
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);
 
428
 
 
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);
 
434
        uregex_close(re);
 
435
 
 
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);
 
443
 
 
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);
 
450
        uregex_close(re);
 
451
    }
 
452
 
 
453
 
 
454
    /*
 
455
     *  lookingAt()    Used in setText test.
 
456
     */
 
457
 
 
458
 
 
459
    /*
 
460
     *  find(), findNext, start, end, reset
 
461
     */
 
462
    {
 
463
        UChar    text1[50];
 
464
        UBool    result;
 
465
        u_uastrncpy(text1, "012rx5rx890rxrx...",  sizeof(text1)/2);
 
466
        status = U_ZERO_ERROR;
 
467
        re = uregex_openC("rx", 0, NULL, &status);
 
468
 
 
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);
 
475
 
 
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);
 
481
 
 
482
        result = uregex_find(re, 14, &status);
 
483
        TEST_ASSERT(result == FALSE);
 
484
        TEST_ASSERT_SUCCESS(status);
 
485
 
 
486
        status = U_ZERO_ERROR;
 
487
        uregex_reset(re, 0, &status);
 
488
 
 
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);
 
494
 
 
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);
 
500
 
 
501
        status = U_ZERO_ERROR;
 
502
        uregex_reset(re, 12, &status);
 
503
 
 
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);
 
509
 
 
510
        result = uregex_findNext(re, &status);
 
511
        TEST_ASSERT(result == FALSE);
 
512
        TEST_ASSERT_SUCCESS(status);
 
513
 
 
514
        uregex_close(re);
 
515
    }
 
516
 
 
517
    /*
 
518
     *  groupCount
 
519
     */
 
520
    {
 
521
        int32_t result;
 
522
 
 
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);
 
528
        uregex_close(re);
 
529
 
 
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);
 
535
        uregex_close(re);
 
536
 
 
537
    }
 
538
 
 
539
 
 
540
    /*
 
541
     *  group()
 
542
     */
 
543
    {
 
544
        UChar    text1[80];
 
545
        UChar    buf[80];
 
546
        UBool    result;
 
547
        int32_t  resultSz;
 
548
        u_uastrncpy(text1, "noise abc interior def, and this is off the end",  sizeof(text1)/2);
 
549
 
 
550
        status = U_ZERO_ERROR;
 
551
        re = uregex_openC("abc(.*?)def", 0, NULL, &status);
 
552
        TEST_ASSERT_SUCCESS(status);
 
553
 
 
554
 
 
555
        uregex_setText(re, text1, -1, &status);
 
556
        result = uregex_find(re, 0, &status);
 
557
        TEST_ASSERT(result==TRUE);
 
558
 
 
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"));
 
565
 
 
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 "));
 
572
 
 
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);
 
577
 
 
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"));
 
583
 
 
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"));
 
592
 
 
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);
 
600
        
 
601
        uregex_close(re);
 
602
 
 
603
    }
 
604
    
 
605
    /*
 
606
     *  Regions
 
607
     */
 
608
        
 
609
        
 
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);
 
621
        TEST_TEARDOWN;
 
622
        
 
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);
 
629
        TEST_TEARDOWN;
 
630
        
 
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);
 
637
        TEST_TEARDOWN;
 
638
         
 
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);
 
647
        TEST_TEARDOWN;
 
648
 
 
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);
 
656
        TEST_TEARDOWN;
 
657
        
 
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);
 
664
        TEST_TEARDOWN;
 
665
        
 
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);
 
673
        TEST_TEARDOWN;
 
674
        
 
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);
 
681
        TEST_TEARDOWN;
 
682
 
 
683
        /* hitEnd()       */
 
684
        TEST_SETUP("[a-f]*", "abcdefghij", 0);
 
685
        TEST_ASSERT(uregex_find(re, 0, &status) == TRUE);
 
686
        TEST_ASSERT(uregex_hitEnd(re, &status) == FALSE);
 
687
        TEST_TEARDOWN;
 
688
 
 
689
        TEST_SETUP("[a-f]*", "abcdef", 0);
 
690
        TEST_ASSERT(uregex_find(re, 0, &status) == TRUE);
 
691
        TEST_ASSERT(uregex_hitEnd(re, &status) == TRUE);
 
692
        TEST_TEARDOWN;
 
693
 
 
694
        /* requireEnd   */
 
695
        TEST_SETUP("abcd", "abcd", 0);
 
696
        TEST_ASSERT(uregex_find(re, 0, &status) == TRUE);
 
697
        TEST_ASSERT(uregex_requireEnd(re, &status) == FALSE);
 
698
        TEST_TEARDOWN;
 
699
 
 
700
        TEST_SETUP("abcd$", "abcd", 0);
 
701
        TEST_ASSERT(uregex_find(re, 0, &status) == TRUE);
 
702
        TEST_ASSERT(uregex_requireEnd(re, &status) == TRUE);
 
703
        TEST_TEARDOWN;
 
704
        
 
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);
 
710
        
 
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);
 
716
        TEST_TEARDOWN;
 
717
        
 
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);
 
723
        
 
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);
 
731
        TEST_TEARDOWN;
 
732
        
 
733
 
 
734
    /*
 
735
     *  replaceFirst()
 
736
     */
 
737
    {
 
738
        UChar    text1[80];
 
739
        UChar    text2[80];
 
740
        UChar    replText[80];
 
741
        UChar    buf[80];
 
742
        int32_t  resultSz;
 
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);
 
746
 
 
747
        status = U_ZERO_ERROR;
 
748
        re = uregex_openC("x(.*?)x", 0, NULL, &status);
 
749
        TEST_ASSERT_SUCCESS(status);
 
750
 
 
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."));
 
757
 
 
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."));
 
765
 
 
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);
 
775
 
 
776
        /* Do the replaceFirst again, without first resetting anything.
 
777
         *  Should give the same results.
 
778
         */
 
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);
 
786
 
 
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."));
 
792
 
 
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);
 
801
 
 
802
        uregex_close(re);
 
803
    }
 
804
 
 
805
 
 
806
    /*
 
807
     *  replaceAll()
 
808
     */
 
809
    {
 
810
        UChar    text1[80];          /*  "Replace xaax x1x x...x." */
 
811
        UChar    text2[80];          /*  "No match Here"           */
 
812
        UChar    replText[80];       /*  "<$1>"                    */
 
813
        UChar    replText2[80];      /*  "<<$1>>"                  */
 
814
        const char * pattern = "x(.*?)x";
 
815
        const char * expectedResult = "Replace <aa> <1> <...>.";
 
816
        const char * expectedResult2 = "Replace <<aa>> <<1>> <<...>>.";
 
817
        UChar    buf[80];
 
818
        int32_t  resultSize;
 
819
        int32_t  expectedResultSize;
 
820
        int32_t  expectedResultSize2;
 
821
        int32_t  i;
 
822
 
 
823
        u_uastrncpy(text1, "Replace xaax x1x x...x.",  sizeof(text1)/2);
 
824
        u_uastrncpy(text2, "No match here.",  sizeof(text2)/2);
 
825
        u_uastrncpy(replText, "<$1>", sizeof(replText)/2);
 
826
        u_uastrncpy(replText2, "<<$1>>", sizeof(replText2)/2);
 
827
        expectedResultSize = strlen(expectedResult);
 
828
        expectedResultSize2 = strlen(expectedResult2);
 
829
 
 
830
        status = U_ZERO_ERROR;
 
831
        re = uregex_openC(pattern, 0, NULL, &status);
 
832
        TEST_ASSERT_SUCCESS(status);
 
833
 
 
834
        /*  Normal case, with match */
 
835
        uregex_setText(re, text1, -1, &status);
 
836
        resultSize = uregex_replaceAll(re, replText, -1, buf, sizeof(buf)/2, &status);
 
837
        TEST_ASSERT_SUCCESS(status);
 
838
        TEST_ASSERT_STRING(expectedResult, buf, TRUE);
 
839
        TEST_ASSERT(resultSize == expectedResultSize);
 
840
 
 
841
        /* No match.  Text should copy to output with no changes.  */
 
842
        status = U_ZERO_ERROR;
 
843
        uregex_setText(re, text2, -1, &status);
 
844
        resultSize = uregex_replaceAll(re, replText, -1, buf, sizeof(buf)/2, &status);
 
845
        TEST_ASSERT_SUCCESS(status);
 
846
        TEST_ASSERT_STRING("No match here.", buf, TRUE);
 
847
        TEST_ASSERT(resultSize == u_strlen(text2));
 
848
 
 
849
        /*  Match, output just fills buffer, no termination warning. */
 
850
        status = U_ZERO_ERROR;
 
851
        uregex_setText(re, text1, -1, &status);
 
852
        memset(buf, -1, sizeof(buf));
 
853
        resultSize = uregex_replaceAll(re, replText, -1, buf, expectedResultSize, &status);
 
854
        TEST_ASSERT(status == U_STRING_NOT_TERMINATED_WARNING);
 
855
        TEST_ASSERT_STRING(expectedResult, buf, FALSE);
 
856
        TEST_ASSERT(resultSize == expectedResultSize);
 
857
        TEST_ASSERT(buf[resultSize] == (UChar)0xffff);
 
858
 
 
859
        /* Do the replaceFirst again, without first resetting anything.
 
860
         *  Should give the same results.
 
861
         */
 
862
        status = U_ZERO_ERROR;
 
863
        memset(buf, -1, sizeof(buf));
 
864
        resultSize = uregex_replaceAll(re, replText, -1, buf, strlen("Replace xaax x1x x...x."), &status);
 
865
        TEST_ASSERT(status == U_STRING_NOT_TERMINATED_WARNING);
 
866
        TEST_ASSERT_STRING("Replace <aa> <1> <...>.", buf, FALSE);
 
867
        TEST_ASSERT(resultSize == (int32_t)strlen("Replace <aa> <1> <...>."));
 
868
        TEST_ASSERT(buf[resultSize] == (UChar)0xffff);
 
869
 
 
870
        /* NULL buffer, zero buffer length */
 
871
        status = U_ZERO_ERROR;
 
872
        resultSize = uregex_replaceAll(re, replText, -1, NULL, 0, &status);
 
873
        TEST_ASSERT(status == U_BUFFER_OVERFLOW_ERROR);
 
874
        TEST_ASSERT(resultSize == (int32_t)strlen("Replace <aa> <1> <...>."));
 
875
 
 
876
        /* Buffer too small.  Try every size, which will tickle edge cases
 
877
         * in uregex_appendReplacement (used by replaceAll)   */
 
878
        for (i=0; i<expectedResultSize; i++) {
 
879
            char  expected[80];
 
880
            status = U_ZERO_ERROR;
 
881
            memset(buf, -1, sizeof(buf));
 
882
            resultSize = uregex_replaceAll(re, replText, -1, buf, i, &status);
 
883
            TEST_ASSERT(status == U_BUFFER_OVERFLOW_ERROR);
 
884
            strcpy(expected, expectedResult);
 
885
            expected[i] = 0;
 
886
            TEST_ASSERT_STRING(expected, buf, FALSE);
 
887
            TEST_ASSERT(resultSize == expectedResultSize);
 
888
            TEST_ASSERT(buf[i] == (UChar)0xffff);
 
889
        }
 
890
 
 
891
        /* Buffer too small.  Same as previous test, except this time the replacement
 
892
         * text is longer than the match capture group, making the length of the complete
 
893
         * replacement longer than the original string.
 
894
         */
 
895
        for (i=0; i<expectedResultSize2; i++) {
 
896
            char  expected[80];
 
897
            status = U_ZERO_ERROR;
 
898
            memset(buf, -1, sizeof(buf));
 
899
            resultSize = uregex_replaceAll(re, replText2, -1, buf, i, &status);
 
900
            TEST_ASSERT(status == U_BUFFER_OVERFLOW_ERROR);
 
901
            strcpy(expected, expectedResult2);
 
902
            expected[i] = 0;
 
903
            TEST_ASSERT_STRING(expected, buf, FALSE);
 
904
            TEST_ASSERT(resultSize == expectedResultSize2);
 
905
            TEST_ASSERT(buf[i] == (UChar)0xffff);
 
906
        }
 
907
 
 
908
 
 
909
        uregex_close(re);
 
910
    }
 
911
 
 
912
 
 
913
    /*
 
914
     *  appendReplacement()
 
915
     */
 
916
    {
 
917
        UChar    text[100];
 
918
        UChar    repl[100];
 
919
        UChar    buf[100];
 
920
        UChar   *bufPtr;
 
921
        int32_t  bufCap;
 
922
 
 
923
 
 
924
        status = U_ZERO_ERROR;
 
925
        re = uregex_openC(".*", 0, 0, &status);
 
926
        TEST_ASSERT_SUCCESS(status);
 
927
 
 
928
        u_uastrncpy(text, "whatever",  sizeof(text)/2);
 
929
        u_uastrncpy(repl, "some other", sizeof(repl)/2);
 
930
        uregex_setText(re, text, -1, &status);
 
931
 
 
932
        /* match covers whole target string */
 
933
        uregex_find(re, 0, &status);
 
934
        TEST_ASSERT_SUCCESS(status);
 
935
        bufPtr = buf;
 
936
        bufCap = sizeof(buf) / 2;
 
937
        uregex_appendReplacement(re, repl, -1, &bufPtr, &bufCap, &status);
 
938
        TEST_ASSERT_SUCCESS(status);
 
939
        TEST_ASSERT_STRING("some other", buf, TRUE);
 
940
 
 
941
        /* Match has \u \U escapes */
 
942
        uregex_find(re, 0, &status);
 
943
        TEST_ASSERT_SUCCESS(status);
 
944
        bufPtr = buf;
 
945
        bufCap = sizeof(buf) / 2;
 
946
        u_uastrncpy(repl, "abc\\u0041\\U00000042 \\\\ $ \\abc", sizeof(repl)/2);
 
947
        uregex_appendReplacement(re, repl, -1, &bufPtr, &bufCap, &status);
 
948
        TEST_ASSERT_SUCCESS(status);
 
949
        TEST_ASSERT_STRING("abcAB \\ $ abc", buf, TRUE); 
 
950
 
 
951
        /* Bug 6813, parameter check of NULL destCapacity; crashed before fix. */
 
952
        status = U_ZERO_ERROR;
 
953
        uregex_find(re, 0, &status);
 
954
        TEST_ASSERT_SUCCESS(status);
 
955
        bufPtr = buf;
 
956
        status = U_BUFFER_OVERFLOW_ERROR;
 
957
        uregex_appendReplacement(re, repl, -1, &bufPtr, NULL, &status);
 
958
        TEST_ASSERT(status == U_BUFFER_OVERFLOW_ERROR);
 
959
 
 
960
        uregex_close(re);
 
961
    }
 
962
 
 
963
 
 
964
    /*
 
965
     *  appendTail().   Checked in ReplaceFirst(), replaceAll().
 
966
     */
 
967
 
 
968
    /*
 
969
     *  split()
 
970
     */
 
971
    {
 
972
        UChar    textToSplit[80];
 
973
        UChar    text2[80];
 
974
        UChar    buf[200];
 
975
        UChar    *fields[10];
 
976
        int32_t  numFields;
 
977
        int32_t  requiredCapacity;
 
978
        int32_t  spaceNeeded;
 
979
        int32_t  sz;
 
980
 
 
981
        u_uastrncpy(textToSplit, "first : second:  third",  sizeof(textToSplit)/2);
 
982
        u_uastrncpy(text2, "No match here.",  sizeof(text2)/2);
 
983
 
 
984
        status = U_ZERO_ERROR;
 
985
        re = uregex_openC(":", 0, NULL, &status);
 
986
 
 
987
 
 
988
        /*  Simple split */ 
 
989
 
 
990
        uregex_setText(re, textToSplit, -1, &status);
 
991
        TEST_ASSERT_SUCCESS(status);
 
992
 
 
993
        /* The TEST_ASSERT_SUCCESS call above should change too... */
 
994
        if (U_SUCCESS(status)) {
 
995
            memset(fields, -1, sizeof(fields));
 
996
            numFields = 
 
997
                uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 10, &status);
 
998
            TEST_ASSERT_SUCCESS(status);
 
999
 
 
1000
            /* The TEST_ASSERT_SUCCESS call above should change too... */
 
1001
            if(U_SUCCESS(status)) {
 
1002
                TEST_ASSERT(numFields == 3);
 
1003
                TEST_ASSERT_STRING("first ",  fields[0], TRUE);
 
1004
                TEST_ASSERT_STRING(" second", fields[1], TRUE);
 
1005
                TEST_ASSERT_STRING("  third", fields[2], TRUE);
 
1006
                TEST_ASSERT(fields[3] == NULL);
 
1007
 
 
1008
                spaceNeeded = u_strlen(textToSplit) -
 
1009
                            (numFields - 1)  +  /* Field delimiters do not appear in output */
 
1010
                            numFields;          /* Each field gets a NUL terminator */ 
 
1011
 
 
1012
                TEST_ASSERT(spaceNeeded == requiredCapacity);
 
1013
            }
 
1014
        }
 
1015
 
 
1016
        uregex_close(re);
 
1017
 
 
1018
    
 
1019
        /*  Split with too few output strings available */
 
1020
        status = U_ZERO_ERROR;
 
1021
        re = uregex_openC(":", 0, NULL, &status);
 
1022
        uregex_setText(re, textToSplit, -1, &status);
 
1023
        TEST_ASSERT_SUCCESS(status);
 
1024
 
 
1025
        /* The TEST_ASSERT_SUCCESS call above should change too... */
 
1026
        if(U_SUCCESS(status)) {
 
1027
            memset(fields, -1, sizeof(fields));
 
1028
            numFields = 
 
1029
                uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 2, &status);
 
1030
            TEST_ASSERT_SUCCESS(status);
 
1031
 
 
1032
            /* The TEST_ASSERT_SUCCESS call above should change too... */
 
1033
            if(U_SUCCESS(status)) {
 
1034
                TEST_ASSERT(numFields == 2);
 
1035
                TEST_ASSERT_STRING("first ",  fields[0], TRUE);
 
1036
                TEST_ASSERT_STRING(" second:  third", fields[1], TRUE);
 
1037
                TEST_ASSERT(!memcmp(&fields[2],&minus1,sizeof(UChar*)));
 
1038
 
 
1039
                spaceNeeded = u_strlen(textToSplit) -
 
1040
                            (numFields - 1)  +  /* Field delimiters do not appear in output */
 
1041
                            numFields;          /* Each field gets a NUL terminator */ 
 
1042
 
 
1043
                TEST_ASSERT(spaceNeeded == requiredCapacity);
 
1044
 
 
1045
                /* Split with a range of output buffer sizes.  */
 
1046
                spaceNeeded = u_strlen(textToSplit) -
 
1047
                    (numFields - 1)  +  /* Field delimiters do not appear in output */
 
1048
                    numFields;          /* Each field gets a NUL terminator */ 
 
1049
                        
 
1050
                for (sz=0; sz < spaceNeeded+1; sz++) {
 
1051
                    memset(fields, -1, sizeof(fields));
 
1052
                    status = U_ZERO_ERROR;
 
1053
                    numFields = 
 
1054
                        uregex_split(re, buf, sz, &requiredCapacity, fields, 10, &status);
 
1055
                    if (sz >= spaceNeeded) {
 
1056
                        TEST_ASSERT_SUCCESS(status);
 
1057
                        TEST_ASSERT_STRING("first ",  fields[0], TRUE);
 
1058
                        TEST_ASSERT_STRING(" second", fields[1], TRUE);
 
1059
                        TEST_ASSERT_STRING("  third", fields[2], TRUE);
 
1060
                    } else {
 
1061
                        TEST_ASSERT(status == U_BUFFER_OVERFLOW_ERROR);
 
1062
                    }
 
1063
                    TEST_ASSERT(numFields == 3);
 
1064
                    TEST_ASSERT(fields[3] == NULL);
 
1065
                    TEST_ASSERT(spaceNeeded == requiredCapacity);
 
1066
                }
 
1067
            }
 
1068
        }
 
1069
 
 
1070
        uregex_close(re);
 
1071
    }
 
1072
 
 
1073
 
 
1074
 
 
1075
 
 
1076
    /* Split(), part 2.  Patterns with capture groups.  The capture group text
 
1077
     *                   comes out as additional fields.  */
 
1078
    {
 
1079
        UChar    textToSplit[80];
 
1080
        UChar    buf[200];
 
1081
        UChar    *fields[10];
 
1082
        int32_t  numFields;
 
1083
        int32_t  requiredCapacity;
 
1084
        int32_t  spaceNeeded;
 
1085
        int32_t  sz;
 
1086
 
 
1087
        u_uastrncpy(textToSplit, "first <tag-a> second<tag-b>  third",  sizeof(textToSplit)/2);
 
1088
 
 
1089
        status = U_ZERO_ERROR;
 
1090
        re = uregex_openC("<(.*?)>", 0, NULL, &status);
 
1091
 
 
1092
        uregex_setText(re, textToSplit, -1, &status);
 
1093
        TEST_ASSERT_SUCCESS(status);
 
1094
 
 
1095
        /* The TEST_ASSERT_SUCCESS call above should change too... */
 
1096
        if(U_SUCCESS(status)) {
 
1097
            memset(fields, -1, sizeof(fields));
 
1098
            numFields = 
 
1099
                uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 10, &status);
 
1100
            TEST_ASSERT_SUCCESS(status);
 
1101
 
 
1102
            /* The TEST_ASSERT_SUCCESS call above should change too... */
 
1103
            if(U_SUCCESS(status)) {
 
1104
                TEST_ASSERT(numFields == 5);
 
1105
                TEST_ASSERT_STRING("first ",  fields[0], TRUE);
 
1106
                TEST_ASSERT_STRING("tag-a",   fields[1], TRUE);
 
1107
                TEST_ASSERT_STRING(" second", fields[2], TRUE);
 
1108
                TEST_ASSERT_STRING("tag-b",   fields[3], TRUE);
 
1109
                TEST_ASSERT_STRING("  third", fields[4], TRUE);
 
1110
                TEST_ASSERT(fields[5] == NULL);
 
1111
                spaceNeeded = strlen("first .tag-a. second.tag-b.  third.");  /* "." at NUL positions */
 
1112
                TEST_ASSERT(spaceNeeded == requiredCapacity);
 
1113
            }
 
1114
        }
 
1115
    
 
1116
        /*  Split with too few output strings available (2) */
 
1117
        status = U_ZERO_ERROR;
 
1118
        memset(fields, -1, sizeof(fields));
 
1119
        numFields = 
 
1120
            uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 2, &status);
 
1121
        TEST_ASSERT_SUCCESS(status);
 
1122
 
 
1123
        /* The TEST_ASSERT_SUCCESS call above should change too... */
 
1124
        if(U_SUCCESS(status)) {
 
1125
            TEST_ASSERT(numFields == 2);
 
1126
            TEST_ASSERT_STRING("first ",  fields[0], TRUE);
 
1127
            TEST_ASSERT_STRING(" second<tag-b>  third", fields[1], TRUE);
 
1128
            TEST_ASSERT(!memcmp(&fields[2],&minus1,sizeof(UChar*)));
 
1129
 
 
1130
            spaceNeeded = strlen("first . second<tag-b>  third.");  /* "." at NUL positions */
 
1131
            TEST_ASSERT(spaceNeeded == requiredCapacity);
 
1132
        }
 
1133
 
 
1134
        /*  Split with too few output strings available (3) */
 
1135
        status = U_ZERO_ERROR;
 
1136
        memset(fields, -1, sizeof(fields));
 
1137
        numFields = 
 
1138
            uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 3, &status);
 
1139
        TEST_ASSERT_SUCCESS(status);
 
1140
 
 
1141
        /* The TEST_ASSERT_SUCCESS call above should change too... */
 
1142
        if(U_SUCCESS(status)) {
 
1143
            TEST_ASSERT(numFields == 3);
 
1144
            TEST_ASSERT_STRING("first ",  fields[0], TRUE);
 
1145
            TEST_ASSERT_STRING("tag-a",   fields[1], TRUE);
 
1146
            TEST_ASSERT_STRING(" second<tag-b>  third", fields[2], TRUE);
 
1147
            TEST_ASSERT(!memcmp(&fields[3],&minus1,sizeof(UChar*)));
 
1148
 
 
1149
            spaceNeeded = strlen("first .tag-a. second<tag-b>  third.");  /* "." at NUL positions */
 
1150
            TEST_ASSERT(spaceNeeded == requiredCapacity);
 
1151
        }
 
1152
 
 
1153
        /*  Split with just enough output strings available (5) */
 
1154
        status = U_ZERO_ERROR;
 
1155
        memset(fields, -1, sizeof(fields));
 
1156
        numFields = 
 
1157
            uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 5, &status);
 
1158
        TEST_ASSERT_SUCCESS(status);
 
1159
 
 
1160
        /* The TEST_ASSERT_SUCCESS call above should change too... */
 
1161
        if(U_SUCCESS(status)) {
 
1162
            TEST_ASSERT(numFields == 5);
 
1163
            TEST_ASSERT_STRING("first ",  fields[0], TRUE);
 
1164
            TEST_ASSERT_STRING("tag-a",   fields[1], TRUE);
 
1165
            TEST_ASSERT_STRING(" second", fields[2], TRUE);
 
1166
            TEST_ASSERT_STRING("tag-b",   fields[3], TRUE);
 
1167
            TEST_ASSERT_STRING("  third", fields[4], TRUE);
 
1168
            TEST_ASSERT(!memcmp(&fields[5],&minus1,sizeof(UChar*)));
 
1169
 
 
1170
            spaceNeeded = strlen("first .tag-a. second.tag-b.  third.");  /* "." at NUL positions */
 
1171
            TEST_ASSERT(spaceNeeded == requiredCapacity);
 
1172
        }
 
1173
 
 
1174
        /* Split, end of text is a field delimiter.   */
 
1175
        status = U_ZERO_ERROR;
 
1176
        sz = strlen("first <tag-a> second<tag-b>");
 
1177
        uregex_setText(re, textToSplit, sz, &status);
 
1178
        TEST_ASSERT_SUCCESS(status);
 
1179
 
 
1180
        /* The TEST_ASSERT_SUCCESS call above should change too... */
 
1181
        if(U_SUCCESS(status)) {
 
1182
            memset(fields, -1, sizeof(fields));
 
1183
            numFields = 
 
1184
                uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 9, &status);
 
1185
            TEST_ASSERT_SUCCESS(status);
 
1186
 
 
1187
            /* The TEST_ASSERT_SUCCESS call above should change too... */
 
1188
            if(U_SUCCESS(status)) {
 
1189
                TEST_ASSERT(numFields == 4);
 
1190
                TEST_ASSERT_STRING("first ",  fields[0], TRUE);
 
1191
                TEST_ASSERT_STRING("tag-a",   fields[1], TRUE);
 
1192
                TEST_ASSERT_STRING(" second", fields[2], TRUE);
 
1193
                TEST_ASSERT_STRING("tag-b",   fields[3], TRUE);
 
1194
                TEST_ASSERT(fields[4] == NULL);
 
1195
                TEST_ASSERT(fields[8] == NULL);
 
1196
                TEST_ASSERT(!memcmp(&fields[9],&minus1,sizeof(UChar*)));
 
1197
                spaceNeeded = strlen("first .tag-a. second.tag-b.");  /* "." at NUL positions */
 
1198
                TEST_ASSERT(spaceNeeded == requiredCapacity);
 
1199
            }
 
1200
        }
 
1201
 
 
1202
        uregex_close(re);
 
1203
    }
 
1204
 
 
1205
    /*
 
1206
     * set/getTimeLimit
 
1207
     */
 
1208
     TEST_SETUP("abc$", "abcdef", 0);
 
1209
     TEST_ASSERT(uregex_getTimeLimit(re, &status) == 0);
 
1210
     uregex_setTimeLimit(re, 1000, &status);
 
1211
     TEST_ASSERT(uregex_getTimeLimit(re, &status) == 1000);
 
1212
     TEST_ASSERT_SUCCESS(status);
 
1213
     uregex_setTimeLimit(re, -1, &status);
 
1214
     TEST_ASSERT(status == U_ILLEGAL_ARGUMENT_ERROR);
 
1215
     status = U_ZERO_ERROR;
 
1216
     TEST_ASSERT(uregex_getTimeLimit(re, &status) == 1000);
 
1217
     TEST_TEARDOWN;
 
1218
 
 
1219
     /*
 
1220
      * set/get Stack Limit
 
1221
      */
 
1222
     TEST_SETUP("abc$", "abcdef", 0);
 
1223
     TEST_ASSERT(uregex_getStackLimit(re, &status) == 8000000);
 
1224
     uregex_setStackLimit(re, 40000, &status);
 
1225
     TEST_ASSERT(uregex_getStackLimit(re, &status) == 40000);
 
1226
     TEST_ASSERT_SUCCESS(status);
 
1227
     uregex_setStackLimit(re, -1, &status);
 
1228
     TEST_ASSERT(status == U_ILLEGAL_ARGUMENT_ERROR);
 
1229
     status = U_ZERO_ERROR;
 
1230
     TEST_ASSERT(uregex_getStackLimit(re, &status) == 40000);
 
1231
     TEST_TEARDOWN;
 
1232
     
 
1233
     
 
1234
     /*
 
1235
      * Get/Set callback functions
 
1236
      *     This test is copied from intltest regex/Callbacks
 
1237
      *     The pattern and test data will run long enough to cause the callback
 
1238
      *       to be invoked.  The nested '+' operators give exponential time
 
1239
      *       behavior with increasing string length.
 
1240
      */
 
1241
     TEST_SETUP("((.)+\\2)+x", "aaaaaaaaaaaaaaaaaaab", 0)
 
1242
     callBackContext cbInfo = {4, 0, 0};
 
1243
     const void     *pContext   = &cbInfo;
 
1244
     URegexMatchCallback    *returnedFn = &TestCallbackFn;
 
1245
     
 
1246
     /*  Getting the callback fn when it hasn't been set must return NULL  */
 
1247
     uregex_getMatchCallback(re, &returnedFn, &pContext, &status);
 
1248
     TEST_ASSERT_SUCCESS(status);
 
1249
     TEST_ASSERT(returnedFn == NULL);
 
1250
     TEST_ASSERT(pContext == NULL);
 
1251
     
 
1252
     /* Set thecallback and do a match.                                   */
 
1253
     /* The callback function should record that it has been called.      */
 
1254
     uregex_setMatchCallback(re, &TestCallbackFn, &cbInfo, &status);
 
1255
     TEST_ASSERT_SUCCESS(status);
 
1256
     TEST_ASSERT(cbInfo.numCalls == 0);
 
1257
     TEST_ASSERT(uregex_matches(re, -1, &status) == FALSE);
 
1258
     TEST_ASSERT_SUCCESS(status);
 
1259
     TEST_ASSERT(cbInfo.numCalls > 0);
 
1260
     
 
1261
     /* Getting the callback should return the values that were set above.  */
 
1262
     uregex_getMatchCallback(re, &returnedFn, &pContext, &status);
 
1263
     TEST_ASSERT(returnedFn == &TestCallbackFn);
 
1264
     TEST_ASSERT(pContext == &cbInfo);
 
1265
 
 
1266
     TEST_TEARDOWN;
 
1267
}
 
1268
 
 
1269
 
 
1270
 
 
1271
static void TestBug4315(void) {
 
1272
    UErrorCode      theICUError = U_ZERO_ERROR;
 
1273
    URegularExpression *theRegEx;
 
1274
    UChar           *textBuff;
 
1275
    const char      *thePattern;
 
1276
    UChar            theString[100];
 
1277
    UChar           *destFields[24];
 
1278
    int32_t         neededLength1;
 
1279
    int32_t         neededLength2;
 
1280
 
 
1281
    int32_t         wordCount = 0;
 
1282
    int32_t         destFieldsSize = 24;
 
1283
 
 
1284
    thePattern  = "ck ";
 
1285
    u_uastrcpy(theString, "The quick brown fox jumped over the slow black turtle.");
 
1286
 
 
1287
    /* open a regex */
 
1288
    theRegEx = uregex_openC(thePattern, 0, NULL, &theICUError);
 
1289
    TEST_ASSERT_SUCCESS(theICUError);
 
1290
 
 
1291
    /* set the input string */
 
1292
    uregex_setText(theRegEx, theString, u_strlen(theString), &theICUError);
 
1293
    TEST_ASSERT_SUCCESS(theICUError);
 
1294
 
 
1295
    /* split */
 
1296
    /*explicitly pass NULL and 0 to force the overflow error -> this is where the
 
1297
     *  error occurs! */
 
1298
    wordCount = uregex_split(theRegEx, NULL, 0, &neededLength1, destFields,
 
1299
        destFieldsSize, &theICUError);
 
1300
 
 
1301
    TEST_ASSERT(theICUError == U_BUFFER_OVERFLOW_ERROR);
 
1302
    TEST_ASSERT(wordCount==3);
 
1303
 
 
1304
    if(theICUError == U_BUFFER_OVERFLOW_ERROR)
 
1305
    {
 
1306
        theICUError = U_ZERO_ERROR;
 
1307
        textBuff = (UChar *) malloc(sizeof(UChar) * (neededLength1 + 1));
 
1308
        wordCount = uregex_split(theRegEx, textBuff, neededLength1+1, &neededLength2,
 
1309
            destFields, destFieldsSize, &theICUError);
 
1310
        TEST_ASSERT(wordCount==3);
 
1311
        TEST_ASSERT_SUCCESS(theICUError);
 
1312
        TEST_ASSERT(neededLength1 == neededLength2);
 
1313
        TEST_ASSERT_STRING("The qui", destFields[0], TRUE);
 
1314
        TEST_ASSERT_STRING("brown fox jumped over the slow bla", destFields[1], TRUE);
 
1315
        TEST_ASSERT_STRING("turtle.", destFields[2], TRUE);
 
1316
        TEST_ASSERT(destFields[3] == NULL);
 
1317
        free(textBuff);
 
1318
    }
 
1319
    uregex_close(theRegEx);
 
1320
}
 
1321
 
 
1322
#endif   /*  !UCONFIG_NO_REGULAR_EXPRESSIONS */