diff --git a/ChangeLog b/ChangeLog index bf439e4f8..51b8221e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Mon Sep 19 17:23:23 2005 Tim Janik + + * glib/gpattern.c: applied a patch from matthias which checks on the + upper bound of GPatternSpec length to optimize matches. + cosmetic fixups. + + * tests/patterntest.c: added more match cases. + 2005-09-16 Tor Lillqvist * glib/gstrfuncs.c (g_ascii_strcasecmp, g_ascii_strncasecmp): Add diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index bf439e4f8..51b8221e6 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,11 @@ +Mon Sep 19 17:23:23 2005 Tim Janik + + * glib/gpattern.c: applied a patch from matthias which checks on the + upper bound of GPatternSpec length to optimize matches. + cosmetic fixups. + + * tests/patterntest.c: added more match cases. + 2005-09-16 Tor Lillqvist * glib/gstrfuncs.c (g_ascii_strcasecmp, g_ascii_strncasecmp): Add diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index bf439e4f8..51b8221e6 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,11 @@ +Mon Sep 19 17:23:23 2005 Tim Janik + + * glib/gpattern.c: applied a patch from matthias which checks on the + upper bound of GPatternSpec length to optimize matches. + cosmetic fixups. + + * tests/patterntest.c: added more match cases. + 2005-09-16 Tor Lillqvist * glib/gstrfuncs.c (g_ascii_strcasecmp, g_ascii_strncasecmp): Add diff --git a/glib/gpattern.c b/glib/gpattern.c index 8381bcca7..49bac6b6b 100644 --- a/glib/gpattern.c +++ b/glib/gpattern.c @@ -46,6 +46,7 @@ struct _GPatternSpec GMatchType match_type; guint pattern_length; guint min_length; + guint max_length; gchar *pattern; }; @@ -128,7 +129,8 @@ g_pattern_match (GPatternSpec *pspec, g_return_val_if_fail (pspec != NULL, FALSE); g_return_val_if_fail (string != NULL, FALSE); - if (pspec->min_length > string_length) + if (string_length < pspec->min_length || + string_length > pspec->max_length) return FALSE; switch (pspec->match_type) @@ -161,9 +163,9 @@ g_pattern_match (GPatternSpec *pspec, return TRUE; case G_MATCH_EXACT: if (pspec->pattern_length != string_length) - return FALSE; + return FALSE; else - return strcmp (pspec->pattern, string) == 0; + return strcmp (pspec->pattern, string) == 0; default: g_return_val_if_fail (pspec->match_type < G_MATCH_LAST, FALSE); return FALSE; @@ -188,6 +190,7 @@ g_pattern_spec_new (const gchar *pattern) pspec = g_new (GPatternSpec, 1); pspec->pattern_length = strlen (pattern); pspec->min_length = 0; + pspec->max_length = 0; pspec->pattern = g_new (gchar, pspec->pattern_length + 1); d = pspec->pattern; for (i = 0, s = pattern; *s != 0; s++) @@ -208,6 +211,7 @@ g_pattern_spec_new (const gchar *pattern) case '?': pending_jokers++; pspec->min_length++; + pspec->max_length += 4; /* maximum UTF-8 character length */ continue; default: for (; pending_jokers; pending_jokers--, i++) { @@ -218,6 +222,7 @@ g_pattern_spec_new (const gchar *pattern) } follows_wildcard = FALSE; pspec->min_length++; + pspec->max_length++; break; } *d++ = *s; @@ -233,6 +238,8 @@ g_pattern_spec_new (const gchar *pattern) seen_joker = hj_pos >= 0; seen_wildcard = hw_pos >= 0; more_wildcards = seen_wildcard && hw_pos != tw_pos; + if (seen_wildcard) + pspec->max_length = G_MAXUINT; /* special case sole head/tail wildcard or exact matches */ if (!seen_joker && !more_wildcards) diff --git a/tests/patterntest.c b/tests/patterntest.c index 6dab50bec..a9aa51968 100644 --- a/tests/patterntest.c +++ b/tests/patterntest.c @@ -58,6 +58,7 @@ struct _GPatternSpec GMatchType match_type; guint pattern_length; guint min_length; + guint max_length; gchar *pattern; }; @@ -273,8 +274,13 @@ main (int argc, char** argv) TEST_MATCH("ab*", "ab\xc3\xa4\xc3\xb6", TRUE); TEST_MATCH("ab*\xc3\xb6", "ab\xc3\xa4\xc3\xb6", TRUE); TEST_MATCH("ab*\xc3\xb6", "aba\xc3\xb6x\xc3\xb6", TRUE); - TEST_MATCH("", "", TRUE); TEST_MATCH("", "abc", FALSE); + + TEST_MATCH("", "", TRUE); + TEST_MATCH("abc", "abc", TRUE); + TEST_MATCH("*fo1*bar", "yyyfoxfo1bar", TRUE); + TEST_MATCH("12*fo1g*bar", "12yyyfoxfo1gbar", TRUE); + TEST_MATCH("__________:*fo1g*bar", "__________:yyyfoxfo1gbar", TRUE); verbose ("\n%u tests passed, %u failed\n", passed, failed);