+Tue Sep 20 13:16:04 2005 Tim Janik <timj@imendio.com>
+
+ * glib/gpattern.c (g_pattern_ph_match): applied significant recursion
+ complexity optimization, based on a patch from Matthias Clasen.
+
+ * tests/patterntest.c: more tests, mostly from matthias.
+
2005-09-20 Matthias Clasen <mclasen@redhat.com>
* glib/gqueue.c (g_queue_insert_sorted): Correct the docs.
+Tue Sep 20 13:16:04 2005 Tim Janik <timj@imendio.com>
+
+ * glib/gpattern.c (g_pattern_ph_match): applied significant recursion
+ complexity optimization, based on a patch from Matthias Clasen.
+
+ * tests/patterntest.c: more tests, mostly from matthias.
+
2005-09-20 Matthias Clasen <mclasen@redhat.com>
* glib/gqueue.c (g_queue_insert_sorted): Correct the docs.
+Tue Sep 20 13:16:04 2005 Tim Janik <timj@imendio.com>
+
+ * glib/gpattern.c (g_pattern_ph_match): applied significant recursion
+ complexity optimization, based on a patch from Matthias Clasen.
+
+ * tests/patterntest.c: more tests, mostly from matthias.
+
2005-09-20 Matthias Clasen <mclasen@redhat.com>
* glib/gqueue.c (g_queue_insert_sorted): Correct the docs.
/* --- functions --- */
-
static inline gboolean
g_pattern_ph_match (const gchar *match_pattern,
- const gchar *match_string)
+ const gchar *match_string,
+ gboolean *wildcard_reached_p)
{
register const gchar *pattern, *string;
register gchar ch;
break;
case '*':
+ *wildcard_reached_p = TRUE;
do
{
ch = *pattern;
return TRUE;
do
{
+ gboolean next_wildcard_reached = FALSE;
while (ch != *string)
{
if (!*string)
string = g_utf8_next_char (string);
}
string++;
- if (g_pattern_ph_match (pattern, string))
+ if (g_pattern_ph_match (pattern, string, &next_wildcard_reached))
return TRUE;
+ if (next_wildcard_reached)
+ /* the forthcoming pattern substring up to the next wildcard has
+ * been matched, but a mismatch occoured for the rest of the
+ * pattern, following the next wildcard.
+ * there's no need to advance the current match position any
+ * further if the rest pattern will not match.
+ */
+ return FALSE;
}
while (*string);
break;
switch (pspec->match_type)
{
+ gboolean dummy;
case G_MATCH_ALL:
- return g_pattern_ph_match (pspec->pattern, string);
+ return g_pattern_ph_match (pspec->pattern, string, &dummy);
case G_MATCH_ALL_TAIL:
if (string_reversed)
- return g_pattern_ph_match (pspec->pattern, string_reversed);
+ return g_pattern_ph_match (pspec->pattern, string_reversed, &dummy);
else
{
gboolean result;
gchar *tmp;
tmp = g_utf8_strreverse (string, string_length);
- result = g_pattern_ph_match (pspec->pattern, tmp);
+ result = g_pattern_ph_match (pspec->pattern, tmp, &dummy);
g_free (tmp);
return result;
}
TEST_MATCH("*fo1*bar", "yyyfoxfo1bar", TRUE);
TEST_MATCH("12*fo1g*bar", "12yyyfoxfo1gbar", TRUE);
TEST_MATCH("__________:*fo1g*bar", "__________:yyyfoxfo1gbar", TRUE);
-
+ TEST_MATCH("*abc*cde", "abcde", FALSE);
+ TEST_MATCH("*abc*cde", "abccde", TRUE);
+ TEST_MATCH("*abc*cde", "abcxcde", TRUE);
+ TEST_MATCH("*abc*?cde", "abccde", FALSE);
+ TEST_MATCH("*abc*?cde", "abcxcde", TRUE);
+ TEST_MATCH("*abc*def", "abababcdededef", TRUE);
+ TEST_MATCH("*abc*def", "abcbcbcdededef", TRUE);
+ TEST_MATCH("*acbc*def", "acbcbcbcdededef", TRUE);
+ TEST_MATCH("*a?bc*def", "acbcbcbcdededef", TRUE);
+ TEST_MATCH("*abc*def", "bcbcbcdefdef", FALSE);
+ TEST_MATCH("*abc*def*ghi", "abcbcbcbcbcbcdefefdefdefghi", TRUE);
+ TEST_MATCH("*abc*def*ghi", "bcbcbcbcbcbcdefdefdefdefghi", FALSE);
+ TEST_MATCH("_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_*abc*def*ghi", "_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_abcbcbcbcbcbcdefefdefdefghi", TRUE);
+ TEST_MATCH("fooooooo*a*bc", "fooooooo_a_bd_a_bc", TRUE);
+
verbose ("\n%u tests passed, %u failed\n", passed, failed);
return failed;