[librsvg: 2/8] Implement rsvg_return_if_fail / rsvg_return_val_if_fail in Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 2/8] Implement rsvg_return_if_fail / rsvg_return_val_if_fail in Rust
- Date: Thu, 9 Apr 2020 05:21:53 +0000 (UTC)
commit a9b5d3fece9aea8e2350d26064968043971fab43
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 c29c9d7c..563b8c72 100644
--- a/librsvg/c_api.rs
+++ b/librsvg/c_api.rs
@@ -926,6 +926,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 ffe1b210..1c472f91 100644
--- a/tests/api.c
+++ b/tests/api.c
@@ -1338,6 +1338,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)
{
@@ -1386,6 +1405,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]