[vte] Revert "lib: Rework how vte stores the match and search regexes"



commit 6710777ac3172f8e025ac33b1ecb9d8a73bfa3cf
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Wed Sep 18 23:33:53 2019 +0000

    Revert "lib: Rework how vte stores the match and search regexes"
    
    This reverts commit 2d0df88babd1faae09ee6b92fb589427ea12437a

 src/refptr.hh           |  50 ------
 src/regex.cc            |   3 +-
 src/vte.cc              | 431 ++++++++++++++++++++++++++++++++++++------------
 src/vtegtk.cc           |  40 +++--
 src/vteinternal.hh      | 133 ++++-----------
 src/vteregex.cc         |  23 ++-
 src/vteregexinternal.hh |  19 +--
 src/widget.cc           |  51 +-----
 src/widget.hh           |  19 +--
 9 files changed, 423 insertions(+), 346 deletions(-)
---
diff --git a/src/refptr.hh b/src/refptr.hh
index 666d061c..ae7a96dd 100644
--- a/src/refptr.hh
+++ b/src/refptr.hh
@@ -34,55 +34,5 @@ public:
         RefPtr(T* obj = nullptr) : base_type{obj, &g_object_unref} { }
 };
 
-template<typename T>
-RefPtr<T>
-make_ref(T* obj)
-{
-        if (obj)
-                g_object_ref(obj);
-        return {obj};
-}
-
-template<typename T>
-RefPtr<T>
-take_ref(T* obj)
-{
-        return {obj};
-}
-
 } // namespace glib
-
-namespace base {
-
-template<class T>
-class Unreffer {
-public:
-        void operator()(T* obj) const
-        {
-                if (obj)
-                        obj->unref();
-        }
-};
-
-template<class T>
-using RefPtr = std::unique_ptr<T, Unreffer<T>>;
-
-template<class T>
-RefPtr<T>
-make_ref(T* obj)
-{
-        if (obj)
-                obj->ref();
-        return RefPtr<T>{obj};
-}
-
-template<class T>
-RefPtr<T>
-take_ref(T* obj)
-{
-        return RefPtr<T>{obj};
-}
-
-} // namespace base
-
 } // namespace vte
diff --git a/src/regex.cc b/src/regex.cc
index 7d6ec2b3..5be07a46 100644
--- a/src/regex.cc
+++ b/src/regex.cc
@@ -21,6 +21,7 @@
 #include "vte/vteenums.h"
 #include "vte/vteregex.h"
 
