[librsvg/wip/subclass] Use libxml's structured error callback instead of vararg one
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/wip/subclass] Use libxml's structured error callback instead of vararg one
- Date: Mon, 18 Feb 2019 16:18:48 +0000 (UTC)
commit c8dafbf705a5641f6c3cf043a356c787d85a0cd5
Author: Kornel LesiĆski <kornel geekhood net>
Date: Mon Feb 18 14:03:02 2019 +0000
Use libxml's structured error callback instead of vararg one
librsvg/rsvg-handle.c | 24 ------------------------
rsvg_internals/src/lib.rs | 2 --
rsvg_internals/src/util.rs | 9 +++++++++
rsvg_internals/src/xml.rs | 13 -------------
rsvg_internals/src/xml2.rs | 2 +-
rsvg_internals/src/xml2_load.rs | 34 ++++++++++++++++++++++++++--------
6 files changed, 36 insertions(+), 48 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index d0e60857..7a1ee909 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -131,9 +131,6 @@
/* Implemented in rsvg_internals/src/xml.rs */
typedef struct RsvgXmlState RsvgXmlState;
-/* Implemented in rsvg_internals/src/xml.rs */
-extern void rsvg_xml_state_error(RsvgXmlState *xml, const char *msg);
-
/* Implemented in rsvg_internals/src/handle.rs */
extern double rsvg_handle_rust_get_dpi_x (RsvgHandle *raw_handle);
extern double rsvg_handle_rust_get_dpi_y (RsvgHandle *raw_handle);
@@ -874,27 +871,6 @@ rsvg_handle_internal_set_testing (RsvgHandle *handle, gboolean testing)
rsvg_handle_rust_set_testing (handle, testing);
}
-/* This one is defined in the C code, because the prototype has varargs
- * and we can't handle those from Rust :(
- */
-G_GNUC_INTERNAL void rsvg_sax_error_cb (void *data, const char *msg, ...);
-
-void
-rsvg_sax_error_cb (void *data, const char *msg, ...)
-{
- RsvgXmlState *xml = data;
- va_list args;
- char *buf;
-
- va_start (args, msg);
- g_vasprintf (&buf, msg, args);
- va_end (args);
-
- rsvg_xml_state_error (xml, buf);
-
- g_free (buf);
-}
-
GType
rsvg_error_get_type(void)
{
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index b064a65e..091074f9 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -89,8 +89,6 @@ pub use pixbuf_utils::{
rsvg_rust_pixbuf_from_file_at_zoom_with_max,
};
-pub use xml::rsvg_xml_state_error;
-
#[macro_use]
mod log;
diff --git a/rsvg_internals/src/util.rs b/rsvg_internals/src/util.rs
index 3a7c7cac..28c7913d 100644
--- a/rsvg_internals/src/util.rs
+++ b/rsvg_internals/src/util.rs
@@ -1,6 +1,7 @@
use libc;
use std::ffi::CStr;
+use std::borrow::Cow;
use std::str;
use glib::translate::*;
@@ -17,6 +18,14 @@ pub unsafe fn utf8_cstr<'a>(s: *const libc::c_char) -> &'a str {
str::from_utf8_unchecked(CStr::from_ptr(s).to_bytes())
}
+/// Error-tolerant C string import
+pub unsafe fn cstr<'a>(s: *const libc::c_char) -> Cow<'a, str> {
+ if s.is_null() {
+ return Cow::Borrowed("(null)");
+ }
+ CStr::from_ptr(s).to_string_lossy()
+}
+
pub fn clamp<T: PartialOrd>(val: T, low: T, high: T) -> T {
if val < low {
low
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index cefd2ec8..d467efcf 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -542,19 +542,6 @@ fn parse_xml_stylesheet_processing_instruction(data: &str) -> Result<Vec<(String
unreachable!();
}
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_xml_state_error(xml: *mut XmlState, msg: *const libc::c_char) {
- assert!(!xml.is_null());
- let xml = &mut *xml;
-
- assert!(!msg.is_null());
- // Unlike the functions that take UTF-8 validated strings from
- // libxml2, I don't trust error messages to be validated.
- let msg: String = from_glib_none(msg);
-
- xml.error(&msg);
-}
-
#[cfg(test)]
mod tests {
use super::*;
diff --git a/rsvg_internals/src/xml2.rs b/rsvg_internals/src/xml2.rs
index 4525fc4b..d6975683 100644
--- a/rsvg_internals/src/xml2.rs
+++ b/rsvg_internals/src/xml2.rs
@@ -107,7 +107,7 @@ pub struct xmlSAXHandler {
pub _private: gpointer,
pub startElementNs: gpointer,
pub endElementNs: gpointer,
- pub serror: gpointer,
+ pub serror: Option<unsafe extern "C" fn(user_data: *mut libc::c_void, error: xmlErrorPtr)>,
}
pub type xmlSAXHandlerPtr = *mut xmlSAXHandler;
diff --git a/rsvg_internals/src/xml2_load.rs b/rsvg_internals/src/xml2_load.rs
index d2dfb091..e32f8097 100644
--- a/rsvg_internals/src/xml2_load.rs
+++ b/rsvg_internals/src/xml2_load.rs
@@ -9,6 +9,7 @@ use std::ptr;
use std::rc::Rc;
use std::slice;
use std::str;
+use std::borrow::Cow;
use glib::translate::*;
@@ -17,13 +18,10 @@ use handle::LoadFlags;
use io::get_input_stream_for_loading;
use property_bag::PropertyBag;
use util::utf8_cstr;
+use util::cstr;
use xml::XmlState;
use xml2::*;
-extern "C" {
- fn rsvg_sax_error_cb(data: *mut libc::c_void);
-}
-
fn get_xml2_sax_handler() -> xmlSAXHandler {
let mut h: xmlSAXHandler = unsafe { mem::zeroed() };
@@ -36,14 +34,34 @@ fn get_xml2_sax_handler() -> xmlSAXHandler {
h.startElement = Some(sax_start_element_cb);
h.endElement = Some(sax_end_element_cb);
h.processingInstruction = Some(sax_processing_instruction_cb);
-
- // This one is defined in the C code, because the prototype has varargs
- // and we can't handle those from Rust :(
- h.error = rsvg_sax_error_cb as *mut _;
+ h.serror = Some(rsvg_sax_serror_cb);
h
}
+unsafe extern "C" fn rsvg_sax_serror_cb(user_data: *mut libc::c_void, error: xmlErrorPtr) {
+ let state = (user_data as *mut XmlState).as_mut().unwrap();
+ let error = error.as_ref().unwrap();
+
+ let level_name = match error.level {
+ 1 => "warning",
+ 2 => "error",
+ 3 => "fatal error",
+ _ => "unknown error",
+ };
+
+ // "int2" is the column number
+ let column = if error.int2 > 0 {
+ Cow::Owned(format!(":{}", error.int2))
+ } else {
+ Cow::Borrowed("")
+ };
+
+ let full_error_message = format!("{} code={} ({}) in {}:{}{}: {}", level_name, error.code, error.domain,
+ cstr(error.file), error.line, column, cstr(error.message));
+ state.error(&full_error_message);
+}
+
fn free_xml_parser_and_doc(parser: xmlParserCtxtPtr) {
// Free the ctxt and its ctxt->myDoc - libxml2 doesn't free them together
// http://xmlsoft.org/html/libxml-parser.html#xmlFreeParserCtxt
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]