[librsvg/librsvg-2.48] Implement rsvg_return_if_fail / rsvg_return_val_if_fail in Rust



commit 3438c3931be8af4627ddd0a61032c76db9d27181
Author: Federico Mena Quintero <federico gnome org>
Date:   Wed Apr 8 17:57:53 2020 -0500

    Implement rsvg_return_if_fail / rsvg_return_val_if_fail in Rust
    
    The macros g_return_if_fail() and g_return_val_if_fail() just call the
    function g_return_if_fail_warning().
    
    We'll implement equivalent macros in Rust, so we can move all the
    argument checks for the C API to Rust.
    
    Then we can hopefully remove the C wrapper library that just calls
    into Rust immediately.

 librsvg/c_api.rs      |  5 +++++
 librsvg/lib.rs        |  4 +++-
 librsvg/messages.rs   | 44 +++++++++++++++++++++++++++++++++++++++++---
 librsvg/rsvg-handle.c |  1 -
 tests/api.c           | 20 ++++++++++++++++++++
 5 files changed, 69 insertions(+), 5 deletions(-)
---
diff --git a/librsvg/c_api.rs b/librsvg/c_api.rs
index 745a2028..8fd405c5 100644
--- a/librsvg/c_api.rs
+++ b/librsvg/c_api.rs
@@ -927,6 +927,11 @@ pub unsafe extern "C" fn rsvg_rust_handle_set_base_url(
     raw_handle: *const RsvgHandle,
     uri: *const libc::c_char,
 ) {
+    rsvg_return_if_fail! {
+        rsvg_handle_set_base_uri;
+        !uri.is_null(),
+    }
+
     let rhandle = get_rust_handle(raw_handle);
 
     assert!(!uri.is_null());
diff --git a/librsvg/lib.rs b/librsvg/lib.rs
index f408bdb6..dc9dcaf7 100644
--- a/librsvg/lib.rs
+++ b/librsvg/lib.rs
@@ -48,7 +48,9 @@ pub use crate::pixbuf_utils::{
     rsvg_rust_pixbuf_from_file_at_zoom_with_max,
 };
 
+#[macro_use]
+mod messages;
+
 mod c_api;
 mod color_utils;
-mod messages;
 mod pixbuf_utils;
diff --git a/librsvg/messages.rs b/librsvg/messages.rs
index 09c7979b..42f46987 100644
--- a/librsvg/messages.rs
+++ b/librsvg/messages.rs
@@ -1,4 +1,4 @@
-use glib_sys::{G_LOG_LEVEL_WARNING, G_LOG_LEVEL_CRITICAL, GLogField, g_log_structured_array};
+use glib_sys::{g_log_structured_array, GLogField, G_LOG_LEVEL_CRITICAL, G_LOG_LEVEL_WARNING};
 
 /*
   G_LOG_LEVEL_CRITICAL          = 1 << 3,
@@ -48,13 +48,11 @@ fn rsvg_g_log(level: glib_sys::GLogLevelFlags, msg: &str) {
             value: priority as *const u8 as *const _,
             length: -1,
         },
-
         GLogField {
             key: b"MESSAGE\0" as *const u8 as *const _,
             value: msg.as_ptr() as *const _,
             length: msg.len() as _,
         },
-
         // This is the G_LOG_DOMAIN set from the Makefile
         GLogField {
             key: b"GLIB_DOMAIN\0" as *const u8 as *const _,
@@ -75,3 +73,43 @@ pub fn rsvg_g_warning(msg: &str) {
 pub fn rsvg_g_critical(msg: &str) {
     rsvg_g_log(glib_sys::G_LOG_LEVEL_CRITICAL, msg);
 }
+
+// Once Rust has a function! macro that gives us the current function name, we
+// can remove the $func_name argument.
+#[macro_export]
+macro_rules! rsvg_return_if_fail {
+    {
+        $func_name:ident;
+        $($condition:expr,)+
+    } => {
+        $(
+            if !$condition {
+                glib_sys::g_return_if_fail_warning(
+                    b"librsvg\0" as *const u8 as *const _,
+                    concat!(stringify!($func_name), "\0").as_ptr() as *const _,
+                    concat!(stringify!($condition), "\0").as_ptr() as *const _,
+                );
+                return;
+            }
+        )+
+    }
+}
+
+#[macro_export]
+macro_rules! rsvg_return_val_if_fail {
+    {
+        $func_name:ident => $retval:expr;
+        $($condition:expr,)+
+    } => {
+        $(
+            if !$condition {
+                glib_sys::g_return_if_fail_warning(
+                    b"librsvg\0" as *const u8 as *const _,
+                    concat!(stringify!($func_name), "\0").as_ptr() as *const _,
+                    concat!(stringify!($condition), "\0").as_ptr() as *const _,
+                );
+                return $retval;
+            }
+        )+
+    }
+}
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 54c45f36..987e3bbe 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -726,7 +726,6 @@ void
 rsvg_handle_set_base_uri (RsvgHandle *handle, const char *base_uri)
 {
     g_return_if_fail (RSVG_IS_HANDLE (handle));
-    g_return_if_fail (base_uri != NULL);
 
     rsvg_rust_handle_set_base_url (handle, base_uri);
 }
diff --git a/tests/api.c b/tests/api.c
index 9a72cbd4..cd043350 100644
--- a/tests/api.c
+++ b/tests/api.c
@@ -1336,6 +1336,25 @@ property_deprecated (void)
     g_object_unref (handle);
 }
 
+static void
+return_if_fail (void)
+{
+    if (g_test_subprocess ()) {
+        RsvgHandle *handle;
+
+        handle = rsvg_handle_new();
+        g_assert_nonnull (handle);
+
+        /* NULL is an invalid argument... */
+        rsvg_handle_set_base_uri (handle, NULL);
+        g_object_unref (handle);
+    }
+
+    g_test_trap_subprocess (NULL, 0, 0);
+    /* ... and here we catch that it was validated */
+    g_test_trap_assert_stderr ("*rsvg_handle_set_base_uri*assertion*failed*");
+}
+
 int
 main (int argc, char **argv)
 {
@@ -1384,6 +1403,7 @@ main (int argc, char **argv)
     g_test_add_func ("/api/property_base_uri", property_base_uri);
     g_test_add_func ("/api/property_dimensions", property_dimensions);
     g_test_add_func ("/api/property_deprecated", property_deprecated);
+    g_test_add_func ("/api/return_if_fail", return_if_fail);
 
     return g_test_run ();
 }


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