[vte] lib: Add GError convenience class
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] lib: Add GError convenience class
- Date: Sun, 1 Dec 2019 21:58:50 +0000 (UTC)
commit f3f7fd4e1b550e22fd6f92d9c5579d23ade81f4c
Author: Christian Persch <chpe src gnome org>
Date: Sun Dec 1 22:58:51 2019 +0100
lib: Add GError convenience class
src/app/app.cc | 90 ++++++++++++++++++++++++-----------------------------
src/app/meson.build | 2 +-
src/decoder-cat.cc | 8 ++---
src/glib-glue.hh | 59 +++++++++++++++++++++++++++++++++++
src/meson.build | 14 ++++++---
src/parser-cat.cc | 8 ++---
src/pty.cc | 15 ++++-----
src/vtegtk.cc | 14 +++------
8 files changed, 130 insertions(+), 80 deletions(-)
---
diff --git a/src/app/app.cc b/src/app/app.cc
index 495e3f41..0a66ad00 100644
--- a/src/app/app.cc
+++ b/src/app/app.cc
@@ -32,6 +32,7 @@
#include <cairo/cairo-gobject.h>
#include <vte/vte.h>
#include "vtepcre2.h"
+#include "glib-glue.hh"
#include <algorithm>
@@ -512,12 +513,11 @@ static void
jit_regex(VteRegex* regex,
char const* pattern)
{
- GError *err = nullptr;
- if (!vte_regex_jit(regex, PCRE2_JIT_COMPLETE, &err) ||
- !vte_regex_jit(regex, PCRE2_JIT_PARTIAL_SOFT, &err)) {
- if (!g_error_matches(err, VTE_REGEX_ERROR, -45 /* PCRE2_ERROR_JIT_BADOPTION: JIT not
supported */))
- verbose_printerr("JITing regex \"%s\" failed: %s\n", pattern, err->message);
- g_error_free(err);
+ auto error = vte::glib::Error{};
+ if (!vte_regex_jit(regex, PCRE2_JIT_COMPLETE, error) ||
+ !vte_regex_jit(regex, PCRE2_JIT_PARTIAL_SOFT, error)) {
+ if (!error.matches(VTE_REGEX_ERROR, -45 /* PCRE2_ERROR_JIT_BADOPTION: JIT not supported */))
+ verbose_printerr("JITing regex \"%s\" failed: %s\n", pattern, error.message());
}
}
@@ -637,22 +637,20 @@ vteapp_search_popover_update_regex(VteappSearchPopover* popover)
popover->regex_pattern = nullptr;
if (search_text[0] != '\0') {
- GError* error = nullptr;
-
- auto regex = compile_regex_for_search(pattern, caseless, &error);
+ auto error = vte::glib::Error{};
+ auto regex = compile_regex_for_search(pattern, caseless, error);
vte_terminal_search_set_regex(popover->terminal, regex, 0);
if (regex != nullptr)
vte_regex_unref(regex);
- if (error == nullptr) {
+ if (error.error()) {
popover->has_regex = true;
popover->regex_pattern = pattern; /* adopt */
pattern = nullptr; /* adopted */
gtk_widget_set_tooltip_text(popover->search_entry, nullptr);
} else {
popover->has_regex = false;
- gtk_widget_set_tooltip_text(popover->search_entry, error->message);
- g_error_free(error);
+ gtk_widget_set_tooltip_text(popover->search_entry, error.message());
}
}
@@ -987,17 +985,17 @@ vteapp_window_add_dingus(VteappWindow* window,
char const* const* dingus)
{
for (auto i = 0; dingus[i] != nullptr; i++) {
- int tag = -1;
- GError* error = nullptr;
- auto regex = compile_regex_for_match(dingus[i], true, &error);
+ auto tag = int{-1};
+ auto error = vte::glib::Error{};
+ auto regex = compile_regex_for_match(dingus[i], true, error);
if (regex) {
tag = vte_terminal_match_add_regex(window->terminal, regex, 0);
vte_regex_unref(regex);
}
- if (error != nullptr) {
- verbose_printerr("Failed to compile regex \"%s\": %s\n", dingus[i], error->message);
- g_error_free(error);
+ if (error.error()) {
+ verbose_printerr("Failed to compile regex \"%s\": %s\n",
+ dingus[i], error.message());
}
if (tag != -1)
@@ -1298,22 +1296,20 @@ vteapp_window_fork(VteappWindow* window,
static void
vteapp_window_launch(VteappWindow* window)
{
- bool rv;
- GError* err = nullptr;
+ auto rv = bool{};
+ auto error = vte::glib::Error{};
if (options.exec_argv != nullptr)
- rv = vteapp_window_launch_argv(window, options.exec_argv, &err);
+ rv = vteapp_window_launch_argv(window, options.exec_argv, error);
else if (options.command != nullptr)
- rv = vteapp_window_launch_commandline(window, options.command, &err);
+ rv = vteapp_window_launch_commandline(window, options.command, error);
else if (!options.no_shell)
- rv = vteapp_window_launch_shell(window, &err);
+ rv = vteapp_window_launch_shell(window, error);
else
- rv = vteapp_window_fork(window, &err);
+ rv = vteapp_window_fork(window, error);
- if (!rv) {
- verbose_printerr("Error launching: %s\n", err->message);
- g_error_free(err);
- }
+ if (!rv)
+ verbose_printerr("Error launching: %s\n", error.message());
}
static void
@@ -1460,9 +1456,9 @@ vteapp_window_show_context_menu(VteappWindow* window,
static const char extra_pattern[] = "(\\d+)\\s*(\\w+)";
char* extra_match = nullptr;
char *extra_subst = nullptr;
- GError* err = nullptr;
- auto regex = compile_regex_for_match(extra_pattern, false, &err);
- g_assert_no_error(err);
+ auto error = vte::glib::Error{};
+ auto regex = compile_regex_for_match(extra_pattern, false, error);
+ error.assert_no_error();
vte_terminal_event_check_regex_simple(window->terminal, event,
®ex, 1, 0,
&extra_match);
@@ -1471,9 +1467,8 @@ vteapp_window_show_context_menu(VteappWindow* window,
(extra_subst = vte_regex_substitute(regex, extra_match, "$2 $1",
PCRE2_SUBSTITUTE_EXTENDED |
PCRE2_SUBSTITUTE_GLOBAL,
- &err)) == nullptr) {
- verbose_printerr("Substitution failed: %s\n", err->message);
- g_error_free(err);
+ error)) == nullptr) {
+ verbose_printerr("Substitution failed: %s\n", error.message());
}
vte_regex_unref(regex);
@@ -1546,22 +1541,20 @@ window_child_exited_cb(VteTerminal* term,
if (options.output_filename != nullptr) {
auto file = g_file_new_for_commandline_arg(options.output_filename);
-
- GError* err = nullptr;
- auto stream = g_file_replace(file, nullptr, false, G_FILE_CREATE_NONE, nullptr, &err);
+ auto error = vte::glib::Error{};
+ auto stream = g_file_replace(file, nullptr, false, G_FILE_CREATE_NONE, nullptr, error);
g_object_unref(file);
if (stream != nullptr) {
vte_terminal_write_contents_sync(window->terminal,
G_OUTPUT_STREAM(stream),
VTE_WRITE_DEFAULT,
- nullptr, &err);
+ nullptr, error);
g_object_unref(stream);
}
- if (err != nullptr) {
+ if (error.error()) {
verbose_printerr("Failed to write output to \"%s\": %s\n",
- options.output_filename, err->message);
- g_error_free(err);
+ options.output_filename, error.message());
}
}
@@ -1870,11 +1863,9 @@ vteapp_window_constructed(GObject *object)
}
if (options.encoding != nullptr) {
- GError* err = nullptr;
- if (!vte_terminal_set_encoding(window->terminal, options.encoding, &err)) {
- g_printerr("Failed to set encoding: %s\n", err->message);
- g_error_free(err);
- }
+ auto error = vte::glib::Error{};
+ if (!vte_terminal_set_encoding(window->terminal, options.encoding, error))
+ g_printerr("Failed to set encoding: %s\n", error.message());
}
if (options.word_char_exceptions != nullptr)
@@ -2159,10 +2150,9 @@ main(int argc,
g_set_prgname("Terminal");
g_set_application_name("Terminal");
- GError* error = nullptr;
- if (!options.parse_argv(argc, argv, &error)) {
- g_printerr("Error parsing arguments: %s\n", error->message);
- g_error_free(error);
+ auto error = vte::glib::Error{};
+ if (!options.parse_argv(argc, argv, error)) {
+ g_printerr("Error parsing arguments: %s\n", error.message());
return EXIT_FAILURE;
}
diff --git a/src/app/meson.build b/src/app/meson.build
index 03068f32..1bed9160 100644
--- a/src/app/meson.build
+++ b/src/app/meson.build
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <https://www.gnu.org/licenses/>.
-app_sources = files(
+app_sources = glib_glue_sources + files(
'app.cc',
)
diff --git a/src/decoder-cat.cc b/src/decoder-cat.cc
index 7d34fd91..c3bd83c5 100644
--- a/src/decoder-cat.cc
+++ b/src/decoder-cat.cc
@@ -32,6 +32,7 @@
#include <string>
#include "debug.h"
+#include "glib-glue.hh"
#include "icu-decoder.hh"
#include "icu-glue.hh"
#include "utf8.hh"
@@ -518,10 +519,9 @@ main(int argc,
_vte_debug_init();
auto options = Options{};
- GError* err{nullptr};
- if (!options.parse(argc, argv, &err)) {
- g_printerr("Failed to parse arguments: %s\n", err->message);
- g_error_free(err);
+ auto error = vte::glib::Error{};
+ if (!options.parse(argc, argv, error)) {
+ g_printerr("Failed to parse arguments: %s\n", error.message());
return EXIT_FAILURE;
}
diff --git a/src/glib-glue.hh b/src/glib-glue.hh
new file mode 100644
index 00000000..c55ef016
--- /dev/null
+++ b/src/glib-glue.hh
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 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 <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <memory>
+
+#include <glib.h>
+
+namespace vte::glib {
+
+class Error {
+public:
+ Error() = default;
+ ~Error() { reset(); }
+
+ Error(Error const&) = delete;
+ Error(Error&&) = delete;
+ Error& operator=(Error const&) = delete;
+ Error& operator=(Error&&) = delete;
+
+ operator GError* () noexcept { return m_error; }
+ operator GError** () noexcept { return &m_error; }
+
+ auto error() const noexcept { return m_error != nullptr; }
+ auto domain() const noexcept { return error() ? m_error->domain : 0; }
+ auto code() const noexcept { return error() ? m_error->code : -1; }
+ auto message() const noexcept { return error() ? m_error->message : nullptr; }
+
+ void assert_no_error() const noexcept { g_assert_no_error(m_error); }
+
+ bool matches(GQuark domain, int code) const noexcept
+ {
+ return error() && g_error_matches(m_error, domain, code);
+ }
+
+ void reset() noexcept { g_clear_error(&m_error); }
+
+ bool propagate(GError** error) noexcept { *error = m_error; m_error = nullptr; return false; }
+
+private:
+ GError* m_error{nullptr};
+};
+
+} // namespace vte::glib
diff --git a/src/meson.build b/src/meson.build
index 78ee6341..428afac6 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -28,6 +28,10 @@ debug_sources = files(
'debug.h',
)
+glib_glue_sources = files(
+ 'glib-glue.hh',
+)
+
icu_sources = files(
'icu-converter.cc',
'icu-converter.hh',
@@ -80,7 +84,7 @@ utf8_sources = files(
'utf8.hh',
)
-libvte_common_sources = debug_sources + modes_sources + parser_sources + pty_sources + regex_sources +
utf8_sources + files(
+libvte_common_sources = debug_sources + glib_glue_sources + modes_sources + parser_sources + pty_sources +
regex_sources + utf8_sources + files(
'attr.hh',
'bidi.cc',
'bidi.hh',
@@ -239,8 +243,8 @@ endif
# decoder cat
-decoder_cat_sources = icu_sources + utf8_sources + debug_sources + files(
- 'decoder-cat.cc'
+decoder_cat_sources = glib_glue_sources + icu_sources + utf8_sources + debug_sources + files(
+ 'decoder-cat.cc',
)
decoder_cat = executable(
@@ -254,8 +258,8 @@ decoder_cat = executable(
# parser cat
-parser_cat_sources = parser_sources + utf8_sources + debug_sources + files(
- 'parser-cat.cc'
+parser_cat_sources = glib_glue_sources + parser_sources + utf8_sources + debug_sources + files(
+ 'parser-cat.cc',
)
parser_cat = executable(
diff --git a/src/parser-cat.cc b/src/parser-cat.cc
index d0091978..083bc58a 100644
--- a/src/parser-cat.cc
+++ b/src/parser-cat.cc
@@ -31,6 +31,7 @@
#include <string>
#include "debug.h"
+#include "glib-glue.hh"
#include "parser.hh"
#include "parser-glue.hh"
#include "utf8.hh"
@@ -904,10 +905,9 @@ main(int argc,
_vte_debug_init();
Options options{};
- GError* err = nullptr;
- if (!options.parse(argc, argv, &err)) {
- g_printerr("Failed to parse arguments: %s\n", err->message);
- g_error_free(err);
+ auto error = vte::glib::Error{};
+ if (!options.parse(argc, argv, error)) {
+ g_printerr("Failed to parse arguments: %s\n", error.message());
return EXIT_FAILURE;
}
diff --git a/src/pty.cc b/src/pty.cc
index 97f0fbe0..c17600c0 100644
--- a/src/pty.cc
+++ b/src/pty.cc
@@ -72,6 +72,8 @@
#include <glib/gi18n-lib.h>
+#include "glib-glue.hh"
+
/* NSIG isn't in POSIX, so if it doesn't exist use this here. See bug #759196 */
#ifndef NSIG
#define NSIG (8 * sizeof(sigset_t))
@@ -389,7 +391,6 @@ Pty::spawn(char const* directory,
bool inherit_envv;
char** envp2;
int i;
- GError* err{nullptr};
GPollFD pollfd;
if (cancellable && !g_cancellable_make_pollfd(cancellable, &pollfd)) {
@@ -431,6 +432,7 @@ Pty::spawn(char const* directory,
m_extra_child_setup.func = child_setup_func;
m_extra_child_setup.data = child_setup_data;
+ auto err = vte::glib::Error{};
ret = vte_spawn_async_with_pipes_cancellable(directory,
argv, envp2,
(GSpawnFlags)spawn_flags,
@@ -440,12 +442,12 @@ Pty::spawn(char const* directory,
nullptr, nullptr, nullptr,
timeout,
cancellable ? &pollfd : nullptr,
- &err);
+ err);
if (!ret &&
directory != nullptr &&
- g_error_matches(err, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR)) {
+ err.matches(G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR)) {
/* try spawning in our working directory */
- g_clear_error(&err);
+ err.reset();
ret = vte_spawn_async_with_pipes_cancellable(nullptr,
argv, envp2,
(GSpawnFlags)spawn_flags,
@@ -455,7 +457,7 @@ Pty::spawn(char const* directory,
nullptr, nullptr, nullptr,
timeout,
cancellable ? &pollfd : nullptr,
- &err);
+ err);
}
g_strfreev (envp2);
@@ -469,8 +471,7 @@ Pty::spawn(char const* directory,
if (ret)
return true;
- g_propagate_error(error, err);
- return false;
+ return err.propagate(error);
}
/*
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index 418564ef..35eee92f 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -48,6 +48,7 @@
#include "vte/vtetypebuiltins.h"
#include "debug.h"
+#include "glib-glue.hh"
#include "marshal.h"
#include "reaper.hh"
#include "vtedefines.hh"
@@ -2792,8 +2793,8 @@ spawn_async_cb (GObject *source,
VtePty *pty = VTE_PTY(source);
GPid pid = -1;
- GError *error = nullptr;
- vte_pty_spawn_finish(pty, result, &pid, &error);
+ auto error = vte::glib::Error{};
+ vte_pty_spawn_finish(pty, result, &pid, error);
/* Now get a ref to the terminal */
VteTerminal* terminal = (VteTerminal*)g_weak_ref_get(&data->wref);
@@ -2828,9 +2829,6 @@ spawn_async_cb (GObject *source,
}
}
- if (error)
- g_error_free(error);
-
spawn_async_callback_data_free(data);
if (terminal != nullptr)
@@ -2917,15 +2915,13 @@ vte_terminal_spawn_async(VteTerminal *terminal,
g_return_if_fail(!child_setup_data_destroy || child_setup_data);
g_return_if_fail(cancellable == nullptr || G_IS_CANCELLABLE (cancellable));
- GError *error = NULL;
- VtePty* pty = vte_terminal_pty_new_sync(terminal, pty_flags, cancellable, &error);
+ auto error = vte::glib::Error{};
+ auto pty = vte_terminal_pty_new_sync(terminal, pty_flags, cancellable, error);
if (pty == nullptr) {
if (child_setup_data_destroy)
child_setup_data_destroy(child_setup_data);
callback(terminal, -1, error, user_data);
-
- g_error_free(error);
return;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]