+
 #include <cassert>
 
 namespace vte {
@@ -31,7 +32,7 @@ static bool
 set_gerror_from_pcre_error(int errcode,
                            GError **error)
 {
-        PCRE2_UCHAR8 buf[256];
+        PCRE2_UCHAR8 buf[128];
         int n = pcre2_get_error_message_8(errcode, buf, sizeof(buf));
         assert(n >= 0);
         g_set_error_literal(error, VTE_REGEX_ERROR, errcode, (char const*)buf);
diff --git a/src/vte.cc b/src/vte.cc
index 6691ab84..79a59ea6 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -935,24 +935,205 @@ Terminal::match_contents_refresh()
        m_match_attributes = array;
 }
 
+static void
+regex_match_clear_cursor (struct vte_match_regex *regex)
+{
+        switch (regex->cursor_mode) {
+                case VTE_REGEX_CURSOR_GDKCURSOR:
+                        if (regex->cursor.cursor != NULL) {
+                                g_object_unref(regex->cursor.cursor);
+                                regex->cursor.cursor = NULL;
+                        }
+                        break;
+                case VTE_REGEX_CURSOR_GDKCURSORTYPE:
+                        break;
+                case VTE_REGEX_CURSOR_NAME:
+                        g_free (regex->cursor.cursor_name);
+                        regex->cursor.cursor_name = NULL;
+                        break;
+               default:
+                       g_assert_not_reached ();
+                       return;
+        }
+}
+
+static void
+regex_and_flags_clear(struct vte_regex_and_flags *regex)
+{
+        if (regex->regex) {
+                vte_regex_unref(regex->regex);
+                regex->regex = nullptr;
+        }
+}
+
+static void
+regex_match_clear (struct vte_match_regex *regex)
+{
+        regex_and_flags_clear(&regex->regex);
+        regex_match_clear_cursor(regex);
+
+        regex->tag = -1;
+}
+
+void
+Terminal::set_cursor_from_regex_match(struct vte_match_regex *regex)
+{
+        GdkCursor *gdk_cursor = nullptr;
+
+        if (!widget_realized())
+                return;
+
+        switch (regex->cursor_mode) {
+                case VTE_REGEX_CURSOR_GDKCURSOR:
+                        if (regex->cursor.cursor != NULL &&
+                            gdk_cursor_get_display(regex->cursor.cursor) == 
gtk_widget_get_display(m_widget)) {
+                                gdk_cursor = (GdkCursor *)g_object_ref(regex->cursor.cursor);
+                        }
+                        break;
+                case VTE_REGEX_CURSOR_GDKCURSORTYPE:
+                        gdk_cursor = gdk_cursor_new_for_display(gtk_widget_get_display(m_widget), 
regex->cursor.cursor_type);
+                        break;
+                case VTE_REGEX_CURSOR_NAME:
+                        gdk_cursor = gdk_cursor_new_from_name(gtk_widget_get_display(m_widget), 
regex->cursor.cursor_name);
+                        break;
+               default:
+                       g_assert_not_reached ();
+                       return;
+        }
+
+        m_real_widget->set_cursor(gdk_cursor);
+
+        if (gdk_cursor)
+                g_object_unref(gdk_cursor);
+}
+
 void
 Terminal::regex_match_remove_all()
 {
-        auto& match_regexes = match_regexes_writable();
-        match_regexes.clear();
-        match_regexes.shrink_to_fit();
+       struct vte_match_regex *regex;
+       guint i;
+
+       for (i = 0; i < m_match_regexes->len; i++) {
+               regex = &g_array_index(m_match_regexes,
+                                      struct vte_match_regex,
+                                      i);
+               /* Unless this is a hole, clean it up. */
+               if (regex->tag >= 0) {
+                        regex_match_clear (regex);
+               }
+       }
+       g_array_set_size(m_match_regexes, 0);
 
        match_hilite_clear();
 }
 
 void
-Terminal::regex_match_remove(int tag) noexcept
+Terminal::regex_match_remove(int tag)
 {
-        auto i = regex_match_get_iter(tag);
-        if (i == std::end(m_match_regexes))
+       struct vte_match_regex *regex;
+
+       if (m_match_regexes->len > (guint)tag) {
+               /* The tag is an index, so find the corresponding struct. */
+               regex = &g_array_index(m_match_regexes,
+                                      struct vte_match_regex,
+                                      tag);
+               /* If it's already been removed, return. */
+               if (regex->tag < 0) {
+                       return;
+               }
+               /* Remove this item and leave a hole in its place. */
+                regex_match_clear (regex);
+       }
+       match_hilite_clear();
+}
+
+int
+Terminal::regex_match_add(struct vte_match_regex *new_regex_match)
+{
+        struct vte_match_regex *regex_match;
+        guint ret, len;
+
+        /* Search for a hole. */
+        len = m_match_regexes->len;
+        for (ret = 0; ret < len; ret++) {
+                regex_match = &g_array_index(m_match_regexes,
+                                             struct vte_match_regex,
+                                             ret);
+                if (regex_match->tag == -1) {
+                        break;
+                }
+        }
+
+        /* Set the tag to the insertion point. */
+        new_regex_match->tag = ret;
+
+        if (ret < len) {
+                /* Overwrite. */
+                g_array_index(m_match_regexes,
+                              struct vte_match_regex,
+                              ret) = *new_regex_match;
+        } else {
+                /* Append. */
+                g_array_append_vals(m_match_regexes, new_regex_match, 1);
+        }
+
+        /* FIXMEchpe: match_hilite_clear() so we can redo the highlighting with the new regex added? */
+
+        return ret;
+}
+
+struct vte_match_regex *
+Terminal::regex_match_get(int tag)
+{
+       if ((guint)tag >= m_match_regexes->len)
+                return nullptr;
+
+       return &g_array_index(m_match_regexes, struct vte_match_regex, tag);
+}
+
+void
+Terminal::regex_match_set_cursor(int tag,
+                                           GdkCursor *gdk_cursor)
+{
+        struct vte_match_regex *regex = regex_match_get(tag);
+        if (regex == nullptr)
+                return;
+
+        regex_match_clear_cursor(regex);
+        regex->cursor_mode = VTE_REGEX_CURSOR_GDKCURSOR;
+       regex->cursor.cursor = gdk_cursor ? (GdkCursor *)g_object_ref(gdk_cursor) : NULL;
+
+       match_hilite_clear();
+}
+
+void
+Terminal::regex_match_set_cursor(int tag,
+                                           GdkCursorType cursor_type)
+{
+        struct vte_match_regex *regex = regex_match_get(tag);
+        if (regex == nullptr)
+                return;
+
+        regex_match_clear_cursor(regex);
+        regex->cursor_mode = VTE_REGEX_CURSOR_GDKCURSORTYPE;
+       regex->cursor.cursor_type = cursor_type;
+
+       match_hilite_clear();
+}
+
+void
+Terminal::regex_match_set_cursor(int tag,
+                                           char const* cursor_name)
+{
+        struct vte_match_regex *regex = regex_match_get(tag);
+        if (regex == nullptr)
                 return;
 
-        match_regexes_writable().erase(i);
+        regex_match_clear_cursor(regex);
+        regex->cursor_mode = VTE_REGEX_CURSOR_NAME;
+       regex->cursor.cursor_name = g_strdup (cursor_name);
+
+       match_hilite_clear();
 }
 
 /*
@@ -1098,18 +1279,19 @@ Terminal::create_match_context()
 }
 
 bool
-Terminal::match_check_pcre(pcre2_match_data_8 *match_data,
-                           pcre2_match_context_8 *match_context,
-                           vte::base::Regex const* regex,
-                           uint32_t match_flags,
-                           gsize sattr,
-                           gsize eattr,
-                           gsize offset,
-                           char **result_ptr,
-                           gsize *start,
-                           gsize *end,
-                           gsize *sblank_ptr,
-                           gsize *eblank_ptr)
+Terminal::match_check_pcre(
+                 pcre2_match_data_8 *match_data,
+                 pcre2_match_context_8 *match_context,
+                 VteRegex *regex,
+                 guint32 match_flags,
+                 gsize sattr,
+                 gsize eattr,
+                 gsize offset,
+                 char **result_ptr,
+                 gsize *start,
+                 gsize *end,
+                 gsize *sblank_ptr,
+                 gsize *eblank_ptr)
 {
         int (* match_fn) (const pcre2_code_8 *,
                           PCRE2_SPTR8, PCRE2_SIZE, PCRE2_SIZE, uint32_t,
@@ -1119,7 +1301,7 @@ Terminal::match_check_pcre(pcre2_match_data_8 *match_data,
         const char *line;
         int r = 0;
 
-        if (regex->jited())
+        if (_vte_regex_get_jited(regex))
                 match_fn = pcre2_jit_match_8;
         else
                 match_fn = pcre2_match_8;
@@ -1137,7 +1319,7 @@ Terminal::match_check_pcre(pcre2_match_data_8 *match_data,
         pcre2_set_offset_limit_8(match_context, eattr);
         position = sattr;
         while (position < eattr &&
-               ((r = match_fn(regex->code(),
+               ((r = match_fn(_vte_regex_get_pcre(regex),
                               (PCRE2_SPTR8)line, line_length, /* subject, length */
                               position, /* start offset */
                               match_flags |
@@ -1217,14 +1399,17 @@ Terminal::match_check_pcre(pcre2_match_data_8 *match_data,
 
 char *
 Terminal::match_check_internal_pcre(vte::grid::column_t column,
-                                    vte::grid::row_t row,
-                                    MatchRegex const** match,
-                                    size_t* start,
-                                    size_t* end)
+                                              vte::grid::row_t row,
+                                              int *tag,
+                                              gsize *start,
+                                              gsize *end)
 {
+        struct vte_match_regex *regex;
+        guint i;
        gsize offset, sattr, eattr, start_blank, end_blank;
         pcre2_match_data_8 *match_data;
         pcre2_match_context_8 *match_context;
+        char *dingu_match = nullptr;
 
        _vte_debug_print(VTE_DEBUG_REGEX,
                          "Checking for pcre match at (%ld,%ld).\n", row, column);
@@ -1240,19 +1425,26 @@ Terminal::match_check_internal_pcre(vte::grid::column_t column,
         match_data = pcre2_match_data_create_8(256 /* should be plenty */, NULL /* general context */);
 
        /* Now iterate over each regex we need to match against. */
-        char* dingu_match{nullptr};
-        for (auto const& rem : m_match_regexes) {
+       for (i = 0; i < m_match_regexes->len; i++) {
                 gsize sblank, eblank;
 
+               regex = &g_array_index(m_match_regexes,
+                                      struct vte_match_regex,
+                                      i);
+               /* Skip holes. */
+               if (regex->tag < 0) {
+                       continue;
+               }
+
                 if (match_check_pcre(match_data, match_context,
-                                     rem.regex(),
-                                     rem.match_flags(),
+                                     regex->regex.regex,
+                                     regex->regex.match_flags,
                                      sattr, eattr, offset,
                                      &dingu_match,
                                      start, end,
                                      &sblank, &eblank)) {
-                        _vte_debug_print(VTE_DEBUG_REGEX, "Matched dingu with tag %d\n", rem.tag());
-                        *match = std::addressof(rem);
+                        _vte_debug_print(VTE_DEBUG_REGEX, "Matched dingu with tag %d\n", regex->tag);
+                        *tag = regex->tag;
                         break;
                 }
 
@@ -1270,7 +1462,6 @@ Terminal::match_check_internal_pcre(vte::grid::column_t column,
                  */
                 *start = start_blank;
                 *end = end_blank - 1;
-                *match = nullptr;
 
                 _VTE_DEBUG_IF(VTE_DEBUG_REGEX) {
                         struct _VteCharAttributes *_sattr, *_eattr;
@@ -1297,69 +1488,69 @@ Terminal::match_check_internal_pcre(vte::grid::column_t column,
  * @terminal:
  * @column:
  * @row:
- * @match: (out):
+ * @tag: (out):
  * @start: (out):
  * @end: (out):
  *
- * Checks m_match_contents for dingu matches, and returns the start, and
- * end of the match in @start, @end, and the matched regex in @match.
- * If no match occurs, @match will be set to %nullptr,
- * and if they are nonzero, @start and @end mark the smallest span in the @row
+ * Checks m_match_contents for dingu matches, and returns the tag, start, and
+ * end of the match in @tag, @start, @end. If no match occurs, @tag will be set to
+ * -1, and if they are nonzero, @start and @end mark the smallest span in the @row
  * in which none of the dingus match.
  *
- * Returns: (transfer full): the matched string, or %nullptr
+ * Returns: (transfer full): the matched string, or %NULL
  */
 char *
 Terminal::match_check_internal(vte::grid::column_t column,
-                               vte::grid::row_t row,
-                               MatchRegex const** match,
-                               size_t* start,
-                               size_t* end)
+                                         vte::grid::row_t row,
+                                         int *tag,
+                                         gsize *start,
+                                         gsize *end)
 {
        if (m_match_contents == nullptr) {
                match_contents_refresh();
        }
 
-        assert(match != nullptr);
-        assert(start != nullptr);
-        assert(end != nullptr);
+        g_assert(tag != NULL);
+        g_assert(start != NULL);
+        g_assert(end != NULL);
 
-        *match = nullptr;
+        *tag = -1;
         *start = 0;
         *end = 0;
 
-        return match_check_internal_pcre(column, row, match, start, end);
+        return match_check_internal_pcre(column, row, tag, start, end);
 }
 
-char*
+char *
 Terminal::regex_match_check(vte::grid::column_t column,
-                            vte::grid::row_t row,
-                            int* tag)
+                                      vte::grid::row_t row,
+                                      int *tag)
 {
+       char *ret;
+
        long delta = m_screen->scroll_delta;
        _vte_debug_print(VTE_DEBUG_EVENTS | VTE_DEBUG_REGEX,
                        "Checking for match at (%ld,%ld).\n",
                        row, column);
-
-        char* ret{nullptr};
-        Terminal::MatchRegex const* match{nullptr};
-
         if (m_match_span.contains(row + delta, column)) {
-                match = regex_match_current(); /* may be nullptr */
-                ret = g_strdup(m_match);
+               if (tag) {
+                       *tag = m_match_tag;
+               }
+               ret = m_match != NULL ?
+                       g_strdup (m_match) :
+                       NULL;
        } else {
                 gsize start, end;
+                int ltag;
 
-                ret = match_check_internal(column, row + delta,
-                                           &match,
-                                           &start, &end);
+               ret = match_check_internal(
+                                                        column, row + delta,
+                                                        tag ? tag : &ltag,
+                                                        &start, &end);
        }
        _VTE_DEBUG_IF(VTE_DEBUG_EVENTS | VTE_DEBUG_REGEX) {
                if (ret != NULL) g_printerr("Matched `%s'.\n", ret);
        }
-        if (tag != nullptr)
-                *tag = (match != nullptr) ? match->tag() : -1;
-
        return ret;
 }
 
@@ -1662,8 +1853,8 @@ Terminal::hyperlink_check(GdkEvent *event)
 }
 
 char *
-Terminal::regex_match_check(GdkEvent* event,
-                            int *tag)
+Terminal::regex_match_check(GdkEvent *event,
+                                      int *tag)
 {
         long col, row;
 
@@ -1680,10 +1871,10 @@ Terminal::regex_match_check(GdkEvent* event,
 
 bool
 Terminal::regex_match_check_extra(GdkEvent *event,
-                                  vte::base::Regex const** regexes,
-                                  size_t n_regexes,
-                                  uint32_t match_flags,
-                                  char** matches)
+                                            VteRegex **regexes,
+                                            gsize n_regexes,
+                                            guint32 match_flags,
+                                            char **matches)
 {
        gsize offset, sattr, eattr;
         pcre2_match_data_8 *match_data;
@@ -1692,9 +1883,9 @@ Terminal::regex_match_check_extra(GdkEvent *event,
         long col, row;
         guint i;
 
-        assert(event);
-        assert(regexes != nullptr || n_regexes == 0);
-        assert(matches != nullptr);
+        g_assert(event);
+        g_assert(regexes != nullptr || n_regexes == 0);
+        g_assert(matches != nullptr);
 
         /* Need to ensure the ringview is updated. */
         ringview_update();
@@ -1719,7 +1910,8 @@ Terminal::regex_match_check_extra(GdkEvent *event,
 
                 g_return_val_if_fail(regexes[i] != nullptr, false);
 
-                if (match_check_pcre(match_data, match_context,
+                if (match_check_pcre(
+                                     match_data, match_context,
                                      regexes[i], match_flags,
                                      sattr, eattr, offset,
                                      &match_string,
@@ -2132,22 +2324,26 @@ Terminal::apply_mouse_cursor()
                 if (m_hyperlink_hover_idx != 0) {
                         _vte_debug_print(VTE_DEBUG_CURSOR,
                                         "Setting hyperlink mouse cursor.\n");
-                        m_real_widget->set_cursor(vte::platform::Widget::CursorType::eHyperlink);
-                } else if (regex_match_has_current()) {
-                        m_real_widget->set_cursor(regex_match_current()->cursor());
+                        m_real_widget->set_cursor(vte::platform::Widget::Cursor::eHyperlink);
+                } else if ((guint)m_match_tag < m_match_regexes->len) {
+                        struct vte_match_regex *regex =
+                                &g_array_index(m_match_regexes,
+                                              struct vte_match_regex,
+                                              m_match_tag);
+                        set_cursor_from_regex_match(regex);
                 } else if (m_mouse_tracking_mode) {
                        _vte_debug_print(VTE_DEBUG_CURSOR,
                                        "Setting mousing cursor.\n");
-                        m_real_widget->set_cursor(vte::platform::Widget::CursorType::eMousing);
+                        m_real_widget->set_cursor(vte::platform::Widget::Cursor::eMousing);
                } else {
                        _vte_debug_print(VTE_DEBUG_CURSOR,
                                        "Setting default mouse cursor.\n");
-                        m_real_widget->set_cursor(vte::platform::Widget::CursorType::eDefault);
+                        m_real_widget->set_cursor(vte::platform::Widget::Cursor::eDefault);
                }
        } else {
                _vte_debug_print(VTE_DEBUG_CURSOR,
                                "Setting to invisible cursor.\n");
-                m_real_widget->set_cursor(vte::platform::Widget::CursorType::eInvisible);
+                m_real_widget->set_cursor(vte::platform::Widget::Cursor::eInvisible);
        }
 }
 
@@ -5904,7 +6100,7 @@ Terminal::hyperlink_hilite_update()
 
         /* Underlining hyperlinks has precedence over regex matches. So when the hovered hyperlink changes,
          * the regex match might need to become or stop being underlined. */
-        if (regex_match_has_current())
+        if (m_match != nullptr)
                 invalidate_match_span();
 
         apply_mouse_cursor();
@@ -5920,14 +6116,16 @@ Terminal::hyperlink_hilite_update()
 void
 Terminal::match_hilite_clear()
 {
-        if (regex_match_has_current())
+        if (m_match != nullptr)
                 invalidate_match_span();
 
         m_match_span.clear();
-        m_match_current = nullptr;
+        m_match_tag = -1;
 
-        g_free(m_match);
-        m_match = nullptr;
+       if (m_match != nullptr) {
+               g_free (m_match);
+               m_match = nullptr;
+       }
 }
 
 /* This is only used by the dingu matching code, so no need to extend the area. */
@@ -5972,7 +6170,7 @@ Terminal::match_hilite_update()
                                !(m_mouse_autohide && m_mouse_cursor_autohidden) &&
                                !m_selecting;
         if (!do_check_hilite) {
-                if (regex_match_has_current())
+                if (m_match != nullptr)
                          match_hilite_clear();
                 return;
         }
@@ -5989,7 +6187,7 @@ Terminal::match_hilite_update()
        gsize start, end;
         auto new_match = match_check_internal(col,
                                               row,
-                                              &m_match_current,
+                                              &m_match_tag,
                                               &start,
                                               &end);
 
@@ -7959,9 +8157,16 @@ Terminal::Terminal(vte::platform::Widget* w,
         save_cursor(&m_alternate_screen);
 
        /* Matching data. */
-        m_match_span.clear(); // FIXMEchpe unnecessary
+       m_match_regexes = g_array_new(FALSE, TRUE,
+                                        sizeof(struct vte_match_regex));
+        m_match_tag = -1;
+        m_match_span.clear();
        match_hilite_clear(); // FIXMEchpe unnecessary
 
+        /* Search data */
+        m_search_regex.regex = nullptr;
+        m_search_regex.match_flags = 0;
+
        /* Rendering data */
        m_draw = _vte_draw_new();
 
@@ -8200,7 +8405,9 @@ Terminal::~Terminal()
         /* Make sure not to change selection while in destruction. See issue vte#89. */
         m_changing_selection = true;
 
+       struct vte_match_regex *regex;
        int sel;
+       guint i;
 
         terminate_child();
         set_pty(nullptr, false /* don't process remaining data */);
@@ -8227,7 +8434,21 @@ Terminal::~Terminal()
                g_array_free(m_match_attributes, TRUE);
        }
        g_free(m_match_contents);
+       if (m_match_regexes != NULL) {
+               for (i = 0; i < m_match_regexes->len; i++) {
+                       regex = &g_array_index(m_match_regexes,
+                                              struct vte_match_regex,
+                                              i);
+                       /* Skip holes. */
+                       if (regex->tag < 0) {
+                               continue;
+                       }
+                        regex_match_clear(regex);
+               }
+               g_array_free(m_match_regexes, TRUE);
+       }
 
+        regex_and_flags_clear(&m_search_regex);
        if (m_search_attrs)
                g_array_free (m_search_attrs, TRUE);
 
@@ -9137,7 +9358,7 @@ Terminal::draw_rows(VteScreen *screen_,
                         determine_colors(cell, selected, &nfore, &nback, &ndeco);
 
                         nhilite = (nhyperlink && cell->attr.hyperlink_idx == m_hyperlink_hover_idx) ||
-                                  (!nhyperlink && regex_match_has_current() && m_match_span.contains(row, 
lcol));
+                                  (!nhyperlink && m_match != nullptr && m_match_span.contains(row, lcol));
 
                         /* See if it no longer fits the run. */
                         if (item_count > 0 &&
@@ -10783,15 +11004,23 @@ Terminal::write_contents_sync (GOutputStream *stream,
  * Sets the regex to search for. Unsets the search regex when passed %nullptr.
  */
 bool
-Terminal::search_set_regex (vte::base::RefPtr<vte::base::Regex>&& regex,
-                            uint32_t flags)
+Terminal::search_set_regex (VteRegex *regex,
+                                      guint32 flags)
 {
-        if (regex == m_search_regex &&
-            flags == m_search_regex_match_flags)
+        struct vte_regex_and_flags *rx;
+
+        rx = &m_search_regex;
+
+        if (rx->regex == regex &&
+            rx->match_flags == flags)
                 return false;
 
-        m_search_regex = std::move(regex);
-        m_search_regex_match_flags = flags;
+        regex_and_flags_clear(rx);
+
+        if (regex != nullptr) {
+                rx->regex = vte_regex_ref(regex);
+                rx->match_flags = flags;
+        }
 
        invalidate_all();
 
@@ -10810,10 +11039,10 @@ Terminal::search_set_wrap_around(bool wrap)
 
 bool
 Terminal::search_rows(pcre2_match_context_8 *match_context,
-                      pcre2_match_data_8 *match_data,
-                      vte::grid::row_t start_row,
-                      vte::grid::row_t end_row,
-                      bool backward)
+                                pcre2_match_data_8 *match_data,
+                                vte::grid::row_t start_row,
+                                vte::grid::row_t end_row,
+                                bool backward)
 {
        int start, end;
        long start_col, end_col;
@@ -10833,15 +11062,15 @@ Terminal::search_rows(pcre2_match_context_8 *match_context,
         gsize *ovector, so, eo;
         int r;
 
-        if (m_search_regex->jited())
+        if (_vte_regex_get_jited(m_search_regex.regex))
                 match_fn = pcre2_jit_match_8;
         else
                 match_fn = pcre2_match_8;
 
-        r = match_fn(m_search_regex->code(),
+        r = match_fn(_vte_regex_get_pcre(m_search_regex.regex),
                      (PCRE2_SPTR8)row_text->str, row_text->len , /* subject, length */
                      0, /* start offset */
-                     m_search_regex_match_flags |
+                     m_search_regex.match_flags |
                      PCRE2_NO_UTF_CHECK | PCRE2_NOTEMPTY | PCRE2_PARTIAL_SOFT /* FIXME: HARD? */,
                      match_data,
                      match_context);
@@ -10952,7 +11181,7 @@ Terminal::search_find (bool backward)
         vte::grid::row_t last_start_row, last_end_row;
         bool match_found = true;
 
-        if (!m_search_regex)
+        if (m_search_regex.regex == nullptr)
                 return false;
 
        /* TODO
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index 27076c9d..3c3cf3dc 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -2081,16 +2081,21 @@ vte_terminal_match_add_regex(VteTerminal *terminal,
                              VteRegex    *regex,
                              guint32      flags)
 {
+       struct vte_match_regex new_regex_match;
+
        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
        g_return_val_if_fail(regex != NULL, -1);
         g_return_val_if_fail(_vte_regex_has_purpose(regex, vte::base::Regex::Purpose::eMatch), -1);
         g_warn_if_fail(_vte_regex_has_multiline_compile_flag(regex));
 
         auto impl = IMPL(terminal);
-        return impl->regex_match_add(vte::base::make_ref(regex_from_wrapper(regex)),
-                                     flags,
-                                     VTE_DEFAULT_CURSOR,
-                                     impl->regex_match_next_tag()).tag();
+
+        new_regex_match.regex.regex = vte_regex_ref(regex);
+        new_regex_match.regex.match_flags = flags;
+        new_regex_match.cursor_mode = VTE_REGEX_CURSOR_GDKCURSORTYPE;
+        new_regex_match.cursor.cursor_type = VTE_DEFAULT_CURSOR;
+
+        return impl->regex_match_add(&new_regex_match);
 }
 
 /**
@@ -2211,11 +2216,7 @@ vte_terminal_event_check_regex_simple(VteTerminal *terminal,
         }
         g_return_val_if_fail(matches != NULL, FALSE);
 
-        return IMPL(terminal)->regex_match_check_extra(event,
-                                                       regex_array_from_wrappers(regexes),
-                                                       n_regexes,
-                                                       match_flags,
-                                                       matches);
+        return IMPL(terminal)->regex_match_check_extra(event, regexes, n_regexes, match_flags, matches);
 }
 
 /**
@@ -2268,9 +2269,7 @@ vte_terminal_match_set_cursor(VteTerminal *terminal,
                               GdkCursor *cursor)
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
-        g_return_if_fail(tag >= 0);
-        if (auto rem = IMPL(terminal)->regex_match_get(tag))
-                rem->set_cursor(vte::glib::make_ref<GdkCursor>(cursor));
+        IMPL(terminal)->regex_match_set_cursor(tag, cursor);
 }
 
 /**
@@ -2290,9 +2289,7 @@ vte_terminal_match_set_cursor_type(VteTerminal *terminal,
                                    GdkCursorType cursor_type)
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
-        g_return_if_fail(tag >= 0);
-        if (auto rem = IMPL(terminal)->regex_match_get(tag))
-                rem->set_cursor(cursor_type);
+        IMPL(terminal)->regex_match_set_cursor(tag, cursor_type);
 }
 
 /**
@@ -2310,11 +2307,10 @@ vte_terminal_match_set_cursor_name(VteTerminal *terminal,
                                    const char *cursor_name)
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
-        g_return_if_fail(tag >= 0);
-        if (auto rem = IMPL(terminal)->regex_match_get(tag))
-                rem->set_cursor(cursor_name);
+        IMPL(terminal)->regex_match_set_cursor(tag, cursor_name);
 }
 
+
 /**
  * vte_terminal_match_remove:
  * @terminal: a #VteTerminal
@@ -2328,6 +2324,7 @@ void
 vte_terminal_match_remove(VteTerminal *terminal, int tag)
 {
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
+        g_return_if_fail(tag != -1);
         IMPL(terminal)->regex_match_remove(tag);
 }
 
@@ -2396,7 +2393,7 @@ vte_terminal_search_set_regex (VteTerminal *terminal,
         g_return_if_fail(regex == nullptr || _vte_regex_has_purpose(regex, 
vte::base::Regex::Purpose::eSearch));
         g_warn_if_fail(regex == nullptr || _vte_regex_has_multiline_compile_flag(regex));
 
-        IMPL(terminal)->search_set_regex(vte::base::make_ref(regex_from_wrapper(regex)), flags);
+        IMPL(terminal)->search_set_regex(regex, flags);
 }
 
 /**
@@ -2410,9 +2407,10 @@ vte_terminal_search_set_regex (VteTerminal *terminal,
 VteRegex *
 vte_terminal_search_get_regex(VteTerminal *terminal)
 {
-        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), nullptr);
+       g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
 
-        return wrapper_from_regex(IMPL(terminal)->search_regex());
+        auto impl = IMPL(terminal);
+        return impl->m_search_regex.regex;
 }
 
 /**
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index a414993d..6eebcf6f 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -42,7 +42,6 @@
 #include <list>
 #include <queue>
 #include <string>
-#include <variant>
 #include <vector>
 
 typedef enum {
@@ -96,21 +95,22 @@ enum {
         VTE_BIDI_FLAG_ALL        = (1 << 4) - 1,
 };
 
-namespace vte {
-namespace platform {
-
-/*
- * Cursor:
- *
- * Holds a platform cursor. This is either a named cursor (string),
- * a reference to a GdkCursor*, or a cursor type.
- */
-using Cursor = std::variant<std::string,
-                            vte::glib::RefPtr<GdkCursor>,
-                            GdkCursorType>;
+struct vte_regex_and_flags {
+        VteRegex *regex;
+        guint32 match_flags;
+};
 
-} // namespace platform
-} // namespace vte
+/* A match regex, with a tag. */
+struct vte_match_regex {
+       gint tag;
+        struct vte_regex_and_flags regex;
+        VteRegexCursorMode cursor_mode;
+        union {
+              GdkCursor *cursor;
+               char *cursor_name;
+               GdkCursorType cursor_type;
+        } cursor;
+};
 
 typedef enum _VteCharacterReplacement {
         VTE_CHARACTER_REPLACEMENT_NONE,
@@ -470,81 +470,11 @@ public:
         double m_mouse_smooth_scroll_delta{0.0};
 
        /* State variables for handling match checks. */
-        int m_match_regex_next_tag{0};
-        auto regex_match_next_tag() noexcept { return m_match_regex_next_tag++; }
-
-        class MatchRegex {
-        public:
-                MatchRegex() = default;
-                MatchRegex(MatchRegex&&) = default;
-                MatchRegex& operator= (MatchRegex&&) = default;
-
-                MatchRegex(MatchRegex const&) = delete;
-                MatchRegex& operator= (MatchRegex const&) = delete;
-
-                MatchRegex(vte::base::RefPtr<vte::base::Regex>&& regex,
-                           uint32_t match_flags,
-                           vte::platform::Cursor&& cursor,
-                           int tag = -1)
-                        : m_regex{std::move(regex)},
-                          m_match_flags{match_flags},
-                          m_cursor{std::move(cursor)},
-                          m_tag{tag}
-                {
-                }
-
-                auto regex() const noexcept { return m_regex.get(); }
-                auto match_flags() const noexcept { return m_match_flags; }
-                auto const& cursor() const noexcept { return m_cursor; }
-                auto tag() const noexcept { return m_tag; }
-
-                void set_cursor(vte::platform::Cursor&& cursor) { m_cursor = std::move(cursor); }
-
-        private:
-                vte::base::RefPtr<vte::base::Regex> m_regex{};
-                uint32_t m_match_flags{0};
-                vte::platform::Cursor m_cursor{VTE_DEFAULT_CURSOR};
-                int m_tag{-1};
-        };
-
-        MatchRegex const* m_match_current{nullptr};
-        bool regex_match_has_current() const noexcept { return m_match_current != nullptr; }
-        auto const* regex_match_current() const noexcept { return m_match_current; }
-
-        std::vector<MatchRegex> m_match_regexes{};
-
-        // m_match_current points into m_match_regex, so every write access to
-        // m_match_regex must go through this function that clears m_current_match
-        auto& match_regexes_writable() noexcept
-        {
-                match_hilite_clear();
-                return m_match_regexes;
-        }
-
-        auto regex_match_get_iter(int tag) noexcept
-        {
-                return std::find_if(std::begin(m_match_regexes), std::end(m_match_regexes),
-                                    [tag](MatchRegex const& rem) { return rem.tag() == tag; });
-        }
-
-        MatchRegex* regex_match_get(int tag) noexcept
-        {
-                auto i = regex_match_get_iter(tag);
-                if (i == std::end(m_match_regexes))
-                        return nullptr;
-
-                return std::addressof(*i);
-        }
-
-        template<class... Args>
-        auto& regex_match_add(Args&&... args)
-        {
-                return match_regexes_writable().emplace_back(std::forward<Args>(args)...);
-        }
-
         char* m_match_contents;
         GArray* m_match_attributes;
+        GArray* m_match_regexes;
         char* m_match;
+        int m_match_tag;
         /* If m_match non-null, then m_match_span contains the region of the match.
          * If m_match is null, and m_match_span is not .empty(), then it contains
          * the minimal region around the last checked coordinates that don't contain
@@ -553,8 +483,7 @@ public:
         vte::grid::span m_match_span;
 
        /* Search data. */
-        vte::base::RefPtr<vte::base::Regex> m_search_regex{};
-        uint32_t m_search_regex_match_flags{0};
+        struct vte_regex_and_flags m_search_regex;
         gboolean m_search_wrap_around;
         GArray* m_search_attrs; /* Cache attrs */
 
@@ -1107,6 +1036,7 @@ public:
 
         void match_contents_clear();
         void match_contents_refresh();
+        void set_cursor_from_regex_match(struct vte_match_regex *regex);
         void match_hilite_clear();
         void match_hilite_update();
 
@@ -1116,12 +1046,14 @@ public:
 
         char *hyperlink_check(GdkEvent *event);
 
-        bool regex_match_check_extra(GdkEvent* event,
-                                     vte::base::Regex const** regexes,
-                                     size_t n_regexes,
-                                     uint32_t match_flags,
-                                     char** matches);
+        bool regex_match_check_extra(GdkEvent *event,
+                                     VteRegex **regexes,
+                                     gsize n_regexes,
+                                     guint32 match_flags,
+                                     char **matches);
 
+        int regex_match_add(struct vte_match_regex *new_regex_match);
+        struct vte_match_regex *regex_match_get(int tag);
         char *regex_match_check(vte::grid::column_t column,
                                 vte::grid::row_t row,
                                 int *tag);
@@ -1144,8 +1076,8 @@ public:
         pcre2_match_context_8 *create_match_context();
         bool match_check_pcre(pcre2_match_data_8 *match_data,
                               pcre2_match_context_8 *match_context,
-                              vte::base::Regex const* regex,
-                              uint32_t match_flags,
+                              VteRegex *regex,
+                              guint32 match_flags,
                               gsize sattr,
                               gsize eattr,
                               gsize offset,
@@ -1156,13 +1088,13 @@ public:
                               gsize *eblank_ptr);
         char *match_check_internal_pcre(vte::grid::column_t column,
                                         vte::grid::row_t row,
-                                        MatchRegex const** match,
+                                        int *tag,
                                         gsize *start,
                                         gsize *end);
 
         char *match_check_internal(vte::grid::column_t column,
                                    vte::grid::row_t row,
-                                   MatchRegex const** match,
+                                   int *tag,
                                    gsize *start,
                                    gsize *end);
 
@@ -1180,9 +1112,8 @@ public:
         void feed_focus_event_initial();
         void maybe_feed_focus_event(bool in);
 
-        bool search_set_regex(vte::base::RefPtr<vte::base::Regex>&& regex,
-                              uint32_t flags) noexcept;
-        auto search_regex() const noexcept { return m_search_regex.get(); }
+        bool search_set_regex (VteRegex *regex,
+                               guint32 flags);
 
         bool search_rows(pcre2_match_context_8 *match_context,
                          pcre2_match_data_8 *match_data,
diff --git a/src/vteregex.cc b/src/vteregex.cc
index d95c77aa..75f33e7b 100644
--- a/src/vteregex.cc
+++ b/src/vteregex.cc
@@ -32,7 +32,8 @@
 #include "regex.hh"
 #include "vteregexinternal.hh"
 
-#define IMPL(wrapper) (regex_from_wrapper(wrapper))
+#define WRAPPER(impl) (reinterpret_cast<VteRegex*>(impl))
+#define IMPL(wrapper) (reinterpret_cast<vte::base::Regex*>(wrapper))
 
 /* GRegex translation */
 
@@ -86,7 +87,7 @@ vte_regex_ref(VteRegex *regex)
 {
         g_return_val_if_fail(regex != nullptr, nullptr);
 
-        return wrapper_from_regex(IMPL(regex)->ref());
+        return WRAPPER(IMPL(regex)->ref());
 }
 
 /**
@@ -114,7 +115,7 @@ vte_regex_new(vte::base::Regex::Purpose purpose,
               uint32_t flags,
               GError** error)
 {
-        return wrapper_from_regex(vte::base::Regex::compile(purpose, pattern, pattern_length, flags, error));
+        return WRAPPER(vte::base::Regex::compile(purpose, pattern, pattern_length, flags, error));
 }
 
 VteRegex*
@@ -268,6 +269,22 @@ _vte_regex_has_purpose(VteRegex *regex,
         return IMPL(regex)->has_purpose(purpose);
 }
 
+const pcre2_code_8 *
+_vte_regex_get_pcre(VteRegex* regex)
+{
+        g_return_val_if_fail(regex != nullptr, nullptr);
+
+        return IMPL(regex)->code();
+}
+
+bool
+_vte_regex_get_jited(VteRegex *regex)
+{
+        g_return_val_if_fail(regex != nullptr, false);
+
+        return IMPL(regex)->jited();
+}
+
 bool
 _vte_regex_has_multiline_compile_flag(VteRegex *regex)
 {
diff --git a/src/vteregexinternal.hh b/src/vteregexinternal.hh
index ac4e675d..d5b744ec 100644
--- a/src/vteregexinternal.hh
+++ b/src/vteregexinternal.hh
@@ -19,26 +19,15 @@
 
 #include "regex.hh"
 
-static inline auto wrapper_from_regex(vte::base::Regex* regex)
-{
-        return reinterpret_cast<VteRegex*>(regex);
-}
-
-static inline auto regex_from_wrapper(VteRegex* regex)
-{
-        return reinterpret_cast<vte::base::Regex*>(regex);
-}
-
-static inline auto regex_array_from_wrappers(VteRegex** regexes)
-{
-        return const_cast<vte::base::Regex const**>(reinterpret_cast<vte::base::Regex**>(regexes));
-}
-
 bool _vte_regex_has_purpose(VteRegex* regex,
                             vte::base::Regex::Purpose purpose);
 
+bool _vte_regex_get_jited(VteRegex* regex);
+
 bool _vte_regex_has_multiline_compile_flag(VteRegex* regex);
 
+const pcre2_code_8 *_vte_regex_get_pcre(VteRegex* regex);
+
 /* GRegex translation */
 VteRegex* _vte_regex_new_gregex(vte::base::Regex::Purpose purpose,
                                 GRegex* gregex);
diff --git a/src/widget.cc b/src/widget.cc
index bbc0dadc..5af5d47c 100644
--- a/src/widget.cc
+++ b/src/widget.cc
@@ -121,47 +121,10 @@ Widget::beep() noexcept
                 gdk_window_beep(gtk_widget_get_window(m_widget));
 }
 
-vte::glib::RefPtr<GdkCursor>
+GdkCursor*
 Widget::create_cursor(GdkCursorType cursor_type) const noexcept
 {
-       return vte::glib::take_ref(gdk_cursor_new_for_display(gtk_widget_get_display(m_widget), cursor_type));
-}
-
-void
-Widget::set_cursor(GdkCursor* cursor) noexcept
-{
-        gdk_window_set_cursor(m_event_window, cursor);
-}
-
-void
-Widget::set_cursor(Cursor const& cursor) noexcept
-{
-        if (!realized())
-                return;
-
-        auto display = gtk_widget_get_display(m_widget);
-        GdkCursor* gdk_cursor{nullptr};
-        switch (cursor.index()) {
-        case 0:
-                gdk_cursor = gdk_cursor_new_from_name(display, std::get<0>(cursor).c_str());
-                break;
-        case 1:
-                gdk_cursor = std::get<1>(cursor).get();
-                if (gdk_cursor != nullptr &&
-                    gdk_cursor_get_display(gdk_cursor) == display) {
-                        g_object_ref(gdk_cursor);
-                } else {
-                        gdk_cursor = nullptr;
-                }
-                break;
-        case 2:
-                gdk_cursor = gdk_cursor_new_for_display(display, std::get<2>(cursor));
-                break;
-        }
-
-        set_cursor(gdk_cursor);
-        if (gdk_cursor)
-                g_object_unref(gdk_cursor);
+       return gdk_cursor_new_for_display(gtk_widget_get_display(m_widget), cursor_type);
 }
 
 void
@@ -345,13 +308,13 @@ Widget::settings_changed() noexcept
 }
 
 void
-Widget::set_cursor(CursorType type) noexcept
+Widget::set_cursor(Cursor type) noexcept
 {
         switch (type) {
-        case CursorType::eDefault:   return set_cursor(m_default_cursor.get());
-        case CursorType::eInvisible: return set_cursor(m_invisible_cursor.get());
-        case CursorType::eMousing:   return set_cursor(m_mousing_cursor.get());
-        case CursorType::eHyperlink: return set_cursor(m_hyperlink_cursor.get());
+        case Cursor::eDefault:   return set_cursor(m_default_cursor.get());
+        case Cursor::eInvisible: return set_cursor(m_invisible_cursor.get());
+        case Cursor::eMousing:   return set_cursor(m_mousing_cursor.get());
+        case Cursor::eHyperlink: return set_cursor(m_hyperlink_cursor.get());
         }
 }
 
diff --git a/src/widget.hh b/src/widget.hh
index 6338cb70..932f7f91 100644
--- a/src/widget.hh
+++ b/src/widget.hh
@@ -18,8 +18,6 @@
 #pragma once
 
 #include <memory>
-#include <string>
-#include <variant>
 
 #include "vteterminal.h"
 #include "vteinternal.hh"
@@ -29,10 +27,8 @@
 namespace vte {
 
 namespace terminal {
-
 class Terminal;
-
-} // namespace terminal
+}
 
 namespace platform {
 
@@ -110,7 +106,7 @@ public:
 
 protected:
 
-        enum class CursorType {
+        enum class Cursor {
                 eDefault,
                 eInvisible,
                 eMousing,
@@ -124,11 +120,14 @@ protected:
                 return gtk_widget_get_realized(m_widget);
         }
 
-        vte::glib::RefPtr<GdkCursor> create_cursor(GdkCursorType cursor_type) const noexcept;
+        GdkCursor *create_cursor(GdkCursorType cursor_type) const noexcept;
+
+        void set_cursor(Cursor type) noexcept;
 
-        void set_cursor(CursorType type) noexcept;
-        void set_cursor(GdkCursor* cursor) noexcept;
-        void set_cursor(Cursor const& cursor) noexcept;
+        void set_cursor(GdkCursor* cursor) noexcept
+        {
+                gdk_window_set_cursor(m_event_window, cursor);
+        }
 
         bool im_filter_keypress(GdkEventKey* event) noexcept;
 



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