Add GRegex for regular expression matching. (#50075)
[platform/upstream/glib.git] / tests / regex-test.c
1 /*
2  * Copyright (C) 2005 - 2006, Marco Barisione <marco@barisione.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #undef G_DISABLE_ASSERT
21 #undef G_LOG_DOMAIN
22
23 #include <string.h>
24 #include <locale.h>
25 #include "glib.h"
26
27 #ifdef ENABLE_REGEX
28
29 /* U+20AC EURO SIGN (symbol, currency) */
30 #define EURO "\xe2\x82\xac"
31 /* U+00E0 LATIN SMALL LETTER A WITH GRAVE (letter, lowercase) */
32 #define AGRAVE "\xc3\xa0"
33 /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE (letter, uppercase) */
34 #define AGRAVE_UPPER "\xc3\x80"
35 /* U+00E8 LATIN SMALL LETTER E WITH GRAVE (letter, lowercase) */
36 #define EGRAVE "\xc3\xa8"
37 /* U+00F2 LATIN SMALL LETTER O WITH GRAVE (letter, lowercase) */
38 #define OGRAVE "\xc3\xb2"
39 /* U+014B LATIN SMALL LETTER ENG (letter, lowercase) */
40 #define ENG "\xc5\x8b"
41 /* U+0127 LATIN SMALL LETTER H WITH STROKE (letter, lowercase) */
42 #define HSTROKE "\xc4\xa7"
43 /* U+0634 ARABIC LETTER SHEEN (letter, other) */
44 #define SHEEN "\xd8\xb4"
45 /* U+1374 ETHIOPIC NUMBER THIRTY (number, other) */
46 #define ETH30 "\xe1\x8d\xb4"
47
48 /* A random value use to mark untouched integer variables. */
49 #define UNTOUCHED -559038737
50
51 static gboolean noisy = FALSE;
52 static gboolean abort_on_fail = FALSE;
53
54 #define PASS passed++
55 #define FAIL \
56   G_STMT_START \
57     { \
58       failed++; \
59       if (abort_on_fail) \
60         goto end; \
61     } \
62   G_STMT_END
63
64 /* A replacement for strcmp that doesn't crash with null pointers. */
65 static gboolean
66 streq (const gchar *s1, const gchar *s2)
67 {
68   if (s1 == NULL && s2 == NULL)
69     return TRUE;
70   else if (s1 == NULL)
71     return FALSE;
72   else if (s2 == NULL)
73     return FALSE;
74   else
75     return strcmp (s1, s2) == 0;
76 }
77
78 static void
79 verbose (const gchar *format, ...)
80 {
81   /* Function copied from glib/tests/patterntest.c by Matthias Clasen. */
82   gchar *msg;
83   va_list args;
84
85   va_start (args, format);
86   msg = g_strdup_vprintf (format, args);
87   va_end (args);
88
89   if (noisy) 
90     g_print (msg);
91   g_free (msg);
92 }
93
94 static gboolean
95 test_new (const gchar        *pattern,
96           GRegexCompileFlags  compile_opts,
97           GRegexMatchFlags    match_opts)
98 {
99   GRegex *regex;
100   
101   verbose ("compiling \"%s\" \t", pattern);
102
103   regex = g_regex_new (pattern, compile_opts, match_opts, NULL);
104   if (regex == NULL)
105     {
106       g_print ("failed \t(pattern: \"%s\", compile: %d, match %d)\n",
107                pattern, compile_opts, match_opts);
108       return FALSE;
109     }
110
111   if (!g_regex_optimize (regex, NULL))
112     {
113       g_print ("failed optimization \t(pattern: \"%s\", compile: %d, match %d)\n",
114                pattern, compile_opts, match_opts);
115       return FALSE;
116     }
117
118   if (!streq (g_regex_get_pattern (regex), pattern))
119     {
120       g_print ("failed \t(pattern: \"%s\")\n",
121                pattern);
122       g_regex_free (regex);
123       return FALSE;
124     }
125
126   g_regex_free (regex);
127   /* Free a null string. */
128   g_regex_free (NULL);
129
130   verbose ("passed\n");
131   return TRUE;
132 }
133
134 #define TEST_NEW(pattern, compile_opts, match_opts) { \
135   total++; \
136   if (test_new (pattern, compile_opts, match_opts)) \
137     PASS; \
138   else \
139     FAIL; \
140 }
141
142 static gboolean
143 test_new_fail (const gchar        *pattern,
144                GRegexCompileFlags  compile_opts)
145 {
146   GRegex *regex;
147   
148   verbose ("compiling \"%s\" (expected a failure) \t", pattern);
149
150   regex = g_regex_new (pattern, compile_opts, 0, NULL);
151
152   if (regex != NULL)
153     {
154       g_print ("failed \t(pattern: \"%s\", compile: %d)\n",
155                pattern, compile_opts);
156       g_regex_free (regex);
157       return FALSE;
158     }
159
160   verbose ("passed\n");
161   return TRUE;
162 }
163
164 #define TEST_NEW_FAIL(pattern, compile_opts) { \
165   total++; \
166   if (test_new_fail (pattern, compile_opts)) \
167     PASS; \
168   else \
169     FAIL; \
170 }
171
172 static gboolean
173 test_copy (const gchar  *pattern)
174 {
175   GRegex *regex1, *regex2, *regex3;
176
177   verbose ("copying \"%s\" \t", pattern);
178
179   regex1 = g_regex_new (pattern, 0, 0, NULL);
180   if (regex1 != NULL)
181     /* pattern can be not valid as we want to test what happens
182      * when the regex passed to g_regex_copy() is null */
183     g_regex_optimize (regex1, NULL);
184   regex2 = g_regex_copy (regex1);
185
186   if (regex1 != NULL &&
187       !streq (g_regex_get_pattern (regex1), g_regex_get_pattern(regex2)))
188     {
189       g_print ("failed \t(pattern: \"%s\")\n", pattern);
190       g_regex_free (regex1);
191       g_regex_free (regex2);
192       return FALSE;
193     }
194
195   g_regex_free (regex1);
196
197   /* force the creation of the internal GRegexMatch */
198   if (regex2 != NULL)
199     g_regex_match (regex2, "a", 0);
200   regex3 = g_regex_copy (regex2);
201   g_regex_free (regex2);
202
203   if (regex3 != NULL &&
204       !streq (g_regex_get_pattern (regex3), pattern))
205     {
206       g_print ("failed \t(pattern: \"%s\")\n", pattern);
207       g_regex_free (regex3);
208       return FALSE;
209     }
210
211   g_regex_free (regex3);
212
213   verbose ("passed\n");
214   return TRUE;
215 }
216
217 #define TEST_COPY(pattern) { \
218   total++; \
219   if (test_copy (pattern)) \
220     PASS; \
221   else \
222     FAIL; \
223 }
224
225 static gboolean
226 test_match_simple (const gchar        *pattern,
227                    const gchar        *string,
228                    GRegexCompileFlags  compile_opts,
229                    GRegexMatchFlags    match_opts,
230                    gboolean            expected)
231 {
232   gboolean match;
233   
234   verbose ("matching \"%s\" against \"%s\" \t", string, pattern);
235
236   match = g_regex_match_simple (pattern, string, compile_opts, match_opts);
237   if (match != expected)
238     {
239       g_print ("failed \t(unexpected %s)\n", match ? "match" : "mismatch");
240       return FALSE;
241     }
242   else
243     {
244       verbose ("passed (%s)\n", match ? "match" : "nomatch");
245       return TRUE;
246     }
247 }
248
249 #define TEST_MATCH_SIMPLE(pattern, string, compile_opts, match_opts, expected) { \
250   total++; \
251   if (test_match_simple (pattern, string, compile_opts, match_opts, expected)) \
252     PASS; \
253   else \
254     FAIL; \
255 }
256
257 static gboolean
258 test_match (const gchar        *pattern,
259             GRegexCompileFlags  compile_opts,
260             GRegexMatchFlags    match_opts,
261             const gchar        *string,
262             gssize              string_len,
263             gint                start_position,
264             GRegexMatchFlags    match_opts2,
265             gboolean            expected)
266 {
267   GRegex *regex;
268   gboolean match;
269   
270   verbose ("matching \"%s\" against \"%s\" (start: %d, len: %d) \t",
271            string, pattern, start_position, string_len);
272
273   regex = g_regex_new (pattern, compile_opts, match_opts, NULL);
274   match = g_regex_match_full (regex, string, string_len,
275                               start_position, match_opts2, NULL);
276   if (match != expected)
277     {
278       g_print ("failed \t(unexpected %s)\n", match ? "match" : "mismatch");
279       g_regex_free (regex);
280       return FALSE;
281     }
282
283   /* Repeat the test to verify that g_regex_clear() is not needed. */
284   match = g_regex_match_full (regex, string, string_len,
285                               start_position, match_opts2, NULL);
286   if (match != expected)
287     {
288       g_print ("failed \t(second match != first match)\n");
289       g_regex_free (regex);
290       return FALSE;
291     }
292
293   if (string_len == -1 && start_position == 0)
294     {
295       match = g_regex_match (regex, string, match_opts2);
296       if (match != expected)
297         {
298           g_print ("failed \t(pattern: \"%s\", string: \"%s\")\n",
299                    pattern, string);
300           g_regex_free (regex);
301           return FALSE;
302         }
303     }
304
305   g_regex_free (regex);
306
307   verbose ("passed (%s)\n", match ? "match" : "nomatch");
308   return TRUE;
309 }
310
311 #define TEST_MATCH(pattern, compile_opts, match_opts, string, \
312                    string_len, start_position, match_opts2, expected) { \
313   total++; \
314   if (test_match (pattern, compile_opts, match_opts, string, \
315                   string_len, start_position, match_opts2, expected)) \
316     PASS; \
317   else \
318     FAIL; \
319 }
320
321 struct _Match
322 {
323   gchar *string;
324   gint start, end;
325 };
326 typedef struct _Match Match;
327
328 static void
329 free_match (gpointer data, gpointer user_data)
330 {
331   Match *match = data;
332   if (match == NULL)
333     return;
334   g_free (match->string);
335   g_free (match);
336 }
337
338 static gboolean
339 test_match_next_full (const gchar          *pattern,
340                       const gchar          *string,
341                       gssize                string_len,
342                       gint                  start_position,
343                       ...)
344 {
345   GRegex *regex;
346   va_list args;
347   GSList *matches = NULL;
348   GSList *expected = NULL;
349   GSList *l_exp, *l_match;
350   gboolean ret = TRUE;
351   
352   verbose ("matching \"%s\" against \"%s\" (start: %d, len: %d) \t",
353            string, pattern, start_position, string_len);
354
355   /* The va_list is a NULL-terminated sequence of: extected matched string,
356    * expected start and expected end. */
357   va_start (args, start_position);
358   while (TRUE)
359    {
360       Match *match;
361       const gchar *expected_string = va_arg (args, const gchar *);
362       if (expected_string == NULL)
363         break;
364       match = g_new0 (Match, 1);
365       match->string = g_strdup (expected_string);
366       match->start = va_arg (args, gint);
367       match->end = va_arg (args, gint);
368       expected = g_slist_prepend (expected, match);
369     }
370   expected = g_slist_reverse (expected);
371   va_end (args);
372
373   regex = g_regex_new (pattern, 0, 0, NULL);
374
375   while (g_regex_match_next_full (regex, string, string_len,
376                                   start_position, 0, NULL))
377    {
378       Match *match = g_new0 (Match, 1);
379       match->string = g_regex_fetch (regex, 0, string);
380       match->start = UNTOUCHED;
381       match->end = UNTOUCHED;
382       g_regex_fetch_pos (regex, 0, &match->start, &match->end);
383       matches = g_slist_prepend (matches, match);
384    }
385   matches = g_slist_reverse (matches);
386
387   if (g_slist_length (matches) != g_slist_length (expected))
388     {
389       gint match_count = g_slist_length (matches);
390       g_print ("failed \t(got %d %s, expected %d)\n", match_count,
391                match_count == 1 ? "match" : "matches", 
392                g_slist_length (expected));
393       ret = FALSE;
394       goto exit;
395     }
396
397   l_exp = expected;
398   l_match =  matches;
399   while (l_exp != NULL)
400     {
401       Match *exp = l_exp->data;
402       Match *match = l_match->data;
403
404       if (!streq(exp->string, match->string))
405         {
406           g_print ("failed \t(got \"%s\", expected \"%s\")\n",
407                    match->string, exp->string);
408           ret = FALSE;
409           goto exit;
410         }
411
412       if (exp->start != match->start || exp->end != match->end)
413         {
414           g_print ("failed \t(got [%d, %d], expected [%d, %d])\n",
415                    match->start, match->end, exp->start, exp->end);
416           ret = FALSE;
417           goto exit;
418         }
419
420       l_exp = g_slist_next (l_exp);
421       l_match = g_slist_next (l_match);
422     }
423
424 exit:
425   if (ret)
426     {
427       gint count = g_slist_length (matches);
428       verbose ("passed (%d %s)\n", count, count == 1 ? "match" : "matches");
429     }
430
431   g_regex_free (regex);
432   g_slist_foreach (expected, free_match, NULL);
433   g_slist_free (expected);
434   g_slist_foreach (matches, free_match, NULL);
435   g_slist_free (matches);
436
437   return ret;
438 }
439
440 static gboolean
441 test_match_next (const gchar          *pattern,
442                  const gchar          *string,
443                  ...)
444 {
445   GRegex *regex;
446   va_list args;
447   GSList *matches = NULL;
448   GSList *expected = NULL;
449   GSList *l_exp, *l_match;
450   gboolean ret = TRUE;
451   
452   verbose ("matching \"%s\" against \"%s\" \t", string, pattern);
453
454   /* The va_list is a NULL-terminated sequence of: extected matched string,
455    * expected start and expected end. */
456   va_start (args, string);
457   while (TRUE)
458    {
459       Match *match;
460       const gchar *expected_string = va_arg (args, const gchar *);
461       if (expected_string == NULL)
462         break;
463       match = g_new0 (Match, 1);
464       match->string = g_strdup (expected_string);
465       match->start = va_arg (args, gint);
466       match->end = va_arg (args, gint);
467       expected = g_slist_prepend (expected, match);
468     }
469   expected = g_slist_reverse (expected);
470   va_end (args);
471
472   regex = g_regex_new (pattern, 0, 0, NULL);
473
474   while (g_regex_match_next (regex, string, 0))
475    {
476       Match *match = g_new0 (Match, 1);
477       match->string = g_regex_fetch (regex, 0, string);
478       match->start = UNTOUCHED;
479       match->end = UNTOUCHED;
480       g_regex_fetch_pos (regex, 0, &match->start, &match->end);
481       matches = g_slist_prepend (matches, match);
482    }
483   matches = g_slist_reverse (matches);
484
485   if (g_slist_length (matches) != g_slist_length (expected))
486     {
487       gint match_count = g_slist_length (matches);
488       g_print ("failed \t(got %d %s, expected %d)\n", match_count,
489                match_count == 1 ? "match" : "matches", 
490                g_slist_length (expected));
491       ret = FALSE;
492       goto exit;
493     }
494
495   l_exp = expected;
496   l_match =  matches;
497   while (l_exp != NULL)
498     {
499       Match *exp = l_exp->data;
500       Match *match = l_match->data;
501
502       if (!streq(exp->string, match->string))
503         {
504           g_print ("failed \t(got \"%s\", expected \"%s\")\n",
505                    match->string, exp->string);
506           ret = FALSE;
507           goto exit;
508         }
509
510       if (exp->start != match->start || exp->end != match->end)
511         {
512           g_print ("failed \t(got [%d, %d], expected [%d, %d])\n",
513                    match->start, match->end, exp->start, exp->end);
514           ret = FALSE;
515           goto exit;
516         }
517
518       l_exp = g_slist_next (l_exp);
519       l_match = g_slist_next (l_match);
520     }
521
522 exit:
523   if (ret)
524     {
525       gint count = g_slist_length (matches);
526       verbose ("passed (%d %s)\n", count, count == 1 ? "match" : "matches");
527     }
528
529   g_regex_free (regex);
530   g_slist_foreach (expected, free_match, NULL);
531   g_slist_free (expected);
532   g_slist_foreach (matches, free_match, NULL);
533   g_slist_free (matches);
534
535   return ret;
536 }
537
538 #define TEST_MATCH_NEXT0(pattern, string, string_len, start_position) { \
539   total++; \
540   if (test_match_next_full (pattern, string, string_len, start_position, NULL)) \
541     PASS; \
542   else \
543     FAIL; \
544   if (string_len == -1 && start_position == 0) \
545   { \
546     total++; \
547     if (test_match_next (pattern, string, NULL)) \
548       PASS; \
549     else \
550       FAIL; \
551   } \
552 }
553
554 #define TEST_MATCH_NEXT1(pattern, string, string_len, start_position, \
555                               t1, s1, e1) { \
556   total++; \
557   if (test_match_next_full (pattern, string, string_len, start_position, \
558                             t1, s1, e1, NULL)) \
559     PASS; \
560   else \
561     FAIL; \
562   if (string_len == -1 && start_position == 0) \
563   { \
564     total++; \
565     if (test_match_next (pattern, string, t1, s1, e1, NULL)) \
566       PASS; \
567     else \
568       FAIL; \
569   } \
570 }
571
572 #define TEST_MATCH_NEXT2(pattern, string, string_len, start_position, \
573                          t1, s1, e1, t2, s2, e2) { \
574   total++; \
575   if (test_match_next_full (pattern, string, string_len, start_position, \
576                             t1, s1, e1, t2, s2, e2, NULL)) \
577     PASS; \
578   else \
579     FAIL; \
580   if (string_len == -1 && start_position == 0) \
581   { \
582     total++; \
583     if (test_match_next (pattern, string, t1, s1, e1, t2, s2, e2, NULL)) \
584       PASS; \
585     else \
586       FAIL; \
587   } \
588 }
589
590 #define TEST_MATCH_NEXT3(pattern, string, string_len, start_position, \
591                          t1, s1, e1, t2, s2, e2, t3, s3, e3) { \
592   total++; \
593   if (test_match_next_full (pattern, string, string_len, start_position, \
594                             t1, s1, e1, t2, s2, e2, t3, s3, e3, NULL)) \
595     PASS; \
596   else \
597     FAIL; \
598   if (string_len == -1 && start_position == 0) \
599   { \
600     total++; \
601     if (test_match_next (pattern, string, t1, s1, e1, t2, s2, e2, t3, s3, e3, NULL)) \
602       PASS; \
603     else \
604       FAIL; \
605   } \
606 }
607
608 #define TEST_MATCH_NEXT4(pattern, string, string_len, start_position, \
609                          t1, s1, e1, t2, s2, e2, t3, s3, e3, t4, s4, e4) { \
610   total++; \
611   if (test_match_next_full (pattern, string, string_len, start_position, \
612                             t1, s1, e1, t2, s2, e2, t3, s3, e3, t4, s4, e4, NULL)) \
613     PASS; \
614   else \
615     FAIL; \
616   if (string_len == -1 && start_position == 0) \
617   { \
618     total++;\
619     if (test_match_next (pattern, string, t1, s1, e1, t2, s2, e2, t3, s3, e3, \
620                          t4, s4, e4, NULL)) \
621       PASS; \
622     else \
623       FAIL; \
624   } \
625 }
626
627 static gboolean
628 test_match_count (const gchar      *pattern,
629                   const gchar      *string,
630                   gint              start_position,
631                   GRegexMatchFlags  match_opts,
632                   gint              expected_count)
633 {
634   GRegex *regex;
635   gint count;
636   
637   verbose ("fetching match count (string: \"%s\", pattern: \"%s\", start: %d) \t",
638            string, pattern, start_position);
639
640   regex = g_regex_new (pattern, 0, 0, NULL);
641
642   g_regex_match_next_full (regex, string, -1, start_position,
643                            match_opts, NULL);
644   count = g_regex_get_match_count (regex);
645
646   if (count != expected_count)
647     {
648       g_print ("failed \t(got %d, expected: %d)\n", count, expected_count);
649       return FALSE;
650     }
651
652   g_regex_free (regex);
653
654   verbose ("passed\n");
655   return TRUE;
656 }
657
658 #define TEST_MATCH_COUNT(pattern, string, start_position, match_opts, expected_count) { \
659   total++; \
660   if (test_match_count (pattern, string, start_position, match_opts, expected_count)) \
661     PASS; \
662   else \
663     FAIL; \
664 }
665
666 static gboolean
667 test_partial (const gchar *pattern,
668               const gchar *string,
669               gboolean     expected)
670 {
671   GRegex *regex;
672   
673   verbose ("partial matching (string: \"%s\", pattern: \"%s\") \t",
674            string, pattern);
675
676   regex = g_regex_new (pattern, 0, 0, NULL);
677
678   g_regex_match (regex, string, G_REGEX_MATCH_PARTIAL);
679   if (expected != g_regex_is_partial_match (regex))
680     {
681       g_print ("failed \t(got %d, expected: %d)\n", !expected, expected);
682       g_regex_free (regex);
683       return FALSE;
684     }
685
686   if (expected && g_regex_fetch_pos (regex, 0, NULL, NULL))
687     {
688       g_print ("failed \t(got sub-pattern 0)\n");
689       g_regex_free (regex);
690       return FALSE;
691     }
692
693   if (expected && g_regex_fetch_pos (regex, 1, NULL, NULL))
694     {
695       g_print ("failed \t(got sub-pattern 1)\n");
696       g_regex_free (regex);
697       return FALSE;
698     }
699
700   g_regex_free (regex);
701
702   verbose ("passed\n");
703   return TRUE;
704 }
705
706 #define TEST_PARTIAL(pattern, string, expected) { \
707   total++; \
708   if (test_partial (pattern, string, expected)) \
709     PASS; \
710   else \
711     FAIL; \
712 }
713
714 static gboolean
715 test_clear (const gchar *pattern,
716             const gchar *string,
717             gint         start_position)
718 {
719   GRegex *regex;
720   gboolean match1, match2;
721   gint start1 = UNTOUCHED;
722   gint end1 = UNTOUCHED;
723   gint start2 = UNTOUCHED;
724   gint end2 = UNTOUCHED;
725   gchar *text1 = NULL;
726   gchar *text2 = NULL;
727   gboolean ret = TRUE;
728   
729   verbose ("testing clear with \"%s\" against \"%s\" (start: %d) \t",
730            string, pattern, start_position);
731
732   regex = g_regex_new (pattern, 0, 0, NULL);
733
734   match1 = g_regex_match_next_full (regex, string, UNTOUCHED, start_position,
735                                     0, NULL);
736   if (match1)
737     {
738       text1 = g_regex_fetch (regex, 0, string);
739       g_regex_fetch_pos (regex, 0, &start1, &end1);
740     }
741
742   g_regex_clear (regex);
743
744   match2 = g_regex_match_next_full (regex, string, UNTOUCHED, start_position,
745                                     0, NULL);
746   if (match2)
747     {
748       text2 = g_regex_fetch (regex, 0, string);
749       g_regex_fetch_pos (regex, 0, &start2, &end2);
750     }
751
752   if (match1 != match2)
753     {
754       g_print ("failed \t(different matches)\n");
755       ret = FALSE;
756     }
757   else if (match1)
758     {
759       if (!streq (text1, text2))
760         {
761           g_print ("failed \t(first: \"%s\", second: \"%s\")\n",
762                    text1, text2);
763           ret = FALSE;
764         }
765       if (start1 != start2 || end1 != end2)
766         {
767           g_print ("failed \t(first: [%d, %d], second: [%d, %d])\n",
768                    start1, end1, start2, end2);
769           ret = FALSE;
770         }
771     }
772
773   g_regex_free (regex);
774   g_free (text1);
775   g_free (text2);
776
777   if (ret)
778     verbose ("passed\n");
779
780   return ret;
781 }
782
783 #define TEST_CLEAR(pattern, string, start_position) { \
784   total++; \
785   if (test_clear (pattern, string, start_position)) \
786     PASS; \
787   else \
788     FAIL; \
789 }
790
791 static gboolean
792 test_sub_pattern (const gchar *pattern,
793                   const gchar *string,
794                   gint         start_position,
795                   gint         sub_n,
796                   const gchar *expected_sub,
797                   gint         expected_start,
798                   gint         expected_end)
799 {
800   GRegex *regex;
801   gchar *sub_expr;
802   gint start = UNTOUCHED, end = UNTOUCHED;
803
804   verbose ("fetching sub-pattern %d from \"%s\" (pattern: \"%s\") \t",
805            sub_n, string, pattern);
806
807   regex = g_regex_new (pattern, 0, 0, NULL);
808   g_regex_match_full (regex, string, -1, start_position, 0, NULL);
809
810   sub_expr = g_regex_fetch (regex, sub_n, string);
811   if (!streq(sub_expr, expected_sub))
812     {
813       g_print ("failed \t(got \"%s\", expected \"%s\")\n",
814                sub_expr, expected_sub);
815       g_free (sub_expr);
816       g_regex_free (regex);
817       return FALSE;
818     }
819   g_free (sub_expr);
820
821   g_regex_fetch_pos (regex, sub_n, &start, &end);
822   if (start != expected_start || end != expected_end)
823     {
824       g_print ("failed \t(got [%d, %d], expected [%d, %d])\n",
825                start, end, expected_start, expected_end);
826       g_regex_free (regex);
827       return FALSE;
828     }
829
830   /* Repeat the test to verify that g_regex_clear() is not needed. */
831   g_regex_match_full (regex, string, -1, start_position, 0, NULL);
832
833   sub_expr = g_regex_fetch (regex, sub_n, string);
834   if (!streq(sub_expr, expected_sub))
835     {
836       g_print ("failed \t(second match != first matchs)\n");
837       g_free (sub_expr);
838       g_regex_free (regex);
839       return FALSE;
840     }
841   g_free (sub_expr);
842
843   g_regex_fetch_pos (regex, sub_n, &start, &end);
844   if (start != expected_start || end != expected_end)
845     {
846       g_print ("failed \t(second match != first matchs)\n");
847       g_regex_free (regex);
848       return FALSE;
849     }
850
851
852   g_regex_free (regex);
853
854   verbose ("passed\n");
855   return TRUE;
856 }
857
858 #define TEST_SUB_PATTERN(pattern, string, start_position, sub_n, expected_sub, \
859                          expected_start, expected_end) { \
860   total++; \
861   if (test_sub_pattern (pattern, string, start_position, sub_n, expected_sub, \
862                         expected_start, expected_end)) \
863     PASS; \
864   else \
865     FAIL; \
866 }
867
868 static gboolean
869 test_named_sub_pattern (const gchar *pattern,
870                         const gchar *string,
871                         gint         start_position,
872                         const gchar *sub_name,
873                         const gchar *expected_sub,
874                         gint         expected_start,
875                         gint         expected_end)
876 {
877   GRegex *regex;
878   gint start = UNTOUCHED, end = UNTOUCHED;
879   gchar *sub_expr;
880
881   verbose ("fetching sub-pattern \"%s\" from \"%s\" (pattern: \"%s\") \t",
882            sub_name, string, pattern);
883
884   regex = g_regex_new (pattern, 0, 0, NULL);
885
886   g_regex_match_full (regex, string, -1, start_position, 0, NULL);
887   sub_expr = g_regex_fetch_named (regex, sub_name, string);
888   if (!streq (sub_expr, expected_sub))
889     {
890       g_print ("failed \t(got \"%s\", expected \"%s\")\n",
891                sub_expr, expected_sub);
892       g_free (sub_expr);
893       g_regex_free (regex);
894       return FALSE;
895     }
896   g_free (sub_expr);
897
898   g_regex_fetch_named_pos (regex, sub_name, &start, &end);
899   if (start != expected_start || end != expected_end)
900     {
901       g_print ("failed \t(got [%d, %d], expected [%d, %d])\n",
902                start, end, expected_start, expected_end);
903       g_regex_free (regex);
904       return FALSE;
905     }
906
907   g_regex_free (regex);
908
909   verbose ("passed\n");
910   return TRUE;
911 }
912
913 #define TEST_NAMED_SUB_PATTERN(pattern, string, start_position, sub_name, \
914                                expected_sub, expected_start, expected_end) { \
915   total++; \
916   if (test_named_sub_pattern (pattern, string, start_position, sub_name, \
917                               expected_sub, expected_start, expected_end)) \
918     PASS; \
919   else \
920     FAIL; \
921 }
922
923 static gboolean
924 test_fetch_all (const gchar *pattern,
925                 const gchar *string,
926                 ...)
927 {
928   GRegex *regex;
929   va_list args;
930   GSList *expected = NULL;
931   GSList *l_exp;
932   gchar **matches;
933   gint match_count;
934   gboolean ret = TRUE;
935   gint i;
936   
937   verbose ("fetching all sub-patterns from \"%s\" (pattern: \"%s\") \t",
938            string, pattern);
939
940   /* The va_list is a NULL-terminated sequence of extected strings. */
941   va_start (args, string);
942   while (TRUE)
943    {
944       gchar *expected_string = va_arg (args, gchar *);
945       if (expected_string == NULL)
946         break;
947       else
948         expected = g_slist_prepend (expected, g_strdup (expected_string));
949     }
950   expected = g_slist_reverse (expected);
951   va_end (args);
952
953   regex = g_regex_new (pattern, 0, 0, NULL);
954   g_regex_match (regex, string, 0);
955   matches = g_regex_fetch_all (regex, string);
956   if (matches)
957     match_count = g_strv_length (matches);
958   else
959     match_count = 0;
960
961   if (match_count != g_slist_length (expected))
962     {
963       g_print ("failed \t(got %d %s, expected %d)\n", match_count,
964                match_count == 1 ? "match" : "matches", 
965                g_slist_length (expected));
966       ret = FALSE;
967       goto exit;
968     }
969
970   l_exp = expected;
971   for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp))
972     {
973       if (!streq(l_exp->data, matches [i]))
974         {
975           g_print ("failed \t(got \"%s\", expected \"%s\")\n",
976                    matches [i], (gchar *)l_exp->data);
977           ret = FALSE;
978           goto exit;
979         }
980     }
981
982   verbose ("passed (%d %s)\n", match_count,
983            match_count == 1 ? "match" : "matches");
984
985 exit:
986   g_regex_free (regex);
987   g_slist_foreach (expected, (GFunc)g_free, NULL);
988   g_slist_free (expected);
989   g_strfreev (matches);
990
991   return ret;
992 }
993
994 #define TEST_FETCH_ALL0(pattern, string) { \
995   total++; \
996   if (test_fetch_all (pattern, string, NULL)) \
997     PASS; \
998   else \
999     FAIL; \
1000 }
1001
1002 #define TEST_FETCH_ALL1(pattern, string, e1) { \
1003   total++; \
1004   if (test_fetch_all (pattern, string, e1, NULL)) \
1005     PASS; \
1006   else \
1007     FAIL; \
1008 }
1009
1010 #define TEST_FETCH_ALL2(pattern, string, e1, e2) { \
1011   total++; \
1012   if (test_fetch_all (pattern, string, e1, e2, NULL)) \
1013     PASS; \
1014   else \
1015     FAIL; \
1016 }
1017
1018 #define TEST_FETCH_ALL3(pattern, string, e1, e2, e3) { \
1019   total++; \
1020   if (test_fetch_all (pattern, string, e1, e2, e3, NULL)) \
1021     PASS; \
1022   else \
1023     FAIL; \
1024 }
1025
1026 static gboolean
1027 test_split_simple (const gchar *pattern,
1028                    const gchar *string,
1029                    ...)
1030 {
1031   va_list args;
1032   GSList *expected = NULL;
1033   GSList *l_exp;
1034   gchar **tokens;
1035   gint token_count;
1036   gboolean ret = TRUE;
1037   gint i;
1038   
1039   verbose ("splitting \"%s\" against \"%s\" \t", string, pattern);
1040
1041   /* The va_list is a NULL-terminated sequence of extected strings. */
1042   va_start (args, string);
1043   while (TRUE)
1044    {
1045       gchar *expected_string = va_arg (args, gchar *);
1046       if (expected_string == NULL)
1047         break;
1048       else
1049         expected = g_slist_prepend (expected, g_strdup (expected_string));
1050     }
1051   expected = g_slist_reverse (expected);
1052   va_end (args);
1053
1054   tokens = g_regex_split_simple (pattern, string, 0, 0);
1055   if (tokens)
1056     token_count = g_strv_length (tokens);
1057   else
1058     token_count = 0;
1059
1060   if (token_count != g_slist_length (expected))
1061     {
1062       g_print ("failed \t(got %d %s, expected %d)\n", token_count,
1063                token_count == 1 ? "match" : "matches", 
1064                g_slist_length (expected));
1065       ret = FALSE;
1066       goto exit;
1067     }
1068
1069   l_exp = expected;
1070   for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp))
1071     {
1072       if (!streq(l_exp->data, tokens [i]))
1073         {
1074           g_print ("failed \t(got \"%s\", expected \"%s\")\n",
1075                    tokens[i], (gchar *)l_exp->data);
1076           ret = FALSE;
1077           goto exit;
1078         }
1079     }
1080
1081   verbose ("passed (%d %s)\n", token_count,
1082            token_count == 1 ? "token" : "tokens");
1083
1084 exit:
1085   g_slist_foreach (expected, (GFunc)g_free, NULL);
1086   g_slist_free (expected);
1087   g_strfreev (tokens);
1088
1089   return ret;
1090 }
1091
1092 #define TEST_SPLIT_SIMPLE0(pattern, string) { \
1093   total++; \
1094   if (test_split_simple (pattern, string, NULL)) \
1095     PASS; \
1096   else \
1097     FAIL; \
1098 }
1099
1100 #define TEST_SPLIT_SIMPLE1(pattern, string, e1) { \
1101   total++; \
1102   if (test_split_simple (pattern, string, e1, NULL)) \
1103     PASS; \
1104   else \
1105     FAIL; \
1106 }
1107
1108 #define TEST_SPLIT_SIMPLE2(pattern, string, e1, e2) { \
1109   total++; \
1110   if (test_split_simple (pattern, string, e1, e2, NULL)) \
1111     PASS; \
1112   else \
1113     FAIL; \
1114 }
1115
1116 #define TEST_SPLIT_SIMPLE3(pattern, string, e1, e2, e3) { \
1117   total++; \
1118   if (test_split_simple (pattern, string, e1, e2, e3, NULL)) \
1119     PASS; \
1120   else \
1121     FAIL; \
1122 }
1123
1124 static gboolean
1125 test_split_full (const gchar *pattern,
1126                  const gchar *string,
1127                  gint         start_position,
1128                  gint         max_tokens,
1129                  ...)
1130 {
1131   GRegex *regex;
1132   va_list args;
1133   GSList *expected = NULL;
1134   GSList *l_exp;
1135   gchar **tokens;
1136   gint token_count;
1137   gboolean ret = TRUE;
1138   gint i;
1139   
1140   verbose ("splitting \"%s\" against \"%s\" (start: %d, max: %d) \t",
1141            string, pattern, start_position, max_tokens);
1142
1143   /* The va_list is a NULL-terminated sequence of extected strings. */
1144   va_start (args, max_tokens);
1145   while (TRUE)
1146    {
1147       gchar *expected_string = va_arg (args, gchar *);
1148       if (expected_string == NULL)
1149         break;
1150       else
1151         expected = g_slist_prepend (expected, g_strdup (expected_string));
1152     }
1153   expected = g_slist_reverse (expected);
1154   va_end (args);
1155
1156   regex = g_regex_new (pattern, 0, 0, NULL);
1157   tokens = g_regex_split_full (regex, string, -1, start_position,
1158                                0, max_tokens, NULL);
1159   if (tokens)
1160     token_count = g_strv_length (tokens);
1161   else
1162     token_count = 0;
1163
1164   if (token_count != g_slist_length (expected))
1165     {
1166       g_print ("failed \t(got %d %s, expected %d)\n", token_count,
1167                token_count == 1 ? "match" : "matches", 
1168                g_slist_length (expected));
1169       ret = FALSE;
1170       goto exit;
1171     }
1172
1173   l_exp = expected;
1174   for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp))
1175     {
1176       if (!streq(l_exp->data, tokens [i]))
1177         {
1178           g_print ("failed \t(got \"%s\", expected \"%s\")\n",
1179                    tokens[i], (gchar *)l_exp->data);
1180           ret = FALSE;
1181           goto exit;
1182         }
1183     }
1184
1185   verbose ("passed (%d %s)\n", token_count,
1186            token_count == 1 ? "token" : "tokens");
1187
1188 exit:
1189   g_regex_free (regex);
1190   g_slist_foreach (expected, (GFunc)g_free, NULL);
1191   g_slist_free (expected);
1192   g_strfreev (tokens);
1193
1194   return ret;
1195 }
1196
1197 static gboolean
1198 test_split (const gchar *pattern,
1199             const gchar *string,
1200             ...)
1201 {
1202   GRegex *regex;
1203   va_list args;
1204   GSList *expected = NULL;
1205   GSList *l_exp;
1206   gchar **tokens;
1207   gint token_count;
1208   gboolean ret = TRUE;
1209   gint i;
1210   
1211   verbose ("splitting \"%s\" against \"%s\" \t", string, pattern);
1212
1213   /* The va_list is a NULL-terminated sequence of extected strings. */
1214   va_start (args, string);
1215   while (TRUE)
1216    {
1217       gchar *expected_string = va_arg (args, gchar *);
1218       if (expected_string == NULL)
1219         break;
1220       else
1221         expected = g_slist_prepend (expected, g_strdup (expected_string));
1222     }
1223   expected = g_slist_reverse (expected);
1224   va_end (args);
1225
1226   regex = g_regex_new (pattern, 0, 0, NULL);
1227   tokens = g_regex_split (regex, string, 0);
1228   if (tokens)
1229     token_count = g_strv_length (tokens);
1230   else
1231     token_count = 0;
1232
1233   if (token_count != g_slist_length (expected))
1234     {
1235       g_print ("failed \t(got %d %s, expected %d)\n", token_count,
1236                token_count == 1 ? "match" : "matches", 
1237                g_slist_length (expected));
1238       ret = FALSE;
1239       goto exit;
1240     }
1241
1242   l_exp = expected;
1243   for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp))
1244     {
1245       if (!streq(l_exp->data, tokens [i]))
1246         {
1247           g_print ("failed \t(got \"%s\", expected \"%s\")\n",
1248                    tokens[i], (gchar *)l_exp->data);
1249           ret = FALSE;
1250           goto exit;
1251         }
1252     }
1253
1254   verbose ("passed (%d %s)\n", token_count,
1255            token_count == 1 ? "token" : "tokens");
1256
1257 exit:
1258   g_regex_free (regex);
1259   g_slist_foreach (expected, (GFunc)g_free, NULL);
1260   g_slist_free (expected);
1261   g_strfreev (tokens);
1262
1263   return ret;
1264 }
1265
1266 #define TEST_SPLIT0(pattern, string, start_position, max_tokens) { \
1267   total++; \
1268   if (test_split_full (pattern, string, start_position, max_tokens, NULL)) \
1269     PASS; \
1270   else \
1271     FAIL; \
1272   if (start_position == 0 && max_tokens <= 0) \
1273   { \
1274     total++; \
1275     if (test_split (pattern, string, NULL)) \
1276       PASS; \
1277     else \
1278       FAIL; \
1279   } \
1280 }
1281
1282 #define TEST_SPLIT1(pattern, string, start_position, max_tokens, e1) { \
1283   total++; \
1284   if (test_split_full (pattern, string, start_position, max_tokens, e1, NULL)) \
1285     PASS; \
1286   else \
1287     FAIL; \
1288   if (start_position == 0 && max_tokens <= 0) \
1289   { \
1290     total++; \
1291     if (test_split (pattern, string, e1, NULL)) \
1292       PASS; \
1293     else \
1294       FAIL; \
1295   } \
1296 }
1297
1298 #define TEST_SPLIT2(pattern, string, start_position, max_tokens, e1, e2) { \
1299   total++; \
1300   if (test_split_full (pattern, string, start_position, max_tokens, e1, e2, NULL)) \
1301     PASS; \
1302   else \
1303     FAIL; \
1304   if (start_position == 0 && max_tokens <= 0) \
1305   { \
1306     total++; \
1307     if (test_split (pattern, string, e1, e2, NULL)) \
1308       PASS; \
1309     else \
1310       FAIL; \
1311   } \
1312 }
1313
1314 #define TEST_SPLIT3(pattern, string, start_position, max_tokens, e1, e2, e3) { \
1315   total++; \
1316   if (test_split_full (pattern, string, start_position, max_tokens, e1, e2, e3, NULL)) \
1317     PASS; \
1318   else \
1319     FAIL; \
1320   if (start_position == 0 && max_tokens <= 0) \
1321   { \
1322     total++; \
1323     if (test_split (pattern, string, e1, e2, e3, NULL)) \
1324       PASS; \
1325     else \
1326       FAIL; \
1327   } \
1328 }
1329
1330 static gboolean
1331 test_split_next_full (const gchar *pattern,
1332                       const gchar *string,
1333                       gint         start_position,
1334                       ...)
1335 {
1336   GRegex *regex;
1337   va_list args;
1338   GSList *expected = NULL;
1339   GSList *tokens;
1340   GSList *l_exp, *l_token;
1341   gint token_count;
1342   gchar *token;
1343   gboolean ret = TRUE;
1344   
1345   verbose ("splitting \"%s\" against \"%s\" (start: %d) \t",
1346            string, pattern, start_position);
1347
1348   /* The va_list is a NULL-terminated sequence of extected strings. */
1349   va_start (args, start_position);
1350   while (TRUE)
1351    {
1352       gchar *expected_string = va_arg (args, gchar *);
1353       if (expected_string == NULL)
1354         break;
1355       else
1356         expected = g_slist_prepend (expected, g_strdup (expected_string));
1357     }
1358   expected = g_slist_reverse (expected);
1359   va_end (args);
1360
1361   regex = g_regex_new (pattern, 0, 0, NULL);
1362
1363   tokens = NULL;
1364   while ((token = g_regex_split_next_full (regex, string, -1,
1365                                            start_position, 0, NULL)))
1366     {
1367       tokens = g_slist_prepend (tokens, token);
1368     }
1369   tokens = g_slist_reverse (tokens);
1370   token_count = g_slist_length (tokens);
1371
1372   if (token_count != g_slist_length (expected))
1373     {
1374       g_print ("failed \t(got %d %s, expected %d)\n", token_count,
1375                token_count == 1 ? "match" : "matches", 
1376                g_slist_length (expected));
1377       ret = FALSE;
1378       goto exit;
1379     }
1380
1381   l_exp = expected;
1382   l_token = tokens;
1383   while (l_exp != NULL)
1384     {
1385       if (!streq(l_exp->data, l_token->data))
1386         {
1387           g_print ("failed \t(got \"%s\", expected \"%s\")\n",
1388                    (gchar *)l_token->data, (gchar *)l_exp->data);
1389           ret = FALSE;
1390           goto exit;
1391         }
1392
1393       l_exp = g_slist_next (l_exp);
1394       l_token = g_slist_next (l_token);
1395     }
1396
1397   verbose ("passed (%d %s)\n", token_count,
1398            token_count == 1 ? "token" : "tokens");
1399
1400 exit:
1401   g_regex_free (regex);
1402   g_slist_foreach (expected, (GFunc)g_free, NULL);
1403   g_slist_free (expected);
1404   g_slist_foreach (tokens, (GFunc)g_free, NULL);
1405   g_slist_free (tokens);
1406
1407   return ret;
1408 }
1409
1410 static gboolean
1411 test_split_next (const gchar *pattern,
1412                  const gchar *string,
1413                  ...)
1414 {
1415   GRegex *regex;
1416   va_list args;
1417   GSList *expected = NULL;
1418   GSList *tokens;
1419   GSList *l_exp, *l_token;
1420   gint token_count;
1421   gchar *token;
1422   gboolean ret = TRUE;
1423   
1424   verbose ("splitting \"%s\" against \"%s\" \t", string, pattern);
1425
1426   /* The va_list is a NULL-terminated sequence of extected strings. */
1427   va_start (args, string);
1428   while (TRUE)
1429    {
1430       gchar *expected_string = va_arg (args, gchar *);
1431       if (expected_string == NULL)
1432         break;
1433       else
1434         expected = g_slist_prepend (expected, g_strdup (expected_string));
1435     }
1436   expected = g_slist_reverse (expected);
1437   va_end (args);
1438
1439   regex = g_regex_new (pattern, 0, 0, NULL);
1440
1441   tokens = NULL;
1442   while ((token = g_regex_split_next (regex, string, 0)))
1443     {
1444       tokens = g_slist_prepend (tokens, token);
1445     }
1446   tokens = g_slist_reverse (tokens);
1447   token_count = g_slist_length (tokens);
1448
1449   if (token_count != g_slist_length (expected))
1450     {
1451       g_print ("failed \t(got %d %s, expected %d)\n", token_count,
1452                token_count == 1 ? "match" : "matches", 
1453                g_slist_length (expected));
1454       ret = FALSE;
1455       goto exit;
1456     }
1457
1458   l_exp = expected;
1459   l_token = tokens;
1460   while (l_exp != NULL)
1461     {
1462       if (!streq(l_exp->data, l_token->data))
1463         {
1464           g_print ("failed \t(got \"%s\", expected \"%s\")\n",
1465                    (gchar *)l_token->data, (gchar *)l_exp->data);
1466           ret = FALSE;
1467           goto exit;
1468         }
1469
1470       l_exp = g_slist_next (l_exp);
1471       l_token = g_slist_next (l_token);
1472     }
1473
1474   verbose ("passed (%d %s)\n", token_count,
1475            token_count == 1 ? "token" : "tokens");
1476
1477 exit:
1478   g_regex_free (regex);
1479   g_slist_foreach (expected, (GFunc)g_free, NULL);
1480   g_slist_free (expected);
1481   g_slist_foreach (tokens, (GFunc)g_free, NULL);
1482   g_slist_free (tokens);
1483
1484   return ret;
1485 }
1486
1487 #define TEST_SPLIT_NEXT1(pattern, string, start_position, e1) { \
1488   total++; \
1489   if (test_split_next_full (pattern, string, start_position, e1, NULL)) \
1490     PASS; \
1491   else \
1492     FAIL; \
1493   if (start_position == 0) \
1494   { \
1495     total++; \
1496     if (test_split_next (pattern, string, e1, NULL)) \
1497       PASS; \
1498     else \
1499       FAIL; \
1500   } \
1501 }
1502
1503 #define TEST_SPLIT_NEXT2(pattern, string, start_position, e1, e2) { \
1504   total++; \
1505   if (test_split_next_full (pattern, string, start_position, e1, e2, NULL)) \
1506     PASS; \
1507   else \
1508     FAIL; \
1509   if (start_position == 0) \
1510   { \
1511     total++; \
1512     if (test_split_next (pattern, string, e1, e2, NULL)) \
1513       PASS; \
1514     else \
1515       FAIL; \
1516   } \
1517 }
1518
1519 #define TEST_SPLIT_NEXT3(pattern, string, start_position, e1, e2, e3) { \
1520   total++; \
1521   if (test_split_next_full (pattern, string, start_position, e1, e2, e3, NULL)) \
1522     PASS; \
1523   else \
1524     FAIL; \
1525   if (start_position == 0) \
1526   { \
1527     total++; \
1528     if (test_split_next (pattern, string, e1, e2, e3, NULL)) \
1529       PASS; \
1530     else \
1531       FAIL; \
1532   } \
1533 }
1534
1535 static gboolean
1536 test_expand (const gchar *pattern,
1537              const gchar *string,
1538              const gchar *string_to_expand,
1539              gboolean     raw,
1540              const gchar *expected)
1541 {
1542   GRegex *regex;
1543   gchar *res;
1544   
1545   verbose ("expanding the references in \"%s\" (pattern: \"%s\", string: \"%s\") \t",
1546            string_to_expand, pattern, string);
1547
1548   regex = g_regex_new (pattern, raw ? G_REGEX_RAW : 0, 0, NULL);
1549   g_regex_match (regex, string, 0);
1550   res = g_regex_expand_references (regex, string, string_to_expand, NULL);
1551   if (!streq (res, expected))
1552     {
1553       g_print ("failed \t(got \"%s\", expected \"%s\")\n", res, expected);
1554       g_free (res);
1555       g_regex_free (regex);
1556       return FALSE;
1557     }
1558
1559   g_free (res);
1560   g_regex_free (regex);
1561
1562   verbose ("passed\n");
1563   return TRUE;
1564 }
1565
1566 #define TEST_EXPAND(pattern, string, string_to_expand, raw, expected) { \
1567   total++; \
1568   if (test_expand (pattern, string, string_to_expand, raw, expected)) \
1569     PASS; \
1570   else \
1571     FAIL; \
1572 }
1573
1574 static gboolean
1575 test_replace (const gchar *pattern,
1576               const gchar *string,
1577               gint         start_position,
1578               const gchar *replacement,
1579               const gchar *expected)
1580 {
1581   GRegex *regex;
1582   gchar *res;
1583   
1584   verbose ("replacing \"%s\" in \"%s\" (pattern: \"%s\", start: %d) \t",
1585            replacement, string, pattern, start_position);
1586
1587   regex = g_regex_new (pattern, 0, 0, NULL);
1588   res = g_regex_replace (regex, string, -1, start_position, replacement, 0, NULL);
1589   if (!streq (res, expected))
1590     {
1591       g_print ("failed \t(got \"%s\", expected \"%s\")\n", res, expected);
1592       g_free (res);
1593       g_regex_free (regex);
1594       return FALSE;
1595     }
1596
1597   g_free (res);
1598   g_regex_free (regex);
1599
1600   verbose ("passed\n");
1601   return TRUE;
1602 }
1603
1604 #define TEST_REPLACE(pattern, string, start_position, replacement, expected) { \
1605   total++; \
1606   if (test_replace (pattern, string, start_position, replacement, expected)) \
1607     PASS; \
1608   else \
1609     FAIL; \
1610 }
1611
1612 static gboolean
1613 test_replace_lit (const gchar *pattern,
1614                   const gchar *string,
1615                   gint         start_position,
1616                   const gchar *replacement,
1617                   const gchar *expected)
1618 {
1619   GRegex *regex;
1620   gchar *res;
1621   
1622   verbose ("replacing literally \"%s\" in \"%s\" (pattern: \"%s\", start: %d) \t",
1623            replacement, string, pattern, start_position);
1624
1625   regex = g_regex_new (pattern, 0, 0, NULL);
1626   res = g_regex_replace_literal (regex, string, -1, start_position,
1627                                  replacement, 0, NULL);
1628   if (!streq (res, expected))
1629     {
1630       g_print ("failed \t(got \"%s\", expected \"%s\")\n", res, expected);
1631       g_free (res);
1632       g_regex_free (regex);
1633       return FALSE;
1634     }
1635
1636   g_free (res);
1637   g_regex_free (regex);
1638
1639   verbose ("passed\n");
1640   return TRUE;
1641 }
1642
1643 #define TEST_REPLACE_LIT(pattern, string, start_position, replacement, expected) { \
1644   total++; \
1645   if (test_replace_lit (pattern, string, start_position, replacement, expected)) \
1646     PASS; \
1647   else \
1648     FAIL; \
1649 }
1650
1651 static gboolean
1652 test_get_string_number (const gchar *pattern,
1653                         const gchar *name,
1654                         gint         expected_num)
1655 {
1656   GRegex *regex;
1657   gint num;
1658   
1659   verbose ("getting the number of \"%s\" (pattern: \"%s\") \t",
1660            name, pattern);
1661
1662   regex = g_regex_new (pattern, 0, 0, NULL);
1663   num = g_regex_get_string_number (regex, name);
1664   g_regex_free (regex);
1665
1666   if (num != expected_num)
1667     {
1668       g_print ("failed \t(got %d, expected %d)\n", num, expected_num);
1669       return FALSE;
1670     }
1671   else
1672     {
1673       verbose ("passed\n");
1674       return TRUE;
1675     }
1676 }
1677
1678 #define TEST_GET_STRING_NUMBER(pattern, name, expected_num) { \
1679   total++; \
1680   if (test_get_string_number (pattern, name, expected_num)) \
1681     PASS; \
1682   else \
1683     FAIL; \
1684 }
1685
1686 static gboolean
1687 test_escape (const gchar *string,
1688              gint         length,
1689              const gchar *expected)
1690 {
1691   gchar *escaped;
1692   
1693   verbose ("escaping \"%s\" (len: %d) \t", string, length);
1694
1695   escaped = g_regex_escape_string (string, length);
1696
1697   if (!streq (escaped, expected))
1698     {
1699       g_print ("failed \t(got \"%s\", expected \"%s\")\n", escaped, expected);
1700       g_free (escaped);
1701       return FALSE;
1702     }
1703
1704   g_free (escaped);
1705
1706   verbose ("passed\n");
1707   return TRUE;
1708 }
1709
1710 #define TEST_ESCAPE(string, length, expected) { \
1711   total++; \
1712   if (test_escape (string, length, expected)) \
1713     PASS; \
1714   else \
1715     FAIL; \
1716 }
1717
1718 static gboolean
1719 test_match_all_full (const gchar *pattern,
1720                      const gchar *string,
1721                      gssize       string_len,
1722                      gint         start_position,
1723                      ...)
1724 {
1725   GRegex *regex;
1726   va_list args;
1727   GSList *expected = NULL;
1728   GSList *l_exp;
1729   gboolean match_ok;
1730   gboolean ret = TRUE;
1731   gint match_count;
1732   gint i;
1733   
1734   verbose ("matching all in \"%s\" against \"%s\" (start: %d, len: %d) \t",
1735            string, pattern, start_position, string_len);
1736
1737   /* The va_list is a NULL-terminated sequence of: extected matched string,
1738    * expected start and expected end. */
1739   va_start (args, start_position);
1740   while (TRUE)
1741    {
1742       Match *match;
1743       const gchar *expected_string = va_arg (args, const gchar *);
1744       if (expected_string == NULL)
1745         break;
1746       match = g_new0 (Match, 1);
1747       match->string = g_strdup (expected_string);
1748       match->start = va_arg (args, gint);
1749       match->end = va_arg (args, gint);
1750       expected = g_slist_prepend (expected, match);
1751     }
1752   expected = g_slist_reverse (expected);
1753   va_end (args);
1754
1755   regex = g_regex_new (pattern, 0, 0, NULL);
1756   match_ok = g_regex_match_all_full (regex, string, string_len,
1757                                      start_position, 0, NULL);
1758
1759   if (match_ok && g_slist_length (expected) == 0)
1760     {
1761       g_print ("failed\n");
1762       ret = FALSE;
1763       goto exit;
1764     }
1765   if (!match_ok && g_slist_length (expected) != 0)
1766     {
1767       g_print ("failed\n");
1768       ret = FALSE;
1769       goto exit;
1770     }
1771
1772   match_count = g_regex_get_match_count (regex);
1773   if (match_count != g_slist_length (expected))
1774     {
1775       g_print ("failed \t(got %d %s, expected %d)\n", match_count,
1776                match_count == 1 ? "match" : "matches", 
1777                g_slist_length (expected));
1778       ret = FALSE;
1779       goto exit;
1780     }
1781
1782   l_exp = expected;
1783   for (i = 0; i < match_count; i++)
1784     {
1785       gint start, end;
1786       gchar *matched_string;
1787       Match *exp = l_exp->data;
1788
1789       matched_string = g_regex_fetch (regex, i, string);
1790       g_regex_fetch_pos (regex, i, &start, &end);
1791
1792       if (!streq(exp->string, matched_string))
1793         {
1794           g_print ("failed \t(got \"%s\", expected \"%s\")\n",
1795                    matched_string, exp->string);
1796           g_free (matched_string);
1797           ret = FALSE;
1798           goto exit;
1799         }
1800       g_free (matched_string);
1801
1802       if (exp->start != start || exp->end != end)
1803         {
1804           g_print ("failed \t(got [%d, %d], expected [%d, %d])\n",
1805                    start, end, exp->start, exp->end);
1806           ret = FALSE;
1807           goto exit;
1808         }
1809
1810       l_exp = g_slist_next (l_exp);
1811     }
1812
1813 exit:
1814   if (ret)
1815     {
1816       verbose ("passed (%d %s)\n", match_count, match_count == 1 ? "match" : "matches");
1817     }
1818
1819   g_regex_free (regex);
1820   g_slist_foreach (expected, free_match, NULL);
1821   g_slist_free (expected);
1822
1823   return ret;
1824 }
1825
1826 static gboolean
1827 test_match_all (const gchar *pattern,
1828                 const gchar *string,
1829                 ...)
1830 {
1831   GRegex *regex;
1832   va_list args;
1833   GSList *expected = NULL;
1834   GSList *l_exp;
1835   gboolean match_ok;
1836   gboolean ret = TRUE;
1837   gint match_count;
1838   gint i;
1839   
1840   verbose ("matching all in \"%s\" against \"%s\" \t", string, pattern);
1841
1842   /* The va_list is a NULL-terminated sequence of: extected matched string,
1843    * expected start and expected end. */
1844   va_start (args, string);
1845   while (TRUE)
1846    {
1847       Match *match;
1848       const gchar *expected_string = va_arg (args, const gchar *);
1849       if (expected_string == NULL)
1850         break;
1851       match = g_new0 (Match, 1);
1852       match->string = g_strdup (expected_string);
1853       match->start = va_arg (args, gint);
1854       match->end = va_arg (args, gint);
1855       expected = g_slist_prepend (expected, match);
1856     }
1857   expected = g_slist_reverse (expected);
1858   va_end (args);
1859
1860   regex = g_regex_new (pattern, 0, 0, NULL);
1861   match_ok = g_regex_match_all (regex, string, 0);
1862
1863   if (match_ok && g_slist_length (expected) == 0)
1864     {
1865       g_print ("failed\n");
1866       ret = FALSE;
1867       goto exit;
1868     }
1869   if (!match_ok && g_slist_length (expected) != 0)
1870     {
1871       g_print ("failed\n");
1872       ret = FALSE;
1873       goto exit;
1874     }
1875
1876   match_count = g_regex_get_match_count (regex);
1877   if (match_count != g_slist_length (expected))
1878     {
1879       g_print ("failed \t(got %d %s, expected %d)\n", match_count,
1880                match_count == 1 ? "match" : "matches", 
1881                g_slist_length (expected));
1882       ret = FALSE;
1883       goto exit;
1884     }
1885
1886   l_exp = expected;
1887   for (i = 0; i < match_count; i++)
1888     {
1889       gint start, end;
1890       gchar *matched_string;
1891       Match *exp = l_exp->data;
1892
1893       matched_string = g_regex_fetch (regex, i, string);
1894       g_regex_fetch_pos (regex, i, &start, &end);
1895
1896       if (!streq(exp->string, matched_string))
1897         {
1898           g_print ("failed \t(got \"%s\", expected \"%s\")\n",
1899                    matched_string, exp->string);
1900           g_free (matched_string);
1901           ret = FALSE;
1902           goto exit;
1903         }
1904       g_free (matched_string);
1905
1906       if (exp->start != start || exp->end != end)
1907         {
1908           g_print ("failed \t(got [%d, %d], expected [%d, %d])\n",
1909                    start, end, exp->start, exp->end);
1910           ret = FALSE;
1911           goto exit;
1912         }
1913
1914       l_exp = g_slist_next (l_exp);
1915     }
1916
1917 exit:
1918   if (ret)
1919     {
1920       verbose ("passed (%d %s)\n", match_count, match_count == 1 ? "match" : "matches");
1921     }
1922
1923   g_regex_free (regex);
1924   g_slist_foreach (expected, free_match, NULL);
1925   g_slist_free (expected);
1926
1927   return ret;
1928 }
1929
1930 #define TEST_MATCH_ALL0(pattern, string, string_len, start_position) { \
1931   total++; \
1932   if (test_match_all_full (pattern, string, string_len, start_position, NULL)) \
1933     PASS; \
1934   else \
1935     FAIL; \
1936   if (string_len == -1 && start_position == 0) \
1937   { \
1938     total++; \
1939     if (test_match_all (pattern, string, NULL)) \
1940       PASS; \
1941     else \
1942       FAIL; \
1943   } \
1944 }
1945
1946 #define TEST_MATCH_ALL1(pattern, string, string_len, start_position, \
1947                         t1, s1, e1) { \
1948   total++; \
1949   if (test_match_all_full (pattern, string, string_len, start_position, \
1950                            t1, s1, e1, NULL)) \
1951     PASS; \
1952   else \
1953     FAIL; \
1954   if (string_len == -1 && start_position == 0) \
1955   { \
1956     total++; \
1957     if (test_match_all (pattern, string, t1, s1, e1, NULL)) \
1958       PASS; \
1959     else \
1960       FAIL; \
1961   } \
1962 }
1963
1964 #define TEST_MATCH_ALL2(pattern, string, string_len, start_position, \
1965                         t1, s1, e1, t2, s2, e2) { \
1966   total++; \
1967   if (test_match_all_full (pattern, string, string_len, start_position, \
1968                            t1, s1, e1, t2, s2, e2, NULL)) \
1969     PASS; \
1970   else \
1971     FAIL; \
1972   if (string_len == -1 && start_position == 0) \
1973   { \
1974     total++; \
1975     if (test_match_all (pattern, string, t1, s1, e1, t2, s2, e2, NULL)) \
1976       PASS; \
1977     else \
1978       FAIL; \
1979   } \
1980 }
1981
1982 #define TEST_MATCH_ALL3(pattern, string, string_len, start_position, \
1983                         t1, s1, e1, t2, s2, e2, t3, s3, e3) { \
1984   total++; \
1985   if (test_match_all_full (pattern, string, string_len, start_position, \
1986                            t1, s1, e1, t2, s2, e2, t3, s3, e3, NULL)) \
1987     PASS; \
1988   else \
1989     FAIL; \
1990   if (string_len == -1 && start_position == 0) \
1991   { \
1992     total++; \
1993     if (test_match_all (pattern, string, t1, s1, e1, t2, s2, e2, t3, s3, e3, NULL)) \
1994       PASS; \
1995     else \
1996       FAIL; \
1997   } \
1998 }
1999
2000 #define TEST_NULL_MATCH(code) \
2001   G_STMT_START \
2002     { \
2003       GRegex *re = g_regex_new ("a", 0, 0, NULL); \
2004       verbose ("trying '" #code "' on a clean regex \t"); \
2005       code; \
2006       g_regex_free (re); \
2007       re = g_regex_new ("a", 0, 0, NULL); \
2008       g_regex_match (re, "b", 0); \
2009       g_regex_clear (re); \
2010       code; \
2011       g_regex_free (re); \
2012       /* this test always passes if the code does not crash */ \
2013       PASS; \
2014       verbose ("passed\n"); \
2015     } \
2016   G_STMT_END
2017
2018 #define TEST_NULL_MATCH_RET(code, expected, type, format) \
2019   G_STMT_START \
2020     { \
2021       type ret; \
2022       GRegex *re = g_regex_new ("a", 0, 0, NULL); \
2023       verbose ("trying '" #code "' on a clean regex \t"); \
2024       ret = code; \
2025       g_regex_free (re); \
2026       if (ret != expected) \
2027         { \
2028           g_print ("failed \t(got '" format "', expected '" format \
2029                    "', with a newly created regex)\n", ret, expected); \
2030           FAIL; \
2031         } \
2032       else \
2033         { \
2034           re = g_regex_new ("a", 0, 0, NULL); \
2035           g_regex_match (re, "a", 0); \
2036           g_regex_clear (re); \
2037           ret = code; \
2038           g_regex_free (re); \
2039           if (ret != expected) \
2040             { \
2041               g_print ("failed \t(got " format ", expected " format \
2042                        ", with a cleared regex)\n", ret, expected); \
2043               FAIL; \
2044             } \
2045           else \
2046             { \
2047               verbose ("passed\n"); \
2048               PASS; \
2049             } \
2050         } \
2051     } \
2052   G_STMT_END
2053
2054 int
2055 main (int argc, char *argv[])
2056 {
2057   gint total = 0;
2058   gint passed = 0;
2059   gint failed = 0;
2060   gint i = 0;
2061
2062   setlocale (LC_ALL, "");
2063
2064   for (i = 1; i < argc; i++)
2065     {
2066       if (streq ("--noisy", argv[i]))
2067         noisy = TRUE;
2068       else if (streq ("--abort", argv[i]))
2069         abort_on_fail = TRUE;
2070     }
2071
2072   g_setenv ("G_DEBUG", "fatal_warnings", TRUE);
2073
2074   /* TEST_NEW(pattern, compile_opts, match_opts) */
2075   TEST_NEW("", 0, 0);
2076   TEST_NEW(".*", 0, 0);
2077   TEST_NEW(".*", G_REGEX_MULTILINE, 0);
2078   TEST_NEW(".*", G_REGEX_DOTALL, 0);
2079   TEST_NEW(".*", G_REGEX_DOTALL, G_REGEX_MATCH_NOTBOL);
2080   TEST_NEW("(123\\d*)[a-zA-Z]+(?P<hello>.*)", 0, 0);
2081   TEST_NEW("(123\\d*)[a-zA-Z]+(?P<hello>.*)", G_REGEX_CASELESS, 0);
2082   TEST_NEW("(?P<A>x)|(?P<A>y)", G_REGEX_DUPNAMES, 0);
2083   /* This gives "internal error: code overflow" with pcre 6.0 */
2084   TEST_NEW("(?i)(?-i)", 0, 0);
2085
2086   /* TEST_NEW_FAIL(pattern, compile_opts) */
2087   TEST_NEW_FAIL("(", 0);
2088   TEST_NEW_FAIL(")", 0);
2089   TEST_NEW_FAIL("[", 0);
2090   TEST_NEW_FAIL("*", 0);
2091   TEST_NEW_FAIL("?", 0);
2092   TEST_NEW_FAIL("(?P<A>x)|(?P<A>y)", 0);
2093
2094   /* TEST_COPY(pattern) */
2095   TEST_COPY("");
2096   TEST_COPY(".*");
2097   TEST_COPY("a|b");
2098   TEST_COPY("(123\\d*)[a-zA-Z]+(?P<hello>.*)");
2099   /* Test if g_regex_copy() works with null regexes. */
2100   TEST_COPY("(");
2101
2102   /* TEST_MATCH_SIMPLE(pattern, string, compile_opts, match_opts, expected) */
2103   TEST_MATCH_SIMPLE("a", "", 0, 0, FALSE);
2104   TEST_MATCH_SIMPLE("a", "a", 0, 0, TRUE);
2105   TEST_MATCH_SIMPLE("a", "ba", 0, 0, TRUE);
2106   TEST_MATCH_SIMPLE("^a", "ba", 0, 0, FALSE);
2107   TEST_MATCH_SIMPLE("a", "ba", G_REGEX_ANCHORED, 0, FALSE);
2108   TEST_MATCH_SIMPLE("a", "ba", 0, G_REGEX_MATCH_ANCHORED, FALSE);
2109   TEST_MATCH_SIMPLE("a", "ab", G_REGEX_ANCHORED, 0, TRUE);
2110   TEST_MATCH_SIMPLE("a", "ab", 0, G_REGEX_MATCH_ANCHORED, TRUE);
2111   TEST_MATCH_SIMPLE("a", "a", G_REGEX_CASELESS, 0, TRUE);
2112   TEST_MATCH_SIMPLE("a", "A", G_REGEX_CASELESS, 0, TRUE);
2113   /* These are needed to test extended properties. */
2114   TEST_MATCH_SIMPLE(AGRAVE, AGRAVE, G_REGEX_CASELESS, 0, TRUE);
2115   TEST_MATCH_SIMPLE(AGRAVE, AGRAVE_UPPER, G_REGEX_CASELESS, 0, TRUE);
2116   TEST_MATCH_SIMPLE("\\p{L}", "a", 0, 0, TRUE);
2117   TEST_MATCH_SIMPLE("\\p{L}", "1", 0, 0, FALSE);
2118   TEST_MATCH_SIMPLE("\\p{L}", AGRAVE, 0, 0, TRUE);
2119   TEST_MATCH_SIMPLE("\\p{L}", AGRAVE_UPPER, 0, 0, TRUE);
2120   TEST_MATCH_SIMPLE("\\p{L}", SHEEN, 0, 0, TRUE);
2121   TEST_MATCH_SIMPLE("\\p{L}", ETH30, 0, 0, FALSE);
2122   TEST_MATCH_SIMPLE("\\p{Ll}", "a", 0, 0, TRUE);
2123   TEST_MATCH_SIMPLE("\\p{Ll}", AGRAVE, 0, 0, TRUE);
2124   TEST_MATCH_SIMPLE("\\p{Ll}", AGRAVE_UPPER, 0, 0, FALSE);
2125   TEST_MATCH_SIMPLE("\\p{Ll}", ETH30, 0, 0, FALSE);
2126   TEST_MATCH_SIMPLE("\\p{Sc}", AGRAVE, 0, 0, FALSE);
2127   TEST_MATCH_SIMPLE("\\p{Sc}", EURO, 0, 0, TRUE);
2128   TEST_MATCH_SIMPLE("\\p{Sc}", ETH30, 0, 0, FALSE);
2129   TEST_MATCH_SIMPLE("\\p{N}", "a", 0, 0, FALSE);
2130   TEST_MATCH_SIMPLE("\\p{N}", "1", 0, 0, TRUE);
2131   TEST_MATCH_SIMPLE("\\p{N}", AGRAVE, 0, 0, FALSE);
2132   TEST_MATCH_SIMPLE("\\p{N}", AGRAVE_UPPER, 0, 0, FALSE);
2133   TEST_MATCH_SIMPLE("\\p{N}", SHEEN, 0, 0, FALSE);
2134   TEST_MATCH_SIMPLE("\\p{N}", ETH30, 0, 0, TRUE);
2135   TEST_MATCH_SIMPLE("\\p{Nd}", "a", 0, 0, FALSE);
2136   TEST_MATCH_SIMPLE("\\p{Nd}", "1", 0, 0, TRUE);
2137   TEST_MATCH_SIMPLE("\\p{Nd}", AGRAVE, 0, 0, FALSE);
2138   TEST_MATCH_SIMPLE("\\p{Nd}", AGRAVE_UPPER, 0, 0, FALSE);
2139   TEST_MATCH_SIMPLE("\\p{Nd}", SHEEN, 0, 0, FALSE);
2140   TEST_MATCH_SIMPLE("\\p{Nd}", ETH30, 0, 0, FALSE);
2141   TEST_MATCH_SIMPLE("\\p{Common}", SHEEN, 0, 0, FALSE);
2142   TEST_MATCH_SIMPLE("\\p{Common}", "a", 0, 0, FALSE);
2143   TEST_MATCH_SIMPLE("\\p{Common}", AGRAVE, 0, 0, FALSE);
2144   TEST_MATCH_SIMPLE("\\p{Common}", AGRAVE_UPPER, 0, 0, FALSE);
2145   TEST_MATCH_SIMPLE("\\p{Common}", ETH30, 0, 0, FALSE);
2146   TEST_MATCH_SIMPLE("\\p{Common}", "%", 0, 0, TRUE);
2147   TEST_MATCH_SIMPLE("\\p{Common}", "1", 0, 0, TRUE);
2148   TEST_MATCH_SIMPLE("\\p{Arabic}", SHEEN, 0, 0, TRUE);
2149   TEST_MATCH_SIMPLE("\\p{Arabic}", "a", 0, 0, FALSE);
2150   TEST_MATCH_SIMPLE("\\p{Arabic}", AGRAVE, 0, 0, FALSE);
2151   TEST_MATCH_SIMPLE("\\p{Arabic}", AGRAVE_UPPER, 0, 0, FALSE);
2152   TEST_MATCH_SIMPLE("\\p{Arabic}", ETH30, 0, 0, FALSE);
2153   TEST_MATCH_SIMPLE("\\p{Arabic}", "%", 0, 0, FALSE);
2154   TEST_MATCH_SIMPLE("\\p{Arabic}", "1", 0, 0, FALSE);
2155   TEST_MATCH_SIMPLE("\\p{Latin}", SHEEN, 0, 0, FALSE);
2156   TEST_MATCH_SIMPLE("\\p{Latin}", "a", 0, 0, TRUE);
2157   TEST_MATCH_SIMPLE("\\p{Latin}", AGRAVE, 0, 0, TRUE);
2158   TEST_MATCH_SIMPLE("\\p{Latin}", AGRAVE_UPPER, 0, 0, TRUE);
2159   TEST_MATCH_SIMPLE("\\p{Latin}", ETH30, 0, 0, FALSE);
2160   TEST_MATCH_SIMPLE("\\p{Latin}", "%", 0, 0, FALSE);
2161   TEST_MATCH_SIMPLE("\\p{Latin}", "1", 0, 0, FALSE);
2162   TEST_MATCH_SIMPLE("\\p{Ethiopic}", SHEEN, 0, 0, FALSE);
2163   TEST_MATCH_SIMPLE("\\p{Ethiopic}", "a", 0, 0, FALSE);
2164   TEST_MATCH_SIMPLE("\\p{Ethiopic}", AGRAVE, 0, 0, FALSE);
2165   TEST_MATCH_SIMPLE("\\p{Ethiopic}", AGRAVE_UPPER, 0, 0, FALSE);
2166   TEST_MATCH_SIMPLE("\\p{Ethiopic}", ETH30, 0, 0, TRUE);
2167   TEST_MATCH_SIMPLE("\\p{Ethiopic}", "%", 0, 0, FALSE);
2168   TEST_MATCH_SIMPLE("\\p{Ethiopic}", "1", 0, 0, FALSE);
2169   TEST_MATCH_SIMPLE("\\p{L}(?<=\\p{Arabic})", SHEEN, 0, 0, TRUE);
2170   TEST_MATCH_SIMPLE("\\p{L}(?<=\\p{Latin})", SHEEN, 0, 0, FALSE);
2171   /* Invalid patterns. */
2172   TEST_MATCH_SIMPLE("\\", "a", 0, 0, FALSE);
2173   TEST_MATCH_SIMPLE("[", "", 0, 0, FALSE);
2174
2175   /* TEST_MATCH(pattern, compile_opts, match_opts, string,
2176    *            string_len, start_position, match_opts2, expected) */
2177   TEST_MATCH("a", 0, 0, "a", -1, 0, 0, TRUE);
2178   TEST_MATCH("a", 0, 0, "A", -1, 0, 0, FALSE);
2179   TEST_MATCH("a", G_REGEX_CASELESS, 0, "A", -1, 0, 0, TRUE);
2180   TEST_MATCH("a", 0, 0, "ab", -1, 1, 0, FALSE);
2181   TEST_MATCH("a", 0, 0, "ba", 1, 0, 0, FALSE);
2182   TEST_MATCH("a", 0, 0, "bab", -1, 0, 0, TRUE);
2183   TEST_MATCH("a", 0, 0, "b", -1, 0, 0, FALSE);
2184   TEST_MATCH("a", 0, G_REGEX_ANCHORED, "a", -1, 0, 0, TRUE);
2185   TEST_MATCH("a", 0, G_REGEX_ANCHORED, "ab", -1, 1, 0, FALSE);
2186   TEST_MATCH("a", 0, G_REGEX_ANCHORED, "ba", 1, 0, 0, FALSE);
2187   TEST_MATCH("a", 0, G_REGEX_ANCHORED, "bab", -1, 0, 0, FALSE);
2188   TEST_MATCH("a", 0, G_REGEX_ANCHORED, "b", -1, 0, 0, FALSE);
2189   TEST_MATCH("a", 0, 0, "a", -1, 0, G_REGEX_ANCHORED, TRUE);
2190   TEST_MATCH("a", 0, 0, "ab", -1, 1, G_REGEX_ANCHORED, FALSE);
2191   TEST_MATCH("a", 0, 0, "ba", 1, 0, G_REGEX_ANCHORED, FALSE);
2192   TEST_MATCH("a", 0, 0, "bab", -1, 0, G_REGEX_ANCHORED, FALSE);
2193   TEST_MATCH("a", 0, 0, "b", -1, 0, G_REGEX_ANCHORED, FALSE);
2194   TEST_MATCH("a|b", 0, 0, "a", -1, 0, 0, TRUE);
2195   TEST_MATCH("\\d", 0, 0, EURO, -1, 0, 0, FALSE);
2196   TEST_MATCH("^.$", 0, 0, EURO, -1, 0, 0, TRUE);
2197   TEST_MATCH("^.{3}$", 0, 0, EURO, -1, 0, 0, FALSE);
2198   TEST_MATCH("^.$", G_REGEX_RAW, 0, EURO, -1, 0, 0, FALSE);
2199   TEST_MATCH("^.{3}$", G_REGEX_RAW, 0, EURO, -1, 0, 0, TRUE);
2200   TEST_MATCH(AGRAVE, G_REGEX_CASELESS, 0, AGRAVE_UPPER, -1, 0, 0, TRUE);
2201
2202   /* New lines handling. */
2203   TEST_MATCH("^a\\Rb$", 0, 0, "a\r\nb", -1, 0, 0, TRUE);
2204   TEST_MATCH("^a\\Rb$", 0, 0, "a\nb", -1, 0, 0, TRUE);
2205   TEST_MATCH("^a\\Rb$", 0, 0, "a\rb", -1, 0, 0, TRUE);
2206   TEST_MATCH("^a\\Rb$", 0, 0, "a\n\rb", -1, 0, 0, FALSE);
2207   TEST_MATCH("^a\\R\\Rb$", 0, 0, "a\n\rb", -1, 0, 0, TRUE);
2208   TEST_MATCH("^a\\nb$", 0, 0, "a\r\nb", -1, 0, 0, FALSE);
2209   TEST_MATCH("^a\\r\\nb$", 0, 0, "a\r\nb", -1, 0, 0, TRUE);
2210
2211   TEST_MATCH("^b$", 0, 0, "a\nb\nc", -1, 0, 0, FALSE);
2212   TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\nb\nc", -1, 0, 0, TRUE);
2213   TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\r\nb\r\nc", -1, 0, 0, TRUE);
2214   TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\rb\rc", -1, 0, 0, TRUE);
2215   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\nb\nc", -1, 0, 0, FALSE);
2216   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\nb\nc", -1, 0, 0, TRUE);
2217   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\nb\nc", -1, 0, 0, FALSE);
2218   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\r\nb\r\nc", -1, 0, 0, FALSE);
2219   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\r\nb\r\nc", -1, 0, 0, FALSE);
2220   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\r\nb\r\nc", -1, 0, 0, TRUE);
2221   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\rb\rc", -1, 0, 0, TRUE);
2222   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\rb\rc", -1, 0, 0, FALSE);
2223   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\rb\rc", -1, 0, 0, FALSE);
2224   TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\nb\nc", -1, 0, 0, FALSE);
2225   TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\nb\nc", -1, 0, 0, TRUE);
2226   TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\nb\nc", -1, 0, 0, FALSE);
2227   TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\r\nb\r\nc", -1, 0, 0, FALSE);
2228   TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\r\nb\r\nc", -1, 0, 0, FALSE);
2229   TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\r\nb\r\nc", -1, 0, 0, TRUE);
2230   TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\rb\rc", -1, 0, 0, TRUE);
2231   TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\rb\rc", -1, 0, 0, FALSE);
2232   TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\rb\rc", -1, 0, 0, FALSE);
2233
2234   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\nb\nc", -1, 0, 0, TRUE);
2235   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\rb\rc", -1, 0, 0, TRUE);
2236   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\r\nb\r\nc", -1, 0, 0, TRUE);
2237   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_LF, "a\nb\nc", -1, 0, 0, TRUE);
2238   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_LF, "a\rb\rc", -1, 0, 0, FALSE);
2239   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_CRLF, "a\r\nb\r\nc", -1, 0, 0, TRUE);
2240   TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_CRLF, "a\rb\rc", -1, 0, 0, FALSE);
2241
2242   TEST_MATCH("a#\nb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE);
2243   TEST_MATCH("a#\r\nb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE);
2244   TEST_MATCH("a#\rb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE);
2245   TEST_MATCH("a#\nb", G_REGEX_EXTENDED, G_REGEX_MATCH_NEWLINE_CR, "a", -1, 0, 0, FALSE);
2246   TEST_MATCH("a#\nb", G_REGEX_EXTENDED | G_REGEX_NEWLINE_CR, 0, "a", -1, 0, 0, TRUE);
2247
2248   /* TEST_MATCH_NEXT#(pattern, string, string_len, start_position, ...) */
2249   TEST_MATCH_NEXT0("a", "x", -1, 0);
2250   TEST_MATCH_NEXT0("a", "ax", -1, 1);
2251   TEST_MATCH_NEXT0("a", "xa", 1, 0);
2252   TEST_MATCH_NEXT0("a", "axa", 1, 2);
2253   TEST_MATCH_NEXT1("a", "a", -1, 0, "a", 0, 1);
2254   TEST_MATCH_NEXT1("a", "xax", -1, 0, "a", 1, 2);
2255   TEST_MATCH_NEXT1(EURO, ENG EURO, -1, 0, EURO, 2, 5);
2256   TEST_MATCH_NEXT1("a*", "", -1, 0, "", 0, 0);
2257   TEST_MATCH_NEXT2("a*", "aa", -1, 0, "aa", 0, 2, "", 2, 2);
2258   TEST_MATCH_NEXT2(EURO "*", EURO EURO, -1, 0, EURO EURO, 0, 6, "", 6, 6);
2259   TEST_MATCH_NEXT2("a", "axa", -1, 0, "a", 0, 1, "a", 2, 3);
2260   TEST_MATCH_NEXT2("a+", "aaxa", -1, 0, "aa", 0, 2, "a", 3, 4);
2261   TEST_MATCH_NEXT2("a", "aa", -1, 0, "a", 0, 1, "a", 1, 2);
2262   TEST_MATCH_NEXT2("a", "ababa", -1, 2, "a", 2, 3, "a", 4, 5);
2263   TEST_MATCH_NEXT2(EURO "+", EURO "-" EURO, -1, 0, EURO, 0, 3, EURO, 4, 7);
2264   TEST_MATCH_NEXT3("", "ab", -1, 0, "", 0, 0, "", 1, 1, "", 2, 2);
2265   TEST_MATCH_NEXT3("", AGRAVE "b", -1, 0, "", 0, 0, "", 2, 2, "", 3, 3);
2266   TEST_MATCH_NEXT3("a", "aaxa", -1, 0, "a", 0, 1, "a", 1, 2, "a", 3, 4);
2267   TEST_MATCH_NEXT3("a", "aa" OGRAVE "a", -1, 0, "a", 0, 1, "a", 1, 2, "a", 4, 5);
2268   TEST_MATCH_NEXT3("a*", "aax", -1, 0, "aa", 0, 2, "", 2, 2, "", 3, 3);
2269   TEST_MATCH_NEXT4("a*", "aaxa", -1, 0, "aa", 0, 2, "", 2, 2, "a", 3, 4, "", 4, 4);
2270
2271   /* TEST_MATCH_COUNT(pattern, string, start_position, match_opts, expected_count) */
2272   TEST_MATCH_COUNT("a", "", 0, 0, 0);
2273   TEST_MATCH_COUNT("a", "a", 0, 0, 1);
2274   TEST_MATCH_COUNT("a", "a", 1, 0, 0);
2275   TEST_MATCH_COUNT("(.)", "a", 0, 0, 2);
2276   TEST_MATCH_COUNT("(.)", EURO, 0, 0, 2);
2277   TEST_MATCH_COUNT("(?:.)", "a", 0, 0, 1);
2278   TEST_MATCH_COUNT("(?P<A>.)", "a", 0, 0, 2);
2279   TEST_MATCH_COUNT("a$", "a", 0, G_REGEX_MATCH_NOTEOL, 0);
2280   TEST_MATCH_COUNT("(a)?(b)", "b", 0, 0, 3);
2281   TEST_MATCH_COUNT("(a)?(b)", "ab", 0, 0, 3);
2282
2283   /* TEST_PARTIAL(pattern, string, expected) */
2284   TEST_PARTIAL("^ab", "a", TRUE);
2285   TEST_PARTIAL("^ab", "xa", FALSE);
2286   TEST_PARTIAL("ab", "xa", TRUE);
2287   TEST_PARTIAL("ab", "ab", FALSE); /* normal match. */
2288   TEST_PARTIAL("a+b", "aa", FALSE); /* PCRE_ERROR_BAD_PARTIAL */
2289   TEST_PARTIAL("(a)+b", "aa", TRUE);
2290   TEST_PARTIAL("a?b", "a", TRUE);
2291
2292   /* TEST_CLEAR(pattern, string, start_position) */
2293   TEST_CLEAR("$^", "aaa", 0);
2294   TEST_CLEAR("a", "xax", 0);
2295   TEST_CLEAR("a", "xax", 1);
2296   TEST_CLEAR("a", "xax", 2);
2297   TEST_CLEAR("a", "aa", 0);
2298   TEST_CLEAR(HSTROKE, HSTROKE, 0);
2299
2300   /* TEST_SUB_PATTERN(pattern, string, start_position, sub_n, expected_sub,
2301    *                  expected_start, expected_end) */
2302   TEST_SUB_PATTERN("a", "a", 0, 0, "a", 0, 1);
2303   TEST_SUB_PATTERN("a(.)", "ab", 0, 1, "b", 1, 2);
2304   TEST_SUB_PATTERN("a(.)", "a" EURO, 0, 1, EURO, 1, 4);
2305   TEST_SUB_PATTERN("(?:.*)(a)(.)", "xxa" ENG, 0, 2, ENG, 3, 5);
2306   TEST_SUB_PATTERN("(" HSTROKE ")", "a" HSTROKE ENG, 0, 1, HSTROKE, 1, 3);
2307   TEST_SUB_PATTERN("a", "a", 0, 1, NULL, UNTOUCHED, UNTOUCHED);
2308   TEST_SUB_PATTERN("a", "a", 0, 1, NULL, UNTOUCHED, UNTOUCHED);
2309   TEST_SUB_PATTERN("(a)?(b)", "b", 0, 0, "b", 0, 1);
2310   TEST_SUB_PATTERN("(a)?(b)", "b", 0, 1, "", -1, -1);
2311   TEST_SUB_PATTERN("(a)?(b)", "b", 0, 2, "b", 0, 1);
2312
2313   /* TEST_NAMED_SUB_PATTERN(pattern, string, start_position, sub_name,
2314    *                        expected_sub, expected_start, expected_end) */
2315   TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", "ab", 0, "A", "b", 1, 2);
2316   TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", "aab", 1, "A", "b", 2, 3);
2317   TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", EURO "ab", 0, "A", "b", 4, 5);
2318   TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", EURO "ab", 0, "B", NULL, UNTOUCHED, UNTOUCHED);
2319   TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", EURO "ab", 0, "C", NULL, UNTOUCHED, UNTOUCHED);
2320   TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", "a" EGRAVE "x", 0, "A", EGRAVE, 1, 3);
2321   TEST_NAMED_SUB_PATTERN("a(?P<A>.)(?P<B>.)?", "a" EGRAVE "x", 0, "B", "x", 3, 4);
2322   TEST_NAMED_SUB_PATTERN("(?P<A>a)?(?P<B>b)", "b", 0, "A", "", -1, -1);
2323   TEST_NAMED_SUB_PATTERN("(?P<A>a)?(?P<B>b)", "b", 0, "B", "b", 0, 1);
2324
2325   /* TEST_FETCH_ALL#(pattern, string, ...) */
2326   TEST_FETCH_ALL0("a", "");
2327   TEST_FETCH_ALL0("a", "b");
2328   TEST_FETCH_ALL1("a", "a", "a");
2329   TEST_FETCH_ALL1("a+", "aa", "aa");
2330   TEST_FETCH_ALL1("(?:a)", "a", "a");
2331   TEST_FETCH_ALL2("(a)", "a", "a", "a");
2332   TEST_FETCH_ALL2("a(.)", "ab", "ab", "b");
2333   TEST_FETCH_ALL2("a(.)", "a" HSTROKE, "a" HSTROKE, HSTROKE);
2334   TEST_FETCH_ALL3("(?:.*)(a)(.)", "xyazk", "xyaz", "a", "z");
2335   TEST_FETCH_ALL3("(?P<A>.)(a)", "xa", "xa", "x", "a");
2336   TEST_FETCH_ALL3("(?P<A>.)(a)", ENG "a", ENG "a", ENG, "a");
2337   TEST_FETCH_ALL3("(a)?(b)", "b", "b", "", "b");
2338   TEST_FETCH_ALL3("(a)?(b)", "ab", "ab", "a", "b");
2339
2340   /* TEST_SPLIT_SIMPLE#(pattern, string, ...) */
2341   TEST_SPLIT_SIMPLE0("", "");
2342   TEST_SPLIT_SIMPLE0("a", "");
2343   TEST_SPLIT_SIMPLE1(",", "a", "a");
2344   TEST_SPLIT_SIMPLE1("(,)\\s*", "a", "a");
2345   TEST_SPLIT_SIMPLE2(",", "a,b", "a", "b");
2346   TEST_SPLIT_SIMPLE3(",", "a,b,c", "a", "b", "c");
2347   TEST_SPLIT_SIMPLE3(",\\s*", "a,b,c", "a", "b", "c");
2348   TEST_SPLIT_SIMPLE3(",\\s*", "a, b, c", "a", "b", "c");
2349   TEST_SPLIT_SIMPLE3("(,)\\s*", "a,b", "a", ",", "b");
2350   TEST_SPLIT_SIMPLE3("(,)\\s*", "a, b", "a", ",", "b");
2351   /* Not matched sub-strings. */
2352   TEST_SPLIT_SIMPLE2("a|(b)", "xay", "x", "y");
2353   TEST_SPLIT_SIMPLE3("a|(b)", "xby", "x", "b", "y");
2354   /* Empty matches. */
2355   TEST_SPLIT_SIMPLE3("", "abc", "a", "b", "c");
2356   TEST_SPLIT_SIMPLE3(" *", "ab c", "a", "b", "c");
2357   /* Invalid patterns. */
2358   TEST_SPLIT_SIMPLE0("\\", "");
2359   TEST_SPLIT_SIMPLE0("[", "");
2360
2361   /* TEST_SPLIT#(pattern, string, start_position, max_tokens, ...) */
2362   TEST_SPLIT0("", "", 0, 0);
2363   TEST_SPLIT0("a", "", 0, 0);
2364   TEST_SPLIT0("a", "", 0, 1);
2365   TEST_SPLIT0("a", "", 0, 2);
2366   TEST_SPLIT0("a", "a", 1, 0);
2367   TEST_SPLIT1(",", "a", 0, 0, "a");
2368   TEST_SPLIT1(",", "a,b", 0, 1, "a,b");
2369   TEST_SPLIT1("(,)\\s*", "a", 0, 0, "a");
2370   TEST_SPLIT1(",", "a,b", 2, 0, "b");
2371   TEST_SPLIT2(",", "a,b", 0, 0, "a", "b");
2372   TEST_SPLIT2(",", "a,b,c", 0, 2, "a", "b,c");
2373   TEST_SPLIT2(",", "a,b", 1, 0, "", "b");
2374   TEST_SPLIT2(",", "a,", 0, 0, "a", "");
2375   TEST_SPLIT3(",", "a,b,c", 0, 0, "a", "b", "c");
2376   TEST_SPLIT3(",\\s*", "a,b,c", 0, 0, "a", "b", "c");
2377   TEST_SPLIT3(",\\s*", "a, b, c", 0, 0, "a", "b", "c");
2378   TEST_SPLIT3("(,)\\s*", "a,b", 0, 0, "a", ",", "b");
2379   TEST_SPLIT3("(,)\\s*", "a, b", 0, 0, "a", ",", "b");
2380   /* Not matched sub-strings. */
2381   TEST_SPLIT2("a|(b)", "xay", 0, 0, "x", "y");
2382   TEST_SPLIT3("a|(b)", "xby", 0, -1, "x", "b", "y");
2383   /* Empty matches. */
2384   TEST_SPLIT2(" *", "ab c", 1, 0, "b", "c");
2385   TEST_SPLIT3("", "abc", 0, 0, "a", "b", "c");
2386   TEST_SPLIT3(" *", "ab c", 0, 0, "a", "b", "c");
2387   TEST_SPLIT1(" *", "ab c", 0, 1, "ab c");
2388   TEST_SPLIT2(" *", "ab c", 0, 2, "a", "b c");
2389   TEST_SPLIT3(" *", "ab c", 0, 3, "a", "b", "c");
2390   TEST_SPLIT3(" *", "ab c", 0, 4, "a", "b", "c");
2391
2392   /* TEST_SPLIT_NEXT#(pattern, string, start_position, ...) */
2393   TEST_SPLIT_NEXT1(",", "a", 0, "a");
2394   TEST_SPLIT_NEXT1("(,)\\s*", "a", 0, "a");
2395   TEST_SPLIT_NEXT1(",", "a,b", 2, "b");
2396   TEST_SPLIT_NEXT2(",", "a,b", 0, "a", "b");
2397   TEST_SPLIT_NEXT2(",", "a,b", 1, "", "b");
2398   TEST_SPLIT_NEXT2(",", "a,", 0, "a", "");
2399   TEST_SPLIT_NEXT3(",", "a,b,c", 0, "a", "b", "c");
2400   TEST_SPLIT_NEXT3(",\\s*", "a,b,c", 0, "a", "b", "c");
2401   TEST_SPLIT_NEXT3(",\\s*", "a, b, c", 0, "a", "b", "c");
2402   TEST_SPLIT_NEXT3("(,)\\s*", "a,b", 0, "a", ",", "b");
2403   TEST_SPLIT_NEXT3("(,)\\s*", "a, b", 0, "a", ",", "b");
2404   /* Not matched sub-strings. */
2405   TEST_SPLIT_NEXT2("a|(b)", "xay", 0, "x", "y");
2406   TEST_SPLIT_NEXT3("a|(b)", "xby", 0, "x", "b", "y");
2407   /* Empty matches. */
2408   TEST_SPLIT_NEXT2(" *", "ab c", 1, "b", "c");
2409   TEST_SPLIT_NEXT3("", "abc", 0, "a", "b", "c");
2410   TEST_SPLIT_NEXT3(" *", "ab c", 0, "a", "b", "c");
2411
2412   /* TEST_EXPAND(pattern, string, string_to_expand, raw, expected) */
2413   TEST_EXPAND("a", "a", "", FALSE, "");
2414   TEST_EXPAND("a", "a", "\\0", FALSE, "a");
2415   TEST_EXPAND("a", "a", "\\1", FALSE, "");
2416   TEST_EXPAND("(a)", "ab", "\\1", FALSE, "a");
2417   TEST_EXPAND("(a)", "a", "\\1", FALSE, "a");
2418   TEST_EXPAND("(a)", "a", "\\g<1>", FALSE, "a");
2419   TEST_EXPAND("a", "a", "\\0130", FALSE, "X");
2420   TEST_EXPAND("a", "a", "\\\\\\0", FALSE, "\\a");
2421   TEST_EXPAND("a(?P<G>.)c", "xabcy", "X\\g<G>X", FALSE, "XbX");
2422   TEST_EXPAND("(.)(?P<1>.)", "ab", "\\1", FALSE, "a");
2423   TEST_EXPAND("(.)(?P<1>.)", "ab", "\\g<1>", FALSE, "a");
2424   TEST_EXPAND(".", EURO, "\\0", FALSE, EURO);
2425   TEST_EXPAND("(.)", EURO, "\\1", FALSE, EURO);
2426   TEST_EXPAND("(?P<G>.)", EURO, "\\g<G>", FALSE, EURO);
2427   TEST_EXPAND(".", "a", EURO, FALSE, EURO);
2428   TEST_EXPAND(".", "a", EURO "\\0", FALSE, EURO "a");
2429   TEST_EXPAND(".", "", "\\Lab\\Ec", FALSE, "abc");
2430   TEST_EXPAND(".", "", "\\LaB\\EC", FALSE, "abC");
2431   TEST_EXPAND(".", "", "\\Uab\\Ec", FALSE, "ABc");
2432   TEST_EXPAND(".", "", "a\\ubc", FALSE, "aBc");
2433   TEST_EXPAND(".", "", "a\\lbc", FALSE, "abc");
2434   TEST_EXPAND(".", "", "A\\uBC", FALSE, "ABC");
2435   TEST_EXPAND(".", "", "A\\lBC", FALSE, "AbC");
2436   TEST_EXPAND(".", "", "A\\l\\\\BC", FALSE, "A\\BC");
2437   TEST_EXPAND(".", "", "\\L" AGRAVE "\\E", FALSE, AGRAVE);
2438   TEST_EXPAND(".", "", "\\U" AGRAVE "\\E", FALSE, AGRAVE_UPPER);
2439   TEST_EXPAND(".", "", "\\u" AGRAVE "a", FALSE, AGRAVE_UPPER "a");
2440   TEST_EXPAND(".", "ab", "x\\U\\0y\\Ez", FALSE, "xAYz");
2441   TEST_EXPAND(".(.)", "AB", "x\\L\\1y\\Ez", FALSE, "xbyz");
2442   TEST_EXPAND(".", "ab", "x\\u\\0y\\Ez", FALSE, "xAyz");
2443   TEST_EXPAND(".(.)", "AB", "x\\l\\1y\\Ez", FALSE, "xbyz");
2444   TEST_EXPAND(".(.)", "a" AGRAVE_UPPER, "x\\l\\1y", FALSE, "x" AGRAVE "y");
2445   TEST_EXPAND("a", "bab", "\\x{61}", FALSE, "a");
2446   TEST_EXPAND("a", "bab", "\\x61", FALSE, "a");
2447   TEST_EXPAND("a", "bab", "\\x5a", FALSE, "Z");
2448   TEST_EXPAND("a", "bab", "\\0\\x5A", FALSE, "aZ");
2449   TEST_EXPAND("a", "bab", "\\1\\x{5A}", FALSE, "Z");
2450   TEST_EXPAND("a", "bab", "\\x{00E0}", FALSE, AGRAVE);
2451   TEST_EXPAND("", "bab", "\\x{0634}", FALSE, SHEEN);
2452   TEST_EXPAND("", "bab", "\\x{634}", FALSE, SHEEN);
2453   TEST_EXPAND("", "", "\\t", FALSE, "\t");
2454   TEST_EXPAND("", "", "\\v", FALSE, "\v");
2455   TEST_EXPAND("", "", "\\r", FALSE, "\r");
2456   TEST_EXPAND("", "", "\\n", FALSE, "\n");
2457   TEST_EXPAND("", "", "\\f", FALSE, "\f");
2458   TEST_EXPAND("", "", "\\a", FALSE, "\a");
2459   TEST_EXPAND("", "", "\\b", FALSE, "\b");
2460   TEST_EXPAND("a(.)", "abc", "\\0\\b\\1", FALSE, "ab\bb");
2461   TEST_EXPAND("a(.)", "abc", "\\0141", FALSE, "a");
2462   TEST_EXPAND("a(.)", "abc", "\\078", FALSE, "\a8");
2463   TEST_EXPAND("a(.)", "abc", "\\077", FALSE, "?");
2464   TEST_EXPAND("a(.)", "abc", "\\0778", FALSE, "?8");
2465   TEST_EXPAND("a(.)", "a" AGRAVE "b", "\\1", FALSE, AGRAVE);
2466   TEST_EXPAND("a(.)", "a" AGRAVE "b", "\\1", TRUE, "\xc3");
2467   TEST_EXPAND("a(.)", "a" AGRAVE "b", "\\0", TRUE, "a\xc3");
2468   /* Invalid strings. */
2469   TEST_EXPAND("", "", "\\Q", FALSE, NULL);
2470   TEST_EXPAND("", "", "x\\Ay", FALSE, NULL);
2471   TEST_EXPAND("", "", "\\g<", FALSE, NULL);
2472   TEST_EXPAND("", "", "\\g<>", FALSE, NULL);
2473   TEST_EXPAND("", "", "\\g<1a>", FALSE, NULL);
2474   TEST_EXPAND("", "", "\\g<a$>", FALSE, NULL);
2475   TEST_EXPAND("", "", "\\", FALSE, NULL);
2476   TEST_EXPAND("a", "a", "\\x{61", FALSE, NULL);
2477   TEST_EXPAND("a", "a", "\\x6X", FALSE, NULL);
2478
2479   /* TEST_REPLACE(pattern, string, start_position, replacement, expected) */
2480   TEST_REPLACE("a", "ababa", 0, "A", "AbAbA");
2481   TEST_REPLACE("a", "ababa", 1, "A", "abAbA");
2482   TEST_REPLACE("a", "ababa", 2, "A", "abAbA");
2483   TEST_REPLACE("a", "ababa", 3, "A", "ababA");
2484   TEST_REPLACE("a", "ababa", 4, "A", "ababA");
2485   TEST_REPLACE("a", "abababa", 2, "A", "abAbAbA");
2486   TEST_REPLACE("$^", "abc", 0, "X", "abc");
2487   TEST_REPLACE("(.)a", "ciao", 0, "a\\1", "caio");
2488   TEST_REPLACE("a.", "abc", 0, "\\0\\0", "ababc");
2489   TEST_REPLACE("a", "asd", 0, "\\0101", "Asd");
2490   TEST_REPLACE("(a).\\1", "aba cda", 0, "\\1\\n", "a\n cda");
2491   TEST_REPLACE("a" AGRAVE "a", "a" AGRAVE "a", 0, "x", "x");
2492   TEST_REPLACE("a" AGRAVE "a", "a" AGRAVE "a", 0, OGRAVE, OGRAVE);
2493   TEST_REPLACE("[^-]", "-" EURO "-x-" HSTROKE, 0, "a", "-a-a-a");
2494   TEST_REPLACE("[^-]", "-" EURO "-" HSTROKE, 0, "a\\g<0>a", "-a" EURO "a-a" HSTROKE "a");
2495   TEST_REPLACE("-", "-" EURO "-" HSTROKE, 0, "", EURO HSTROKE);
2496   TEST_REPLACE(".*", "hello", 0, "\\U\\0\\E", "HELLO");
2497   TEST_REPLACE(".*", "hello", 0, "\\u\\0", "Hello");
2498   TEST_REPLACE("\\S+", "hello world", 0, "\\U-\\0-", "-HELLO- -WORLD-");
2499   TEST_REPLACE(".", "a", 0, "\\A", NULL);
2500   TEST_REPLACE(".", "a", 0, "\\g", NULL);
2501
2502   /* TEST_REPLACE_LIT(pattern, string, start_position, replacement, expected) */
2503   TEST_REPLACE_LIT("a", "ababa", 0, "A", "AbAbA");
2504   TEST_REPLACE_LIT("a", "ababa", 1, "A", "abAbA");
2505   TEST_REPLACE_LIT("a", "ababa", 2, "A", "abAbA");
2506   TEST_REPLACE_LIT("a", "ababa", 3, "A", "ababA");
2507   TEST_REPLACE_LIT("a", "ababa", 4, "A", "ababA");
2508   TEST_REPLACE_LIT("a", "abababa", 2, "A", "abAbAbA");
2509   TEST_REPLACE_LIT("a", "abcadaa", 0, "A", "AbcAdAA");
2510   TEST_REPLACE_LIT("$^", "abc", 0, "X", "abc");
2511   TEST_REPLACE_LIT("(.)a", "ciao", 0, "a\\1", "ca\\1o");
2512   TEST_REPLACE_LIT("a.", "abc", 0, "\\0\\0\\n", "\\0\\0\\nc");
2513   TEST_REPLACE_LIT("a" AGRAVE "a", "a" AGRAVE "a", 0, "x", "x");
2514   TEST_REPLACE_LIT("a" AGRAVE "a", "a" AGRAVE "a", 0, OGRAVE, OGRAVE);
2515   TEST_REPLACE_LIT(AGRAVE, "-" AGRAVE "-" HSTROKE, 0, "a" ENG "a", "-a" ENG "a-" HSTROKE);
2516   TEST_REPLACE_LIT("[^-]", "-" EURO "-" AGRAVE "-" HSTROKE, 0, "a", "-a-a-a");
2517   TEST_REPLACE_LIT("[^-]", "-" EURO "-" AGRAVE, 0, "a\\g<0>a", "-a\\g<0>a-a\\g<0>a");
2518   TEST_REPLACE_LIT("-", "-" EURO "-" AGRAVE "-" HSTROKE, 0, "", EURO AGRAVE HSTROKE);
2519
2520   /* TEST_GET_STRING_NUMBER(pattern, name, expected_num) */
2521   TEST_GET_STRING_NUMBER("", "A", -1);
2522   TEST_GET_STRING_NUMBER("(?P<A>.)", "A", 1);
2523   TEST_GET_STRING_NUMBER("(?P<A>.)", "B", -1);
2524   TEST_GET_STRING_NUMBER("(?P<A>.)(?P<B>a)", "A", 1);
2525   TEST_GET_STRING_NUMBER("(?P<A>.)(?P<B>a)", "B", 2);
2526   TEST_GET_STRING_NUMBER("(?P<A>.)(?P<B>a)", "C", -1);
2527   TEST_GET_STRING_NUMBER("(?P<A>.)(.)(?P<B>a)", "A", 1);
2528   TEST_GET_STRING_NUMBER("(?P<A>.)(.)(?P<B>a)", "B", 3);
2529   TEST_GET_STRING_NUMBER("(?P<A>.)(.)(?P<B>a)", "C", -1);
2530   TEST_GET_STRING_NUMBER("(?:a)(?P<A>.)", "A", 1);
2531   TEST_GET_STRING_NUMBER("(?:a)(?P<A>.)", "B", -1);
2532
2533   /* TEST_ESCAPE(string, length, expected) */
2534   TEST_ESCAPE("hello world", -1, "hello world");
2535   TEST_ESCAPE("hello world", 5, "hello");
2536   TEST_ESCAPE("hello.world", -1, "hello\\.world");
2537   TEST_ESCAPE("a(b\\b.$", -1, "a\\(b\\\\b\\.\\$");
2538   TEST_ESCAPE("hello\0world", -1, "hello");
2539   TEST_ESCAPE("hello\0world", 11, "hello\\0world");
2540   TEST_ESCAPE(EURO "*" ENG, -1, EURO "\\*" ENG);
2541   TEST_ESCAPE("a$", -1, "a\\$");
2542   TEST_ESCAPE("$a", -1, "\\$a");
2543   TEST_ESCAPE("a$a", -1, "a\\$a");
2544   TEST_ESCAPE("$a$", -1, "\\$a\\$");
2545   TEST_ESCAPE("$a$", 0, "");
2546   TEST_ESCAPE("$a$", 1, "\\$");
2547   TEST_ESCAPE("$a$", 2, "\\$a");
2548   TEST_ESCAPE("$a$", 3, "\\$a\\$");
2549   TEST_ESCAPE("$a$", 4, "\\$a\\$\\0");
2550   TEST_ESCAPE("|()[]{}^$*+?.", -1, "\\|\\(\\)\\[\\]\\{\\}\\^\\$\\*\\+\\?\\.");
2551   TEST_ESCAPE("a|a(a)a[a]a{a}a^a$a*a+a?a.a", -1,
2552               "a\\|a\\(a\\)a\\[a\\]a\\{a\\}a\\^a\\$a\\*a\\+a\\?a\\.a");
2553
2554   /* TEST_MATCH_ALL#(pattern, string, string_len, start_position, ...) */
2555   TEST_MATCH_ALL0("<.*>", "", -1, 0);
2556   TEST_MATCH_ALL0("a+", "", -1, 0);
2557   TEST_MATCH_ALL0("a+", "a", 0, 0);
2558   TEST_MATCH_ALL0("a+", "a", -1, 1);
2559   TEST_MATCH_ALL1("<.*>", "<a>", -1, 0, "<a>", 0, 3);
2560   TEST_MATCH_ALL1("a+", "a", -1, 0, "a", 0, 1);
2561   TEST_MATCH_ALL1("a+", "aa", 1, 0, "a", 0, 1);
2562   TEST_MATCH_ALL1("a+", "aa", -1, 1, "a", 1, 2);
2563   TEST_MATCH_ALL1("a+", "aa", 2, 1, "a", 1, 2);
2564   TEST_MATCH_ALL1(".+", ENG, -1, 0, ENG, 0, 2);
2565   TEST_MATCH_ALL2("<.*>", "<a><b>", -1, 0, "<a><b>", 0, 6, "<a>", 0, 3);
2566   TEST_MATCH_ALL2("a+", "aa", -1, 0, "aa", 0, 2, "a", 0, 1);
2567   TEST_MATCH_ALL2(".+", ENG EURO, -1, 0, ENG EURO, 0, 5, ENG, 0, 2);
2568   TEST_MATCH_ALL3("<.*>", "<a><b><c>", -1, 0, "<a><b><c>", 0, 9,
2569                   "<a><b>", 0, 6, "<a>", 0, 3);
2570   TEST_MATCH_ALL3("a+", "aaa", -1, 0, "aaa", 0, 3, "aa", 0, 2, "a", 0, 1);
2571
2572   /* TEST_NULL_MATCH(code) */
2573   /* TEST_NULL_MATCH_RET(code, expected, type) */
2574   /* Test to see what happens if a function needing GRegexMatch is called
2575    * when GRegexMatch is NULL. The result should be the same when the function
2576    * is called after g_regex_clear.
2577    * "re" is a GRegex, the pattern is "a". */
2578   TEST_NULL_MATCH(g_regex_clear (re));
2579   TEST_NULL_MATCH(g_regex_get_pattern (re));
2580   TEST_NULL_MATCH_RET(g_regex_optimize (re, NULL), TRUE, gboolean, "%d");
2581   TEST_NULL_MATCH_RET(g_regex_match (re, "a", 0), TRUE, gboolean, "%d");
2582   TEST_NULL_MATCH_RET(g_regex_match (re, "b", 0), FALSE, gboolean, "%d");
2583   TEST_NULL_MATCH_RET(g_regex_match_full (re, "a", -1, 0, 0, NULL), TRUE, gboolean, "%d");
2584   TEST_NULL_MATCH_RET(g_regex_match_full (re, "a", -1, 1, 0, NULL), FALSE, gboolean, "%d");
2585   TEST_NULL_MATCH_RET(g_regex_match_full (re, "b", -1, 0, 0, NULL), FALSE, gboolean, "%d");
2586   TEST_NULL_MATCH_RET(g_regex_get_match_count (re), -1, gint, "%d");
2587   TEST_NULL_MATCH_RET(g_regex_is_partial_match (re), FALSE, gboolean, "%d");
2588   TEST_NULL_MATCH_RET(g_regex_fetch (re, 0, "abc"), NULL, gchar *, "%p");
2589   TEST_NULL_MATCH_RET(g_regex_fetch_pos (re, 0, NULL, NULL), FALSE, gboolean, "%d");
2590   TEST_NULL_MATCH_RET(g_regex_fetch_all (re, "b"), NULL, gchar **, "%p");
2591   TEST_NULL_MATCH_RET(g_regex_get_string_number (re, "X"), -1, gint, "%d");
2592
2593 end: /* if abort_on_fail is TRUE the flow passes to this label. */
2594   verbose ("\n%u tests passed, %u failed\n", passed, failed);
2595   return failed;
2596 }
2597
2598 #else /* ENABLE_REGEX false */
2599
2600 int
2601 main (int argc, char *argv[])
2602 {
2603   g_print ("GRegex is disabled.\n");
2604   return 0;
2605 }
2606
2607 #endif /* ENABLE_REGEX */