[gnome-terminal] search: Use PCRE2 and JIT the regexes
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-terminal] search: Use PCRE2 and JIT the regexes
- Date: Wed, 30 Sep 2015 14:54:16 +0000 (UTC)
commit fed45f7eb1abdf5d730547e32c0b609d299e6a78
Author: Christian Persch <chpe gnome org>
Date: Wed Sep 30 16:53:41 2015 +0200
search: Use PCRE2 and JIT the regexes
Use VteRegex if PCRE2 support is enabled, and JIT the regexes which speeds
up the matching.
src/terminal-search-popover.c | 94 +++++++++++++++++++++++++++++++++--------
src/terminal-search-popover.h | 7 +++-
src/terminal-window.c | 16 +++++++
3 files changed, 98 insertions(+), 19 deletions(-)
---
diff --git a/src/terminal-search-popover.c b/src/terminal-search-popover.c
index 4f286ad..4585b2e 100644
--- a/src/terminal-search-popover.c
+++ b/src/terminal-search-popover.c
@@ -23,6 +23,10 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
+#ifdef WITH_PCRE2
+#include "terminal-pcre2.h"
+#endif
+
#include "terminal-search-popover.h"
#include "terminal-intl.h"
#include "terminal-window.h"
@@ -61,8 +65,14 @@ struct _TerminalSearchPopoverPrivate
gboolean search_text_changed;
/* Cached regex */
+ gboolean regex_caseless;
+ gboolean regex_multiline;
+ char *regex_pattern;
+#ifdef WITH_PCRE2
+ VteRegex *regex;
+#else
GRegex *regex;
- GRegexCompileFlags regex_compile_flags;
+#endif
};
enum {
@@ -242,20 +252,18 @@ static void
update_regex (TerminalSearchPopover *popover)
{
TerminalSearchPopoverPrivate *priv = PRIV (popover);
- GRegexCompileFlags compile_flags;
const char *search_text;
+ gboolean caseless, multiline = FALSE;
gs_free char *pattern;
+ gs_free_error GError *error = NULL;
search_text = gtk_entry_get_text (GTK_ENTRY (priv->search_entry));
- compile_flags = G_REGEX_OPTIMIZE;
-
- if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->match_case_checkbutton)))
- compile_flags |= G_REGEX_CASELESS;
+ caseless = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->match_case_checkbutton));
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->regex_checkbutton))) {
pattern = g_strdup (search_text);
- compile_flags |= G_REGEX_MULTILINE;
+ multiline = TRUE;
} else {
pattern = g_regex_escape_string (search_text, -1);
}
@@ -267,20 +275,53 @@ update_regex (TerminalSearchPopover *popover)
pattern = new_pattern;
}
- if (priv->regex != NULL &&
- priv->regex_compile_flags == compile_flags &&
- g_strcmp0 (pattern, g_regex_get_pattern (priv->regex)) == 0)
+ if (priv->regex_caseless == caseless &&
+ priv->regex_multiline == multiline &&
+ g_strcmp0 (priv->regex_pattern, pattern) == 0)
return;
- priv->regex_compile_flags = compile_flags;
- if (priv->regex)
+ if (priv->regex) {
+#ifdef WITH_PCRE2
+ vte_regex_unref (priv->regex);
+#else
g_regex_unref (priv->regex);
+#endif
+ }
+
+ g_clear_pointer (&priv->regex_pattern, g_free);
/* FIXME: if comping the regex fails, show the error message somewhere */
- if (search_text[0] != '\0')
- priv->regex = g_regex_new (pattern, compile_flags, 0, NULL);
- else
+ if (search_text[0] != '\0') {
+#ifdef WITH_PCRE2
+ guint32 compile_flags;
+
+ compile_flags = PCRE2_UTF | PCRE2_NO_UTF_CHECK;
+ if (caseless)
+ compile_flags |= PCRE2_CASELESS;
+ if (multiline)
+ compile_flags |= PCRE2_MULTILINE;
+
+ priv->regex = vte_regex_new (pattern, -1, compile_flags, &error);
+ if (priv->regex != NULL &&
+ (!vte_regex_jit (priv->regex, PCRE2_JIT_COMPLETE, NULL) ||
+ !vte_regex_jit (priv->regex, PCRE2_JIT_PARTIAL_SOFT, NULL))) {
+ }
+#else
+ GRegexCompileFlags compile_flags;
+
+ compile_flags = G_REGEX_OPTIMIZE;
+ if (caseless)
+ compile_flags |= G_REGEX_CASELESS;
+ if (multiline)
+ compile_flags |= G_REGEX_MULTILINE;
+
+ priv->regex = g_regex_new (pattern, compile_flags, 0, &error);
+#endif
+ if (priv->regex != NULL)
+ gs_transfer_out_value (&priv->regex_pattern, &pattern);
+ } else {
priv->regex = NULL;
+ }
update_sensitivity (popover);
@@ -321,6 +362,9 @@ terminal_search_popover_init (TerminalSearchPopover *popover)
TerminalSearchPopoverPrivate *priv = PRIV (popover);
GtkWidget *widget = GTK_WIDGET (popover);
+ priv->regex_pattern = 0;
+ priv->regex_caseless = priv->regex_multiline = FALSE;
+
gtk_widget_init_template (widget);
/* Make the search entry reasonably wide */
@@ -364,7 +408,6 @@ terminal_search_popover_init (TerminalSearchPopover *popover)
priv->revealer, "reveal-child",
G_BINDING_DEFAULT);
- priv->regex = NULL;
update_sensitivity (popover);
g_signal_connect (priv->search_entry, "search-changed", G_CALLBACK (search_text_changed_cb), popover);
@@ -381,8 +424,15 @@ terminal_search_popover_finalize (GObject *object)
TerminalSearchPopover *popover = TERMINAL_SEARCH_POPOVER (object);
TerminalSearchPopoverPrivate *priv = PRIV (popover);
- if (priv->regex)
- g_regex_unref(priv->regex);
+ if (priv->regex) {
+#ifdef WITH_PCRE2
+ vte_regex_unref (priv->regex);
+#else
+ g_regex_unref (priv->regex);
+#endif
+ }
+
+ g_free (priv->regex_pattern);
G_OBJECT_CLASS (terminal_search_popover_parent_class)->finalize (object);
}
@@ -448,7 +498,11 @@ terminal_search_popover_class_init (TerminalSearchPopoverClass *klass)
pspecs[PROP_REGEX] =
g_param_spec_boxed ("regex", NULL, NULL,
+#ifdef WITH_PCRE2
+ VTE_TYPE_REGEX,
+#else
G_TYPE_REGEX,
+#endif
G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
pspecs[PROP_WRAP_AROUND] =
@@ -492,7 +546,11 @@ terminal_search_popover_new (GtkWidget *relative_to_widget)
*
* Returns: (transfer none): the search regex, or %NULL
*/
+#ifdef WITH_PCRE2
+VteRegex *
+#else
GRegex *
+#endif
terminal_search_popover_get_regex (TerminalSearchPopover *popover)
{
g_return_val_if_fail (TERMINAL_IS_SEARCH_POPOVER (popover), NULL);
diff --git a/src/terminal-search-popover.h b/src/terminal-search-popover.h
index 8998144..813f0f3 100644
--- a/src/terminal-search-popover.h
+++ b/src/terminal-search-popover.h
@@ -39,7 +39,12 @@ GType terminal_search_popover_get_type (void);
TerminalSearchPopover *terminal_search_popover_new (GtkWidget *relative_to_widget);
-GRegex *terminal_search_popover_get_regex (TerminalSearchPopover *popover);
+#ifdef WITH_PCRE2
+VteRegex *
+#else
+GRegex *
+#endif
+ terminal_search_popover_get_regex (TerminalSearchPopover *popover);
gboolean terminal_search_popover_get_wrap_around (TerminalSearchPopover *popover);
diff --git a/src/terminal-window.c b/src/terminal-window.c
index f673e99..1dfb500 100644
--- a/src/terminal-window.c
+++ b/src/terminal-window.c
@@ -888,13 +888,21 @@ search_popover_notify_regex_cb (TerminalSearchPopover *popover,
TerminalWindow *window)
{
TerminalWindowPrivate *priv = window->priv;
+#ifdef WITH_PCRE2
+ VteRegex *regex;
+#else
GRegex *regex;
+#endif
if (G_UNLIKELY (priv->active_screen == NULL))
return;
regex = terminal_search_popover_get_regex (popover);
+#ifdef WITH_PCRE2
+ vte_terminal_search_set_regex (VTE_TERMINAL (priv->active_screen), regex, 0);
+#else
vte_terminal_search_set_gregex (VTE_TERMINAL (priv->active_screen), regex, 0);
+#endif
terminal_window_update_search_sensitivity (priv->active_screen, window);
}
@@ -967,7 +975,11 @@ action_find_cb (GSimpleAction *action,
} else if (g_str_equal (mode, "previous")) {
vte_terminal_search_find_previous (VTE_TERMINAL (priv->active_screen));
} else if (g_str_equal (mode, "clear")) {
+#ifdef WITH_PCRE2
+ vte_terminal_search_set_regex (VTE_TERMINAL (priv->active_screen), NULL, 0);
+#else
vte_terminal_search_set_gregex (VTE_TERMINAL (priv->active_screen), NULL, 0);
+#endif
} else
return;
}
@@ -1776,7 +1788,11 @@ terminal_window_update_search_sensitivity (TerminalScreen *screen,
if (screen != priv->active_screen)
return;
+#ifdef WITH_PCRE2
+ can_search = vte_terminal_search_get_regex (VTE_TERMINAL (screen)) != NULL;
+#else
can_search = vte_terminal_search_get_gregex (VTE_TERMINAL (screen)) != NULL;
+#endif
action = gtk_action_group_get_action (priv->action_group, "SearchFindNext");
gtk_action_set_sensitive (action, can_search);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]