[gnome-terminal] screen: Use PCRE2 and JIT the regexes



commit 0c906ef32b9374a1e5052c3c7e8cacfb1695d37c
Author: Christian Persch <chpe gnome org>
Date:   Wed Sep 30 16:53:41 2015 +0200

    screen: Use PCRE2 and JIT the regexes
    
    Use VteRegex if PCRE2 support is enabled, and JIT the regexes which speeds
    up the matching.

 src/terminal-screen.c |   45 ++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 38 insertions(+), 7 deletions(-)
---
diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index a48de10..787d13a 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -19,6 +19,10 @@
 #include "config.h"
 #define _GNU_SOURCE /* for dup3 */
 
+#ifdef WITH_PCRE2
+#include "terminal-pcre2.h"
+#endif
+
 #include "terminal-screen.h"
 
 #include <errno.h>
@@ -173,18 +177,22 @@ static guint signals[LAST_SIGNAL];
 typedef struct {
   const char *pattern;
   TerminalURLFlavour flavor;
-  GRegexCompileFlags flags;
+  gboolean caseless;
 } TerminalRegexPattern;
 
 static const TerminalRegexPattern url_regex_patterns[] = {
-  { SCHEME "//(?:" USERPASS "\\@)?" HOST PORT URLPATH, FLAVOR_AS_IS, G_REGEX_CASELESS },
-  { "(?:www|ftp)" HOSTCHARS_CLASS "*\\." HOST PORT URLPATH , FLAVOR_DEFAULT_TO_HTTP, G_REGEX_CASELESS  },
-  { "(?:callto:|h323:|sip:)" USERCHARS_CLASS "[" USERCHARS ".]*(?:" PORT "/[a-z0-9]+)?\\@" HOST, 
FLAVOR_VOIP_CALL, G_REGEX_CASELESS  },
-  { "(?:mailto:)?" USERCHARS_CLASS "[" USERCHARS ".]*\\@" HOSTCHARS_CLASS "+\\." HOST, FLAVOR_EMAIL, 
G_REGEX_CASELESS  },
-  { "(?:news:|man:|info:)[-[:alnum:]\\Q^_{|}~!\"#$%&'()*+,./;:=?`\\E]+", FLAVOR_AS_IS, G_REGEX_CASELESS  },
+  { SCHEME "//(?:" USERPASS "\\@)?" HOST PORT URLPATH, FLAVOR_AS_IS, TRUE },
+  { "(?:www|ftp)" HOSTCHARS_CLASS "*\\." HOST PORT URLPATH , FLAVOR_DEFAULT_TO_HTTP, TRUE  },
+  { "(?:callto:|h323:|sip:)" USERCHARS_CLASS "[" USERCHARS ".]*(?:" PORT "/[a-z0-9]+)?\\@" HOST, 
FLAVOR_VOIP_CALL, TRUE },
+  { "(?:mailto:)?" USERCHARS_CLASS "[" USERCHARS ".]*\\@" HOSTCHARS_CLASS "+\\." HOST, FLAVOR_EMAIL, TRUE },
+  { "(?:news:|man:|info:)[-[:alnum:]\\Q^_{|}~!\"#$%&'()*+,./;:=?`\\E]+", FLAVOR_AS_IS, TRUE },
 };
 
+#ifdef WITH_PCRE2
+static VteRegex **url_regexes;
+#else
 static GRegex **url_regexes;
+#endif
 static TerminalURLFlavour *url_regex_flavors;
 static guint n_url_regexes;
 
@@ -332,7 +340,11 @@ terminal_screen_init (TerminalScreen *screen)
 
       tag_data = g_slice_new (TagData);
       tag_data->flavor = url_regex_flavors[i];
+#ifdef WITH_PCRE2
+      tag_data->tag = vte_terminal_match_add_regex (terminal, url_regexes[i], 0);
+#else
       tag_data->tag = vte_terminal_match_add_gregex (terminal, url_regexes[i], 0);
+#endif
       vte_terminal_match_set_cursor_type (terminal, tag_data->tag, URL_MATCH_CURSOR);
 
       priv->match_tags = g_slist_prepend (priv->match_tags, tag_data);
@@ -536,17 +548,36 @@ terminal_screen_class_init (TerminalScreenClass *klass)
 
   /* Precompile the regexes */
   n_url_regexes = G_N_ELEMENTS (url_regex_patterns);
+#ifdef WITH_PCRE2
+  url_regexes = g_new0 (VteRegex*, n_url_regexes);
+#else
   url_regexes = g_new0 (GRegex*, n_url_regexes);
+#endif
   url_regex_flavors = g_new0 (TerminalURLFlavour, n_url_regexes);
 
   for (i = 0; i < n_url_regexes; ++i)
     {
       GError *error = NULL;
 
+#ifdef WITH_PCRE2
+      url_regexes[i] = vte_regex_new (url_regex_patterns[i].pattern, -1,
+                                      PCRE2_UTF | PCRE2_NO_UTF_CHECK |
+                                      (url_regex_patterns[i].caseless ? PCRE2_CASELESS : 0),
+                                      &error);
+      g_assert_no_error (error);
+
+      if (!vte_regex_jit (url_regexes[i], PCRE2_JIT_COMPLETE, &error) ||
+          !vte_regex_jit (url_regexes[i], PCRE2_JIT_PARTIAL_SOFT, &error)) {
+        g_printerr ("Failed to JIT regex '%s': %s\n", url_regex_patterns[i].pattern, error->message);
+        g_clear_error (&error);
+      }
+#else
       url_regexes[i] = g_regex_new (url_regex_patterns[i].pattern,
-                                    url_regex_patterns[i].flags | G_REGEX_OPTIMIZE,
+                                    G_REGEX_OPTIMIZE |
+                                    (url_regex_patterns[i].caseless ? G_REGEX_CASELESS : 0),
                                     0, &error);
       g_assert_no_error (error);
+#endif
 
       url_regex_flavors[i] = url_regex_patterns[i].flavor;
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]