[vte] regex: Translate GRegex to PCRE2
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] regex: Translate GRegex to PCRE2
- Date: Thu, 4 Aug 2016 16:01:29 +0000 (UTC)
commit 00f252725c1eb1c5dc65fd9901221523418e18be
Author: Christian Persch <chpe gnome org>
Date: Thu Aug 4 17:51:44 2016 +0200
regex: Translate GRegex to PCRE2
Instead of duplicating all internal functions to deal with either
a PCRE2 regex or a GRegex, just translate the GRegex to PCRE2 in
the API entry points.
src/vte.cc | 344 +++--------------------------------------------
src/vtegtk.cc | 72 ++++------
src/vteinternal.hh | 42 +------
src/vteregex.cc | 90 ++++++++++++
src/vteregexinternal.hh | 6 +
5 files changed, 149 insertions(+), 405 deletions(-)
---
diff --git a/src/vte.cc b/src/vte.cc
index d3ff12a..0348b3b 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -1052,14 +1052,10 @@ regex_match_clear_cursor (struct vte_match_regex *regex)
static void
regex_and_flags_clear(struct vte_regex_and_flags *regex)
{
- if (regex->mode == VTE_REGEX_PCRE2) {
- vte_regex_unref(regex->pcre.regex);
- regex->pcre.regex = NULL;
- } else if (regex->mode == VTE_REGEX_GREGEX) {
- g_regex_unref(regex->gregex.regex);
- regex->gregex.regex = NULL;
+ if (regex->regex) {
+ vte_regex_unref(regex->regex);
+ regex->regex = nullptr;
}
- regex->mode = VTE_REGEX_UNDECIDED;
}
static void
@@ -1155,9 +1151,6 @@ VteTerminalPrivate::regex_match_add(struct vte_match_regex *new_regex_match)
struct vte_match_regex *regex_match;
guint ret, len;
- g_assert(m_match_regex_mode == VTE_REGEX_UNDECIDED || m_match_regex_mode ==
new_regex_match->regex.mode);
- m_match_regex_mode = new_regex_match->regex.mode;
-
/* Search for a hole. */
len = m_match_regexes->len;
for (ret = 0; ret < len; ret++) {
@@ -1545,11 +1538,9 @@ VteTerminalPrivate::match_check_internal_pcre(vte::grid::column_t column,
continue;
}
- g_assert_cmpint(regex->regex.mode, ==, VTE_REGEX_PCRE2);
-
if (match_check_pcre(match_data, match_context,
- regex->regex.pcre.regex,
- regex->regex.pcre.match_flags,
+ regex->regex.regex,
+ regex->regex.match_flags,
sattr, eattr, offset,
&dingu_match,
start, end,
@@ -1597,178 +1588,6 @@ VteTerminalPrivate::match_check_internal_pcre(vte::grid::column_t column,
#endif /* WITH_PCRE2 */
-bool
-VteTerminalPrivate::match_check_gregex(GRegex *regex,
- GRegexMatchFlags match_flags,
- gsize sattr,
- gsize eattr,
- gsize offset,
- char **result_ptr,
- gsize *start,
- gsize *end,
- gsize *sblank_ptr,
- gsize *eblank_ptr)
-{
- GMatchInfo *match_info;
- const char *line;
- gsize line_length;
- gint sblank = G_MININT, eblank = G_MAXINT;
-
- line = m_match_contents;
- line_length = eattr;
-
- /* We'll only match the first item in the buffer which
- * matches, so we'll have to skip each match until we
- * stop getting matches. */
- if (!g_regex_match_full(regex,
- line, line_length, /* subject, length */
- sattr, /* start position */
- match_flags,
- &match_info,
- NULL)) {
- g_match_info_free(match_info);
- return FALSE;
- }
-
- while (g_match_info_matches(match_info)) {
- gint ko = offset;
- gint rm_so, rm_eo;
-
- if (g_match_info_fetch_pos (match_info, 0, &rm_so, &rm_eo)) {
- /* The offsets should be "sane". */
- g_assert(rm_so < (int)eattr);
- g_assert(rm_eo <= (int)eattr);
- _VTE_DEBUG_IF(VTE_DEBUG_REGEX) {
- gchar *result;
- struct _VteCharAttributes *_sattr, *_eattr;
- result = g_strndup(line + rm_so, rm_eo - rm_so);
- _sattr = &g_array_index(m_match_attributes,
- struct _VteCharAttributes,
- rm_so);
- _eattr = &g_array_index(m_match_attributes,
- struct _VteCharAttributes,
- rm_eo - 1);
- g_printerr("Match `%s' from %d(%ld,%ld) to %d(%ld,%ld) (%" G_GSIZE_FORMAT
").\n",
- result,
- rm_so,
- _sattr->column,
- _sattr->row,
- rm_eo - 1,
- _eattr->column,
- _eattr->row,
- offset);
- g_free(result);
-
- }
- /* If the pointer is in this substring,
- * then we're done. */
- if (ko >= rm_so && ko < rm_eo) {
- *start = rm_so;
- *end = rm_eo - 1;
- *result_ptr = g_match_info_fetch(match_info, 0);
-
- g_match_info_free(match_info);
- return true;
- }
-
- if (ko >= rm_eo && rm_eo > sblank) {
- sblank = rm_eo;
- }
- if (ko < rm_so && rm_so < eblank) {
- eblank = rm_so;
- }
- }
-
- g_match_info_next(match_info, NULL);
- }
-
- g_match_info_free(match_info);
-
- *sblank_ptr = sblank;
- *eblank_ptr = eblank;
- return false;
-}
-
-char *
-VteTerminalPrivate::match_check_internal_gregex(vte::grid::column_t column,
- vte::grid::row_t row,
- int *tag,
- gsize *start,
- gsize *end)
-{
- guint i;
- struct vte_match_regex *regex = nullptr;
- gsize sattr, eattr, offset, start_blank, end_blank;
- char *dingu_match = nullptr;
-
- _vte_debug_print(VTE_DEBUG_REGEX,
- "Checking for gregex match at (%ld,%ld).\n", row, column);
-
- if (!match_rowcol_to_offset(column, row,
- &offset, &sattr, &eattr))
- return nullptr;
-
- start_blank = sattr;
- end_blank = eattr;
-
- /* Now iterate over each regex we need to match against. */
- for (i = 0; i < m_match_regexes->len; i++) {
- gsize sblank = 0, eblank = G_MAXSIZE;
-
- regex = &g_array_index(m_match_regexes,
- struct vte_match_regex,
- i);
- /* Skip holes. */
- if (regex->tag < 0) {
- continue;
- }
-
- g_assert_cmpint(regex->regex.mode, ==, VTE_REGEX_GREGEX);
-
- if (match_check_gregex(regex->regex.gregex.regex,
- regex->regex.gregex.match_flags,
- sattr, eattr, offset,
- &dingu_match,
- start, end,
- &sblank, &eblank)) {
- _vte_debug_print(VTE_DEBUG_REGEX, "Matched dingu with tag %d\n", regex->tag);
- set_cursor_from_regex_match(regex);
- *tag = regex->tag;
- break;
- }
-
- if (sblank > start_blank) {
- start_blank = sblank;
- }
- if (eblank < end_blank) {
- end_blank = eblank;
- }
- }
-
- if (dingu_match == nullptr) {
- /* If we get here, there was no dingu match.
- * Record smallest span where none of the dingus match.
- */
- *start = start_blank;
- *end = end_blank - 1;
-
- _VTE_DEBUG_IF(VTE_DEBUG_REGEX) {
- struct _VteCharAttributes *_sattr, *_eattr;
- _sattr = &g_array_index(m_match_attributes,
- struct _VteCharAttributes,
- start_blank);
- _eattr = &g_array_index(m_match_attributes,
- struct _VteCharAttributes,
- end_blank - 1);
- g_printerr("No-match region from %" G_GSIZE_FORMAT "(%ld,%ld) to %" G_GSIZE_FORMAT
"(%ld,%ld)\n",
- start_blank, _sattr->column, _sattr->row,
- end_blank - 1, _eattr->column, _eattr->row);
- }
- }
-
- return dingu_match;
-}
-
/*
* vte_terminal_match_check_internal:
* @terminal:
@@ -1805,13 +1624,10 @@ VteTerminalPrivate::match_check_internal(vte::grid::column_t column,
*end = 0;
#ifdef WITH_PCRE2
- if (G_LIKELY(m_match_regex_mode == VTE_REGEX_PCRE2))
- return match_check_internal_pcre(column, row, tag, start, end);
-#endif
- if (m_match_regex_mode == VTE_REGEX_GREGEX)
- return match_check_internal_gregex(column, row, tag, start, end);
-
+ return match_check_internal_pcre(column, row, tag, start, end);
+#else
return nullptr;
+#endif
}
char *
@@ -2071,55 +1887,6 @@ VteTerminalPrivate::regex_match_check_extra(GdkEvent *event,
#endif
}
-bool
-VteTerminalPrivate::regex_match_check_extra(GdkEvent *event,
- GRegex **regexes,
- gsize n_regexes,
- GRegexMatchFlags match_flags,
- char **matches)
-{
- gsize offset, sattr, eattr;
- gboolean any_matches = FALSE;
- long col, row;
- guint i;
-
- g_assert(event);
- g_assert(regexes != nullptr || n_regexes == 0);
- g_assert(matches != nullptr);
-
- if (!rowcol_from_event(event, &col, &row))
- return false;
-
- if (m_match_contents == nullptr) {
- match_contents_refresh();
- }
-
- if (!match_rowcol_to_offset(col, row,
- &offset, &sattr, &eattr))
- return false;
-
- for (i = 0; i < n_regexes; i++) {
- gsize start, end, sblank, eblank;
- char *match_string;
-
- g_return_val_if_fail(regexes[i] != nullptr, FALSE);
-
- if (match_check_gregex(
- regexes[i], match_flags,
- sattr, eattr, offset,
- &match_string,
- &start, &end,
- &sblank, &eblank)) {
- _vte_debug_print(VTE_DEBUG_REGEX, "Matched gregex with text: %s\n", match_string);
- matches[i] = match_string;
- any_matches = true;
- } else
- matches[i] = nullptr;
- }
-
- return any_matches;
-}
-
/* Emit an adjustment changed signal on our adjustment object. */
void
VteTerminalPrivate::emit_adjustment_changed()
@@ -8116,7 +7883,6 @@ VteTerminalPrivate::VteTerminalPrivate(VteTerminal *t) :
save_cursor(&m_alternate_screen);
/* Matching data. */
- m_match_regex_mode = VTE_REGEX_UNDECIDED;
m_match_regexes = g_array_new(FALSE, TRUE,
sizeof(struct vte_match_regex));
m_match_tag = -1;
@@ -8124,7 +7890,8 @@ VteTerminalPrivate::VteTerminalPrivate(VteTerminal *t) :
match_hilite_clear(); // FIXMEchpe unnecessary
/* Search data */
- m_search_regex.mode = VTE_REGEX_UNDECIDED;
+ m_search_regex.regex = nullptr;
+ m_search_regex.match_flags = 0;
/* Rendering data */
m_draw = _vte_draw_new();
@@ -10979,17 +10746,15 @@ VteTerminalPrivate::search_set_regex (VteRegex *regex,
rx = &m_search_regex;
- if (rx->mode == VTE_REGEX_PCRE2 &&
- rx->pcre.regex == regex &&
- rx->pcre.match_flags == flags)
+ if (rx->regex == regex &&
+ rx->match_flags == flags)
return false;
regex_and_flags_clear(rx);
- if (regex != NULL) {
- rx->mode = VTE_REGEX_PCRE2;
- rx->pcre.regex = vte_regex_ref(regex);
- rx->pcre.match_flags = flags;
+ if (regex != nullptr) {
+ rx->regex = vte_regex_ref(regex);
+ rx->match_flags = flags;
}
invalidate_all();
@@ -10999,37 +10764,6 @@ VteTerminalPrivate::search_set_regex (VteRegex *regex,
#endif /* WITH_PCRE2 */
-/*
- * VteTerminalPrivate::search_set_gregex:
- * @gregex: (allow-none): a #GRegex, or %nullptr
- * @gflags: flags from #GRegexMatchFlags
- *
- * Sets the #GRegex regex to search for. Unsets the search regex when passed %nullptr.
- */
-bool
-VteTerminalPrivate::search_set_gregex(GRegex *gregex,
- GRegexMatchFlags gflags)
-{
- struct vte_regex_and_flags *rx = &m_search_regex;
-
- if (rx->mode == VTE_REGEX_GREGEX &&
- rx->gregex.regex == gregex &&
- rx->gregex.match_flags == gflags)
- return false;
-
- regex_and_flags_clear(rx);
-
- if (gregex != NULL) {
- rx->mode = VTE_REGEX_GREGEX;
- rx->gregex.regex = g_regex_ref(gregex);
- rx->gregex.match_flags = gflags;
- }
-
- invalidate_all();
-
- return true;
-}
-
bool
VteTerminalPrivate::search_set_wrap_around(bool wrap)
{
@@ -11069,22 +10803,21 @@ VteTerminalPrivate::search_rows(
&row_text_length);
#ifdef WITH_PCRE2
- if (G_LIKELY(m_search_regex.mode == VTE_REGEX_PCRE2)) {
int (* match_fn) (const pcre2_code_8 *,
PCRE2_SPTR8, PCRE2_SIZE, PCRE2_SIZE, uint32_t,
pcre2_match_data_8 *, pcre2_match_context_8 *);
gsize *ovector, so, eo;
int r;
- if (_vte_regex_get_jited(m_search_regex.pcre.regex))
+ if (_vte_regex_get_jited(m_search_regex.regex))
match_fn = pcre2_jit_match_8;
else
match_fn = pcre2_match_8;
- r = match_fn(_vte_regex_get_pcre(m_search_regex.pcre.regex),
+ r = match_fn(_vte_regex_get_pcre(m_search_regex.regex),
(PCRE2_SPTR8)row_text, row_text_length , /* subject, length */
0, /* start offset */
- m_search_regex.pcre.match_flags |
+ m_search_regex.match_flags |
PCRE2_NO_UTF_CHECK | PCRE2_NOTEMPTY | PCRE2_PARTIAL_SOFT /* FIXME: HARD? */,
match_data,
match_context);
@@ -11104,37 +10837,9 @@ VteTerminalPrivate::search_rows(
start = so;
end = eo;
word = g_strndup(row_text, end - start);
- } else
+#else
+ return false;
#endif /* WITH_PCRE2 */
- {
- GMatchInfo *match_info;
- GError *error = NULL;
-
- g_assert_cmpint(m_search_regex.mode, ==, VTE_REGEX_GREGEX);
-
- g_regex_match_full (m_search_regex.gregex.regex, row_text, row_text_length, 0,
- (GRegexMatchFlags)(m_search_regex.gregex.match_flags |
G_REGEX_MATCH_NOTEMPTY),
- &match_info, &error);
- if (error) {
- g_printerr ("Error while matching: %s\n", error->message);
- g_error_free (error);
- g_match_info_free (match_info);
- g_free (row_text);
- return false;
- }
-
- if (!g_match_info_matches (match_info)) {
- g_match_info_free (match_info);
- g_free (row_text);
- return false;
- }
-
- word = g_match_info_fetch (match_info, 0);
- /* This gives us the offset in the buffer */
- g_match_info_fetch_pos (match_info, 0, &start, &end);
-
- g_match_info_free (match_info);
- }
/* Fetch text again, with attributes */
g_free (row_text);
@@ -11237,19 +10942,14 @@ VteTerminalPrivate::search_find (bool backward)
pcre2_match_data_8 *match_data = nullptr;
#endif
- if (m_search_regex.mode == VTE_REGEX_UNDECIDED)
- return false;
-
/* TODO
* Currently We only find one result per extended line, and ignore columns
* Moreover, the whole search thing is implemented very inefficiently.
*/
#ifdef WITH_PCRE2
- if (G_LIKELY(m_search_regex.mode == VTE_REGEX_PCRE2)) {
- match_context = create_match_context();
- match_data = pcre2_match_data_create_8(256 /* should be plenty */, nullptr /* general
context */);
- }
+ match_context = create_match_context();
+ match_data = pcre2_match_data_create_8(256 /* should be plenty */, nullptr /* general context */);
#endif
buffer_start_row = _vte_ring_delta (m_screen->row_data);
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index 944ab1c..d875a95 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -1692,7 +1692,7 @@ vte_terminal_paste_primary(VteTerminal *terminal)
* this expression, the text will be highlighted.
*
* Returns: an integer associated with this expression, or -1 if @gregex could not be
- * transformed into a #VteRegex or @flags were incompatible
+ * transformed into a #VteRegex or @gflags were incompatible
*
* Deprecated: 0.46: Use vte_terminal_match_add_regex() or vte_terminal_match_add_regex_full() instead.
*/
@@ -1701,24 +1701,17 @@ vte_terminal_match_add_gregex(VteTerminal *terminal,
GRegex *gregex,
GRegexMatchFlags gflags)
{
- struct vte_match_regex new_regex_match;
-
- g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
g_return_val_if_fail(gregex != NULL, -1);
-
- auto impl = IMPL(terminal);
- /* Can't mix GRegex and PCRE2 */
- g_return_val_if_fail(impl->m_match_regex_mode != VTE_REGEX_PCRE2, -1);
-
g_warn_if_fail(g_regex_get_compile_flags(gregex) & G_REGEX_MULTILINE);
- new_regex_match.regex.mode = VTE_REGEX_GREGEX;
- new_regex_match.regex.gregex.regex = g_regex_ref(gregex);
- new_regex_match.regex.gregex.match_flags = gflags;
- new_regex_match.cursor_mode = VTE_REGEX_CURSOR_GDKCURSORTYPE;
- new_regex_match.cursor.cursor_type = VTE_DEFAULT_CURSOR;
+ auto regex = _vte_regex_new_gregex(VteRegexPurpose::match, gregex);
+ if (regex == NULL)
+ return -1;
- return impl->regex_match_add(&new_regex_match);
+ auto rv = vte_terminal_match_add_regex(terminal, regex,
+ _vte_regex_translate_gregex_match_flags(gflags));
+ vte_regex_unref(regex);
+ return rv;
}
/**
@@ -1747,12 +1740,9 @@ vte_terminal_match_add_regex(VteTerminal *terminal,
g_return_val_if_fail(_vte_regex_has_purpose(regex, VteRegexPurpose::match), -1);
auto impl = IMPL(terminal);
- /* Can't mix GRegex and PCRE2 */
- g_return_val_if_fail(impl->m_match_regex_mode != VTE_REGEX_GREGEX, -1);
- new_regex_match.regex.mode = VTE_REGEX_PCRE2;
- new_regex_match.regex.pcre.regex = vte_regex_ref(regex);
- new_regex_match.regex.pcre.match_flags = flags;
+ 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;
@@ -1863,12 +1853,9 @@ vte_terminal_event_check_regex_simple(VteTerminal *terminal,
* @match_flags: the #GRegexMatchFlags to use when matching the regexes
* @matches: (out caller-allocates) (array length=n_regexes): a location to store the matches
*
- * Checks each regex in @regexes if the text in and around the position of
- * the event matches the regular expressions. If a match exists, the matched
- * text is stored in @matches at the position of the regex in @regexes; otherwise
- * %NULL is stored there.
+ * This function does nothing.
*
- * Returns: %TRUE iff any of the regexes produced a match
+ * Returns: %FALSE
*
* Since: 0.44
* Deprecated: 0.46: Use vte_terminal_event_check_regex_simple() instead.
@@ -1886,7 +1873,7 @@ vte_terminal_event_check_gregex_simple(VteTerminal *terminal,
g_return_val_if_fail(regexes != NULL || n_regexes == 0, FALSE);
g_return_val_if_fail(matches != NULL, FALSE);
- return IMPL(terminal)->regex_match_check_extra(event, regexes, n_regexes, match_flags, matches);
+ return FALSE;
}
/**
@@ -1983,7 +1970,7 @@ vte_terminal_match_remove_all(VteTerminal *terminal)
* @terminal: a #VteTerminal
*
* Searches the previous string matching the search regex set with
- * vte_terminal_search_set_gregex().
+ * vte_terminal_search_set_regex().
*
* Returns: %TRUE if a match was found
*/
@@ -1999,7 +1986,7 @@ vte_terminal_search_find_previous (VteTerminal *terminal)
* @terminal: a #VteTerminal
*
* Searches the next string matching the search regex set with
- * vte_terminal_search_set_gregex().
+ * vte_terminal_search_set_regex().
*
* Returns: %TRUE if a match was found
*/
@@ -2047,10 +2034,7 @@ vte_terminal_search_get_regex(VteTerminal *terminal)
g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
auto impl = IMPL(terminal);
- if (G_LIKELY(impl->m_search_regex.mode == VTE_REGEX_PCRE2))
- return impl->m_search_regex.pcre.regex;
- else
- return NULL;
+ return impl->m_search_regex.regex;
}
/**
@@ -2068,16 +2052,22 @@ vte_terminal_search_set_gregex (VteTerminal *terminal,
GRegex *gregex,
GRegexMatchFlags gflags)
{
- g_return_if_fail(VTE_IS_TERMINAL(terminal));
+ VteRegex *regex = nullptr;
+ if (gregex)
+ regex = _vte_regex_new_gregex(VteRegexPurpose::search, gregex);
+
+ vte_terminal_search_set_regex(terminal, regex,
+ _vte_regex_translate_gregex_match_flags(gflags));
- IMPL(terminal)->search_set_gregex(gregex, gflags);
+ if (regex)
+ vte_regex_unref(regex);
}
/**
* vte_terminal_search_get_gregex:
* @terminal: a #VteTerminal
*
- * Returns: (transfer none): the search #GRegex regex set in @terminal, or %NULL
+ * Returns: (transfer none): %NULL
*
* Deprecated: 0.46: use vte_terminal_search_get_regex() instead.
*/
@@ -2086,11 +2076,7 @@ vte_terminal_search_get_gregex (VteTerminal *terminal)
{
g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
- auto impl = IMPL(terminal);
- if (G_LIKELY(impl->m_search_regex.mode == VTE_REGEX_GREGEX))
- return impl->m_search_regex.gregex.regex;
- else
- return NULL;
+ return NULL;
}
/**
@@ -2305,7 +2291,7 @@ vte_terminal_spawn_sync(VteTerminal *terminal,
/**
* vte_terminal_feed:
* @terminal: a #VteTerminal
- * @data: (array length=length) (element-type guint8): a string in the terminal's current encoding
+ * @data: (array length=length) (element-type guint8) (allow-none): a string in the terminal's current
encoding
* @length: the length of the string, or -1 to use the full length or a nul-terminated string
*
* Interprets @data as if it were data received from a child process. This
@@ -2326,7 +2312,7 @@ vte_terminal_feed(VteTerminal *terminal,
/**
* vte_terminal_feed_child:
* @terminal: a #VteTerminal
- * @text: data to send to the child
+ * @text: (element-type utf8) (allow-none): data to send to the child
* @length: length of @text in bytes, or -1 if @text is NUL-terminated
*
* Sends a block of UTF-8 text to the child as if it were entered by the user
@@ -2346,7 +2332,7 @@ vte_terminal_feed_child(VteTerminal *terminal,
/**
* vte_terminal_feed_child_binary:
* @terminal: a #VteTerminal
- * @data: data to send to the child
+ * @data: (array length=length) (element-type guint8) (allow-none): data to send to the child
* @length: length of @data
*
* Sends a block of binary data to the child.
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 7292c33..a5f1bbe 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -32,12 +32,6 @@
#endif
typedef enum {
- VTE_REGEX_UNDECIDED,
- VTE_REGEX_PCRE2,
- VTE_REGEX_GREGEX
-} VteRegexMode;
-
-typedef enum {
VTE_REGEX_CURSOR_GDKCURSOR,
VTE_REGEX_CURSOR_GDKCURSORTYPE,
VTE_REGEX_CURSOR_NAME
@@ -54,17 +48,8 @@ typedef enum {
} MouseTrackingMode;
struct vte_regex_and_flags {
- VteRegexMode mode;
- union { /* switched on @mode */
- struct {
- VteRegex *regex;
- guint32 match_flags;
- } pcre;
- struct {
- GRegex *regex;
- GRegexMatchFlags match_flags;
- } gregex;
- };
+ VteRegex *regex;
+ guint32 match_flags;
};
/* A match regex, with a tag. */
@@ -451,7 +436,6 @@ public:
/* State variables for handling match checks. */
char* m_match_contents;
GArray* m_match_attributes;
- VteRegexMode m_match_regex_mode;
GArray* m_match_regexes;
char* m_match;
int m_match_tag;
@@ -979,11 +963,6 @@ public:
gsize n_regexes,
guint32 match_flags,
char **matches);
- bool regex_match_check_extra(GdkEvent *event,
- GRegex **regexes,
- gsize n_regexes,
- GRegexMatchFlags match_flags,
- char **matches);
int regex_match_add(struct vte_match_regex *new_regex_match);
struct vte_match_regex *regex_match_get(int tag);
@@ -1025,21 +1004,6 @@ public:
gsize *start,
gsize *end);
#endif
- bool match_check_gregex(GRegex *regex,
- GRegexMatchFlags match_flags,
- gsize sattr,
- gsize eattr,
- gsize offset,
- char **result,
- gsize *start,
- gsize *end,
- gsize *sblank_ptr,
- gsize *eblank_ptr);
- char *match_check_internal_gregex(vte::grid::column_t column,
- vte::grid::row_t row,
- int *tag,
- gsize *start,
- gsize *end);
char *match_check_internal(vte::grid::column_t column,
vte::grid::row_t row,
@@ -1065,8 +1029,6 @@ public:
bool search_set_regex (VteRegex *regex,
guint32 flags);
#endif
- bool search_set_gregex (GRegex *gregex,
- GRegexMatchFlags gflags);
bool search_rows(
#ifdef WITH_PCRE2
diff --git a/src/vteregex.cc b/src/vteregex.cc
index 672bf02..d6b6a29 100644
--- a/src/vteregex.cc
+++ b/src/vteregex.cc
@@ -52,6 +52,35 @@ struct _VteRegex {
#define DEFAULT_MATCH_OPTIONS (0)
#endif /* WITH_PCRE2 */
+/* GRegex translation */
+
+typedef struct {
+ guint32 gflag;
+ guint32 pflag;
+} FlagTranslation;
+
+static void
+translate_flags(FlagTranslation const* const table,
+ gsize table_len,
+ guint32 *gflagsptr /* inout */,
+ guint32 *pflagsptr /* inout */)
+{
+ auto gflags = *gflagsptr;
+ auto pflags = *pflagsptr;
+ for (guint i = 0; i < table_len; i++) {
+ auto gflag = table[i].gflag;
+ if ((gflags & gflag) == gflag) {
+ pflags |= table[i].pflag;
+ gflags &= ~gflag;
+ }
+ }
+
+ *gflagsptr = gflags;
+ *pflagsptr = pflags;
+}
+
+/* internal */
+
#ifdef WITH_PCRE2
static VteRegex *
@@ -194,6 +223,67 @@ vte_regex_new(VteRegexPurpose purpose,
#endif /* WITH_PCRE2 */
}
+VteRegex *
+_vte_regex_new_gregex(VteRegexPurpose purpose,
+ GRegex *gregex)
+{
+ g_return_val_if_fail(gregex != NULL, NULL);
+
+ guint32 pflags = 0;
+
+#ifdef WITH_PCRE2
+ static FlagTranslation const table[] = {
+ { G_REGEX_CASELESS, PCRE2_CASELESS },
+ { G_REGEX_MULTILINE, PCRE2_MULTILINE },
+ { G_REGEX_DOTALL, PCRE2_DOTALL },
+ { G_REGEX_EXTENDED, PCRE2_EXTENDED },
+ { G_REGEX_ANCHORED, PCRE2_ANCHORED },
+ { G_REGEX_DOLLAR_ENDONLY, PCRE2_DOLLAR_ENDONLY },
+ { G_REGEX_UNGREEDY, PCRE2_UNGREEDY },
+ { G_REGEX_NO_AUTO_CAPTURE, PCRE2_NO_AUTO_CAPTURE },
+ { G_REGEX_OPTIMIZE, 0 }, /* accepted but unused */
+ { G_REGEX_FIRSTLINE, PCRE2_FIRSTLINE },
+ { G_REGEX_DUPNAMES, PCRE2_DUPNAMES }
+ };
+
+ guint32 gflags = g_regex_get_compile_flags(gregex);
+ translate_flags(table, G_N_ELEMENTS(table), &gflags, &pflags);
+
+ if (gflags != 0) {
+ g_warning("Incompatible GRegex compile flags left untranslated: %08x", gflags);
+ }
+#endif
+
+ GError *err = nullptr;
+ auto regex = vte_regex_new(purpose, g_regex_get_pattern(gregex), -1, pflags, &err);
+ if (regex == NULL) {
+ g_warning("Failed to translated GRegex: %s", err->message);
+ g_error_free(err);
+ }
+ return regex;
+}
+
+guint32
+_vte_regex_translate_gregex_match_flags(GRegexMatchFlags flags)
+{
+ static FlagTranslation const table[] = {
+ { G_REGEX_MATCH_ANCHORED, PCRE2_ANCHORED },
+ { G_REGEX_MATCH_NOTBOL, PCRE2_NOTBOL },
+ { G_REGEX_MATCH_NOTEOL, PCRE2_NOTEOL },
+ { G_REGEX_MATCH_NOTEMPTY, PCRE2_NOTEMPTY },
+ { G_REGEX_MATCH_NOTEMPTY_ATSTART, PCRE2_NOTEMPTY_ATSTART }
+ };
+
+ guint32 gflags = flags;
+ guint32 pflags = 0;
+ translate_flags(table, G_N_ELEMENTS(table), &gflags, &pflags);
+ if (gflags != 0) {
+ g_warning("Incompatible GRegex match flags left untranslated: %08x", gflags);
+ }
+
+ return pflags;
+}
+
/**
* vte_regex_new_for_match:
* @pattern: a regex pattern string
diff --git a/src/vteregexinternal.hh b/src/vteregexinternal.hh
index 88fb848..eaf42dc 100644
--- a/src/vteregexinternal.hh
+++ b/src/vteregexinternal.hh
@@ -30,3 +30,9 @@ gboolean _vte_regex_get_jited(VteRegex *regex);
#ifdef WITH_PCRE2
const pcre2_code_8 *_vte_regex_get_pcre (VteRegex *regex);
#endif
+
+/* GRegex translation */
+VteRegex *_vte_regex_new_gregex(VteRegexPurpose purpose,
+ GRegex *gregex);
+
+guint32 _vte_regex_translate_gregex_match_flags(GRegexMatchFlags flags);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]