sl@0: /* sl@0: * Copyright (C) 2005 - 2006, Marco Barisione sl@0: * Portions copyright (c) 2009 Nokia Corporation. All rights reserved. sl@0: * This library is free software; you can redistribute it and/or sl@0: * modify it under the terms of the GNU Lesser General Public sl@0: * License as published by the Free Software Foundation; either sl@0: * version 2 of the License, or (at your option) any later version. sl@0: * sl@0: * This library is distributed in the hope that it will be useful, sl@0: * but WITHOUT ANY WARRANTY; without even the implied warranty of sl@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU sl@0: * Lesser General Public License for more details. sl@0: * sl@0: * You should have received a copy of the GNU Lesser General Public sl@0: * License along with this library; if not, write to the sl@0: * Free Software Foundation, Inc., 59 Temple Place - Suite 330, sl@0: * Boston, MA 02111-1307, USA. sl@0: */ sl@0: sl@0: #undef G_DISABLE_ASSERT sl@0: #undef G_LOG_DOMAIN sl@0: #define ENABLE_REGEX sl@0: #include sl@0: #include sl@0: #include "glib.h" sl@0: #ifdef __SYMBIAN32__ sl@0: #include "mrt2_glib2_test.h" sl@0: #endif /*__SYMBIAN32__*/ sl@0: #ifdef ENABLE_REGEX sl@0: sl@0: /* U+20AC EURO SIGN (symbol, currency) */ sl@0: #define EURO "\xe2\x82\xac" sl@0: /* U+00E0 LATIN SMALL LETTER A WITH GRAVE (letter, lowercase) */ sl@0: #define AGRAVE "\xc3\xa0" sl@0: /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE (letter, uppercase) */ sl@0: #define AGRAVE_UPPER "\xc3\x80" sl@0: /* U+00E8 LATIN SMALL LETTER E WITH GRAVE (letter, lowercase) */ sl@0: #define EGRAVE "\xc3\xa8" sl@0: /* U+00F2 LATIN SMALL LETTER O WITH GRAVE (letter, lowercase) */ sl@0: #define OGRAVE "\xc3\xb2" sl@0: /* U+014B LATIN SMALL LETTER ENG (letter, lowercase) */ sl@0: #define ENG "\xc5\x8b" sl@0: /* U+0127 LATIN SMALL LETTER H WITH STROKE (letter, lowercase) */ sl@0: #define HSTROKE "\xc4\xa7" sl@0: /* U+0634 ARABIC LETTER SHEEN (letter, other) */ sl@0: #define SHEEN "\xd8\xb4" sl@0: /* U+1374 ETHIOPIC NUMBER THIRTY (number, other) */ sl@0: #define ETH30 "\xe1\x8d\xb4" sl@0: sl@0: /* A random value use to mark untouched integer variables. */ sl@0: #define UNTOUCHED -559038737 sl@0: sl@0: static gboolean noisy = FALSE; sl@0: static gboolean abort_on_fail = FALSE; sl@0: sl@0: #define PASS passed++ sl@0: #define FAIL \ sl@0: G_STMT_START \ sl@0: { \ sl@0: failed++; \ sl@0: if (abort_on_fail) \ sl@0: goto end; \ sl@0: } \ sl@0: G_STMT_END sl@0: sl@0: /* A replacement for strcmp that doesn't crash with null pointers. */ sl@0: static gboolean sl@0: streq (const gchar *s1, const gchar *s2) sl@0: { sl@0: if (s1 == NULL && s2 == NULL) sl@0: return TRUE; sl@0: else if (s1 == NULL) sl@0: return FALSE; sl@0: else if (s2 == NULL) sl@0: return FALSE; sl@0: else sl@0: return strcmp (s1, s2) == 0; sl@0: } sl@0: sl@0: static void sl@0: verbose (const gchar *format, ...) sl@0: { sl@0: /* Function copied from glib/tests/patterntest.c by Matthias Clasen. */ sl@0: gchar *msg; sl@0: va_list args; sl@0: sl@0: va_start (args, format); sl@0: msg = g_strdup_vprintf (format, args); sl@0: va_end (args); sl@0: sl@0: if (noisy) sl@0: g_print ("%s", msg); sl@0: g_free (msg); sl@0: } sl@0: sl@0: static gboolean sl@0: test_new (const gchar *pattern, sl@0: GRegexCompileFlags compile_opts, sl@0: GRegexMatchFlags match_opts) sl@0: { sl@0: GRegex *regex; sl@0: sl@0: verbose ("compiling \"%s\" \t", pattern); sl@0: sl@0: regex = g_regex_new (pattern, compile_opts, match_opts, NULL); sl@0: if (regex == NULL) sl@0: { sl@0: g_print ("failed \t(pattern: \"%s\", compile: %d, match %d)\n", sl@0: pattern, compile_opts, match_opts); sl@0: return FALSE; sl@0: } sl@0: sl@0: if (!streq (g_regex_get_pattern (regex), pattern)) sl@0: { sl@0: g_print ("failed \t(pattern: \"%s\")\n", sl@0: pattern); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: sl@0: g_regex_unref (regex); sl@0: sl@0: verbose ("passed\n"); sl@0: return TRUE; sl@0: } sl@0: sl@0: #define TEST_NEW(pattern, compile_opts, match_opts) { \ sl@0: total++; \ sl@0: if (test_new (pattern, compile_opts, match_opts)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_new_fail (const gchar *pattern, sl@0: GRegexCompileFlags compile_opts, sl@0: GRegexError expected_error) sl@0: { sl@0: GRegex *regex; sl@0: GError *error = NULL; sl@0: sl@0: verbose ("compiling \"%s\" (expected a failure) \t", pattern); sl@0: sl@0: regex = g_regex_new (pattern, compile_opts, 0, &error); sl@0: sl@0: if (regex != NULL) sl@0: { sl@0: g_print ("failed \t(pattern: \"%s\", compile: %d)\n", sl@0: pattern, compile_opts); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: sl@0: if (error->code != expected_error) sl@0: { sl@0: g_print ("failed \t(pattern: \"%s\", compile: %d, got error: %d, " sl@0: "expected error: %d)\n", sl@0: pattern, compile_opts, error->code, expected_error); sl@0: g_error_free (error); sl@0: return FALSE; sl@0: } sl@0: sl@0: verbose ("passed\n"); sl@0: return TRUE; sl@0: } sl@0: sl@0: #define TEST_NEW_FAIL(pattern, compile_opts, expected_error) { \ sl@0: total++; \ sl@0: if (test_new_fail (pattern, compile_opts, expected_error)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_match_simple (const gchar *pattern, sl@0: const gchar *string, sl@0: GRegexCompileFlags compile_opts, sl@0: GRegexMatchFlags match_opts, sl@0: gboolean expected) sl@0: { sl@0: gboolean match; sl@0: sl@0: verbose ("matching \"%s\" against \"%s\" \t", string, pattern); sl@0: sl@0: match = g_regex_match_simple (pattern, string, compile_opts, match_opts); sl@0: if (match != expected) sl@0: { sl@0: g_print ("failed \t(unexpected %s)\n", match ? "match" : "mismatch"); sl@0: return FALSE; sl@0: } sl@0: else sl@0: { sl@0: verbose ("passed (%s)\n", match ? "match" : "nomatch"); sl@0: return TRUE; sl@0: } sl@0: } sl@0: sl@0: #define TEST_MATCH_SIMPLE(pattern, string, compile_opts, match_opts, expected) { \ sl@0: total++; \ sl@0: if (test_match_simple (pattern, string, compile_opts, match_opts, expected)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_match (const gchar *pattern, sl@0: GRegexCompileFlags compile_opts, sl@0: GRegexMatchFlags match_opts, sl@0: const gchar *string, sl@0: gssize string_len, sl@0: gint start_position, sl@0: GRegexMatchFlags match_opts2, sl@0: gboolean expected) sl@0: { sl@0: GRegex *regex; sl@0: gboolean match; sl@0: sl@0: verbose ("matching \"%s\" against \"%s\" (start: %d, len: %d) \t", sl@0: string, pattern, start_position, string_len); sl@0: sl@0: regex = g_regex_new (pattern, compile_opts, match_opts, NULL); sl@0: match = g_regex_match_full (regex, string, string_len, sl@0: start_position, match_opts2, NULL, NULL); sl@0: if (match != expected) sl@0: { sl@0: gchar *e1 = g_strescape (pattern, NULL); sl@0: gchar *e2 = g_strescape (string, NULL); sl@0: g_print ("failed \t(unexpected %s) '%s' against '%s'\n", match ? "match" : "mismatch", e1, e2); sl@0: g_free (e1); sl@0: g_free (e2); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: sl@0: if (string_len == -1 && start_position == 0) sl@0: { sl@0: match = g_regex_match (regex, string, match_opts2, NULL); sl@0: if (match != expected) sl@0: { sl@0: g_print ("failed \t(pattern: \"%s\", string: \"%s\")\n", sl@0: pattern, string); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: } sl@0: sl@0: g_regex_unref (regex); sl@0: sl@0: verbose ("passed (%s)\n", match ? "match" : "nomatch"); sl@0: return TRUE; sl@0: } sl@0: sl@0: #define TEST_MATCH(pattern, compile_opts, match_opts, string, \ sl@0: string_len, start_position, match_opts2, expected) { \ sl@0: total++; \ sl@0: if (test_match (pattern, compile_opts, match_opts, string, \ sl@0: string_len, start_position, match_opts2, expected)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: struct _Match sl@0: { sl@0: gchar *string; sl@0: gint start, end; sl@0: }; sl@0: typedef struct _Match Match; sl@0: sl@0: static void sl@0: free_match (gpointer data, gpointer user_data) sl@0: { sl@0: Match *match = data; sl@0: if (match == NULL) sl@0: return; sl@0: g_free (match->string); sl@0: g_free (match); sl@0: } sl@0: sl@0: static gboolean sl@0: test_match_next (const gchar *pattern, sl@0: const gchar *string, sl@0: gssize string_len, sl@0: gint start_position, sl@0: ...) sl@0: { sl@0: GRegex *regex; sl@0: GMatchInfo *match_info; sl@0: va_list args; sl@0: GSList *matches = NULL; sl@0: GSList *expected = NULL; sl@0: GSList *l_exp, *l_match; sl@0: gboolean ret = TRUE; sl@0: sl@0: verbose ("matching \"%s\" against \"%s\" (start: %d, len: %d) \t", sl@0: string, pattern, start_position, string_len); sl@0: sl@0: /* The va_list is a NULL-terminated sequence of: extected matched string, sl@0: * expected start and expected end. */ sl@0: va_start (args, start_position); sl@0: while (TRUE) sl@0: { sl@0: Match *match; sl@0: const gchar *expected_string = va_arg (args, const gchar *); sl@0: if (expected_string == NULL) sl@0: break; sl@0: match = g_new0 (Match, 1); sl@0: match->string = g_strdup (expected_string); sl@0: match->start = va_arg (args, gint); sl@0: match->end = va_arg (args, gint); sl@0: expected = g_slist_prepend (expected, match); sl@0: } sl@0: expected = g_slist_reverse (expected); sl@0: va_end (args); sl@0: sl@0: regex = g_regex_new (pattern, 0, 0, NULL); sl@0: sl@0: g_regex_match_full (regex, string, string_len, sl@0: start_position, 0, &match_info, NULL); sl@0: while (g_match_info_matches (match_info)) sl@0: { sl@0: Match *match = g_new0 (Match, 1); sl@0: match->string = g_match_info_fetch (match_info, 0); sl@0: match->start = UNTOUCHED; sl@0: match->end = UNTOUCHED; sl@0: g_match_info_fetch_pos (match_info, 0, &match->start, &match->end); sl@0: matches = g_slist_prepend (matches, match); sl@0: g_match_info_next (match_info, NULL); sl@0: } sl@0: g_assert (regex == g_match_info_get_regex (match_info)); sl@0: g_assert (string == g_match_info_get_string (match_info)); sl@0: g_match_info_free (match_info); sl@0: matches = g_slist_reverse (matches); sl@0: sl@0: if (g_slist_length (matches) != g_slist_length (expected)) sl@0: { sl@0: gint match_count = g_slist_length (matches); sl@0: g_print ("failed \t(got %d %s, expected %d)\n", match_count, sl@0: match_count == 1 ? "match" : "matches", sl@0: g_slist_length (expected)); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: l_exp = expected; sl@0: l_match = matches; sl@0: while (l_exp != NULL) sl@0: { sl@0: Match *exp = l_exp->data; sl@0: Match *match = l_match->data; sl@0: sl@0: if (!streq(exp->string, match->string)) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", sl@0: match->string, exp->string); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: if (exp->start != match->start || exp->end != match->end) sl@0: { sl@0: g_print ("failed \t(got [%d, %d], expected [%d, %d])\n", sl@0: match->start, match->end, exp->start, exp->end); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: l_exp = g_slist_next (l_exp); sl@0: l_match = g_slist_next (l_match); sl@0: } sl@0: sl@0: exit: sl@0: if (ret) sl@0: { sl@0: gint count = g_slist_length (matches); sl@0: verbose ("passed (%d %s)\n", count, count == 1 ? "match" : "matches"); sl@0: } sl@0: sl@0: g_regex_unref (regex); sl@0: g_slist_foreach (expected, free_match, NULL); sl@0: g_slist_free (expected); sl@0: g_slist_foreach (matches, free_match, NULL); sl@0: g_slist_free (matches); sl@0: sl@0: return ret; sl@0: } sl@0: sl@0: #define TEST_MATCH_NEXT0(pattern, string, string_len, start_position) { \ sl@0: total++; \ sl@0: if (test_match_next (pattern, string, string_len, start_position, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: #define TEST_MATCH_NEXT1(pattern, string, string_len, start_position, \ sl@0: t1, s1, e1) { \ sl@0: total++; \ sl@0: if (test_match_next (pattern, string, string_len, start_position, \ sl@0: t1, s1, e1, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: #define TEST_MATCH_NEXT2(pattern, string, string_len, start_position, \ sl@0: t1, s1, e1, t2, s2, e2) { \ sl@0: total++; \ sl@0: if (test_match_next (pattern, string, string_len, start_position, \ sl@0: t1, s1, e1, t2, s2, e2, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: #define TEST_MATCH_NEXT3(pattern, string, string_len, start_position, \ sl@0: t1, s1, e1, t2, s2, e2, t3, s3, e3) { \ sl@0: total++; \ sl@0: if (test_match_next (pattern, string, string_len, start_position, \ sl@0: t1, s1, e1, t2, s2, e2, t3, s3, e3, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: #define TEST_MATCH_NEXT4(pattern, string, string_len, start_position, \ sl@0: t1, s1, e1, t2, s2, e2, t3, s3, e3, t4, s4, e4) { \ sl@0: total++; \ sl@0: if (test_match_next (pattern, string, string_len, start_position, \ sl@0: t1, s1, e1, t2, s2, e2, t3, s3, e3, t4, s4, e4, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_match_count (const gchar *pattern, sl@0: const gchar *string, sl@0: gint start_position, sl@0: GRegexMatchFlags match_opts, sl@0: gint expected_count) sl@0: { sl@0: GRegex *regex; sl@0: GMatchInfo *match_info; sl@0: gint count; sl@0: sl@0: verbose ("fetching match count (string: \"%s\", pattern: \"%s\", start: %d) \t", sl@0: string, pattern, start_position); sl@0: sl@0: regex = g_regex_new (pattern, 0, 0, NULL); sl@0: sl@0: g_regex_match_full (regex, string, -1, start_position, sl@0: match_opts, &match_info, NULL); sl@0: count = g_match_info_get_match_count (match_info); sl@0: sl@0: if (count != expected_count) sl@0: { sl@0: g_print ("failed \t(got %d, expected: %d)\n", count, expected_count); sl@0: return FALSE; sl@0: } sl@0: sl@0: g_match_info_free (match_info); sl@0: g_regex_unref (regex); sl@0: sl@0: verbose ("passed\n"); sl@0: return TRUE; sl@0: } sl@0: sl@0: #define TEST_MATCH_COUNT(pattern, string, start_position, match_opts, expected_count) { \ sl@0: total++; \ sl@0: if (test_match_count (pattern, string, start_position, match_opts, expected_count)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_partial (const gchar *pattern, sl@0: const gchar *string, sl@0: gboolean expected) sl@0: { sl@0: GRegex *regex; sl@0: GMatchInfo *match_info; sl@0: sl@0: verbose ("partial matching (string: \"%s\", pattern: \"%s\") \t", sl@0: string, pattern); sl@0: sl@0: regex = g_regex_new (pattern, 0, 0, NULL); sl@0: sl@0: g_regex_match (regex, string, G_REGEX_MATCH_PARTIAL, &match_info); sl@0: if (expected != g_match_info_is_partial_match (match_info)) sl@0: { sl@0: g_print ("failed \t(got %d, expected: %d)\n", !expected, expected); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: sl@0: if (expected && g_match_info_fetch_pos (match_info, 0, NULL, NULL)) sl@0: { sl@0: g_print ("failed \t(got sub-pattern 0)\n"); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: sl@0: if (expected && g_match_info_fetch_pos (match_info, 1, NULL, NULL)) sl@0: { sl@0: g_print ("failed \t(got sub-pattern 1)\n"); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: sl@0: g_match_info_free (match_info); sl@0: g_regex_unref (regex); sl@0: sl@0: verbose ("passed\n"); sl@0: return TRUE; sl@0: } sl@0: sl@0: #define TEST_PARTIAL(pattern, string, expected) { \ sl@0: total++; \ sl@0: if (test_partial (pattern, string, expected)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_sub_pattern (const gchar *pattern, sl@0: const gchar *string, sl@0: gint start_position, sl@0: gint sub_n, sl@0: const gchar *expected_sub, sl@0: gint expected_start, sl@0: gint expected_end) sl@0: { sl@0: GRegex *regex; sl@0: GMatchInfo *match_info; sl@0: gchar *sub_expr; sl@0: gint start = UNTOUCHED, end = UNTOUCHED; sl@0: sl@0: verbose ("fetching sub-pattern %d from \"%s\" (pattern: \"%s\") \t", sl@0: sub_n, string, pattern); sl@0: sl@0: regex = g_regex_new (pattern, 0, 0, NULL); sl@0: g_regex_match_full (regex, string, -1, start_position, 0, &match_info, NULL); sl@0: sl@0: sub_expr = g_match_info_fetch (match_info, sub_n); sl@0: if (!streq(sub_expr, expected_sub)) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", sl@0: sub_expr, expected_sub); sl@0: g_free (sub_expr); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: g_free (sub_expr); sl@0: sl@0: g_match_info_fetch_pos (match_info, sub_n, &start, &end); sl@0: if (start != expected_start || end != expected_end) sl@0: { sl@0: g_print ("failed \t(got [%d, %d], expected [%d, %d])\n", sl@0: start, end, expected_start, expected_end); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: sl@0: g_match_info_free (match_info); sl@0: g_regex_unref (regex); sl@0: sl@0: verbose ("passed\n"); sl@0: return TRUE; sl@0: } sl@0: sl@0: #define TEST_SUB_PATTERN(pattern, string, start_position, sub_n, expected_sub, \ sl@0: expected_start, expected_end) { \ sl@0: total++; \ sl@0: if (test_sub_pattern (pattern, string, start_position, sub_n, expected_sub, \ sl@0: expected_start, expected_end)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_named_sub_pattern (const gchar *pattern, sl@0: GRegexCompileFlags flags, sl@0: const gchar *string, sl@0: gint start_position, sl@0: const gchar *sub_name, sl@0: const gchar *expected_sub, sl@0: gint expected_start, sl@0: gint expected_end) sl@0: { sl@0: GRegex *regex; sl@0: GMatchInfo *match_info; sl@0: gint start = UNTOUCHED, end = UNTOUCHED; sl@0: gchar *sub_expr; sl@0: sl@0: verbose ("fetching sub-pattern \"%s\" from \"%s\" (pattern: \"%s\") \t", sl@0: sub_name, string, pattern); sl@0: sl@0: regex = g_regex_new (pattern, flags, 0, NULL); sl@0: sl@0: g_regex_match_full (regex, string, -1, start_position, 0, &match_info, NULL); sl@0: sub_expr = g_match_info_fetch_named (match_info, sub_name); sl@0: if (!streq (sub_expr, expected_sub)) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", sl@0: sub_expr, expected_sub); sl@0: g_free (sub_expr); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: g_free (sub_expr); sl@0: sl@0: g_match_info_fetch_named_pos (match_info, sub_name, &start, &end); sl@0: if (start != expected_start || end != expected_end) sl@0: { sl@0: g_print ("failed \t(got [%d, %d], expected [%d, %d])\n", sl@0: start, end, expected_start, expected_end); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: sl@0: g_match_info_free (match_info); sl@0: g_regex_unref (regex); sl@0: sl@0: verbose ("passed\n"); sl@0: return TRUE; sl@0: } sl@0: sl@0: #define TEST_NAMED_SUB_PATTERN(pattern, string, start_position, sub_name, \ sl@0: expected_sub, expected_start, expected_end) { \ sl@0: total++; \ sl@0: if (test_named_sub_pattern (pattern, 0, string, start_position, sub_name, \ sl@0: expected_sub, expected_start, expected_end)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: #define TEST_NAMED_SUB_PATTERN_DUPNAMES(pattern, string, start_position, sub_name, \ sl@0: expected_sub, expected_start, expected_end) { \ sl@0: total++; \ sl@0: if (test_named_sub_pattern (pattern, G_REGEX_DUPNAMES, string, start_position, \ sl@0: sub_name, expected_sub, expected_start, expected_end)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_fetch_all (const gchar *pattern, sl@0: const gchar *string, sl@0: ...) sl@0: { sl@0: GRegex *regex; sl@0: GMatchInfo *match_info; sl@0: va_list args; sl@0: GSList *expected = NULL; sl@0: GSList *l_exp; sl@0: gchar **matches; sl@0: gint match_count; sl@0: gboolean ret = TRUE; sl@0: gint i; sl@0: sl@0: verbose ("fetching all sub-patterns from \"%s\" (pattern: \"%s\") \t", sl@0: string, pattern); sl@0: sl@0: /* The va_list is a NULL-terminated sequence of extected strings. */ sl@0: va_start (args, string); sl@0: while (TRUE) sl@0: { sl@0: gchar *expected_string = va_arg (args, gchar *); sl@0: if (expected_string == NULL) sl@0: break; sl@0: else sl@0: expected = g_slist_prepend (expected, g_strdup (expected_string)); sl@0: } sl@0: expected = g_slist_reverse (expected); sl@0: va_end (args); sl@0: sl@0: regex = g_regex_new (pattern, 0, 0, NULL); sl@0: g_regex_match (regex, string, 0, &match_info); sl@0: matches = g_match_info_fetch_all (match_info); sl@0: if (matches) sl@0: match_count = g_strv_length (matches); sl@0: else sl@0: match_count = 0; sl@0: sl@0: if (match_count != g_slist_length (expected)) sl@0: { sl@0: g_print ("failed \t(got %d %s, expected %d)\n", match_count, sl@0: match_count == 1 ? "match" : "matches", sl@0: g_slist_length (expected)); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: l_exp = expected; sl@0: for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp)) sl@0: { sl@0: if (!streq(l_exp->data, matches [i])) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", sl@0: matches [i], (gchar *)l_exp->data); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: } sl@0: sl@0: verbose ("passed (%d %s)\n", match_count, sl@0: match_count == 1 ? "match" : "matches"); sl@0: sl@0: exit: sl@0: g_match_info_free (match_info); sl@0: g_regex_unref (regex); sl@0: g_slist_foreach (expected, (GFunc)g_free, NULL); sl@0: g_slist_free (expected); sl@0: g_strfreev (matches); sl@0: sl@0: return ret; sl@0: } sl@0: sl@0: #define TEST_FETCH_ALL0(pattern, string) { \ sl@0: total++; \ sl@0: if (test_fetch_all (pattern, string, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: #define TEST_FETCH_ALL1(pattern, string, e1) { \ sl@0: total++; \ sl@0: if (test_fetch_all (pattern, string, e1, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: #define TEST_FETCH_ALL2(pattern, string, e1, e2) { \ sl@0: total++; \ sl@0: if (test_fetch_all (pattern, string, e1, e2, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: #define TEST_FETCH_ALL3(pattern, string, e1, e2, e3) { \ sl@0: total++; \ sl@0: if (test_fetch_all (pattern, string, e1, e2, e3, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_split_simple (const gchar *pattern, sl@0: const gchar *string, sl@0: ...) sl@0: { sl@0: va_list args; sl@0: GSList *expected = NULL; sl@0: GSList *l_exp; sl@0: gchar **tokens; sl@0: gint token_count; sl@0: gboolean ret = TRUE; sl@0: gint i; sl@0: sl@0: verbose ("splitting \"%s\" against \"%s\" \t", string, pattern); sl@0: sl@0: /* The va_list is a NULL-terminated sequence of extected strings. */ sl@0: va_start (args, string); sl@0: while (TRUE) sl@0: { sl@0: gchar *expected_string = va_arg (args, gchar *); sl@0: if (expected_string == NULL) sl@0: break; sl@0: else sl@0: expected = g_slist_prepend (expected, g_strdup (expected_string)); sl@0: } sl@0: expected = g_slist_reverse (expected); sl@0: va_end (args); sl@0: sl@0: tokens = g_regex_split_simple (pattern, string, 0, 0); sl@0: if (tokens) sl@0: token_count = g_strv_length (tokens); sl@0: else sl@0: token_count = 0; sl@0: sl@0: if (token_count != g_slist_length (expected)) sl@0: { sl@0: g_print ("failed \t(got %d %s, expected %d)\n", token_count, sl@0: token_count == 1 ? "match" : "matches", sl@0: g_slist_length (expected)); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: l_exp = expected; sl@0: for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp)) sl@0: { sl@0: if (!streq(l_exp->data, tokens [i])) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", sl@0: tokens[i], (gchar *)l_exp->data); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: } sl@0: sl@0: verbose ("passed (%d %s)\n", token_count, sl@0: token_count == 1 ? "token" : "tokens"); sl@0: sl@0: exit: sl@0: g_slist_foreach (expected, (GFunc)g_free, NULL); sl@0: g_slist_free (expected); sl@0: g_strfreev (tokens); sl@0: sl@0: return ret; sl@0: } sl@0: sl@0: #define TEST_SPLIT_SIMPLE0(pattern, string) { \ sl@0: total++; \ sl@0: if (test_split_simple (pattern, string, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: #define TEST_SPLIT_SIMPLE1(pattern, string, e1) { \ sl@0: total++; \ sl@0: if (test_split_simple (pattern, string, e1, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: #define TEST_SPLIT_SIMPLE2(pattern, string, e1, e2) { \ sl@0: total++; \ sl@0: if (test_split_simple (pattern, string, e1, e2, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: #define TEST_SPLIT_SIMPLE3(pattern, string, e1, e2, e3) { \ sl@0: total++; \ sl@0: if (test_split_simple (pattern, string, e1, e2, e3, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_split_full (const gchar *pattern, sl@0: const gchar *string, sl@0: gint start_position, sl@0: gint max_tokens, sl@0: ...) sl@0: { sl@0: GRegex *regex; sl@0: va_list args; sl@0: GSList *expected = NULL; sl@0: GSList *l_exp; sl@0: gchar **tokens; sl@0: gint token_count; sl@0: gboolean ret = TRUE; sl@0: gint i; sl@0: sl@0: verbose ("splitting \"%s\" against \"%s\" (start: %d, max: %d) \t", sl@0: string, pattern, start_position, max_tokens); sl@0: sl@0: /* The va_list is a NULL-terminated sequence of extected strings. */ sl@0: va_start (args, max_tokens); sl@0: while (TRUE) sl@0: { sl@0: gchar *expected_string = va_arg (args, gchar *); sl@0: if (expected_string == NULL) sl@0: break; sl@0: else sl@0: expected = g_slist_prepend (expected, g_strdup (expected_string)); sl@0: } sl@0: expected = g_slist_reverse (expected); sl@0: va_end (args); sl@0: sl@0: regex = g_regex_new (pattern, 0, 0, NULL); sl@0: tokens = g_regex_split_full (regex, string, -1, start_position, sl@0: 0, max_tokens, NULL); sl@0: if (tokens) sl@0: token_count = g_strv_length (tokens); sl@0: else sl@0: token_count = 0; sl@0: sl@0: if (token_count != g_slist_length (expected)) sl@0: { sl@0: g_print ("failed \t(got %d %s, expected %d)\n", token_count, sl@0: token_count == 1 ? "match" : "matches", sl@0: g_slist_length (expected)); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: l_exp = expected; sl@0: for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp)) sl@0: { sl@0: if (!streq(l_exp->data, tokens [i])) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", sl@0: tokens[i], (gchar *)l_exp->data); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: } sl@0: sl@0: verbose ("passed (%d %s)\n", token_count, sl@0: token_count == 1 ? "token" : "tokens"); sl@0: sl@0: exit: sl@0: g_regex_unref (regex); sl@0: g_slist_foreach (expected, (GFunc)g_free, NULL); sl@0: g_slist_free (expected); sl@0: g_strfreev (tokens); sl@0: sl@0: return ret; sl@0: } sl@0: sl@0: static gboolean sl@0: test_split (const gchar *pattern, sl@0: const gchar *string, sl@0: ...) sl@0: { sl@0: GRegex *regex; sl@0: va_list args; sl@0: GSList *expected = NULL; sl@0: GSList *l_exp; sl@0: gchar **tokens; sl@0: gint token_count; sl@0: gboolean ret = TRUE; sl@0: gint i; sl@0: sl@0: verbose ("splitting \"%s\" against \"%s\" \t", string, pattern); sl@0: sl@0: /* The va_list is a NULL-terminated sequence of extected strings. */ sl@0: va_start (args, string); sl@0: while (TRUE) sl@0: { sl@0: gchar *expected_string = va_arg (args, gchar *); sl@0: if (expected_string == NULL) sl@0: break; sl@0: else sl@0: expected = g_slist_prepend (expected, g_strdup (expected_string)); sl@0: } sl@0: expected = g_slist_reverse (expected); sl@0: va_end (args); sl@0: sl@0: regex = g_regex_new (pattern, 0, 0, NULL); sl@0: tokens = g_regex_split (regex, string, 0); sl@0: if (tokens) sl@0: token_count = g_strv_length (tokens); sl@0: else sl@0: token_count = 0; sl@0: sl@0: if (token_count != g_slist_length (expected)) sl@0: { sl@0: g_print ("failed \t(got %d %s, expected %d)\n", token_count, sl@0: token_count == 1 ? "match" : "matches", sl@0: g_slist_length (expected)); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: l_exp = expected; sl@0: for (i = 0; l_exp != NULL; i++, l_exp = g_slist_next (l_exp)) sl@0: { sl@0: if (!streq(l_exp->data, tokens [i])) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", sl@0: tokens[i], (gchar *)l_exp->data); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: } sl@0: sl@0: verbose ("passed (%d %s)\n", token_count, sl@0: token_count == 1 ? "token" : "tokens"); sl@0: sl@0: exit: sl@0: g_regex_unref (regex); sl@0: g_slist_foreach (expected, (GFunc)g_free, NULL); sl@0: g_slist_free (expected); sl@0: g_strfreev (tokens); sl@0: sl@0: return ret; sl@0: } sl@0: sl@0: #define TEST_SPLIT0(pattern, string, start_position, max_tokens) { \ sl@0: total++; \ sl@0: if (test_split_full (pattern, string, start_position, max_tokens, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: if (start_position == 0 && max_tokens <= 0) \ sl@0: { \ sl@0: total++; \ sl@0: if (test_split (pattern, string, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } \ sl@0: } sl@0: sl@0: #define TEST_SPLIT1(pattern, string, start_position, max_tokens, e1) { \ sl@0: total++; \ sl@0: if (test_split_full (pattern, string, start_position, max_tokens, e1, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: if (start_position == 0 && max_tokens <= 0) \ sl@0: { \ sl@0: total++; \ sl@0: if (test_split (pattern, string, e1, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } \ sl@0: } sl@0: sl@0: #define TEST_SPLIT2(pattern, string, start_position, max_tokens, e1, e2) { \ sl@0: total++; \ sl@0: if (test_split_full (pattern, string, start_position, max_tokens, e1, e2, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: if (start_position == 0 && max_tokens <= 0) \ sl@0: { \ sl@0: total++; \ sl@0: if (test_split (pattern, string, e1, e2, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } \ sl@0: } sl@0: sl@0: #define TEST_SPLIT3(pattern, string, start_position, max_tokens, e1, e2, e3) { \ sl@0: total++; \ sl@0: if (test_split_full (pattern, string, start_position, max_tokens, e1, e2, e3, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: if (start_position == 0 && max_tokens <= 0) \ sl@0: { \ sl@0: total++; \ sl@0: if (test_split (pattern, string, e1, e2, e3, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_check_replacement (const gchar *string_to_expand, sl@0: gboolean expected, sl@0: gboolean expected_refs) sl@0: { sl@0: gboolean result; sl@0: gboolean has_refs; sl@0: sl@0: verbose ("checking replacement string \"%s\" \t", string_to_expand); sl@0: sl@0: result = g_regex_check_replacement (string_to_expand, &has_refs, NULL); sl@0: if (expected != result) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", sl@0: result ? "TRUE" : "FALSE", sl@0: expected ? "TRUE" : "FALSE"); sl@0: return FALSE; sl@0: } sl@0: sl@0: if (expected && expected_refs != has_refs) sl@0: { sl@0: g_print ("failed \t(got has_references \"%s\", expected \"%s\")\n", sl@0: has_refs ? "TRUE" : "FALSE", sl@0: expected_refs ? "TRUE" : "FALSE"); sl@0: return FALSE; sl@0: } sl@0: sl@0: verbose ("passed\n"); sl@0: return TRUE; sl@0: } sl@0: sl@0: #define TEST_CHECK_REPLACEMENT(string_to_expand, expected, expected_refs) { \ sl@0: total++; \ sl@0: if (test_check_replacement (string_to_expand, expected, expected_refs)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: static gboolean sl@0: test_expand (const gchar *pattern, sl@0: const gchar *string, sl@0: const gchar *string_to_expand, sl@0: gboolean raw, sl@0: const gchar *expected) sl@0: { sl@0: GRegex *regex = NULL; sl@0: GMatchInfo *match_info = NULL; sl@0: gchar *res; sl@0: sl@0: verbose ("expanding the references in \"%s\" (pattern: \"%s\", string: \"%s\") \t", sl@0: string_to_expand, sl@0: pattern ? pattern : "(null)", sl@0: string ? string : "(null)"); sl@0: sl@0: if (pattern) sl@0: { sl@0: regex = g_regex_new (pattern, raw ? G_REGEX_RAW : 0, 0, NULL); sl@0: g_regex_match (regex, string, 0, &match_info); sl@0: } sl@0: sl@0: res = g_match_info_expand_references (match_info, string_to_expand, NULL); sl@0: if (!streq (res, expected)) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", res, expected); sl@0: g_free (res); sl@0: g_match_info_free (match_info); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: sl@0: g_free (res); sl@0: g_match_info_free (match_info); sl@0: if (regex) sl@0: g_regex_unref (regex); sl@0: sl@0: verbose ("passed\n"); sl@0: return TRUE; sl@0: } sl@0: sl@0: #define TEST_EXPAND(pattern, string, string_to_expand, raw, expected) { \ sl@0: total++; \ sl@0: if (test_expand (pattern, string, string_to_expand, raw, expected)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_replace (const gchar *pattern, sl@0: const gchar *string, sl@0: gint start_position, sl@0: const gchar *replacement, sl@0: const gchar *expected) sl@0: { sl@0: GRegex *regex; sl@0: gchar *res; sl@0: sl@0: verbose ("replacing \"%s\" in \"%s\" (pattern: \"%s\", start: %d) \t", sl@0: replacement, string, pattern, start_position); sl@0: sl@0: regex = g_regex_new (pattern, 0, 0, NULL); sl@0: res = g_regex_replace (regex, string, -1, start_position, replacement, 0, NULL); sl@0: if (!streq (res, expected)) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", res, expected); sl@0: g_free (res); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: sl@0: g_free (res); sl@0: g_regex_unref (regex); sl@0: sl@0: verbose ("passed\n"); sl@0: return TRUE; sl@0: } sl@0: sl@0: #define TEST_REPLACE(pattern, string, start_position, replacement, expected) { \ sl@0: total++; \ sl@0: if (test_replace (pattern, string, start_position, replacement, expected)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_replace_lit (const gchar *pattern, sl@0: const gchar *string, sl@0: gint start_position, sl@0: const gchar *replacement, sl@0: const gchar *expected) sl@0: { sl@0: GRegex *regex; sl@0: gchar *res; sl@0: sl@0: verbose ("replacing literally \"%s\" in \"%s\" (pattern: \"%s\", start: %d) \t", sl@0: replacement, string, pattern, start_position); sl@0: sl@0: regex = g_regex_new (pattern, 0, 0, NULL); sl@0: res = g_regex_replace_literal (regex, string, -1, start_position, sl@0: replacement, 0, NULL); sl@0: if (!streq (res, expected)) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", res, expected); sl@0: g_free (res); sl@0: g_regex_unref (regex); sl@0: return FALSE; sl@0: } sl@0: sl@0: g_free (res); sl@0: g_regex_unref (regex); sl@0: sl@0: verbose ("passed\n"); sl@0: return TRUE; sl@0: } sl@0: sl@0: #define TEST_REPLACE_LIT(pattern, string, start_position, replacement, expected) { \ sl@0: total++; \ sl@0: if (test_replace_lit (pattern, string, start_position, replacement, expected)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_get_string_number (const gchar *pattern, sl@0: const gchar *name, sl@0: gint expected_num) sl@0: { sl@0: GRegex *regex; sl@0: gint num; sl@0: sl@0: verbose ("getting the number of \"%s\" (pattern: \"%s\") \t", sl@0: name, pattern); sl@0: sl@0: regex = g_regex_new (pattern, 0, 0, NULL); sl@0: num = g_regex_get_string_number (regex, name); sl@0: g_regex_unref (regex); sl@0: sl@0: if (num != expected_num) sl@0: { sl@0: g_print ("failed \t(got %d, expected %d)\n", num, expected_num); sl@0: return FALSE; sl@0: } sl@0: else sl@0: { sl@0: verbose ("passed\n"); sl@0: return TRUE; sl@0: } sl@0: } sl@0: sl@0: #define TEST_GET_STRING_NUMBER(pattern, name, expected_num) { \ sl@0: total++; \ sl@0: if (test_get_string_number (pattern, name, expected_num)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_escape (const gchar *string, sl@0: gint length, sl@0: const gchar *expected) sl@0: { sl@0: gchar *escaped; sl@0: sl@0: verbose ("escaping \"%s\" (len: %d) \t", string, length); sl@0: sl@0: escaped = g_regex_escape_string (string, length); sl@0: sl@0: if (!streq (escaped, expected)) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", escaped, expected); sl@0: g_free (escaped); sl@0: return FALSE; sl@0: } sl@0: sl@0: g_free (escaped); sl@0: sl@0: verbose ("passed\n"); sl@0: return TRUE; sl@0: } sl@0: sl@0: #define TEST_ESCAPE(string, length, expected) { \ sl@0: total++; \ sl@0: if (test_escape (string, length, expected)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } sl@0: sl@0: static gboolean sl@0: test_match_all_full (const gchar *pattern, sl@0: const gchar *string, sl@0: gssize string_len, sl@0: gint start_position, sl@0: ...) sl@0: { sl@0: GRegex *regex; sl@0: GMatchInfo *match_info; sl@0: va_list args; sl@0: GSList *expected = NULL; sl@0: GSList *l_exp; sl@0: gboolean match_ok; sl@0: gboolean ret = TRUE; sl@0: gint match_count; sl@0: gint i; sl@0: sl@0: verbose ("matching all in \"%s\" against \"%s\" (start: %d, len: %d) \t", sl@0: string, pattern, start_position, string_len); sl@0: sl@0: /* The va_list is a NULL-terminated sequence of: extected matched string, sl@0: * expected start and expected end. */ sl@0: va_start (args, start_position); sl@0: while (TRUE) sl@0: { sl@0: Match *match; sl@0: const gchar *expected_string = va_arg (args, const gchar *); sl@0: if (expected_string == NULL) sl@0: break; sl@0: match = g_new0 (Match, 1); sl@0: match->string = g_strdup (expected_string); sl@0: match->start = va_arg (args, gint); sl@0: match->end = va_arg (args, gint); sl@0: expected = g_slist_prepend (expected, match); sl@0: } sl@0: expected = g_slist_reverse (expected); sl@0: va_end (args); sl@0: sl@0: regex = g_regex_new (pattern, 0, 0, NULL); sl@0: match_ok = g_regex_match_all_full (regex, string, string_len, start_position, sl@0: 0, &match_info, NULL); sl@0: sl@0: if (match_ok && g_slist_length (expected) == 0) sl@0: { sl@0: g_print ("failed\n"); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: if (!match_ok && g_slist_length (expected) != 0) sl@0: { sl@0: g_print ("failed\n"); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: match_count = g_match_info_get_match_count (match_info); sl@0: if (match_count != g_slist_length (expected)) sl@0: { sl@0: g_print ("failed \t(got %d %s, expected %d)\n", match_count, sl@0: match_count == 1 ? "match" : "matches", sl@0: g_slist_length (expected)); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: l_exp = expected; sl@0: for (i = 0; i < match_count; i++) sl@0: { sl@0: gint start, end; sl@0: gchar *matched_string; sl@0: Match *exp = l_exp->data; sl@0: sl@0: matched_string = g_match_info_fetch (match_info, i); sl@0: g_match_info_fetch_pos (match_info, i, &start, &end); sl@0: sl@0: if (!streq(exp->string, matched_string)) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", sl@0: matched_string, exp->string); sl@0: g_free (matched_string); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: g_free (matched_string); sl@0: sl@0: if (exp->start != start || exp->end != end) sl@0: { sl@0: g_print ("failed \t(got [%d, %d], expected [%d, %d])\n", sl@0: start, end, exp->start, exp->end); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: l_exp = g_slist_next (l_exp); sl@0: } sl@0: sl@0: exit: sl@0: if (ret) sl@0: { sl@0: verbose ("passed (%d %s)\n", match_count, match_count == 1 ? "match" : "matches"); sl@0: } sl@0: sl@0: g_match_info_free (match_info); sl@0: g_regex_unref (regex); sl@0: g_slist_foreach (expected, free_match, NULL); sl@0: g_slist_free (expected); sl@0: sl@0: return ret; sl@0: } sl@0: sl@0: static gboolean sl@0: test_match_all (const gchar *pattern, sl@0: const gchar *string, sl@0: ...) sl@0: { sl@0: GRegex *regex; sl@0: GMatchInfo *match_info; sl@0: va_list args; sl@0: GSList *expected = NULL; sl@0: GSList *l_exp; sl@0: gboolean match_ok; sl@0: gboolean ret = TRUE; sl@0: gint match_count; sl@0: gint i; sl@0: sl@0: verbose ("matching all in \"%s\" against \"%s\" \t", string, pattern); sl@0: sl@0: /* The va_list is a NULL-terminated sequence of: extected matched string, sl@0: * expected start and expected end. */ sl@0: va_start (args, string); sl@0: while (TRUE) sl@0: { sl@0: Match *match; sl@0: const gchar *expected_string = va_arg (args, const gchar *); sl@0: if (expected_string == NULL) sl@0: break; sl@0: match = g_new0 (Match, 1); sl@0: match->string = g_strdup (expected_string); sl@0: match->start = va_arg (args, gint); sl@0: match->end = va_arg (args, gint); sl@0: expected = g_slist_prepend (expected, match); sl@0: } sl@0: expected = g_slist_reverse (expected); sl@0: va_end (args); sl@0: sl@0: regex = g_regex_new (pattern, 0, 0, NULL); sl@0: match_ok = g_regex_match_all (regex, string, 0, &match_info); sl@0: sl@0: if (match_ok && g_slist_length (expected) == 0) sl@0: { sl@0: g_print ("failed\n"); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: if (!match_ok && g_slist_length (expected) != 0) sl@0: { sl@0: g_print ("failed\n"); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: match_count = g_match_info_get_match_count (match_info); sl@0: if (match_count != g_slist_length (expected)) sl@0: { sl@0: g_print ("failed \t(got %d %s, expected %d)\n", match_count, sl@0: match_count == 1 ? "match" : "matches", sl@0: g_slist_length (expected)); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: l_exp = expected; sl@0: for (i = 0; i < match_count; i++) sl@0: { sl@0: gint start, end; sl@0: gchar *matched_string; sl@0: Match *exp = l_exp->data; sl@0: sl@0: matched_string = g_match_info_fetch (match_info, i); sl@0: g_match_info_fetch_pos (match_info, i, &start, &end); sl@0: sl@0: if (!streq(exp->string, matched_string)) sl@0: { sl@0: g_print ("failed \t(got \"%s\", expected \"%s\")\n", sl@0: matched_string, exp->string); sl@0: g_free (matched_string); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: g_free (matched_string); sl@0: sl@0: if (exp->start != start || exp->end != end) sl@0: { sl@0: g_print ("failed \t(got [%d, %d], expected [%d, %d])\n", sl@0: start, end, exp->start, exp->end); sl@0: ret = FALSE; sl@0: goto exit; sl@0: } sl@0: sl@0: l_exp = g_slist_next (l_exp); sl@0: } sl@0: sl@0: exit: sl@0: if (ret) sl@0: { sl@0: verbose ("passed (%d %s)\n", match_count, match_count == 1 ? "match" : "matches"); sl@0: } sl@0: sl@0: g_match_info_free (match_info); sl@0: g_regex_unref (regex); sl@0: g_slist_foreach (expected, free_match, NULL); sl@0: g_slist_free (expected); sl@0: sl@0: return ret; sl@0: } sl@0: sl@0: #define TEST_MATCH_ALL0(pattern, string, string_len, start_position) { \ sl@0: total++; \ sl@0: if (test_match_all_full (pattern, string, string_len, start_position, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: if (string_len == -1 && start_position == 0) \ sl@0: { \ sl@0: total++; \ sl@0: if (test_match_all (pattern, string, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } \ sl@0: } sl@0: sl@0: #define TEST_MATCH_ALL1(pattern, string, string_len, start_position, \ sl@0: t1, s1, e1) { \ sl@0: total++; \ sl@0: if (test_match_all_full (pattern, string, string_len, start_position, \ sl@0: t1, s1, e1, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: if (string_len == -1 && start_position == 0) \ sl@0: { \ sl@0: total++; \ sl@0: if (test_match_all (pattern, string, t1, s1, e1, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } \ sl@0: } sl@0: sl@0: #define TEST_MATCH_ALL2(pattern, string, string_len, start_position, \ sl@0: t1, s1, e1, t2, s2, e2) { \ sl@0: total++; \ sl@0: if (test_match_all_full (pattern, string, string_len, start_position, \ sl@0: t1, s1, e1, t2, s2, e2, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: if (string_len == -1 && start_position == 0) \ sl@0: { \ sl@0: total++; \ sl@0: if (test_match_all (pattern, string, t1, s1, e1, t2, s2, e2, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } \ sl@0: } sl@0: sl@0: #define TEST_MATCH_ALL3(pattern, string, string_len, start_position, \ sl@0: t1, s1, e1, t2, s2, e2, t3, s3, e3) { \ sl@0: total++; \ sl@0: if (test_match_all_full (pattern, string, string_len, start_position, \ sl@0: t1, s1, e1, t2, s2, e2, t3, s3, e3, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: if (string_len == -1 && start_position == 0) \ sl@0: { \ sl@0: total++; \ sl@0: if (test_match_all (pattern, string, t1, s1, e1, t2, s2, e2, t3, s3, e3, NULL)) \ sl@0: PASS; \ sl@0: else \ sl@0: FAIL; \ sl@0: } \ sl@0: } sl@0: sl@0: int sl@0: main (int argc, char *argv[]) sl@0: { sl@0: gint total = 0; sl@0: gint passed = 0; sl@0: gint failed = 0; sl@0: gint i = 0; sl@0: #ifdef __SYMBIAN32__ sl@0: g_log_set_handler (NULL, G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL); sl@0: g_set_print_handler(mrtPrintHandler); sl@0: #endif /*__SYMBIAN32__*/ sl@0: setlocale (LC_ALL, ""); sl@0: sl@0: for (i = 1; i < argc; i++) sl@0: { sl@0: if (streq ("-noisy", argv[i])) sl@0: noisy = TRUE; sl@0: else if (streq ("-abort", argv[i])) sl@0: abort_on_fail = TRUE; sl@0: } sl@0: sl@0: g_setenv ("G_DEBUG", "fatal_warnings", TRUE); sl@0: sl@0: /* TEST_NEW(pattern, compile_opts, match_opts) */ sl@0: TEST_NEW("", 0, 0); sl@0: TEST_NEW(".*", 0, 0); sl@0: TEST_NEW(".*", G_REGEX_OPTIMIZE, 0); sl@0: TEST_NEW(".*", G_REGEX_MULTILINE, 0); sl@0: TEST_NEW(".*", G_REGEX_DOTALL, 0); sl@0: TEST_NEW(".*", G_REGEX_DOTALL, G_REGEX_MATCH_NOTBOL); sl@0: TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", 0, 0); sl@0: TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_CASELESS, 0); sl@0: TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_CASELESS | G_REGEX_OPTIMIZE, 0); sl@0: TEST_NEW("(?Px)|(?Py)", G_REGEX_DUPNAMES, 0); sl@0: TEST_NEW("(?Px)|(?Py)", G_REGEX_DUPNAMES | G_REGEX_OPTIMIZE, 0); sl@0: /* This gives "internal error: code overflow" with pcre 6.0 */ sl@0: TEST_NEW("(?i)(?-i)", 0, 0); sl@0: sl@0: /* TEST_NEW_FAIL(pattern, compile_opts, expected_error) */ sl@0: TEST_NEW_FAIL("(", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); sl@0: TEST_NEW_FAIL(")", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); sl@0: TEST_NEW_FAIL("[", 0, G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS); sl@0: TEST_NEW_FAIL("*", 0, G_REGEX_ERROR_NOTHING_TO_REPEAT); sl@0: TEST_NEW_FAIL("?", 0, G_REGEX_ERROR_NOTHING_TO_REPEAT); sl@0: TEST_NEW_FAIL("(?Px)|(?Py)", 0, G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME); sl@0: sl@0: /* TEST_MATCH_SIMPLE(pattern, string, compile_opts, match_opts, expected) */ sl@0: TEST_MATCH_SIMPLE("a", "", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("a", "a", 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("a", "ba", 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("^a", "ba", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("a", "ba", G_REGEX_ANCHORED, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("a", "ba", 0, G_REGEX_MATCH_ANCHORED, FALSE); sl@0: TEST_MATCH_SIMPLE("a", "ab", G_REGEX_ANCHORED, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("a", "ab", 0, G_REGEX_MATCH_ANCHORED, TRUE); sl@0: TEST_MATCH_SIMPLE("a", "a", G_REGEX_CASELESS, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("a", "A", G_REGEX_CASELESS, 0, TRUE); sl@0: /* These are needed to test extended properties. */ sl@0: TEST_MATCH_SIMPLE(AGRAVE, AGRAVE, G_REGEX_CASELESS, 0, TRUE); sl@0: TEST_MATCH_SIMPLE(AGRAVE, AGRAVE_UPPER, G_REGEX_CASELESS, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{L}", "a", 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{L}", "1", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{L}", AGRAVE, 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{L}", AGRAVE_UPPER, 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{L}", SHEEN, 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{L}", ETH30, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Ll}", "a", 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{Ll}", AGRAVE, 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{Ll}", AGRAVE_UPPER, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Ll}", ETH30, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Sc}", AGRAVE, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Sc}", EURO, 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{Sc}", ETH30, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{N}", "a", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{N}", "1", 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{N}", AGRAVE, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{N}", AGRAVE_UPPER, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{N}", SHEEN, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{N}", ETH30, 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{Nd}", "a", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Nd}", "1", 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{Nd}", AGRAVE, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Nd}", AGRAVE_UPPER, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Nd}", SHEEN, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Nd}", ETH30, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Common}", SHEEN, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Common}", "a", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Common}", AGRAVE, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Common}", AGRAVE_UPPER, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Common}", ETH30, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Common}", "%", 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{Common}", "1", 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{Arabic}", SHEEN, 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{Arabic}", "a", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Arabic}", AGRAVE, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Arabic}", AGRAVE_UPPER, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Arabic}", ETH30, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Arabic}", "%", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Arabic}", "1", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Latin}", SHEEN, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Latin}", "a", 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{Latin}", AGRAVE, 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{Latin}", AGRAVE_UPPER, 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{Latin}", ETH30, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Latin}", "%", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Latin}", "1", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Ethiopic}", SHEEN, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Ethiopic}", "a", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Ethiopic}", AGRAVE, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Ethiopic}", AGRAVE_UPPER, 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Ethiopic}", ETH30, 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{Ethiopic}", "%", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{Ethiopic}", "1", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("\\p{L}(?<=\\p{Arabic})", SHEEN, 0, 0, TRUE); sl@0: TEST_MATCH_SIMPLE("\\p{L}(?<=\\p{Latin})", SHEEN, 0, 0, FALSE); sl@0: /* Invalid patterns. */ sl@0: TEST_MATCH_SIMPLE("\\", "a", 0, 0, FALSE); sl@0: TEST_MATCH_SIMPLE("[", "", 0, 0, FALSE); sl@0: sl@0: /* TEST_MATCH(pattern, compile_opts, match_opts, string, sl@0: * string_len, start_position, match_opts2, expected) */ sl@0: TEST_MATCH("a", 0, 0, "a", -1, 0, 0, TRUE); sl@0: TEST_MATCH("a", 0, 0, "A", -1, 0, 0, FALSE); sl@0: TEST_MATCH("a", G_REGEX_CASELESS, 0, "A", -1, 0, 0, TRUE); sl@0: TEST_MATCH("a", 0, 0, "ab", -1, 1, 0, FALSE); sl@0: TEST_MATCH("a", 0, 0, "ba", 1, 0, 0, FALSE); sl@0: TEST_MATCH("a", 0, 0, "bab", -1, 0, 0, TRUE); sl@0: TEST_MATCH("a", 0, 0, "b", -1, 0, 0, FALSE); sl@0: TEST_MATCH("a", 0, G_REGEX_ANCHORED, "a", -1, 0, 0, TRUE); sl@0: TEST_MATCH("a", 0, G_REGEX_ANCHORED, "ab", -1, 1, 0, FALSE); sl@0: TEST_MATCH("a", 0, G_REGEX_ANCHORED, "ba", 1, 0, 0, FALSE); sl@0: TEST_MATCH("a", 0, G_REGEX_ANCHORED, "bab", -1, 0, 0, FALSE); sl@0: TEST_MATCH("a", 0, G_REGEX_ANCHORED, "b", -1, 0, 0, FALSE); sl@0: TEST_MATCH("a", 0, 0, "a", -1, 0, G_REGEX_ANCHORED, TRUE); sl@0: TEST_MATCH("a", 0, 0, "ab", -1, 1, G_REGEX_ANCHORED, FALSE); sl@0: TEST_MATCH("a", 0, 0, "ba", 1, 0, G_REGEX_ANCHORED, FALSE); sl@0: TEST_MATCH("a", 0, 0, "bab", -1, 0, G_REGEX_ANCHORED, FALSE); sl@0: TEST_MATCH("a", 0, 0, "b", -1, 0, G_REGEX_ANCHORED, FALSE); sl@0: TEST_MATCH("a|b", 0, 0, "a", -1, 0, 0, TRUE); sl@0: TEST_MATCH("\\d", 0, 0, EURO, -1, 0, 0, FALSE); sl@0: TEST_MATCH("^.$", 0, 0, EURO, -1, 0, 0, TRUE); sl@0: TEST_MATCH("^.{3}$", 0, 0, EURO, -1, 0, 0, FALSE); sl@0: TEST_MATCH("^.$", G_REGEX_RAW, 0, EURO, -1, 0, 0, FALSE); sl@0: TEST_MATCH("^.{3}$", G_REGEX_RAW, 0, EURO, -1, 0, 0, TRUE); sl@0: TEST_MATCH(AGRAVE, G_REGEX_CASELESS, 0, AGRAVE_UPPER, -1, 0, 0, TRUE); sl@0: sl@0: /* New lines handling. */ sl@0: TEST_MATCH("^a\\Rb$", 0, 0, "a\r\nb", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^a\\Rb$", 0, 0, "a\nb", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^a\\Rb$", 0, 0, "a\rb", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^a\\Rb$", 0, 0, "a\n\rb", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^a\\R\\Rb$", 0, 0, "a\n\rb", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^a\\nb$", 0, 0, "a\r\nb", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^a\\r\\nb$", 0, 0, "a\r\nb", -1, 0, 0, TRUE); sl@0: sl@0: TEST_MATCH("^b$", 0, 0, "a\nb\nc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\nb\nc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\r\nb\r\nc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\rb\rc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\nb\nc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\nb\nc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\nb\nc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\r\nb\r\nc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\r\nb\r\nc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\r\nb\r\nc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\rb\rc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\rb\rc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\rb\rc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\nb\nc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\nb\nc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\nb\nc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\r\nb\r\nc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\r\nb\r\nc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\r\nb\r\nc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\rb\rc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\rb\rc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\rb\rc", -1, 0, 0, FALSE); sl@0: sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\nb\nc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\rb\rc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\r\nb\r\nc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_LF, "a\nb\nc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_LF, "a\rb\rc", -1, 0, 0, FALSE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_CRLF, "a\r\nb\r\nc", -1, 0, 0, TRUE); sl@0: TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_CRLF, "a\rb\rc", -1, 0, 0, FALSE); sl@0: sl@0: TEST_MATCH("a#\nb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE); sl@0: TEST_MATCH("a#\r\nb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE); sl@0: TEST_MATCH("a#\rb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE); sl@0: TEST_MATCH("a#\nb", G_REGEX_EXTENDED, G_REGEX_MATCH_NEWLINE_CR, "a", -1, 0, 0, FALSE); sl@0: TEST_MATCH("a#\nb", G_REGEX_EXTENDED | G_REGEX_NEWLINE_CR, 0, "a", -1, 0, 0, TRUE); sl@0: sl@0: /* TEST_MATCH_NEXT#(pattern, string, string_len, start_position, ...) */ sl@0: TEST_MATCH_NEXT0("a", "x", -1, 0); sl@0: TEST_MATCH_NEXT0("a", "ax", -1, 1); sl@0: TEST_MATCH_NEXT0("a", "xa", 1, 0); sl@0: TEST_MATCH_NEXT0("a", "axa", 1, 2); sl@0: TEST_MATCH_NEXT1("a", "a", -1, 0, "a", 0, 1); sl@0: TEST_MATCH_NEXT1("a", "xax", -1, 0, "a", 1, 2); sl@0: TEST_MATCH_NEXT1(EURO, ENG EURO, -1, 0, EURO, 2, 5); sl@0: TEST_MATCH_NEXT1("a*", "", -1, 0, "", 0, 0); sl@0: TEST_MATCH_NEXT2("a*", "aa", -1, 0, "aa", 0, 2, "", 2, 2); sl@0: TEST_MATCH_NEXT2(EURO "*", EURO EURO, -1, 0, EURO EURO, 0, 6, "", 6, 6); sl@0: TEST_MATCH_NEXT2("a", "axa", -1, 0, "a", 0, 1, "a", 2, 3); sl@0: TEST_MATCH_NEXT2("a+", "aaxa", -1, 0, "aa", 0, 2, "a", 3, 4); sl@0: TEST_MATCH_NEXT2("a", "aa", -1, 0, "a", 0, 1, "a", 1, 2); sl@0: TEST_MATCH_NEXT2("a", "ababa", -1, 2, "a", 2, 3, "a", 4, 5); sl@0: TEST_MATCH_NEXT2(EURO "+", EURO "-" EURO, -1, 0, EURO, 0, 3, EURO, 4, 7); sl@0: TEST_MATCH_NEXT3("", "ab", -1, 0, "", 0, 0, "", 1, 1, "", 2, 2); sl@0: TEST_MATCH_NEXT3("", AGRAVE "b", -1, 0, "", 0, 0, "", 2, 2, "", 3, 3); sl@0: TEST_MATCH_NEXT3("a", "aaxa", -1, 0, "a", 0, 1, "a", 1, 2, "a", 3, 4); sl@0: TEST_MATCH_NEXT3("a", "aa" OGRAVE "a", -1, 0, "a", 0, 1, "a", 1, 2, "a", 4, 5); sl@0: TEST_MATCH_NEXT3("a*", "aax", -1, 0, "aa", 0, 2, "", 2, 2, "", 3, 3); sl@0: TEST_MATCH_NEXT3("(?=[A-Z0-9])", "RegExTest", -1, 0, "", 0, 0, "", 3, 3, "", 5, 5); sl@0: TEST_MATCH_NEXT4("a*", "aaxa", -1, 0, "aa", 0, 2, "", 2, 2, "a", 3, 4, "", 4, 4); sl@0: sl@0: /* TEST_MATCH_COUNT(pattern, string, start_position, match_opts, expected_count) */ sl@0: TEST_MATCH_COUNT("a", "", 0, 0, 0); sl@0: TEST_MATCH_COUNT("a", "a", 0, 0, 1); sl@0: TEST_MATCH_COUNT("a", "a", 1, 0, 0); sl@0: TEST_MATCH_COUNT("(.)", "a", 0, 0, 2); sl@0: TEST_MATCH_COUNT("(.)", EURO, 0, 0, 2); sl@0: TEST_MATCH_COUNT("(?:.)", "a", 0, 0, 1); sl@0: TEST_MATCH_COUNT("(?P.)", "a", 0, 0, 2); sl@0: TEST_MATCH_COUNT("a$", "a", 0, G_REGEX_MATCH_NOTEOL, 0); sl@0: TEST_MATCH_COUNT("(a)?(b)", "b", 0, 0, 3); sl@0: TEST_MATCH_COUNT("(a)?(b)", "ab", 0, 0, 3); sl@0: sl@0: /* TEST_PARTIAL(pattern, string, expected) */ sl@0: TEST_PARTIAL("^ab", "a", TRUE); sl@0: TEST_PARTIAL("^ab", "xa", FALSE); sl@0: TEST_PARTIAL("ab", "xa", TRUE); sl@0: TEST_PARTIAL("ab", "ab", FALSE); /* normal match. */ sl@0: TEST_PARTIAL("a+b", "aa", FALSE); /* PCRE_ERROR_BAD_PARTIAL */ sl@0: TEST_PARTIAL("(a)+b", "aa", TRUE); sl@0: TEST_PARTIAL("a?b", "a", TRUE); sl@0: sl@0: /* TEST_SUB_PATTERN(pattern, string, start_position, sub_n, expected_sub, sl@0: * expected_start, expected_end) */ sl@0: TEST_SUB_PATTERN("a", "a", 0, 0, "a", 0, 1); sl@0: TEST_SUB_PATTERN("a(.)", "ab", 0, 1, "b", 1, 2); sl@0: TEST_SUB_PATTERN("a(.)", "a" EURO, 0, 1, EURO, 1, 4); sl@0: TEST_SUB_PATTERN("(?:.*)(a)(.)", "xxa" ENG, 0, 2, ENG, 3, 5); sl@0: TEST_SUB_PATTERN("(" HSTROKE ")", "a" HSTROKE ENG, 0, 1, HSTROKE, 1, 3); sl@0: TEST_SUB_PATTERN("a", "a", 0, 1, NULL, UNTOUCHED, UNTOUCHED); sl@0: TEST_SUB_PATTERN("a", "a", 0, 1, NULL, UNTOUCHED, UNTOUCHED); sl@0: TEST_SUB_PATTERN("(a)?(b)", "b", 0, 0, "b", 0, 1); sl@0: TEST_SUB_PATTERN("(a)?(b)", "b", 0, 1, "", -1, -1); sl@0: TEST_SUB_PATTERN("(a)?(b)", "b", 0, 2, "b", 0, 1); sl@0: sl@0: /* TEST_NAMED_SUB_PATTERN(pattern, string, start_position, sub_name, sl@0: * expected_sub, expected_start, expected_end) */ sl@0: TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", "ab", 0, "A", "b", 1, 2); sl@0: TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", "aab", 1, "A", "b", 2, 3); sl@0: TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", EURO "ab", 0, "A", "b", 4, 5); sl@0: TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", EURO "ab", 0, "B", NULL, UNTOUCHED, UNTOUCHED); sl@0: TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", EURO "ab", 0, "C", NULL, UNTOUCHED, UNTOUCHED); sl@0: TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", "a" EGRAVE "x", 0, "A", EGRAVE, 1, 3); sl@0: TEST_NAMED_SUB_PATTERN("a(?P.)(?P.)?", "a" EGRAVE "x", 0, "B", "x", 3, 4); sl@0: TEST_NAMED_SUB_PATTERN("(?Pa)?(?Pb)", "b", 0, "A", "", -1, -1); sl@0: TEST_NAMED_SUB_PATTERN("(?Pa)?(?Pb)", "b", 0, "B", "b", 0, 1); sl@0: sl@0: /* TEST_NAMED_SUB_PATTERN_DUPNAMES(pattern, string, start_position, sub_name, sl@0: * expected_sub, expected_start, expected_end) */ sl@0: TEST_NAMED_SUB_PATTERN_DUPNAMES("(?Pa)|(?Pb)", "ab", 0, "N", "a", 0, 1); sl@0: TEST_NAMED_SUB_PATTERN_DUPNAMES("(?Paa)|(?Pa)", "aa", 0, "N", "aa", 0, 2); sl@0: TEST_NAMED_SUB_PATTERN_DUPNAMES("(?Paa)(?Pa)", "aaa", 0, "N", "aa", 0, 2); sl@0: TEST_NAMED_SUB_PATTERN_DUPNAMES("(?Px)|(?Pa)", "a", 0, "N", "a", 0, 1); sl@0: TEST_NAMED_SUB_PATTERN_DUPNAMES("(?Px)y|(?Pa)b", "ab", 0, "N", "a", 0, 1); sl@0: sl@0: /* DUPNAMES option inside the pattern */ sl@0: TEST_NAMED_SUB_PATTERN("(?J)(?Pa)|(?Pb)", "ab", 0, "N", "a", 0, 1); sl@0: TEST_NAMED_SUB_PATTERN("(?J)(?Paa)|(?Pa)", "aa", 0, "N", "aa", 0, 2); sl@0: TEST_NAMED_SUB_PATTERN("(?J)(?Paa)(?Pa)", "aaa", 0, "N", "aa", 0, 2); sl@0: TEST_NAMED_SUB_PATTERN("(?J)(?Px)|(?Pa)", "a", 0, "N", "a", 0, 1); sl@0: TEST_NAMED_SUB_PATTERN("(?J)(?Px)y|(?Pa)b", "ab", 0, "N", "a", 0, 1); sl@0: sl@0: /* TEST_FETCH_ALL#(pattern, string, ...) */ sl@0: TEST_FETCH_ALL0("a", ""); sl@0: TEST_FETCH_ALL0("a", "b"); sl@0: TEST_FETCH_ALL1("a", "a", "a"); sl@0: TEST_FETCH_ALL1("a+", "aa", "aa"); sl@0: TEST_FETCH_ALL1("(?:a)", "a", "a"); sl@0: TEST_FETCH_ALL2("(a)", "a", "a", "a"); sl@0: TEST_FETCH_ALL2("a(.)", "ab", "ab", "b"); sl@0: TEST_FETCH_ALL2("a(.)", "a" HSTROKE, "a" HSTROKE, HSTROKE); sl@0: TEST_FETCH_ALL3("(?:.*)(a)(.)", "xyazk", "xyaz", "a", "z"); sl@0: TEST_FETCH_ALL3("(?P.)(a)", "xa", "xa", "x", "a"); sl@0: TEST_FETCH_ALL3("(?P.)(a)", ENG "a", ENG "a", ENG, "a"); sl@0: TEST_FETCH_ALL3("(a)?(b)", "b", "b", "", "b"); sl@0: TEST_FETCH_ALL3("(a)?(b)", "ab", "ab", "a", "b"); sl@0: sl@0: /* TEST_SPLIT_SIMPLE#(pattern, string, ...) */ sl@0: TEST_SPLIT_SIMPLE0("", ""); sl@0: TEST_SPLIT_SIMPLE0("a", ""); sl@0: TEST_SPLIT_SIMPLE1(",", "a", "a"); sl@0: TEST_SPLIT_SIMPLE1("(,)\\s*", "a", "a"); sl@0: TEST_SPLIT_SIMPLE2(",", "a,b", "a", "b"); sl@0: TEST_SPLIT_SIMPLE3(",", "a,b,c", "a", "b", "c"); sl@0: TEST_SPLIT_SIMPLE3(",\\s*", "a,b,c", "a", "b", "c"); sl@0: TEST_SPLIT_SIMPLE3(",\\s*", "a, b, c", "a", "b", "c"); sl@0: TEST_SPLIT_SIMPLE3("(,)\\s*", "a,b", "a", ",", "b"); sl@0: TEST_SPLIT_SIMPLE3("(,)\\s*", "a, b", "a", ",", "b"); sl@0: /* Not matched sub-strings. */ sl@0: TEST_SPLIT_SIMPLE2("a|(b)", "xay", "x", "y"); sl@0: TEST_SPLIT_SIMPLE3("a|(b)", "xby", "x", "b", "y"); sl@0: /* Empty matches. */ sl@0: TEST_SPLIT_SIMPLE3("", "abc", "a", "b", "c"); sl@0: TEST_SPLIT_SIMPLE3(" *", "ab c", "a", "b", "c"); sl@0: /* Invalid patterns. */ sl@0: TEST_SPLIT_SIMPLE0("\\", ""); sl@0: TEST_SPLIT_SIMPLE0("[", ""); sl@0: sl@0: /* TEST_SPLIT#(pattern, string, start_position, max_tokens, ...) */ sl@0: TEST_SPLIT0("", "", 0, 0); sl@0: TEST_SPLIT0("a", "", 0, 0); sl@0: TEST_SPLIT0("a", "", 0, 1); sl@0: TEST_SPLIT0("a", "", 0, 2); sl@0: TEST_SPLIT0("a", "a", 1, 0); sl@0: TEST_SPLIT1(",", "a", 0, 0, "a"); sl@0: TEST_SPLIT1(",", "a,b", 0, 1, "a,b"); sl@0: TEST_SPLIT1("(,)\\s*", "a", 0, 0, "a"); sl@0: TEST_SPLIT1(",", "a,b", 2, 0, "b"); sl@0: TEST_SPLIT2(",", "a,b", 0, 0, "a", "b"); sl@0: TEST_SPLIT2(",", "a,b,c", 0, 2, "a", "b,c"); sl@0: TEST_SPLIT2(",", "a,b", 1, 0, "", "b"); sl@0: TEST_SPLIT2(",", "a,", 0, 0, "a", ""); sl@0: TEST_SPLIT3(",", "a,b,c", 0, 0, "a", "b", "c"); sl@0: TEST_SPLIT3(",\\s*", "a,b,c", 0, 0, "a", "b", "c"); sl@0: TEST_SPLIT3(",\\s*", "a, b, c", 0, 0, "a", "b", "c"); sl@0: TEST_SPLIT3("(,)\\s*", "a,b", 0, 0, "a", ",", "b"); sl@0: TEST_SPLIT3("(,)\\s*", "a, b", 0, 0, "a", ",", "b"); sl@0: /* Not matched sub-strings. */ sl@0: TEST_SPLIT2("a|(b)", "xay", 0, 0, "x", "y"); sl@0: TEST_SPLIT3("a|(b)", "xby", 0, -1, "x", "b", "y"); sl@0: /* Empty matches. */ sl@0: TEST_SPLIT2(" *", "ab c", 1, 0, "b", "c"); sl@0: TEST_SPLIT3("", "abc", 0, 0, "a", "b", "c"); sl@0: TEST_SPLIT3(" *", "ab c", 0, 0, "a", "b", "c"); sl@0: TEST_SPLIT1(" *", "ab c", 0, 1, "ab c"); sl@0: TEST_SPLIT2(" *", "ab c", 0, 2, "a", "b c"); sl@0: TEST_SPLIT3(" *", "ab c", 0, 3, "a", "b", "c"); sl@0: TEST_SPLIT3(" *", "ab c", 0, 4, "a", "b", "c"); sl@0: sl@0: /* TEST_CHECK_REPLACEMENT(string_to_expand, expected, expected_refs) */ sl@0: TEST_CHECK_REPLACEMENT("", TRUE, FALSE); sl@0: TEST_CHECK_REPLACEMENT("a", TRUE, FALSE); sl@0: TEST_CHECK_REPLACEMENT("\\t\\n\\v\\r\\f\\a\\b\\\\\\x{61}", TRUE, FALSE); sl@0: TEST_CHECK_REPLACEMENT("\\0", TRUE, TRUE); sl@0: TEST_CHECK_REPLACEMENT("\\n\\2", TRUE, TRUE); sl@0: TEST_CHECK_REPLACEMENT("\\g", TRUE, TRUE); sl@0: /* Invalid strings */ sl@0: TEST_CHECK_REPLACEMENT("\\Q", FALSE, FALSE); sl@0: TEST_CHECK_REPLACEMENT("x\\Ay", FALSE, FALSE); sl@0: sl@0: /* TEST_EXPAND(pattern, string, string_to_expand, raw, expected) */ sl@0: TEST_EXPAND("a", "a", "", FALSE, ""); sl@0: TEST_EXPAND("a", "a", "\\0", FALSE, "a"); sl@0: TEST_EXPAND("a", "a", "\\1", FALSE, ""); sl@0: TEST_EXPAND("(a)", "ab", "\\1", FALSE, "a"); sl@0: TEST_EXPAND("(a)", "a", "\\1", FALSE, "a"); sl@0: TEST_EXPAND("(a)", "a", "\\g<1>", FALSE, "a"); sl@0: TEST_EXPAND("a", "a", "\\0130", FALSE, "X"); sl@0: TEST_EXPAND("a", "a", "\\\\\\0", FALSE, "\\a"); sl@0: TEST_EXPAND("a(?P.)c", "xabcy", "X\\gX", FALSE, "XbX"); sl@0: TEST_EXPAND("(.)(?P<1>.)", "ab", "\\1", FALSE, "a"); sl@0: TEST_EXPAND("(.)(?P<1>.)", "ab", "\\g<1>", FALSE, "a"); sl@0: TEST_EXPAND(".", EURO, "\\0", FALSE, EURO); sl@0: TEST_EXPAND("(.)", EURO, "\\1", FALSE, EURO); sl@0: TEST_EXPAND("(?P.)", EURO, "\\g", FALSE, EURO); sl@0: TEST_EXPAND(".", "a", EURO, FALSE, EURO); sl@0: TEST_EXPAND(".", "a", EURO "\\0", FALSE, EURO "a"); sl@0: TEST_EXPAND(".", "", "\\Lab\\Ec", FALSE, "abc"); sl@0: TEST_EXPAND(".", "", "\\LaB\\EC", FALSE, "abC"); sl@0: TEST_EXPAND(".", "", "\\Uab\\Ec", FALSE, "ABc"); sl@0: TEST_EXPAND(".", "", "a\\ubc", FALSE, "aBc"); sl@0: TEST_EXPAND(".", "", "a\\lbc", FALSE, "abc"); sl@0: TEST_EXPAND(".", "", "A\\uBC", FALSE, "ABC"); sl@0: TEST_EXPAND(".", "", "A\\lBC", FALSE, "AbC"); sl@0: TEST_EXPAND(".", "", "A\\l\\\\BC", FALSE, "A\\BC"); sl@0: TEST_EXPAND(".", "", "\\L" AGRAVE "\\E", FALSE, AGRAVE); sl@0: TEST_EXPAND(".", "", "\\U" AGRAVE "\\E", FALSE, AGRAVE_UPPER); sl@0: TEST_EXPAND(".", "", "\\u" AGRAVE "a", FALSE, AGRAVE_UPPER "a"); sl@0: TEST_EXPAND(".", "ab", "x\\U\\0y\\Ez", FALSE, "xAYz"); sl@0: TEST_EXPAND(".(.)", "AB", "x\\L\\1y\\Ez", FALSE, "xbyz"); sl@0: TEST_EXPAND(".", "ab", "x\\u\\0y\\Ez", FALSE, "xAyz"); sl@0: TEST_EXPAND(".(.)", "AB", "x\\l\\1y\\Ez", FALSE, "xbyz"); sl@0: TEST_EXPAND(".(.)", "a" AGRAVE_UPPER, "x\\l\\1y", FALSE, "x" AGRAVE "y"); sl@0: TEST_EXPAND("a", "bab", "\\x{61}", FALSE, "a"); sl@0: TEST_EXPAND("a", "bab", "\\x61", FALSE, "a"); sl@0: TEST_EXPAND("a", "bab", "\\x5a", FALSE, "Z"); sl@0: TEST_EXPAND("a", "bab", "\\0\\x5A", FALSE, "aZ"); sl@0: TEST_EXPAND("a", "bab", "\\1\\x{5A}", FALSE, "Z"); sl@0: TEST_EXPAND("a", "bab", "\\x{00E0}", FALSE, AGRAVE); sl@0: TEST_EXPAND("", "bab", "\\x{0634}", FALSE, SHEEN); sl@0: TEST_EXPAND("", "bab", "\\x{634}", FALSE, SHEEN); sl@0: TEST_EXPAND("", "", "\\t", FALSE, "\t"); sl@0: TEST_EXPAND("", "", "\\v", FALSE, "\v"); sl@0: TEST_EXPAND("", "", "\\r", FALSE, "\r"); sl@0: TEST_EXPAND("", "", "\\n", FALSE, "\n"); sl@0: TEST_EXPAND("", "", "\\f", FALSE, "\f"); sl@0: TEST_EXPAND("", "", "\\a", FALSE, "\a"); sl@0: TEST_EXPAND("", "", "\\b", FALSE, "\b"); sl@0: TEST_EXPAND("a(.)", "abc", "\\0\\b\\1", FALSE, "ab\bb"); sl@0: TEST_EXPAND("a(.)", "abc", "\\0141", FALSE, "a"); sl@0: TEST_EXPAND("a(.)", "abc", "\\078", FALSE, "\a8"); sl@0: TEST_EXPAND("a(.)", "abc", "\\077", FALSE, "?"); sl@0: TEST_EXPAND("a(.)", "abc", "\\0778", FALSE, "?8"); sl@0: TEST_EXPAND("a(.)", "a" AGRAVE "b", "\\1", FALSE, AGRAVE); sl@0: TEST_EXPAND("a(.)", "a" AGRAVE "b", "\\1", TRUE, "\xc3"); sl@0: TEST_EXPAND("a(.)", "a" AGRAVE "b", "\\0", TRUE, "a\xc3"); sl@0: /* Invalid strings. */ sl@0: TEST_EXPAND("", "", "\\Q", FALSE, NULL); sl@0: TEST_EXPAND("", "", "x\\Ay", FALSE, NULL); sl@0: TEST_EXPAND("", "", "\\g<", FALSE, NULL); sl@0: TEST_EXPAND("", "", "\\g<>", FALSE, NULL); sl@0: TEST_EXPAND("", "", "\\g<1a>", FALSE, NULL); sl@0: TEST_EXPAND("", "", "\\g", FALSE, NULL); sl@0: TEST_EXPAND("", "", "\\", FALSE, NULL); sl@0: TEST_EXPAND("a", "a", "\\x{61", FALSE, NULL); sl@0: TEST_EXPAND("a", "a", "\\x6X", FALSE, NULL); sl@0: /* Pattern-less. */ sl@0: TEST_EXPAND(NULL, NULL, "", FALSE, ""); sl@0: TEST_EXPAND(NULL, NULL, "\\n", FALSE, "\n"); sl@0: /* Invalid strings */ sl@0: TEST_EXPAND(NULL, NULL, "\\Q", FALSE, NULL); sl@0: TEST_EXPAND(NULL, NULL, "x\\Ay", FALSE, NULL); sl@0: sl@0: /* TEST_REPLACE(pattern, string, start_position, replacement, expected) */ sl@0: TEST_REPLACE("a", "ababa", 0, "A", "AbAbA"); sl@0: TEST_REPLACE("a", "ababa", 1, "A", "abAbA"); sl@0: TEST_REPLACE("a", "ababa", 2, "A", "abAbA"); sl@0: TEST_REPLACE("a", "ababa", 3, "A", "ababA"); sl@0: TEST_REPLACE("a", "ababa", 4, "A", "ababA"); sl@0: TEST_REPLACE("a", "ababa", 5, "A", "ababa"); sl@0: TEST_REPLACE("a", "ababa", 6, "A", "ababa"); sl@0: TEST_REPLACE("a", "abababa", 2, "A", "abAbAbA"); sl@0: TEST_REPLACE("a", "abab", 0, "A", "AbAb"); sl@0: TEST_REPLACE("a", "baba", 0, "A", "bAbA"); sl@0: TEST_REPLACE("a", "bab", 0, "A", "bAb"); sl@0: TEST_REPLACE("$^", "abc", 0, "X", "abc"); sl@0: TEST_REPLACE("(.)a", "ciao", 0, "a\\1", "caio"); sl@0: TEST_REPLACE("a.", "abc", 0, "\\0\\0", "ababc"); sl@0: TEST_REPLACE("a", "asd", 0, "\\0101", "Asd"); sl@0: TEST_REPLACE("(a).\\1", "aba cda", 0, "\\1\\n", "a\n cda"); sl@0: TEST_REPLACE("a" AGRAVE "a", "a" AGRAVE "a", 0, "x", "x"); sl@0: TEST_REPLACE("a" AGRAVE "a", "a" AGRAVE "a", 0, OGRAVE, OGRAVE); sl@0: TEST_REPLACE("[^-]", "-" EURO "-x-" HSTROKE, 0, "a", "-a-a-a"); sl@0: TEST_REPLACE("[^-]", "-" EURO "-" HSTROKE, 0, "a\\g<0>a", "-a" EURO "a-a" HSTROKE "a"); sl@0: TEST_REPLACE("-", "-" EURO "-" HSTROKE, 0, "", EURO HSTROKE); sl@0: TEST_REPLACE(".*", "hello", 0, "\\U\\0\\E", "HELLO"); sl@0: TEST_REPLACE(".*", "hello", 0, "\\u\\0", "Hello"); sl@0: TEST_REPLACE("\\S+", "hello world", 0, "\\U-\\0-", "-HELLO- -WORLD-"); sl@0: TEST_REPLACE(".", "a", 0, "\\A", NULL); sl@0: TEST_REPLACE(".", "a", 0, "\\g", NULL); sl@0: sl@0: /* TEST_REPLACE_LIT(pattern, string, start_position, replacement, expected) */ sl@0: TEST_REPLACE_LIT("a", "ababa", 0, "A", "AbAbA"); sl@0: TEST_REPLACE_LIT("a", "ababa", 1, "A", "abAbA"); sl@0: TEST_REPLACE_LIT("a", "ababa", 2, "A", "abAbA"); sl@0: TEST_REPLACE_LIT("a", "ababa", 3, "A", "ababA"); sl@0: TEST_REPLACE_LIT("a", "ababa", 4, "A", "ababA"); sl@0: TEST_REPLACE_LIT("a", "ababa", 5, "A", "ababa"); sl@0: TEST_REPLACE_LIT("a", "ababa", 6, "A", "ababa"); sl@0: TEST_REPLACE_LIT("a", "abababa", 2, "A", "abAbAbA"); sl@0: TEST_REPLACE_LIT("a", "abcadaa", 0, "A", "AbcAdAA"); sl@0: TEST_REPLACE_LIT("$^", "abc", 0, "X", "abc"); sl@0: TEST_REPLACE_LIT("(.)a", "ciao", 0, "a\\1", "ca\\1o"); sl@0: TEST_REPLACE_LIT("a.", "abc", 0, "\\0\\0\\n", "\\0\\0\\nc"); sl@0: TEST_REPLACE_LIT("a" AGRAVE "a", "a" AGRAVE "a", 0, "x", "x"); sl@0: TEST_REPLACE_LIT("a" AGRAVE "a", "a" AGRAVE "a", 0, OGRAVE, OGRAVE); sl@0: TEST_REPLACE_LIT(AGRAVE, "-" AGRAVE "-" HSTROKE, 0, "a" ENG "a", "-a" ENG "a-" HSTROKE); sl@0: TEST_REPLACE_LIT("[^-]", "-" EURO "-" AGRAVE "-" HSTROKE, 0, "a", "-a-a-a"); sl@0: TEST_REPLACE_LIT("[^-]", "-" EURO "-" AGRAVE, 0, "a\\g<0>a", "-a\\g<0>a-a\\g<0>a"); sl@0: TEST_REPLACE_LIT("-", "-" EURO "-" AGRAVE "-" HSTROKE, 0, "", EURO AGRAVE HSTROKE); sl@0: TEST_REPLACE_LIT("(?=[A-Z0-9])", "RegExTest", 0, "_", "_Reg_Ex_Test"); sl@0: TEST_REPLACE_LIT("(?=[A-Z0-9])", "RegExTest", 1, "_", "Reg_Ex_Test"); sl@0: sl@0: /* TEST_GET_STRING_NUMBER(pattern, name, expected_num) */ sl@0: TEST_GET_STRING_NUMBER("", "A", -1); sl@0: TEST_GET_STRING_NUMBER("(?P.)", "A", 1); sl@0: TEST_GET_STRING_NUMBER("(?P.)", "B", -1); sl@0: TEST_GET_STRING_NUMBER("(?P.)(?Pa)", "A", 1); sl@0: TEST_GET_STRING_NUMBER("(?P.)(?Pa)", "B", 2); sl@0: TEST_GET_STRING_NUMBER("(?P.)(?Pa)", "C", -1); sl@0: TEST_GET_STRING_NUMBER("(?P.)(.)(?Pa)", "A", 1); sl@0: TEST_GET_STRING_NUMBER("(?P.)(.)(?Pa)", "B", 3); sl@0: TEST_GET_STRING_NUMBER("(?P.)(.)(?Pa)", "C", -1); sl@0: TEST_GET_STRING_NUMBER("(?:a)(?P.)", "A", 1); sl@0: TEST_GET_STRING_NUMBER("(?:a)(?P.)", "B", -1); sl@0: sl@0: /* TEST_ESCAPE(string, length, expected) */ sl@0: TEST_ESCAPE("hello world", -1, "hello world"); sl@0: TEST_ESCAPE("hello world", 5, "hello"); sl@0: TEST_ESCAPE("hello.world", -1, "hello\\.world"); sl@0: TEST_ESCAPE("a(b\\b.$", -1, "a\\(b\\\\b\\.\\$"); sl@0: TEST_ESCAPE("hello\0world", -1, "hello"); sl@0: TEST_ESCAPE("hello\0world", 11, "hello\\0world"); sl@0: TEST_ESCAPE(EURO "*" ENG, -1, EURO "\\*" ENG); sl@0: TEST_ESCAPE("a$", -1, "a\\$"); sl@0: TEST_ESCAPE("$a", -1, "\\$a"); sl@0: TEST_ESCAPE("a$a", -1, "a\\$a"); sl@0: TEST_ESCAPE("$a$", -1, "\\$a\\$"); sl@0: TEST_ESCAPE("$a$", 0, ""); sl@0: TEST_ESCAPE("$a$", 1, "\\$"); sl@0: TEST_ESCAPE("$a$", 2, "\\$a"); sl@0: TEST_ESCAPE("$a$", 3, "\\$a\\$"); sl@0: TEST_ESCAPE("$a$", 4, "\\$a\\$\\0"); sl@0: TEST_ESCAPE("|()[]{}^$*+?.", -1, "\\|\\(\\)\\[\\]\\{\\}\\^\\$\\*\\+\\?\\."); sl@0: TEST_ESCAPE("a|a(a)a[a]a{a}a^a$a*a+a?a.a", -1, sl@0: "a\\|a\\(a\\)a\\[a\\]a\\{a\\}a\\^a\\$a\\*a\\+a\\?a\\.a"); sl@0: sl@0: /* TEST_MATCH_ALL#(pattern, string, string_len, start_position, ...) */ sl@0: TEST_MATCH_ALL0("<.*>", "", -1, 0); sl@0: TEST_MATCH_ALL0("a+", "", -1, 0); sl@0: TEST_MATCH_ALL0("a+", "a", 0, 0); sl@0: TEST_MATCH_ALL0("a+", "a", -1, 1); sl@0: // TEST_MATCH_ALL1("<.*>", "", -1, 0, "", 0, 3); sl@0: TEST_MATCH_ALL1("a+", "a", -1, 0, "a", 0, 1); sl@0: TEST_MATCH_ALL1("a+", "aa", 1, 0, "a", 0, 1); sl@0: TEST_MATCH_ALL1("a+", "aa", -1, 1, "a", 1, 2); sl@0: TEST_MATCH_ALL1("a+", "aa", 2, 1, "a", 1, 2); sl@0: TEST_MATCH_ALL1(".+", ENG, -1, 0, ENG, 0, 2); sl@0: // TEST_MATCH_ALL2("<.*>", "", -1, 0, "", 0, 6, "", 0, 3); sl@0: TEST_MATCH_ALL2("a+", "aa", -1, 0, "aa", 0, 2, "a", 0, 1); sl@0: TEST_MATCH_ALL2(".+", ENG EURO, -1, 0, ENG EURO, 0, 5, ENG, 0, 2); sl@0: // TEST_MATCH_ALL3("<.*>", "", -1, 0, "", 0, 9, sl@0: // "", 0, 6, "", 0, 3); sl@0: // TEST_MATCH_ALL3("a+", "aaa", -1, 0, "aaa", 0, 3, "aa", 0, 2, "a", 0, 1); sl@0: sl@0: end: /* if abort_on_fail is TRUE the flow passes to this label. */ sl@0: verbose ("\n%u tests passed, %u failed\n", passed, failed); sl@0: #if __SYMBIAN32__ sl@0: testResultXml("regex-test"); sl@0: #endif /* EMULATOR */ sl@0: return failed; sl@0: } sl@0: sl@0: #else /* ENABLE_REGEX false */ sl@0: sl@0: int sl@0: main (int argc, char *argv[]) sl@0: { sl@0: g_print ("GRegex is disabled.\n"); sl@0: return 0; sl@0: } sl@0: sl@0: #endif /* ENABLE_REGEX */