[vte/wip/regex-builtins: 1/3] regex: Make regex a C++ class
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/wip/regex-builtins: 1/3] regex: Make regex a C++ class
- Date: Wed, 8 May 2019 15:36:20 +0000 (UTC)
commit 0e22309d9cec3972da1543377b66d40f7507d71a
Author: Christian Persch <chpe src gnome org>
Date: Wed May 8 17:35:07 2019 +0200
regex: Make regex a C++ class
Make regex a C++ class and the public VteRegex only a wrapper.
.dir-locals.el | 4 +
src/meson.build | 7 +-
src/regex.cc | 238 +++++++++++++++++++++++++++++++++++++++
src/regex.hh | 83 ++++++++++++++
src/vtegtk.cc | 18 +--
src/vtepcre2.h | 9 +-
src/vteregex.cc | 292 ++++++++----------------------------------------
src/vteregexinternal.hh | 21 ++--
8 files changed, 400 insertions(+), 272 deletions(-)
---
diff --git a/.dir-locals.el b/.dir-locals.el
index 46a2b10f..b611d45c 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -13,3 +13,7 @@
(c-basic-offset . 2)
(tab-width . 2)
(show-trailing-whitespace . t))))
+
+(defun my-c-setup ()
+ (c-set-offset 'innamespace [0]))
+(add-hook 'c++-mode-hook 'my-c-setup)
diff --git a/src/meson.build b/src/meson.build
index 4dc6a86b..2ce7d6e2 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -49,12 +49,17 @@ parser_sources = files(
'parser.hh',
)
+regex_sources = files(
+ 'regex.cc',
+ 'regex.hh'
+)
+
utf8_sources = files(
'utf8.cc',
'utf8.hh',
)
-libvte_common_sources = debug_sources + modes_sources + parser_sources + utf8_sources + files(
+libvte_common_sources = debug_sources + modes_sources + parser_sources + regex_sources + utf8_sources +
files(
'attr.hh',
'buffer.h',
'caps.hh',
diff --git a/src/regex.cc b/src/regex.cc
new file mode 100644
index 00000000..5be07a46
--- /dev/null
+++ b/src/regex.cc
@@ -0,0 +1,238 @@
+/*
+ * Copyright © 2015, 2019 Christian Persch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "regex.hh"
+#include "vte/vteenums.h"
+#include "vte/vteregex.h"
+
+
+#include <cassert>
+
+namespace vte {
+
+namespace base {
+
+static bool
+set_gerror_from_pcre_error(int errcode,
+ GError **error)
+{
+ 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);
+ return false;
+}
+
+Regex*
+Regex::ref() noexcept
+{
+ g_atomic_int_inc(&m_refcount);
+ return this;
+}
+
+void
+Regex::unref() noexcept
+{
+ if (g_atomic_int_dec_and_test(&m_refcount))
+ delete this;
+}
+
+bool
+Regex::check_pcre_config_unicode(GError** error)
+{
+ /* Check library compatibility */
+ guint32 v;
+ int r = pcre2_config_8(PCRE2_CONFIG_UNICODE, &v);
+ if (r != 0 || v != 1) {
+ g_set_error(error, VTE_REGEX_ERROR, VTE_REGEX_ERROR_INCOMPATIBLE,
+ "PCRE2 library was built without unicode support");
+ return false;
+ }
+
+ return true;
+}
+
+bool
+Regex::check_pcre_config_jit(void)
+{
+ static bool warned = false;
+
+ char s[256];
+ int r = pcre2_config_8(PCRE2_CONFIG_JITTARGET, &s);
+ if (r == PCRE2_ERROR_BADOPTION && !warned) {
+ g_printerr("PCRE2 library was built without JIT support\n");
+ warned = true;
+ }
+
+ return r >= 1;
+}
+
+Regex*
+Regex::compile(Regex::Purpose purpose,
+ char const* pattern,
+ ssize_t pattern_length,
+ uint32_t flags,
+ GError** error)
+{
+
+ assert(pattern != nullptr || pattern_length == 0);
+ assert(error == nullptr || *error == nullptr);
+
+ if (!check_pcre_config_unicode(error))
+ return nullptr;
+
+ int errcode;
+ PCRE2_SIZE erroffset;
+ auto code = pcre2_compile_8((PCRE2_SPTR8)pattern,
+ pattern_length >= 0 ? pattern_length : PCRE2_ZERO_TERMINATED,
+ (uint32_t)flags |
+ PCRE2_UTF |
+ (flags & PCRE2_UTF ? PCRE2_NO_UTF_CHECK : 0) |
+ PCRE2_NEVER_BACKSLASH_C |
+ PCRE2_USE_OFFSET_LIMIT,
+ &errcode, &erroffset,
+ nullptr);
+
+ if (code == nullptr) {
+ set_gerror_from_pcre_error(errcode, error);
+ g_prefix_error(error, "Failed to compile pattern to regex at offset %" G_GSIZE_FORMAT ":",
+ erroffset);
+ return nullptr;
+ }
+
+ return new Regex{code, purpose};
+}
+
+/*
+ * Regex::jit:
+ * @flags: JIT flags
+ *
+ * If the platform supports JITing, JIT compiles the regex.
+ *
+ * Returns: %true if JITing succeeded (or PCRE2 was built without
+ * JIT support), or %false with @error filled in
+ */
+bool
+Regex::jit(uint32_t flags,
+ GError** error)
+{
+ if (!check_pcre_config_jit())
+ return TRUE;
+
+ int r = pcre2_jit_compile_8(code(), flags);
+ if (r < 0)
+ return set_gerror_from_pcre_error(r, error);
+
+ return true;
+}
+
+/*
+ * Regex::jited:
+ *
+ * Note: We can't tell if the regex has been JITed for a particular mode,
+ * just if it has been JITed at all.
+ *
+ * Returns: %true iff the regex has been JITed
+ */
+bool
+Regex::jited() const noexcept
+{
+ PCRE2_SIZE s;
+ int r = pcre2_pattern_info_8(code(), PCRE2_INFO_JITSIZE, &s);
+
+ return r == 0 && s != 0;
+}
+
+/*
+ * Regex::has_compile_flags:
+ * @flags:
+ *
+ * Returns: true if the compile flags include all of @flags.
+ */
+bool
+Regex::has_compile_flags(uint32_t flags) const noexcept
+{
+ uint32_t v;
+ int r = pcre2_pattern_info_8(code(), PCRE2_INFO_ARGOPTIONS, &v);
+
+ return r == 0 ? ((v & flags) == flags) : false;
+}
+
+/*
+ * Regex::substitute:
+ * @subject: the subject string
+ * @replacement: the replacement string
+ * @flags: PCRE2 match flags
+ * @error: (nullable): return location for a #GError, or %NULL
+ *
+ * See man:pcre2api(3) on pcre2_substitute() for more information.
+ *
+ * Returns: (transfer full): the substituted string, or %NULL
+ * if an error occurred
+ */
+char*
+Regex::substitute(char const* subject,
+ char const* replacement,
+ uint32_t flags,
+ GError** error) const noexcept
+{
+ assert(subject != nullptr);
+ assert(replacement != nullptr);
+ assert (!(flags & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH));
+
+ uint8_t outbuf[2048];
+ PCRE2_SIZE outlen = sizeof(outbuf);
+ int r = pcre2_substitute_8(code(),
+ (PCRE2_SPTR8)subject, PCRE2_ZERO_TERMINATED,
+ 0 /* start offset */,
+ flags | PCRE2_SUBSTITUTE_OVERFLOW_LENGTH,
+ nullptr /* match data */,
+ nullptr /* match context */,
+ (PCRE2_SPTR8)replacement, PCRE2_ZERO_TERMINATED,
+ (PCRE2_UCHAR8*)outbuf, &outlen);
+
+ if (r >= 0)
+ return g_strndup((char*)outbuf, outlen);
+
+ if (r == PCRE2_ERROR_NOMEMORY) {
+ /* The buffer was not large enough; allocated a buffer of the
+ * required size and try again. Note that @outlen as returned
+ * from pcre2_substitute_8() above includes the trailing \0.
+ */
+ uint8_t *outbuf2 = (uint8_t*)g_malloc(outlen);
+ r = pcre2_substitute_8(code(),
+ (PCRE2_SPTR8)subject, PCRE2_ZERO_TERMINATED,
+ 0 /* start offset */,
+ flags | PCRE2_SUBSTITUTE_OVERFLOW_LENGTH,
+ nullptr /* match data */,
+ nullptr /* match context */,
+ (PCRE2_SPTR8)replacement, PCRE2_ZERO_TERMINATED,
+ (PCRE2_UCHAR8*)outbuf2, &outlen);
+ if (r >= 0)
+ return (char*)outbuf2;
+
+ g_free(outbuf2);
+ }
+
+ set_gerror_from_pcre_error(r, error);
+ return nullptr;
+}
+
+} // namespace base
+} // namespace vte
diff --git a/src/regex.hh b/src/regex.hh
new file mode 100644
index 00000000..4cb92a04
--- /dev/null
+++ b/src/regex.hh
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2015, 2019 Christian Persch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <memory>
+
+#include <glib.h>
+
+#include "vtepcre2.h"
+
+namespace vte {
+
+namespace base {
+
+class Regex {
+public:
+ enum class Purpose {
+ eMatch,
+ eSearch,
+ };
+
+ static bool check_pcre_config_unicode(GError** error);
+ static bool check_pcre_config_jit(void);
+ static Regex* compile(Purpose purpose,
+ char const* pattern,
+ ssize_t pattern_length,
+ uint32_t flags,
+ GError** error);
+
+private:
+ mutable volatile int m_refcount{1};
+ std::unique_ptr<pcre2_code_8, decltype(&pcre2_code_free_8)> m_code;
+ Purpose m_purpose;
+
+public:
+ Regex(pcre2_code_8* code,
+ Purpose purpose) noexcept :
+ m_code{code, &pcre2_code_free_8},
+ m_purpose{purpose}
+ { }
+
+ Regex(Regex const&) = delete;
+ Regex(Regex&&) = delete;
+ Regex operator=(Regex const&) = delete;
+ Regex operator=(Regex&&) = delete;
+
+ Regex* ref() noexcept;
+ void unref() noexcept;
+
+ pcre2_code_8* code() const noexcept { return m_code.get(); }
+ constexpr inline bool has_purpose(Purpose purpose) const noexcept { return m_purpose == purpose; }
+ bool has_compile_flags(uint32_t flags ) const noexcept;
+
+ bool jit(uint32_t flags,
+ GError** error) noexcept;
+
+ bool jited() const noexcept;
+
+ char* substitute(char const* subject,
+ char const* replacement,
+ uint32_t flags,
+ GError** error) const noexcept;
+
+}; // class Regex
+
+} // namespace base
+
+} // namespace vte
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index c47a5c4a..bbaac158 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -1925,8 +1925,8 @@ vte_terminal_match_add_gregex(VteTerminal *terminal,
{
g_return_val_if_fail(gregex != NULL, -1);
- auto regex = _vte_regex_new_gregex(VteRegexPurpose::match, gregex);
- if (regex == NULL)
+ auto regex = _vte_regex_new_gregex(vte::base::Regex::Purpose::eMatch, gregex);
+ if (regex == nullptr)
return -1;
auto rv = vte_terminal_match_add_regex(terminal, regex,
@@ -1958,8 +1958,8 @@ vte_terminal_match_add_regex(VteTerminal *terminal,
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, VteRegexPurpose::match), -1);
- g_warn_if_fail(_vte_regex_get_compile_flags(regex) & PCRE2_MULTILINE);
+ 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);
@@ -2084,8 +2084,8 @@ vte_terminal_event_check_regex_simple(VteTerminal *terminal,
g_return_val_if_fail(event != NULL, FALSE);
g_return_val_if_fail(regexes != NULL || n_regexes == 0, FALSE);
for (gsize i = 0; i < n_regexes; i++) {
- g_return_val_if_fail(_vte_regex_has_purpose(regexes[i], VteRegexPurpose::match), -1);
- g_warn_if_fail(_vte_regex_get_compile_flags(regexes[i]) & PCRE2_MULTILINE);
+ g_return_val_if_fail(_vte_regex_has_purpose(regexes[i], vte::base::Regex::Purpose::eMatch),
-1);
+ g_warn_if_fail(_vte_regex_has_multiline_compile_flag(regexes[i]));
}
g_return_val_if_fail(matches != NULL, FALSE);
@@ -2263,8 +2263,8 @@ vte_terminal_search_set_regex (VteTerminal *terminal,
guint32 flags)
{
g_return_if_fail(VTE_IS_TERMINAL(terminal));
- g_return_if_fail(regex == nullptr || _vte_regex_has_purpose(regex, VteRegexPurpose::search));
- g_warn_if_fail(regex == nullptr || _vte_regex_get_compile_flags(regex) & PCRE2_MULTILINE);
+ 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(regex, flags);
}
@@ -2303,7 +2303,7 @@ vte_terminal_search_set_gregex (VteTerminal *terminal,
{
VteRegex *regex = nullptr;
if (gregex)
- regex = _vte_regex_new_gregex(VteRegexPurpose::search, gregex);
+ regex = _vte_regex_new_gregex(vte::base::Regex::Purpose::eSearch, gregex);
vte_terminal_search_set_regex(terminal, regex,
_vte_regex_translate_gregex_match_flags(gflags));
diff --git a/src/vtepcre2.h b/src/vtepcre2.h
index ddca5ff6..1094edf0 100644
--- a/src/vtepcre2.h
+++ b/src/vtepcre2.h
@@ -19,9 +19,10 @@
#define PCRE2_CODE_UNIT_WIDTH 0
#include <pcre2.h>
+#include <cstdint>
/* Assert compatibility of PCRE2 and GLib types */
-G_STATIC_ASSERT(sizeof(PCRE2_UCHAR8) == sizeof (guint8));
-G_STATIC_ASSERT(sizeof(PCRE2_SIZE) == sizeof (gsize));
-G_STATIC_ASSERT(PCRE2_UNSET == (gsize)-1);
-G_STATIC_ASSERT(PCRE2_ZERO_TERMINATED == (gsize)-1);
+static_assert(sizeof(PCRE2_UCHAR8) == sizeof (uint8_t), "PCRE2_UCHAR2 has wrong size");
+static_assert(sizeof(PCRE2_SIZE) == sizeof (size_t), "PCRE2_SIZE has wrong size");
+static_assert(PCRE2_UNSET == (size_t)-1, "PCRE2_UNSET has wrong value");
+static_assert(PCRE2_ZERO_TERMINATED == (size_t)-1, "PCRE2_ZERO_TERMINATED has wrong value");
diff --git a/src/vteregex.cc b/src/vteregex.cc
index b06e5e7d..75f33e7b 100644
--- a/src/vteregex.cc
+++ b/src/vteregex.cc
@@ -29,17 +29,11 @@
#include "vteregex.h"
#include "vtepcre2.h"
+#include "regex.hh"
#include "vteregexinternal.hh"
-struct _VteRegex {
- volatile int ref_count;
- VteRegexPurpose purpose;
- pcre2_code_8 *code;
-};
-
-#define DEFAULT_COMPILE_OPTIONS (PCRE2_UTF)
-#define JIT_OPTIONS (PCRE2_JIT_COMPLETE)
-#define DEFAULT_MATCH_OPTIONS (0)
+#define WRAPPER(impl) (reinterpret_cast<VteRegex*>(impl))
+#define IMPL(wrapper) (reinterpret_cast<vte::base::Regex*>(wrapper))
/* GRegex translation */
@@ -68,41 +62,7 @@ translate_flags(FlagTranslation const* const table,
*pflagsptr = pflags;
}
-/* internal */
-
-static VteRegex *
-regex_new(pcre2_code_8 *code,
- VteRegexPurpose purpose)
-{
- VteRegex *regex;
-
- regex = g_slice_new(VteRegex);
- regex->ref_count = 1;
- regex->purpose = purpose;
- regex->code = code;
-
- return regex;
-}
-
-static void
-regex_free(VteRegex *regex)
-{
- pcre2_code_free_8(regex->code);
- g_slice_free(VteRegex, regex);
-}
-
-static gboolean
-set_gerror_from_pcre_error(int errcode,
- GError **error)
-{
- PCRE2_UCHAR8 buf[128];
- int n;
-
- n = pcre2_get_error_message_8(errcode, buf, sizeof (buf));
- g_assert(n >= 0);
- g_set_error_literal(error, VTE_REGEX_ERROR, errcode, (const char*)buf);
- return FALSE;
-}
+/* Type registration */
#pragma GCC diagnostic push
#if defined(__GNUC__) && !defined(__clang__)
@@ -125,11 +85,9 @@ G_DEFINE_QUARK(vte-regex-error, vte_regex_error)
VteRegex *
vte_regex_ref(VteRegex *regex)
{
- g_return_val_if_fail (regex, NULL);
-
- g_atomic_int_inc (®ex->ref_count);
+ g_return_val_if_fail(regex != nullptr, nullptr);
- return regex;
+ return WRAPPER(IMPL(regex)->ref());
}
/**
@@ -142,86 +100,26 @@ vte_regex_ref(VteRegex *regex)
* Returns: %NULL
*/
VteRegex *
-vte_regex_unref(VteRegex *regex)
-{
- g_return_val_if_fail (regex, NULL);
-
- if (g_atomic_int_dec_and_test (®ex->ref_count))
- regex_free (regex);
-
- return NULL;
-}
-
-static gboolean
-check_pcre_config_unicode(GError** error)
+vte_regex_unref(VteRegex* regex)
{
- /* Check library compatibility */
- guint32 v;
- int r = pcre2_config_8(PCRE2_CONFIG_UNICODE, &v);
- if (r != 0 || v != 1) {
- g_set_error(error, VTE_REGEX_ERROR, VTE_REGEX_ERROR_INCOMPATIBLE,
- "PCRE2 library was built without unicode support");
- return FALSE;
- }
+ g_return_val_if_fail(regex != nullptr, nullptr);
- return TRUE;
+ IMPL(regex)->unref();
+ return nullptr;
}
-static gboolean
-check_pcre_config_jit(void)
+static VteRegex*
+vte_regex_new(vte::base::Regex::Purpose purpose,
+ char const* pattern,
+ ssize_t pattern_length,
+ uint32_t flags,
+ GError** error)
{
- static gboolean warned = FALSE;
-
- char s[256];
- int r = pcre2_config_8(PCRE2_CONFIG_JITTARGET, &s);
- if (r == PCRE2_ERROR_BADOPTION && !warned) {
- g_printerr("PCRE2 library was built without JIT support\n");
- warned = TRUE;
- }
-
- return r >= 1;
+ return WRAPPER(vte::base::Regex::compile(purpose, pattern, pattern_length, flags, error));
}
-static VteRegex *
-vte_regex_new(VteRegexPurpose purpose,
- const char *pattern,
- gssize pattern_length,
- guint32 flags,
- GError **error)
-{
- pcre2_code_8 *code;
- int errcode;
- PCRE2_SIZE erroffset;
-
- g_return_val_if_fail(pattern != NULL, NULL);
- g_return_val_if_fail(pattern_length >= -1, NULL);
- g_return_val_if_fail(error == NULL || *error == NULL, NULL);
-
- if (!check_pcre_config_unicode(error))
- return FALSE;
-
- code = pcre2_compile_8((PCRE2_SPTR8)pattern,
- pattern_length >= 0 ? pattern_length : PCRE2_ZERO_TERMINATED,
- (uint32_t)flags |
- PCRE2_UTF |
- (flags & PCRE2_UTF ? PCRE2_NO_UTF_CHECK : 0) |
- PCRE2_NEVER_BACKSLASH_C |
- PCRE2_USE_OFFSET_LIMIT,
- &errcode, &erroffset,
- NULL);
-
- if (code == nullptr) {
- set_gerror_from_pcre_error(errcode, error);
- g_prefix_error(error, "Failed to compile pattern to regex at offset %" G_GSIZE_FORMAT ":",
- erroffset);
- return NULL;
- }
-
- return regex_new(code, purpose);
-}
-
-VteRegex *
-_vte_regex_new_gregex(VteRegexPurpose purpose,
+VteRegex*
+_vte_regex_new_gregex(vte::base::Regex::Purpose purpose,
GRegex *gregex)
{
g_return_val_if_fail(gregex != NULL, NULL);
@@ -250,9 +148,9 @@ _vte_regex_new_gregex(VteRegexPurpose purpose,
g_warning("Incompatible GRegex compile flags left untranslated: %08x", gflags);
}
- GError *err = nullptr;
+ GError* err = nullptr;
auto regex = vte_regex_new(purpose, g_regex_get_pattern(gregex), -1, pflags, &err);
- if (regex == NULL) {
+ if (regex == nullptr) {
g_warning("Failed to translated GRegex: %s", err->message);
g_error_free(err);
}
@@ -306,7 +204,7 @@ vte_regex_new_for_match(const char *pattern,
guint32 flags,
GError **error)
{
- return vte_regex_new(VteRegexPurpose::match,
+ return vte_regex_new(vte::base::Regex::Purpose::eMatch,
pattern, pattern_length,
flags,
error);
@@ -337,62 +235,12 @@ vte_regex_new_for_search(const char *pattern,
guint32 flags,
GError **error)
{
- return vte_regex_new(VteRegexPurpose::search,
+ return vte_regex_new(vte::base::Regex::Purpose::eSearch,
pattern, pattern_length,
flags,
error);
}
-#if 0
-/*
- * vte_regex_new_pcre:
- * @code: a #pcre2_code_8
- *
- * Creates a new #VteRegex for @code. @code must have been compiled with
- * %PCRE2_UTF and %PCRE2_NEVER_BACKSLASH_C.
- *
- * Returns: (transfer full): a newly created #VteRegex, or %NULL if VTE
- * was not compiled with PCRE2 support.
- */
-VteRegex *
-vte_regex_new_pcre(pcre2_code_8 *code,
- GError **error)
-{
- guint32 flags;
-
- g_return_val_if_fail(code != NULL, NULL);
- g_return_val_if_fail(error == NULL || *error == NULL, NULL);
-
- pcre2_pattern_info_8(code, PCRE2_INFO_ALLOPTIONS, &flags);
- g_return_val_if_fail(flags & PCRE2_UTF, NULL);
- g_return_val_if_fail(flags & PCRE2_NEVER_BACKSLASH_C, NULL);
-
- return regex_new(code);
-}
-#endif
-
-gboolean
-_vte_regex_has_purpose(VteRegex *regex,
- VteRegexPurpose purpose)
-{
- return regex->purpose == purpose;
-}
-
-/*
- * _vte_regex_get_pcre:
- * @regex: a #VteRegex
- *
- *
- * Returns: the #pcre2_code_8 from @regex
- */
-const pcre2_code_8 *
-_vte_regex_get_pcre(VteRegex const* regex)
-{
- g_return_val_if_fail(regex != NULL, NULL);
-
- return regex->code;
-}
-
/**
* vte_regex_jit:
* @regex: a #VteRegex
@@ -407,55 +255,42 @@ vte_regex_jit(VteRegex *regex,
guint flags,
GError **error)
{
- int r;
-
- g_return_val_if_fail(regex != NULL, FALSE);
+ g_return_val_if_fail(regex != nullptr, false);
- if (!check_pcre_config_jit())
- return TRUE;
+ return IMPL(regex)->jit(flags, error);
+}
- r = pcre2_jit_compile_8(regex->code, flags);
- if (r < 0)
- return set_gerror_from_pcre_error(r, error);
+bool
+_vte_regex_has_purpose(VteRegex *regex,
+ vte::base::Regex::Purpose purpose)
+{
+ g_return_val_if_fail(regex != nullptr, false);
- return TRUE;
+ return IMPL(regex)->has_purpose(purpose);
}
-/*
- * _vte_regex_get_jited:
- *
- * Note: We can't tell if the regex has been JITed for a particular mode,
- * just if it has been JITed at all.
- *
- * Returns: %TRUE iff the regex has been JITed
- */
-gboolean
-_vte_regex_get_jited(VteRegex *regex)
+const pcre2_code_8 *
+_vte_regex_get_pcre(VteRegex* regex)
{
- PCRE2_SIZE s;
- int r;
+ g_return_val_if_fail(regex != nullptr, nullptr);
- g_return_val_if_fail(regex != NULL, FALSE);
+ return IMPL(regex)->code();
+}
- r = pcre2_pattern_info_8(regex->code, PCRE2_INFO_JITSIZE, &s);
+bool
+_vte_regex_get_jited(VteRegex *regex)
+{
+ g_return_val_if_fail(regex != nullptr, false);
- return r == 0 && s != 0;
+ return IMPL(regex)->jited();
}
-/*
- * _vte_regex_get_compile_flags:
- *
- * Returns: the PCRE2 flags used to compile @regex
- */
-guint32
-_vte_regex_get_compile_flags(VteRegex *regex)
+bool
+_vte_regex_has_multiline_compile_flag(VteRegex *regex)
{
g_return_val_if_fail(regex != nullptr, 0);
- uint32_t v;
- int r = pcre2_pattern_info_8(regex->code, PCRE2_INFO_ARGOPTIONS, &v);
-
- return r == 0 ? v : 0u;
+ return IMPL(regex)->has_compile_flags(PCRE2_MULTILINE);
}
/**
@@ -485,40 +320,5 @@ vte_regex_substitute(VteRegex *regex,
g_return_val_if_fail(replacement != nullptr, nullptr);
g_return_val_if_fail (!(flags & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH), nullptr);
- uint8_t outbuf[2048];
- PCRE2_SIZE outlen = sizeof(outbuf);
- int r = pcre2_substitute_8(_vte_regex_get_pcre(regex),
- (PCRE2_SPTR8)subject, PCRE2_ZERO_TERMINATED,
- 0 /* start offset */,
- flags | PCRE2_SUBSTITUTE_OVERFLOW_LENGTH,
- nullptr /* match data */,
- nullptr /* match context */,
- (PCRE2_SPTR8)replacement, PCRE2_ZERO_TERMINATED,
- (PCRE2_UCHAR8*)outbuf, &outlen);
-
- if (r >= 0)
- return g_strndup((char*)outbuf, outlen);
-
- if (r == PCRE2_ERROR_NOMEMORY) {
- /* The buffer was not large enough; allocated a buffer of the
- * required size and try again. Note that @outlen as returned
- * from pcre2_substitute_8() above includes the trailing \0.
- */
- uint8_t *outbuf2 = (uint8_t*)g_malloc(outlen);
- r = pcre2_substitute_8(_vte_regex_get_pcre(regex),
- (PCRE2_SPTR8)subject, PCRE2_ZERO_TERMINATED,
- 0 /* start offset */,
- flags | PCRE2_SUBSTITUTE_OVERFLOW_LENGTH,
- nullptr /* match data */,
- nullptr /* match context */,
- (PCRE2_SPTR8)replacement, PCRE2_ZERO_TERMINATED,
- (PCRE2_UCHAR8*)outbuf2, &outlen);
- if (r >= 0)
- return (char*)outbuf2;
-
- g_free(outbuf2);
- }
-
- set_gerror_from_pcre_error(r, error);
- return nullptr;
+ return IMPL(regex)->substitute(subject, replacement, flags, error);
}
diff --git a/src/vteregexinternal.hh b/src/vteregexinternal.hh
index 1b4a78fd..d5b744ec 100644
--- a/src/vteregexinternal.hh
+++ b/src/vteregexinternal.hh
@@ -17,22 +17,19 @@
#pragma once
-enum class VteRegexPurpose {
- match,
- search
-};
+#include "regex.hh"
-gboolean _vte_regex_has_purpose(VteRegex *regex,
- VteRegexPurpose purpose);
+bool _vte_regex_has_purpose(VteRegex* regex,
+ vte::base::Regex::Purpose purpose);
-gboolean _vte_regex_get_jited(VteRegex *regex);
+bool _vte_regex_get_jited(VteRegex* regex);
-guint32 _vte_regex_get_compile_flags (VteRegex *regex);
+bool _vte_regex_has_multiline_compile_flag(VteRegex* regex);
-const pcre2_code_8 *_vte_regex_get_pcre (VteRegex const* regex);
+const pcre2_code_8 *_vte_regex_get_pcre(VteRegex* regex);
/* GRegex translation */
-VteRegex *_vte_regex_new_gregex(VteRegexPurpose purpose,
- GRegex *gregex);
+VteRegex* _vte_regex_new_gregex(vte::base::Regex::Purpose purpose,
+ GRegex* gregex);
-guint32 _vte_regex_translate_gregex_match_flags(GRegexMatchFlags flags);
+uint32_t _vte_regex_translate_gregex_match_flags(GRegexMatchFlags flags);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]