From 502d803a2efc9f7de5560f86829e33bf78e47584 Mon Sep 17 00:00:00 2001 From: matt Date: Sat, 2 Apr 2011 18:29:26 +0100 Subject: [PATCH] use glib regex for list_window_jump. Compile a single regex search string in list_window_jump instead of using g_regex_match which compiles a new one each time. --- src/list_window.c | 46 +++++++++++++++++++++++++++++++--------------- src/match.c | 34 ++++++++++++++++++++++++++++++++++ src/match.h | 8 ++++++++ 3 files changed, 73 insertions(+), 15 deletions(-) diff --git a/src/list_window.c b/src/list_window.c index d44fd29..9d120c1 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -489,44 +489,60 @@ list_window_rfind(struct list_window *lw, return false; } -static bool -jump_match(const char *haystack, const char *needle) -{ #ifdef NCMPC_MINI - bool jump_prefix_only = true; -#else - bool jump_prefix_only = options.jump_prefix_only; -#endif +bool +list_window_jump(struct list_window *lw, + list_window_callback_fn_t callback, + void *callback_data, + const char *str) +{ + unsigned i; + const char *label; - assert(haystack != NULL); - assert(needle != NULL); + assert(str != NULL); - return jump_prefix_only - ? g_ascii_strncasecmp(haystack, needle, strlen(needle)) == 0 - : match_line(haystack, needle); -} + for (i = 0; i < lw->length; i++) { + label = callback(i, callback_data); + assert(label != NULL); + if (g_ascii_strncasecmp(label, str, strlen(str)) == 0) { + list_window_move_cursor(lw, i); + return true; + } + } + return false; +} +#else bool list_window_jump(struct list_window *lw, list_window_callback_fn_t callback, void *callback_data, const char *str) { + unsigned i; const char *label; + GRegex *regex; assert(str != NULL); - for (unsigned i = 0; i < lw->length; ++i) { + regex = compile_regex(str, options.jump_prefix_only); + if (regex == NULL) + return false; + + for (i = 0; i < lw->length; i++) { label = callback(i, callback_data); assert(label != NULL); - if (jump_match(label, str)) { + if (match_regex(regex, label)) { + g_regex_unref(regex); list_window_move_cursor(lw, i); return true; } } + g_regex_unref(regex); return false; } +#endif /* perform basic list window commands (movement) */ bool diff --git a/src/match.c b/src/match.c index d987913..7a05db3 100644 --- a/src/match.c +++ b/src/match.c @@ -34,6 +34,40 @@ locale_casefold(const char *src) return folded; } +GRegex * +compile_regex(const char *src, bool anchor) +{ + GRegex *regex; + GRegexCompileFlags compile_flags; + char *src_folded = locale_casefold(src); + + compile_flags = G_REGEX_CASELESS | G_REGEX_DOTALL | G_REGEX_OPTIMIZE; + if (anchor) + compile_flags |= G_REGEX_ANCHORED; + + regex = g_regex_new ((const gchar*)src_folded, compile_flags, 0, NULL); + + g_free(src_folded); + + return regex; +} + +bool +match_regex(GRegex *regex, const char *line) +{ + GMatchInfo *match_info; + bool match; + char *line_folded = locale_casefold(line); + + g_regex_match(regex, line_folded, 0, &match_info); + match = (bool)g_match_info_matches(match_info); + + g_match_info_free(match_info); + g_free(line_folded); + + return match; +} + bool match_line(const char *line, const char *needle) { diff --git a/src/match.h b/src/match.h index cb1266a..8ad0fd9 100644 --- a/src/match.h +++ b/src/match.h @@ -35,6 +35,14 @@ match_line(const char *line, const char *needle) } #else +#include + +GRegex * +compile_regex(const char *src, bool anchor); + +bool +match_regex(GRegex *regex, const char *line); + /** * Checks whether the specified line matches the search string. Case * is ignored. -- 2.30.2