[retro-gtk/auto-goodness: 33/36] Add error handling helpers



commit 783d05b794741dd6d06a1de1afe342c901a90d26
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Mon Jan 27 10:19:26 2020 +0100

    Add error handling helpers
    
    Add RetroError, retro_error_ensure_free(), retro_throw_if_fail() and
    retro_throw_val_if_fail() to streamline error handling.

 shared/meson.build           |   1 +
 shared/retro-error-private.h | 126 +++++++++++++++++++++++++++++++++++++++++++
 shared/retro-error.c         |  13 +++++
 3 files changed, 140 insertions(+)
---
diff --git a/shared/meson.build b/shared/meson.build
index 0aec622..82054d7 100644
--- a/shared/meson.build
+++ b/shared/meson.build
@@ -9,6 +9,7 @@ shared_sources = files([
   'retro-controller-codes.c',
   'retro-controller-state.c',
   'retro-controller-type.c',
+  'retro-error.c',
   'retro-framebuffer.c',
   'retro-input.c',
   'retro-memfd.c',
diff --git a/shared/retro-error-private.h b/shared/retro-error-private.h
new file mode 100644
index 0000000..701f553
--- /dev/null
+++ b/shared/retro-error-private.h
@@ -0,0 +1,126 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#pragma once
+
+#if !defined(__RETRO_GTK_INSIDE__) && !defined(RETRO_GTK_COMPILATION)
+# error "Only <retro-gtk.h> can be included directly."
+#endif
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef GError RetroError;
+
+void retro_error_ensure_free (RetroError *error);
+
+/**
+ * retro_propagate_if_error:
+ * @dest: (out callee-allocates) (optional) (nullable): error return location
+ * @src: (transfer full): error to checkmove into the return location
+ *
+ * Verifies that the source error @src has not been set, which imlplies it is
+ * %NULL.
+ * If the function returns a value, use retro_propagate_val_if_error() instead.
+ *
+ * If @src is non-%NULL and @dest is %NULL, free @src; otherwise, moves @src
+ * into *@dest and return.
+ * The error variable @dest points to must be %NULL.
+ */
+#define retro_propagate_if_error(dest, src) \
+  G_STMT_START { \
+    if (G_UNLIKELY (src != NULL)) { \
+      g_propagate_error (dest, src); \
+      src = NULL; \
+      return; \
+    } \
+  } G_STMT_END
+
+/**
+ * retro_propagate_val_if_error:
+ * @dest: (out callee-allocates) (optional) (nullable): error return location
+ * @src: (transfer full): error to checkmove into the return location
+ * @val: the value to return from the current function
+ *       if the error is propagated
+ *
+ * Verifies that the source error @src has not been set, which imlplies it is
+ * %NULL.
+ * If the function does not return a value, use retro_propagate_if_error() instead.
+ *
+ * If @src is non-%NULL and @dest is %NULL, free @src; otherwise, moves @src
+ * into *@dest and return @val.
+ * The error variable @dest points to must be %NULL.
+ */
+#define retro_propagate_val_if_error(dest, src, val) \
+  G_STMT_START { \
+    if (G_UNLIKELY (src != NULL)) { \
+      g_propagate_error (dest, src); \
+      src = NULL; \
+      return (val); \
+    } \
+  } G_STMT_END
+
+/**
+ * retro_throw_if_fail:
+ * @err: (out callee-allocates) (optional): a return location for a #GError
+ * @expr: the expression to check
+ * @domain: error domain
+ * @code: error code
+ * @format: printf()-style format
+ * @...: args for @format
+ *
+ * Verifies that the expression @expr, usually representing an error condition,
+ * evaluates to %TRUE. If the function returns a value, use
+ * retro_throw_val_if_fail() instead.
+ *
+ * If @expr evaluates to %FALSE, an error condition has been found and the
+ * current function must throw it and return immediately.
+ *
+ * To throw this error, if @expr evaluates to %FALSE, does nothing if @err is
+ * %NULL; if @err is non-%NULL, then *@err must be %NULL. A new #GError is
+ * created and assigned to *@err. Then, the current function returns.
+ */
+#define retro_throw_if_fail(err, expr, domain, code, format, ...) \
+  G_STMT_START { \
+    if (G_LIKELY (expr)) { } \
+    else { \
+      g_set_error (err, domain, code, format __VA_OPT__(,) __VA_ARGS__); \
+      return; \
+    } \
+  } G_STMT_END
+
+/**
+ * retro_throw_val_if_fail:
+ * @err: (out callee-allocates) (optional): a return location for a #GError
+ * @expr: the expression to check
+ * @val: the value to return from the current function
+ *       if the expression is not true
+ * @domain: error domain
+ * @code: error code
+ * @format: printf()-style format
+ * @...: args for @format
+ *
+ * Verifies that the expression @expr, usually representing an error condition,
+ * evaluates to %TRUE. If the function does not return a value, use
+ * retro_throw_if_fail() instead.
+ *
+ * If @expr evaluates to %FALSE, an error condition has been found and the
+ * current function must throw it and return immediately.
+ *
+ * To throw this error, if @expr evaluates to %FALSE, does nothing if @err is
+ * %NULL; if @err is non-%NULL, then *@err must be %NULL. A new #GError is
+ * created and assigned to *@err. Then, @val is returned from the current
+ * function.
+ */
+#define retro_throw_val_if_fail(err, expr, val, domain, code, format, ...) \
+  G_STMT_START { \
+    if (G_LIKELY (expr)) { } \
+    else { \
+      g_set_error (err, domain, code, format __VA_OPT__(,) __VA_ARGS__); \
+      return (val); \
+    } \
+  } G_STMT_END
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (RetroError, retro_error_ensure_free)
+
+G_END_DECLS
diff --git a/shared/retro-error.c b/shared/retro-error.c
new file mode 100644
index 0000000..9aa5821
--- /dev/null
+++ b/shared/retro-error.c
@@ -0,0 +1,13 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#include "retro-error-private.h"
+
+void
+retro_error_ensure_free (RetroError *error)
+{
+  if (error == NULL)
+    return;
+
+  g_critical ("Unhandled error: %s", error->message);
+  g_error_free (error);
+}


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