Code

use glib regex for list_window_jump.
authormatt <matt.r.portas@gmail.com>
Sat, 2 Apr 2011 17:29:26 +0000 (18:29 +0100)
committerMax Kellermann <max@duempel.org>
Thu, 23 Jun 2011 06:37:23 +0000 (08:37 +0200)
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
src/match.c
src/match.h

index d44fd29329b427965abedef04a113f3445187015..9d120c14e24eb97d2ce17994364cc830cfe78409 100644 (file)
@@ -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
index d9879132c19accfcd9133eb2a6cfcb3aea9c232d..7a05db329e174846d0dc192f0ab30439b250b72b 100644 (file)
@@ -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)
 {
index cb1266a38f4bfe535ccffd32e345ffbdbe7a05c3..8ad0fd94d433c2f97047c919d3217c965568a1d9 100644 (file)
@@ -35,6 +35,14 @@ match_line(const char *line, const char *needle)
 }
 #else
 
+#include <glib.h>
+
+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.