#![allow(
missing_docs,
non_snake_case,
non_camel_case_types,
non_upper_case_globals
)]
#![allow(unused_variables)]
#![allow(private_interfaces)]
#![allow(unused_assignments)]
#![allow(unused_unsafe)]
#![allow(clippy::missing_safety_doc)]
#![allow(clippy::not_unsafe_ptr_arg_deref)]
use core::ffi::c_void;
use core::ptr;
use std::mem::size_of;
use std::os::raw::{c_char, c_int};
use crate::abi::allocator::{xmlFreeImpl, xmlMallocImpl, xmlMallocZero};
use crate::abi::structs::*;
use crate::abi::types::xmlChar;
use crate::abi::types::xmlElementType::*;
use crate::abi::types::xmlEntityType::*;
use crate::xml::debug::_IO_FILE;
use crate::xml::io;
use crate::xml::string::{check_utf8, xml_strdup, xml_strlen, xml_strndup};
use crate::xml::tree::{
copy_node, free_node_list, get_doc_entity, new_ns, new_text, node_get_content, search_ns,
search_ns_by_href, serialize_attr_value, serialize_node_opts,
};
extern "C" {
static mut stdout: *mut c_void;
}
const XML_ENT_PARSED: c_int = 1 << 0;
const XML_ENT_EXPANDING: c_int = 1 << 3;
const XML_CHECK_FOUND_ELEMENT: c_int = 5000;
const XML_CHECK_FOUND_ATTRIBUTE: c_int = 5001;
const XML_CHECK_FOUND_TEXT: c_int = 5002;
const XML_CHECK_FOUND_CDATA: c_int = 5003;
const XML_CHECK_FOUND_ENTITYREF: c_int = 5004;
const XML_CHECK_FOUND_ENTITY: c_int = 5005;
const XML_CHECK_FOUND_PI: c_int = 5006;
const XML_CHECK_FOUND_COMMENT: c_int = 5007;
const XML_CHECK_FOUND_DOCTYPE: c_int = 5008;
const XML_CHECK_FOUND_FRAGMENT: c_int = 5009;
const XML_CHECK_FOUND_NOTATION: c_int = 5010;
const XML_CHECK_UNKNOWN_NODE: c_int = 5011;
const XML_CHECK_ENTITY_TYPE: c_int = 5012;
const XML_CHECK_NO_PARENT: c_int = 5013;
const XML_CHECK_NO_DOC: c_int = 5014;
const XML_CHECK_NO_NAME: c_int = 5015;
const XML_CHECK_NO_ELEM: c_int = 5016;
const XML_CHECK_WRONG_DOC: c_int = 5017;
const XML_CHECK_NO_PREV: c_int = 5018;
const XML_CHECK_WRONG_PREV: c_int = 5019;
const XML_CHECK_NO_NEXT: c_int = 5020;
const XML_CHECK_WRONG_NEXT: c_int = 5021;
const XML_CHECK_NOT_DTD: c_int = 5022;
const XML_CHECK_NOT_ATTR_DECL: c_int = 5024;
const XML_CHECK_NOT_ELEM_DECL: c_int = 5025;
const XML_CHECK_NOT_ENTITY_DECL: c_int = 5026;
const XML_CHECK_NOT_NS_DECL: c_int = 5027;
const XML_CHECK_NO_HREF: c_int = 5028;
const XML_CHECK_WRONG_PARENT: c_int = 5029;
const XML_CHECK_NS_SCOPE: c_int = 5030;
const XML_CHECK_NS_ANCESTOR: c_int = 5031;
const XML_CHECK_NOT_UTF8: c_int = 5032;
const XML_CHECK_NOT_NCNAME: c_int = 5034;
const XML_CHECK_WRONG_NAME: c_int = 5036;
const XML_CHECK_NAME_NOT_NULL: c_int = 5037;
const XML_ESCAPE_ATTR: c_int = 1 << 0;
const XML_ESCAPE_NON_ASCII: c_int = 1 << 1;
const XML_ESCAPE_HTML: c_int = 1 << 2;
const XML_ESCAPE_QUOT: c_int = 1 << 3;
const unsafe fn c_str_eq_bytes(s: *const xmlChar, b: &[u8]) -> bool {
if s.is_null() {
return false;
}
let mut i = 0usize;
while i < b.len() {
if unsafe { *s.add(i) } != b[i] {
return false;
}
i += 1;
}
unsafe { *s.add(i) == 0 }
}
unsafe fn get_utf8_char(utf: *const xmlChar, len: *mut c_int) -> c_int {
if utf.is_null() || len.is_null() || unsafe { *len } < 1 {
return -1;
}
unsafe {
let u0 = *utf;
if u0 < 0x80 {
*len = 1;
return u0 as c_int;
}
if *len < 2 {
return -1;
}
if (u0 & 0xE0) == 0xC0 {
let u1 = *utf.add(1);
if (u1 & 0xC0) != 0x80 {
return -1;
}
if (u0 & 0x1F) < 2 {
return -1;
}
*len = 2;
return (((u0 & 0x1F) as c_int) << 6) | ((u1 & 0x3F) as c_int);
}
if *len < 3 {
return -1;
}
if (u0 & 0xF0) == 0xE0 {
let u1 = *utf.add(1);
let u2 = *utf.add(2);
if (u1 & 0xC0) != 0x80 || (u2 & 0xC0) != 0x80 {
return -1;
}
if (u0 & 0x0F) == 0 && (u1 & 0x20) == 0 {
return -1;
}
*len = 3;
return (((u0 & 0x0F) as c_int) << 12)
| (((u1 & 0x3F) as c_int) << 6)
| ((u2 & 0x3F) as c_int);
}
if *len < 4 {
return -1;
}
if (u0 & 0xF8) == 0xF0 {
let u1 = *utf.add(1);
let u2 = *utf.add(2);
let u3 = *utf.add(3);
if (u1 & 0xC0) != 0x80 || (u2 & 0xC0) != 0x80 || (u3 & 0xC0) != 0x80 {
return -1;
}
if (u0 & 0x07) == 0 && (u1 & 0x30) == 0 {
return -1;
}
*len = 4;
return (((u0 & 0x07) as c_int) << 18)
| (((u1 & 0x3F) as c_int) << 12)
| (((u2 & 0x3F) as c_int) << 6)
| ((u3 & 0x3F) as c_int);
}
}
-1
}
unsafe fn new_doc_text(doc: *const _xmlDoc, content: *const xmlChar) -> *mut _xmlNode {
if !doc.is_null() {
let t = unsafe { (*doc).type_ };
if t != XML_DOCUMENT_NODE as c_int && t != XML_HTML_DOCUMENT_NODE as c_int {
return ptr::null_mut();
}
}
let node = new_text(content);
if node.is_null() {
return ptr::null_mut();
}
if !doc.is_null() {
unsafe { (*node).doc = doc as *mut _xmlDoc };
}
node
}
unsafe fn new_entity_ref(doc: *const _xmlDoc, name: *const xmlChar) -> *mut _xmlNode {
if name.is_null() {
return ptr::null_mut();
}
if !doc.is_null() {
let t = unsafe { (*doc).type_ };
if t != XML_DOCUMENT_NODE as c_int && t != XML_HTML_DOCUMENT_NODE as c_int {
return ptr::null_mut();
}
}
let node = xmlMallocZero(size_of::<_xmlNode>()) as *mut _xmlNode;
if node.is_null() {
return ptr::null_mut();
}
let name_copy = xml_strdup(name);
if name_copy.is_null() {
xmlFreeImpl(node as *mut c_void);
return ptr::null_mut();
}
unsafe {
(*node).type_ = XML_ENTITY_REF_NODE as c_int;
(*node).name = name_copy;
if !doc.is_null() {
(*node).doc = doc as *mut _xmlDoc;
}
}
node
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyCharMultiByte(mut out: *mut xmlChar, val: c_int) -> c_int {
if out.is_null() || val < 0 {
return 0;
}
if val >= 0x80 {
let savedout = out;
let mut bits: c_int;
if val < 0x800 {
unsafe { *out = ((val >> 6) | 0xC0) as xmlChar };
out = unsafe { out.add(1) };
bits = 0;
} else if val < 0x10000 {
unsafe { *out = ((val >> 12) | 0xE0) as xmlChar };
out = unsafe { out.add(1) };
bits = 6;
} else if val < 0x110000 {
unsafe { *out = ((val >> 18) | 0xF0) as xmlChar };
out = unsafe { out.add(1) };
bits = 12;
} else {
return 0;
}
while bits >= 0 {
unsafe {
*out = (((val >> bits) & 0x3F) | 0x80) as xmlChar;
}
out = unsafe { out.add(1) };
bits -= 6;
}
return unsafe { out.offset_from(savedout) } as c_int;
}
unsafe { *out = val as xmlChar };
1
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyChar(_len: c_int, out: *mut xmlChar, val: c_int) -> c_int {
if out.is_null() || val < 0 {
return 0;
}
if val >= 0x80 {
return xmlCopyCharMultiByte(out, val);
}
unsafe { *out = val as xmlChar };
1
}
unsafe fn escape_text_flags(str: *const xmlChar, flags: c_int) -> *mut xmlChar {
if str.is_null() {
return ptr::null_mut();
}
let mut out: Vec<u8> = Vec::with_capacity(64);
let mut cur = str;
unsafe {
loop {
if *cur == 0 {
break;
}
let base = cur;
let mut offset: c_int = -1;
let mut c: u8 = 0;
loop {
c = *cur;
if c == 0 {
offset = 0;
break;
}
if c < 0x80 {
offset = escape_tab_offset(c, flags);
if offset >= 0 {
break;
}
} else if (flags & XML_ESCAPE_NON_ASCII) != 0 {
break;
}
cur = cur.add(1);
}
let run_len = cur.offset_from(base) as usize;
out.extend_from_slice(core::slice::from_raw_parts(base, run_len));
if offset >= 0 {
if c != 0 {
out.extend_from_slice(escape_replacement(offset));
cur = cur.add(1);
}
} else {
let mut len: c_int = 4;
let mut val = get_utf8_char(cur, &mut len);
if val < 0 {
val = 0xFFFD;
cur = cur.add(1);
} else {
if val == 0xFFFE || val == 0xFFFF {
val = 0xFFFD;
}
cur = cur.add(len as usize);
}
let hex = format!("&#x{:X};", val as u32);
out.extend_from_slice(hex.as_bytes());
}
}
}
out.push(0);
let p = xmlMallocImpl(out.len()) as *mut xmlChar;
if p.is_null() {
return ptr::null_mut();
}
unsafe {
ptr::copy_nonoverlapping(out.as_ptr(), p, out.len());
}
p
}
const fn escape_tab_offset(c: u8, flags: c_int) -> c_int {
if (flags & XML_ESCAPE_HTML) != 0 {
return match c {
b'&' => 33,
b'<' => 39,
b'>' => 44,
b'"' if (flags & XML_ESCAPE_ATTR) != 0 => 26,
_ => -1,
};
}
if (flags & XML_ESCAPE_QUOT) != 0 {
return match c {
b'\r' => 20,
b'"' => 26,
b'&' => 33,
b'<' => 39,
b'>' => 44,
_ => -1,
};
}
if (flags & XML_ESCAPE_ATTR) != 0 {
return match c {
b'\t' => 9,
b'\n' => 14,
b'\r' => 20,
b'"' => 26,
b'&' => 33,
b'<' => 39,
b'>' => 44,
_ => -1,
};
}
match c {
b'\r' => 20,
b'&' => 33,
b'<' => 39,
b'>' => 44,
_ => -1,
}
}
const fn escape_replacement(offset: c_int) -> &'static [u8] {
match offset {
9 => b"	",
14 => b" ",
20 => b" ",
26 => b""",
33 => b"&",
39 => b"<",
44 => b">",
_ => b"",
}
}
unsafe fn node_list_get_string_internal(
node: *const _xmlNode,
escape: c_int,
flags: c_int,
) -> *mut xmlChar {
if node.is_null() {
return xml_strdup(b"" as *const u8 as *const xmlChar);
}
unsafe {
let n = &*node;
if escape == 0
&& (n.type_ == XML_TEXT_NODE as c_int || n.type_ == XML_CDATA_SECTION_NODE as c_int)
&& n.next.is_null()
{
if n.content.is_null() {
return xml_strdup(b"" as *const u8 as *const xmlChar);
}
return xml_strdup(n.content);
}
}
let buf = io::buf_create(50);
if buf.is_null() {
return ptr::null_mut();
}
let mut cur = node;
while !cur.is_null() {
unsafe {
let t = (*cur).type_;
if t == XML_TEXT_NODE as c_int || t == XML_CDATA_SECTION_NODE as c_int {
if !(*cur).content.is_null() {
if escape == 0 {
io::buf_cat(buf, (*cur).content);
} else {
let encoded = escape_text_flags((*cur).content, flags);
if encoded.is_null() {
io::buf_free(buf);
return ptr::null_mut();
}
io::buf_cat(buf, encoded);
xmlFreeImpl(encoded as *mut c_void);
}
}
} else if t == XML_ENTITY_REF_NODE as c_int {
if escape == 0 {
let content = node_get_content(cur as *mut _xmlNode);
if !content.is_null() {
io::buf_cat(buf, content);
xmlFreeImpl(content as *mut c_void);
}
} else {
io::buf_add(buf, b"&" as *const u8, 1);
if !(*cur).name.is_null() {
io::buf_cat(buf, (*cur).name);
}
io::buf_add(buf, b";" as *const u8, 1);
}
}
cur = (*cur).next;
}
}
let content = io::buf_content(buf);
let len = io::buf_length(buf);
let ret = if !content.is_null() && len > 0 {
xml_strdup(content)
} else {
xml_strdup(b"" as *const u8 as *const xmlChar)
};
io::buf_free(buf);
ret
}
#[no_mangle]
pub unsafe extern "C" fn xmlNodeListGetString(
doc: *mut _xmlDoc,
list: *const _xmlNode,
inLine: c_int,
) -> *mut xmlChar {
let mut flags: c_int = 0;
let mut escape: c_int = 0;
if list.is_null() {
return ptr::null_mut();
}
if inLine == 0 {
escape = 1;
if !doc.is_null() && (*doc).type_ == XML_HTML_DOCUMENT_NODE as c_int {
flags |= XML_ESCAPE_HTML;
} else if doc.is_null() || (*doc).encoding.is_null() {
flags |= XML_ESCAPE_NON_ASCII;
}
if !list.is_null() {
let parent = unsafe { (*list).parent };
if !parent.is_null() && (*parent).type_ == XML_ATTRIBUTE_NODE as c_int {
flags |= XML_ESCAPE_ATTR;
}
}
}
node_list_get_string_internal(list, escape, flags)
}
#[no_mangle]
pub unsafe extern "C" fn xmlNodeListGetRawString(
_doc: *const _xmlDoc,
list: *const _xmlNode,
inLine: c_int,
) -> *mut xmlChar {
let mut escape: c_int = 0;
let mut flags: c_int = 0;
if list.is_null() {
return ptr::null_mut();
}
if inLine == 0 {
escape = 1;
flags = XML_ESCAPE_QUOT;
}
node_list_get_string_internal(list, escape, flags)
}
unsafe fn node_parse_att_value(
doc: *const _xmlDoc,
attr: *mut _xmlNode,
value: *const xmlChar,
len: usize,
list_ptr: *mut *mut _xmlNode,
) -> c_int {
let mut head: *mut _xmlNode = ptr::null_mut();
let mut last: *mut _xmlNode = ptr::null_mut();
if !list_ptr.is_null() {
unsafe { *list_ptr = ptr::null_mut() };
}
if value.is_null() || unsafe { *value } == 0 {
return 0;
}
let mut buf: Vec<u8> = Vec::new();
let mut cur = value;
let mut q = cur;
let mut remaining = len;
'scan: loop {
if remaining == 0 || unsafe { *cur } == 0 {
break 'scan;
}
if unsafe { *cur } == b'&' {
let mut charval: u32 = 0;
if cur != q {
unsafe {
buf.extend_from_slice(core::slice::from_raw_parts(
q,
cur.offset_from(q) as usize,
));
}
}
if remaining > 2 && unsafe { *cur.add(1) } == b'#' && unsafe { *cur.add(2) } == b'x' {
let mut tmp: u8 = 0;
unsafe {
cur = cur.add(3);
}
remaining -= 3;
loop {
if remaining == 0 {
break;
}
tmp = unsafe { *cur };
if tmp == b';' {
break;
}
let digit: u32 = match tmp {
b'0'..=b'9' => (tmp - b'0') as u32,
b'a'..=b'f' => (tmp - b'a' + 10) as u32,
b'A'..=b'F' => (tmp - b'A' + 10) as u32,
_ => {
charval = 0;
break;
}
};
charval = charval.wrapping_mul(16).wrapping_add(digit);
if charval > 0x110000 {
charval = 0x110000;
}
unsafe {
cur = cur.add(1);
}
remaining -= 1;
}
if tmp == b';' {
unsafe {
cur = cur.add(1);
}
remaining -= 1;
}
q = cur;
} else if remaining > 1 && unsafe { *cur.add(1) } == b'#' {
let mut tmp: u8 = 0;
unsafe {
cur = cur.add(2);
}
remaining -= 2;
loop {
if remaining == 0 {
break;
}
tmp = unsafe { *cur };
if tmp == b';' {
break;
}
if !tmp.is_ascii_digit() {
charval = 0;
break;
}
charval = charval.wrapping_mul(10).wrapping_add((tmp - b'0') as u32);
if charval > 0x110000 {
charval = 0x110000;
}
unsafe {
cur = cur.add(1);
}
remaining -= 1;
}
if tmp == b';' {
unsafe {
cur = cur.add(1);
}
remaining -= 1;
}
q = cur;
} else {
unsafe {
cur = cur.add(1);
}
remaining -= 1;
q = cur;
while remaining > 0 && unsafe { *cur } != 0 && unsafe { *cur } != b';' {
unsafe {
cur = cur.add(1);
}
remaining -= 1;
}
if remaining == 0 || unsafe { *cur } == 0 {
break 'scan;
}
if cur != q {
let name = unsafe { xml_strndup(q, cur.offset_from(q) as usize) };
if name.is_null() {
free_node_list(head);
return -1;
}
let ent = get_doc_entity(doc, name);
if !ent.is_null() && (*ent).etype == XML_INTERNAL_PREDEFINED_ENTITY as c_int {
let content = (*ent).content;
let clen = xml_strlen(content);
unsafe {
buf.extend_from_slice(core::slice::from_raw_parts(content, clen));
}
} else if ent.is_null() || ((*ent).flags & XML_ENT_EXPANDING) == 0 {
if !buf.is_empty() {
buf.push(0);
let node = new_doc_text(doc, buf.as_ptr() as *const xmlChar);
buf.pop();
if node.is_null() {
xmlFreeImpl(name as *mut c_void);
free_node_list(head);
return -1;
}
(*node).parent = attr;
if last.is_null() {
head = node;
} else {
(*last).next = node;
(*node).prev = last;
}
last = node;
buf.clear();
}
if !ent.is_null()
&& ((*ent).flags & XML_ENT_PARSED) == 0
&& !(*ent).content.is_null()
{
(*ent).flags |= XML_ENT_EXPANDING;
let res = node_parse_att_value(
doc,
ent as *mut _xmlNode,
(*ent).content,
usize::MAX,
ptr::null_mut(),
);
(*ent).flags &= !XML_ENT_EXPANDING;
if res < 0 {
xmlFreeImpl(name as *mut c_void);
free_node_list(head);
return -1;
}
(*ent).flags |= XML_ENT_PARSED;
}
let node = new_entity_ref(doc, name);
if node.is_null() {
xmlFreeImpl(name as *mut c_void);
free_node_list(head);
return -1;
}
(*node).parent = attr;
(*node).last = ent as *mut _xmlNode;
if !ent.is_null() {
(*node).children = ent as *mut _xmlNode;
(*node).content = (*ent).content;
}
if last.is_null() {
head = node;
} else {
(*last).next = node;
(*node).prev = last;
}
last = node;
}
xmlFreeImpl(name as *mut c_void);
}
unsafe {
cur = cur.add(1);
}
remaining -= 1;
q = cur;
}
if charval != 0 {
if charval >= 0x110000 {
charval = 0xFFFD;
}
let mut buffer = [0u8; 10];
let l = xmlCopyCharMultiByte(buffer.as_mut_ptr(), charval as c_int);
buf.extend_from_slice(&buffer[..l as usize]);
}
} else {
unsafe {
cur = cur.add(1);
}
remaining -= 1;
}
}
if cur != q {
unsafe {
buf.extend_from_slice(core::slice::from_raw_parts(q, cur.offset_from(q) as usize));
}
}
if !buf.is_empty() {
buf.push(0);
let node = new_doc_text(doc, buf.as_ptr() as *const xmlChar);
buf.pop();
if node.is_null() {
free_node_list(head);
return -1;
}
(*node).parent = attr;
if last.is_null() {
head = node;
} else {
(*last).next = node;
(*node).prev = last;
}
last = node;
} else if head.is_null() {
head = new_doc_text(doc, b"" as *const u8 as *const xmlChar);
if head.is_null() {
return -1;
}
(*head).parent = attr;
last = head;
}
if !attr.is_null() {
(*attr).children = head;
(*attr).last = last;
}
if !list_ptr.is_null() {
unsafe { *list_ptr = head };
}
0
}
#[no_mangle]
pub unsafe extern "C" fn xmlStringGetNodeList(
doc: *const _xmlDoc,
value: *const xmlChar,
) -> *mut _xmlNode {
let mut ret: *mut _xmlNode = ptr::null_mut();
unsafe {
node_parse_att_value(doc, ptr::null_mut(), value, usize::MAX, &mut ret);
}
ret
}
unsafe fn set_tree_doc(tree: *mut _xmlNode, doc: *mut _xmlDoc) {
if tree.is_null() {
return;
}
unsafe {
let t = (*tree).type_;
if t == XML_NAMESPACE_DECL as c_int {
return;
}
if (*tree).doc != doc {
if t == XML_ELEMENT_NODE as c_int {
let mut prop = (*tree).properties;
while !prop.is_null() {
if (*prop).type_ == XML_ATTRIBUTE_NODE as c_int {
set_tree_doc(prop as *mut _xmlNode, doc);
}
prop = (*prop).next;
}
}
if !(*tree).children.is_null() && t != XML_ENTITY_REF_NODE as c_int {
set_tree_doc((*tree).children, doc);
}
(*tree).doc = doc;
}
}
}
unsafe fn new_reconciled_ns(
doc: *mut _xmlDoc,
tree: *mut _xmlNode,
ns: *mut _xmlNs,
) -> *mut _xmlNs {
if tree.is_null() {
return ptr::null_mut();
}
let def = search_ns(doc, tree, unsafe { (*ns).prefix });
if !def.is_null() {
return def;
}
let def = search_ns_by_href(doc, tree, unsafe { (*ns).href });
if !def.is_null() {
return def;
}
new_ns(tree, unsafe { (*ns).href }, unsafe { (*ns).prefix })
}
unsafe fn static_copy_node(
node: *const _xmlNode,
doc: *mut _xmlDoc,
parent: *mut _xmlNode,
extended: c_int,
) -> *mut _xmlNode {
if node.is_null() {
return ptr::null_mut();
}
let n = unsafe { &*node };
match n.type_ {
t if t == XML_TEXT_NODE as c_int
|| t == XML_CDATA_SECTION_NODE as c_int
|| t == XML_ELEMENT_NODE as c_int
|| t == XML_DOCUMENT_FRAG_NODE as c_int
|| t == XML_ENTITY_REF_NODE as c_int
|| t == XML_PI_NODE as c_int
|| t == XML_COMMENT_NODE as c_int
|| t == XML_XINCLUDE_START as c_int
|| t == XML_XINCLUDE_END as c_int => {}
t if t == XML_ATTRIBUTE_NODE as c_int => {
return copy_prop_internal(doc, parent, node as *mut _xmlAttr) as *mut _xmlNode;
}
t if t == XML_NAMESPACE_DECL as c_int => {
return copy_namespace_list(node as *mut _xmlNs) as *mut _xmlNode;
}
t if t == XML_DTD_NODE as c_int => {
return copy_dtd_internal(node as *mut _xmlDtd) as *mut _xmlNode;
}
t if t == XML_DOCUMENT_NODE as c_int || t == XML_HTML_DOCUMENT_NODE as c_int => {
return crate::xml::tree::copy_doc(node as *const _xmlDoc, extended) as *mut _xmlNode;
}
_ => {
return ptr::null_mut();
}
}
let ret = xmlMallocZero(size_of::<_xmlNode>()) as *mut _xmlNode;
if ret.is_null() {
return ptr::null_mut();
}
unsafe {
(*ret).type_ = n.type_;
(*ret).doc = doc;
(*ret).parent = parent;
if !n.name.is_null() {
(*ret).name = xml_strdup(n.name);
if (*ret).name.is_null() {
free_node(ret);
return ptr::null_mut();
}
}
if n.type_ != XML_ELEMENT_NODE as c_int
&& !n.content.is_null()
&& n.type_ != XML_ENTITY_REF_NODE as c_int
&& n.type_ != XML_XINCLUDE_END as c_int
&& n.type_ != XML_XINCLUDE_START as c_int
{
(*ret).content = xml_strdup(n.content);
if (*ret).content.is_null() {
free_node(ret);
return ptr::null_mut();
}
} else if n.type_ == XML_ELEMENT_NODE as c_int {
(*ret).line = n.line;
}
}
if extended == 0 {
return ret;
}
if (n.type_ == XML_ELEMENT_NODE as c_int || n.type_ == XML_XINCLUDE_START as c_int)
&& !n.nsDef.is_null()
{
let nsdef = copy_namespace_list(n.nsDef);
if nsdef.is_null() {
free_node(ret);
return ptr::null_mut();
}
unsafe { (*ret).nsDef = nsdef };
}
if n.type_ == XML_ELEMENT_NODE as c_int && !n.ns.is_null() {
let mut ns = search_ns(doc, ret, unsafe { (*n.ns).prefix });
if ns.is_null() {
ns = search_ns(unsafe { (*n.ns).context }, node as *mut _xmlNode, unsafe {
(*n.ns).prefix
});
if !ns.is_null() {
let mut root = ret;
while unsafe { !(*root).parent.is_null() } {
root = unsafe { (*root).parent };
}
let newns = new_ns(root, unsafe { (*ns).href }, unsafe { (*ns).prefix });
if newns.is_null() {
free_node(ret);
return ptr::null_mut();
}
unsafe { (*ret).ns = newns };
} else {
let newns = new_reconciled_ns(doc, ret, unsafe { n.ns });
if newns.is_null() {
free_node(ret);
return ptr::null_mut();
}
unsafe { (*ret).ns = newns };
}
} else {
unsafe { (*ret).ns = ns };
}
}
if n.type_ == XML_ELEMENT_NODE as c_int && !n.properties.is_null() {
let props = copy_prop_list(ret, n.properties);
if props.is_null() {
free_node(ret);
return ptr::null_mut();
}
unsafe { (*ret).properties = props };
}
if n.type_ == XML_ENTITY_REF_NODE as c_int {
unsafe {
let children = if doc.is_null() || (*node).doc != doc {
get_doc_entity(doc, (*ret).name) as *mut _xmlNode
} else {
(*node).children
};
(*ret).children = children;
(*ret).last = children;
}
} else if !n.children.is_null() && extended != 2 {
let mut cur = n.children;
let mut insert = ret;
while !cur.is_null() {
let copy = static_copy_node(cur, doc, insert, 2);
if copy.is_null() {
free_node(ret);
return ptr::null_mut();
}
unsafe {
if (*insert).last != copy {
if (*insert).last.is_null() {
(*insert).children = copy;
} else {
(*copy).prev = (*insert).last;
(*(*insert).last).next = copy;
}
(*insert).last = copy;
}
if (*cur).type_ != XML_ENTITY_REF_NODE as c_int && !(*cur).children.is_null() {
cur = (*cur).children;
insert = copy;
continue;
}
}
loop {
unsafe {
if !(*cur).next.is_null() {
cur = (*cur).next;
break;
}
cur = (*cur).parent;
insert = (*insert).parent;
if std::ptr::eq(cur, node) {
cur = ptr::null_mut();
break;
}
}
}
}
}
ret
}
unsafe fn static_copy_node_list(
node: *const _xmlNode,
doc: *mut _xmlDoc,
parent: *mut _xmlNode,
) -> *mut _xmlNode {
let mut ret: *mut _xmlNode = ptr::null_mut();
let mut p: *mut _xmlNode = ptr::null_mut();
let mut new_subset: *mut _xmlDtd = ptr::null_mut();
let mut linked_subset: c_int = 0;
let mut cur = node;
while !cur.is_null() {
unsafe {
let next = (*cur).next;
let mut q: *mut _xmlNode = ptr::null_mut();
if (*cur).type_ == XML_DTD_NODE as c_int {
if doc.is_null() {
cur = next;
continue;
}
if (*doc).intSubset.is_null() && new_subset.is_null() {
q = copy_dtd_internal(cur as *mut _xmlDtd) as *mut _xmlNode;
if q.is_null() {
free_node_list(ret);
if !new_subset.is_null() {
free_dtd_internal(new_subset);
}
return ptr::null_mut();
}
set_tree_doc(q, doc);
(*q).parent = parent;
new_subset = q as *mut _xmlDtd;
} else {
linked_subset = 1;
q = (*doc).intSubset as *mut _xmlNode;
if (*q).prev.is_null() {
if !(*q).parent.is_null() {
(*(*q).parent).children = (*q).next;
}
} else {
(*(*q).prev).next = (*q).next;
}
if (*q).next.is_null() {
if !(*q).parent.is_null() {
(*(*q).parent).last = (*q).prev;
}
} else {
(*(*q).next).prev = (*q).prev;
}
(*q).parent = parent;
(*q).next = ptr::null_mut();
(*q).prev = ptr::null_mut();
}
} else {
q = static_copy_node(cur, doc, parent, 1);
}
if q.is_null() {
free_node_list(ret);
if !new_subset.is_null() {
free_dtd_internal(new_subset);
}
if linked_subset != 0 && !doc.is_null() {
(*(*doc).intSubset).next = ptr::null_mut();
(*(*doc).intSubset).prev = ptr::null_mut();
}
return ptr::null_mut();
}
if ret.is_null() {
(*q).prev = ptr::null_mut();
ret = q;
p = q;
} else if p != q {
(*p).next = q;
(*q).prev = p;
p = q;
}
cur = next;
}
}
if !doc.is_null() && !new_subset.is_null() {
unsafe { (*doc).intSubset = new_subset };
}
ret
}
unsafe fn copy_prop_internal(
doc: *mut _xmlDoc,
target: *mut _xmlNode,
cur: *mut _xmlAttr,
) -> *mut _xmlAttr {
if cur.is_null() {
return ptr::null_mut();
}
if !target.is_null() && unsafe { (*target).type_ } != XML_ELEMENT_NODE as c_int {
return ptr::null_mut();
}
let ret_doc: *mut _xmlDoc = if !target.is_null() {
unsafe { (*target).doc }
} else if !doc.is_null() {
doc
} else if !unsafe { (*cur).parent }.is_null() {
unsafe { (*(*cur).parent).doc }
} else if !unsafe { (*cur).children }.is_null() {
unsafe { (*(*cur).children).doc }
} else {
ptr::null_mut()
};
let ret = xmlMallocZero(size_of::<_xmlAttr>()) as *mut _xmlAttr;
if ret.is_null() {
return ptr::null_mut();
}
unsafe {
(*ret).type_ = XML_ATTRIBUTE_NODE as c_int;
(*ret).name = xml_strdup((*cur).name);
(*ret).doc = ret_doc;
(*ret).parent = target;
if !(*cur).ns.is_null() && !target.is_null() {
let mut ns = search_ns((*target).doc, target, (*(*cur).ns).prefix);
if ns.is_null() {
let orig_parent = (*cur).parent;
if !orig_parent.is_null() {
ns = search_ns((*orig_parent).doc, orig_parent, (*(*cur).ns).prefix);
}
if !ns.is_null() {
let mut root = target;
let mut pred: *mut _xmlNode = ptr::null_mut();
while !(*root).parent.is_null() {
pred = root;
root = (*root).parent;
}
if root == (*target).doc as *mut _xmlNode {
root = pred;
}
(*ret).ns = new_ns(root, (*ns).href, (*ns).prefix);
if (*ret).ns.is_null() {
free_prop_internal(ret);
return ptr::null_mut();
}
}
} else if !(*ns).href.is_null()
&& !(*(*cur).ns).href.is_null()
&& crate::abi::exports_xml2::xmlStrEqual((*ns).href, (*(*cur).ns).href) != 0
{
(*ret).ns = ns;
} else {
let newns = new_reconciled_ns((*target).doc, target, (*cur).ns);
if newns.is_null() {
free_prop_internal(ret);
return ptr::null_mut();
}
(*ret).ns = newns;
}
}
if !(*cur).children.is_null() {
let children = static_copy_node_list((*cur).children, ret_doc, ret as *mut _xmlNode);
if children.is_null() {
free_prop_internal(ret);
return ptr::null_mut();
}
(*ret).children = children;
let mut tmp = children;
while !tmp.is_null() {
if (*tmp).next.is_null() {
(*ret).last = tmp;
}
tmp = (*tmp).next;
}
}
}
ret
}
unsafe fn free_prop_internal(prop: *mut _xmlAttr) {
if prop.is_null() {
return;
}
unsafe {
if !(*prop).name.is_null() {
xmlFreeImpl((*prop).name as *mut c_void);
}
if !(*prop).children.is_null() {
free_node_list((*prop).children);
}
xmlFreeImpl(prop as *mut c_void);
}
}
unsafe fn free_node(node: *mut _xmlNode) {
if node.is_null() {
return;
}
unsafe {
let t = (*node).type_;
if t == XML_DTD_NODE as c_int {
free_dtd_internal(node as *mut _xmlDtd);
return;
}
if !(*node).name.is_null() {
xmlFreeImpl((*node).name as *mut c_void);
}
if !(*node).content.is_null()
&& t != XML_ATTRIBUTE_NODE as c_int
&& t != XML_ENTITY_REF_NODE as c_int
{
xmlFreeImpl((*node).content as *mut c_void);
}
if !(*node).properties.is_null() {
let mut cur = (*node).properties;
while !cur.is_null() {
let next = (*cur).next;
free_prop_internal(cur);
cur = next;
}
}
if !(*node).children.is_null() {
free_node_list((*node).children);
}
xmlFreeImpl(node as *mut c_void);
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyNamespace(cur: *mut _xmlNs) -> *mut _xmlNs {
if cur.is_null() {
return ptr::null_mut();
}
if unsafe { (*cur).type_ } != XML_NAMESPACE_DECL as c_int {
return ptr::null_mut();
}
unsafe { new_ns(ptr::null_mut(), (*cur).href, (*cur).prefix) }
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyNamespaceList(cur: *mut _xmlNs) -> *mut _xmlNs {
copy_namespace_list(cur)
}
unsafe fn copy_namespace_list(cur: *mut _xmlNs) -> *mut _xmlNs {
let mut ret: *mut _xmlNs = ptr::null_mut();
let mut p: *mut _xmlNs = ptr::null_mut();
let mut c = cur;
while !c.is_null() {
let q = xmlCopyNamespace(c);
if q.is_null() {
free_ns_list(ret);
return ptr::null_mut();
}
if p.is_null() {
ret = q;
p = q;
} else {
unsafe { (*p).next = q };
p = q;
}
c = unsafe { (*c).next };
}
ret
}
unsafe fn free_ns_list(ns: *mut _xmlNs) {
let mut cur = ns;
while !cur.is_null() {
let next = unsafe { (*cur).next };
unsafe {
if !(*cur).href.is_null() {
xmlFreeImpl((*cur).href as *mut c_void);
}
if !(*cur).prefix.is_null() {
xmlFreeImpl((*cur).prefix as *mut c_void);
}
xmlFreeImpl(cur as *mut c_void);
}
cur = next;
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyProp(target: *mut _xmlNode, cur: *mut _xmlAttr) -> *mut _xmlAttr {
copy_prop_internal(ptr::null_mut(), target, cur)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyPropList(
target: *mut _xmlNode,
cur: *mut _xmlAttr,
) -> *mut _xmlAttr {
copy_prop_list(target, cur)
}
unsafe fn copy_prop_list(target: *mut _xmlNode, cur: *mut _xmlAttr) -> *mut _xmlAttr {
if !target.is_null() && unsafe { (*target).type_ } != XML_ELEMENT_NODE as c_int {
return ptr::null_mut();
}
let mut ret: *mut _xmlAttr = ptr::null_mut();
let mut p: *mut _xmlAttr = ptr::null_mut();
let mut c = cur;
while !c.is_null() {
let q = xmlCopyProp(target, c);
if q.is_null() {
free_prop_list(ret);
return ptr::null_mut();
}
if p.is_null() {
ret = q;
p = q;
} else {
unsafe {
(*p).next = q;
(*q).prev = p;
}
p = q;
}
c = unsafe { (*c).next };
}
ret
}
unsafe fn free_prop_list(prop: *mut _xmlAttr) {
let mut cur = prop;
while !cur.is_null() {
let next = unsafe { (*cur).next };
free_prop_internal(cur);
cur = next;
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyNodeList(node: *mut _xmlNode) -> *mut _xmlNode {
static_copy_node_list(node, ptr::null_mut(), ptr::null_mut())
}
#[no_mangle]
pub unsafe extern "C" fn xmlDocCopyNode(
node: *mut _xmlNode,
doc: *mut _xmlDoc,
recursive: c_int,
) -> *mut _xmlNode {
static_copy_node(node, doc, ptr::null_mut(), recursive)
}
#[no_mangle]
pub unsafe extern "C" fn xmlDocCopyNodeList(
doc: *mut _xmlDoc,
node: *mut _xmlNode,
) -> *mut _xmlNode {
static_copy_node_list(node, doc, ptr::null_mut())
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyEnumeration(cur: *mut _xmlEnumeration) -> *mut _xmlEnumeration {
let mut ret: *mut _xmlEnumeration = ptr::null_mut();
let mut last: *mut _xmlEnumeration = ptr::null_mut();
let mut c = cur;
while !c.is_null() {
let copy = xmlMallocZero(size_of::<_xmlEnumeration>()) as *mut _xmlEnumeration;
if copy.is_null() {
free_enumeration(ret);
return ptr::null_mut();
}
unsafe {
if !(*c).name.is_null() {
(*copy).name = xml_strdup((*c).name);
if (*copy).name.is_null() {
xmlFreeImpl(copy as *mut c_void);
free_enumeration(ret);
return ptr::null_mut();
}
}
}
if ret.is_null() {
ret = copy;
last = copy;
} else {
unsafe { (*last).next = copy };
last = copy;
}
c = unsafe { (*c).next };
}
ret
}
unsafe fn free_enumeration(cur: *mut _xmlEnumeration) {
let mut c = cur;
while !c.is_null() {
let next = unsafe { (*c).next };
unsafe {
if !(*c).name.is_null() {
xmlFreeImpl((*c).name as *mut c_void);
}
xmlFreeImpl(c as *mut c_void);
}
c = next;
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyDocElementContent(
_doc: *mut _xmlDoc,
cur: *mut _xmlElementContent,
) -> *mut _xmlElementContent {
if cur.is_null() {
return ptr::null_mut();
}
let ret = xmlMallocZero(size_of::<_xmlElementContent>()) as *mut _xmlElementContent;
if ret.is_null() {
return ptr::null_mut();
}
unsafe {
(*ret).type_ = (*cur).type_;
(*ret).ocur = (*cur).ocur;
if !(*cur).name.is_null() {
(*ret).name = xml_strdup((*cur).name);
if (*ret).name.is_null() {
free_element_content_internal(ret);
return ptr::null_mut();
}
}
if !(*cur).prefix.is_null() {
(*ret).prefix = xml_strdup((*cur).prefix);
if (*ret).prefix.is_null() {
free_element_content_internal(ret);
return ptr::null_mut();
}
}
if !(*cur).c1.is_null() {
(*ret).c1 = xmlCopyDocElementContent(_doc, (*cur).c1);
if (*ret).c1.is_null() {
free_element_content_internal(ret);
return ptr::null_mut();
}
(*(*ret).c1).parent = ret;
}
let mut prev = ret;
let mut cc = (*cur).c2;
while !cc.is_null() {
let tmp = xmlMallocZero(size_of::<_xmlElementContent>()) as *mut _xmlElementContent;
if tmp.is_null() {
free_element_content_internal(ret);
return ptr::null_mut();
}
(*tmp).type_ = (*cc).type_;
(*tmp).ocur = (*cc).ocur;
(*prev).c2 = tmp;
(*tmp).parent = prev;
if !(*cc).name.is_null() {
(*tmp).name = xml_strdup((*cc).name);
if (*tmp).name.is_null() {
free_element_content_internal(ret);
return ptr::null_mut();
}
}
if !(*cc).prefix.is_null() {
(*tmp).prefix = xml_strdup((*cc).prefix);
if (*tmp).prefix.is_null() {
free_element_content_internal(ret);
return ptr::null_mut();
}
}
if !(*cc).c1.is_null() {
(*tmp).c1 = xmlCopyDocElementContent(_doc, (*cc).c1);
if (*tmp).c1.is_null() {
free_element_content_internal(ret);
return ptr::null_mut();
}
(*(*tmp).c1).parent = tmp;
}
prev = tmp;
cc = (*cc).c2;
}
}
ret
}
unsafe fn free_element_content_internal(cur: *mut _xmlElementContent) {
if cur.is_null() {
return;
}
unsafe {
if !(*cur).c1.is_null() {
free_element_content_internal((*cur).c1);
}
if !(*cur).c2.is_null() {
free_element_content_internal((*cur).c2);
}
if !(*cur).name.is_null() {
xmlFreeImpl((*cur).name as *mut c_void);
}
if !(*cur).prefix.is_null() {
xmlFreeImpl((*cur).prefix as *mut c_void);
}
xmlFreeImpl(cur as *mut c_void);
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyDtd(dtd: *mut _xmlDtd) -> *mut _xmlDtd {
copy_dtd_internal(dtd)
}
unsafe fn copy_dtd_internal(dtd: *mut _xmlDtd) -> *mut _xmlDtd {
if dtd.is_null() {
return ptr::null_mut();
}
unsafe {
let d = &*dtd;
let ret = crate::xml::tree::new_dtd(ptr::null_mut(), d.name, d.ExternalID, d.SystemID);
if ret.is_null() {
return ptr::null_mut();
}
if !d.entities.is_null() {
let t = xmlCopyEntitiesTable(d.entities);
if t.is_null() {
free_dtd_internal(ret);
return ptr::null_mut();
}
(*ret).entities = t;
}
if !d.notations.is_null() {
let t = xmlCopyNotationTable(d.notations);
if t.is_null() {
free_dtd_internal(ret);
return ptr::null_mut();
}
(*ret).notations = t;
}
if !d.elements.is_null() {
let t = xmlCopyElementTable(d.elements);
if t.is_null() {
free_dtd_internal(ret);
return ptr::null_mut();
}
(*ret).elements = t;
}
if !d.attributes.is_null() {
let t = xmlCopyAttributeTable(d.attributes);
if t.is_null() {
free_dtd_internal(ret);
return ptr::null_mut();
}
(*ret).attributes = t;
}
if !d.pentities.is_null() {
let t = xmlCopyEntitiesTable(d.pentities);
if t.is_null() {
free_dtd_internal(ret);
return ptr::null_mut();
}
(*ret).pentities = t;
}
let mut cur = d.children;
let mut p: *mut _xmlNode = ptr::null_mut();
while !cur.is_null() {
let mut q: *mut _xmlNode = ptr::null_mut();
let ct = (*cur).type_;
if ct == XML_ENTITY_DECL as c_int {
let tmp = cur as *mut _xmlEntity;
match (*tmp).etype {
t if t == XML_INTERNAL_GENERAL_ENTITY as c_int
|| t == XML_EXTERNAL_GENERAL_PARSED_ENTITY as c_int
|| t == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY as c_int =>
{
q = crate::xml::entities::get_entity_from_dtd(ret, (*tmp).name)
as *mut _xmlNode;
}
t if t == XML_INTERNAL_PARAMETER_ENTITY as c_int
|| t == XML_EXTERNAL_PARAMETER_ENTITY as c_int =>
{
q = crate::xml::hash::hash_lookup(
(*ret).pentities as *mut crate::xml::hash::HashTable,
(*tmp).name,
) as *mut _xmlNode;
}
_ => {}
}
} else if ct == XML_ELEMENT_DECL as c_int {
let tmp = cur as *mut _xmlElement;
q = crate::xml::dtd::get_element_decl(ret, (*tmp).name) as *mut _xmlNode;
} else if ct == XML_ATTRIBUTE_DECL as c_int {
let tmp = cur as *mut _xmlAttribute;
let elem = if (*tmp).elem.is_null() {
ptr::null_mut()
} else {
crate::xml::dtd::get_element_decl(ret, (*tmp).elem)
};
q = crate::xml::dtd::get_attribute_decl(ret, elem, (*tmp).name, 0) as *mut _xmlNode;
} else if ct == XML_COMMENT_NODE as c_int {
q = copy_node(cur, 0);
if q.is_null() {
free_dtd_internal(ret);
return ptr::null_mut();
}
}
if !q.is_null() {
if p.is_null() {
(*ret).children = q;
} else {
(*p).next = q;
(*q).prev = p;
}
p = q;
}
cur = (*cur).next;
}
ret
}
}
unsafe fn free_dtd_internal(dtd: *mut _xmlDtd) {
if dtd.is_null() {
return;
}
unsafe {
if !(*dtd).children.is_null() {
let mut c = (*dtd).children;
while !c.is_null() {
let next = (*c).next;
let t = (*c).type_;
if t != crate::abi::types::xmlElementType::XML_ELEMENT_DECL as c_int
&& t != crate::abi::types::xmlElementType::XML_ATTRIBUTE_DECL as c_int
&& t != crate::abi::types::xmlElementType::XML_ENTITY_DECL as c_int
{
free_node(c);
}
c = next;
}
}
if !(*dtd).name.is_null() {
xmlFreeImpl((*dtd).name as *mut c_void);
}
if !(*dtd).ExternalID.is_null() {
xmlFreeImpl((*dtd).ExternalID as *mut c_void);
}
if !(*dtd).SystemID.is_null() {
xmlFreeImpl((*dtd).SystemID as *mut c_void);
}
unsafe extern "C" fn free_notation_wrapper(payload: *mut c_void, _name: *mut u8) {
crate::xml::dtd::free_notation(payload as *mut _xmlNotation);
}
unsafe extern "C" fn free_element_wrapper(payload: *mut c_void, _name: *mut u8) {
crate::xml::dtd::free_element(payload as *mut _xmlElement);
}
unsafe extern "C" fn free_attribute_wrapper(payload: *mut c_void, _name: *mut u8) {
crate::xml::dtd::free_attribute(payload as *mut _xmlAttribute);
}
unsafe extern "C" fn free_entity_wrapper(payload: *mut c_void, _name: *mut u8) {
crate::xml::entities::free_entity(payload as *mut _xmlEntity);
}
if !(*dtd).notations.is_null() {
crate::xml::hash::hash_free(
(*dtd).notations as *mut crate::xml::hash::HashTable,
Some(free_notation_wrapper),
);
}
if !(*dtd).elements.is_null() {
crate::xml::hash::hash_free(
(*dtd).elements as *mut crate::xml::hash::HashTable,
Some(free_element_wrapper),
);
}
if !(*dtd).attributes.is_null() {
crate::xml::hash::hash_free(
(*dtd).attributes as *mut crate::xml::hash::HashTable,
Some(free_attribute_wrapper),
);
}
if !(*dtd).entities.is_null() {
crate::xml::hash::hash_free(
(*dtd).entities as *mut crate::xml::hash::HashTable,
Some(free_entity_wrapper),
);
}
if !(*dtd).pentities.is_null() {
crate::xml::hash::hash_free(
(*dtd).pentities as *mut crate::xml::hash::HashTable,
Some(free_entity_wrapper),
);
}
xmlFreeImpl(dtd as *mut c_void);
}
}
unsafe extern "C" fn copy_element_cb(payload: *mut c_void, _name: *const xmlChar) -> *mut c_void {
crate::xml::dtd::copy_element(payload as *mut _xmlElement) as *mut c_void
}
unsafe extern "C" fn copy_attribute_cb(payload: *mut c_void, _name: *const xmlChar) -> *mut c_void {
crate::xml::dtd::copy_attribute_decl(payload as *mut _xmlAttribute) as *mut c_void
}
unsafe extern "C" fn copy_notation_cb(payload: *mut c_void, _name: *const xmlChar) -> *mut c_void {
crate::xml::dtd::copy_notation(payload as *mut _xmlNotation) as *mut c_void
}
unsafe extern "C" fn copy_entity_cb(payload: *mut c_void, _name: *const xmlChar) -> *mut c_void {
crate::xml::entities::copy_entity(payload as *mut _xmlEntity) as *mut c_void
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyElementTable(table: *mut c_void) -> *mut c_void {
crate::xml::hash::hash_copy(
table as *mut crate::xml::hash::HashTable,
Some(copy_element_cb),
) as *mut c_void
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyAttributeTable(table: *mut c_void) -> *mut c_void {
crate::xml::hash::hash_copy(
table as *mut crate::xml::hash::HashTable,
Some(copy_attribute_cb),
) as *mut c_void
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyNotationTable(table: *mut c_void) -> *mut c_void {
crate::xml::hash::hash_copy(
table as *mut crate::xml::hash::HashTable,
Some(copy_notation_cb),
) as *mut c_void
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyEntitiesTable(table: *mut c_void) -> *mut c_void {
crate::xml::hash::hash_copy(
table as *mut crate::xml::hash::HashTable,
Some(copy_entity_cb),
) as *mut c_void
}
unsafe fn write_quoted_string(buf: *mut _xmlBuffer, str: *const xmlChar) {
io::buf_ccat(buf, b'"');
if !str.is_null() {
let mut i = 0usize;
while unsafe { *str.add(i) } != 0 {
let ch = unsafe { *str.add(i) };
if ch == b'"' {
io::buf_add(buf, b""" as *const u8, 6);
} else {
io::buf_add(buf, &ch as *const u8, 1);
}
i += 1;
}
}
io::buf_ccat(buf, b'"');
}
unsafe fn dump_notation_decl(buf: *mut _xmlBuffer, nota: *mut _xmlNotation) {
let n = unsafe { &*nota };
io::buf_add(buf, b"<!NOTATION " as *const u8, 11);
if !n.name.is_null() {
io::buf_cat(buf, n.name);
}
if !n.PublicID.is_null() {
io::buf_add(buf, b" PUBLIC " as *const u8, 8);
write_quoted_string(buf, n.PublicID);
if !n.SystemID.is_null() {
io::buf_ccat(buf, b' ');
write_quoted_string(buf, n.SystemID);
}
} else {
io::buf_add(buf, b" SYSTEM " as *const u8, 8);
write_quoted_string(buf, n.SystemID);
}
io::buf_add(buf, b" >\n" as *const u8, 4);
}
#[no_mangle]
pub unsafe extern "C" fn xmlDumpElementDecl(buf: *mut _xmlBuffer, elem: *mut _xmlElement) {
if buf.is_null() || elem.is_null() {
return;
}
serialize_node_opts(elem as *mut _xmlNode, buf, 0, 0, ptr::null(), 0);
}
#[no_mangle]
pub unsafe extern "C" fn xmlDumpAttributeDecl(buf: *mut _xmlBuffer, attr: *mut _xmlAttribute) {
if buf.is_null() || attr.is_null() {
return;
}
serialize_node_opts(attr as *mut _xmlNode, buf, 0, 0, ptr::null(), 0);
}
#[no_mangle]
pub unsafe extern "C" fn xmlDumpEntityDecl(buf: *mut _xmlBuffer, ent: *mut _xmlEntity) {
if buf.is_null() || ent.is_null() {
return;
}
serialize_node_opts(ent as *mut _xmlNode, buf, 0, 0, ptr::null(), 0);
}
#[no_mangle]
pub unsafe extern "C" fn xmlDumpNotationDecl(buf: *mut _xmlBuffer, nota: *mut _xmlNotation) {
if buf.is_null() || nota.is_null() {
return;
}
dump_notation_decl(buf, nota);
}
unsafe extern "C" fn dump_element_decl_cb(
payload: *mut c_void,
data: *mut c_void,
_name: *const xmlChar,
) {
if !payload.is_null() && !data.is_null() {
serialize_node_opts(
payload as *mut _xmlNode,
data as *mut _xmlBuffer,
0,
0,
ptr::null(),
0,
);
}
}
unsafe extern "C" fn dump_attribute_decl_cb(
payload: *mut c_void,
data: *mut c_void,
_name: *const xmlChar,
) {
if !payload.is_null() && !data.is_null() {
serialize_node_opts(
payload as *mut _xmlNode,
data as *mut _xmlBuffer,
0,
0,
ptr::null(),
0,
);
}
}
unsafe extern "C" fn dump_entity_decl_cb(
payload: *mut c_void,
data: *mut c_void,
_name: *const xmlChar,
) {
if !payload.is_null() && !data.is_null() {
serialize_node_opts(
payload as *mut _xmlNode,
data as *mut _xmlBuffer,
0,
0,
ptr::null(),
0,
);
}
}
unsafe extern "C" fn dump_notation_decl_cb(
payload: *mut c_void,
data: *mut c_void,
_name: *const xmlChar,
) {
if !payload.is_null() && !data.is_null() {
dump_notation_decl(data as *mut _xmlBuffer, payload as *mut _xmlNotation);
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlDumpElementTable(buf: *mut _xmlBuffer, table: *mut c_void) {
if buf.is_null() || table.is_null() {
return;
}
crate::xml::hash::hash_scan(
table as *mut crate::xml::hash::HashTable,
Some(dump_element_decl_cb),
buf as *mut c_void,
);
}
#[no_mangle]
pub unsafe extern "C" fn xmlDumpAttributeTable(buf: *mut _xmlBuffer, table: *mut c_void) {
if buf.is_null() || table.is_null() {
return;
}
crate::xml::hash::hash_scan(
table as *mut crate::xml::hash::HashTable,
Some(dump_attribute_decl_cb),
buf as *mut c_void,
);
}
#[no_mangle]
pub unsafe extern "C" fn xmlDumpNotationTable(buf: *mut _xmlBuffer, table: *mut c_void) {
if buf.is_null() || table.is_null() {
return;
}
crate::xml::hash::hash_scan(
table as *mut crate::xml::hash::HashTable,
Some(dump_notation_decl_cb),
buf as *mut c_void,
);
}
#[no_mangle]
pub unsafe extern "C" fn xmlDumpEntitiesTable(buf: *mut _xmlBuffer, table: *mut c_void) {
if buf.is_null() || table.is_null() {
return;
}
crate::xml::hash::hash_scan(
table as *mut crate::xml::hash::HashTable,
Some(dump_entity_decl_cb),
buf as *mut c_void,
);
}
#[no_mangle]
pub unsafe extern "C" fn xmlAttrSerializeTxtContent(
buf: *mut _xmlBuffer,
_doc: *mut _xmlDoc,
_attr: *mut _xmlAttr,
string: *const xmlChar,
) {
if buf.is_null() || string.is_null() {
return;
}
serialize_attr_value(buf, string);
}
#[no_mangle]
pub unsafe extern "C" fn xmlNodeDumpOutput(
buf: *mut _xmlOutputBuffer,
_doc: *mut _xmlDoc,
cur: *mut _xmlNode,
level: c_int,
format: c_int,
_encoding: *const c_char,
) {
if buf.is_null() || cur.is_null() {
return;
}
let level = level.clamp(0, 100);
let tmp = io::buf_create(-1);
if tmp.is_null() {
return;
}
serialize_node_opts(cur, tmp, format, level, ptr::null(), 0);
let content = io::buf_content(tmp);
let len = io::buf_length(tmp);
if !content.is_null() && len > 0 {
io::output_buffer_write(buf, len, content as *const c_char);
}
io::buf_free(tmp);
}
#[no_mangle]
pub unsafe extern "C" fn xmlElemDump(f: *mut c_void, doc: *mut _xmlDoc, cur: *mut _xmlNode) {
if f.is_null() || cur.is_null() {
return;
}
let out = io::output_buffer_create_file(f as *mut libc::FILE, ptr::null_mut());
if out.is_null() {
return;
}
let tmp = io::buf_create(-1);
if tmp.is_null() {
io::output_buffer_close(out);
return;
}
if !doc.is_null() && (*doc).type_ == XML_HTML_DOCUMENT_NODE as c_int {
crate::xml::html::serialize_node(cur, tmp, 1, 0);
} else {
serialize_node_opts(cur, tmp, 1, 0, ptr::null(), 0);
}
let content = io::buf_content(tmp);
let len = io::buf_length(tmp);
if !content.is_null() && len > 0 {
io::output_buffer_write(out, len, content as *const c_char);
}
io::buf_free(tmp);
io::output_buffer_close(out);
}
#[no_mangle]
pub unsafe extern "C" fn xmlDocFormatDump(
f: *mut c_void,
cur: *mut _xmlDoc,
format: c_int,
) -> c_int {
if cur.is_null() {
return -1;
}
let out = io::output_buffer_create_file(f as *mut libc::FILE, ptr::null_mut());
if out.is_null() {
return -1;
}
let tmp = io::buf_create(-1);
if tmp.is_null() {
io::output_buffer_close(out);
return -1;
}
serialize_node_opts(cur as *mut _xmlNode, tmp, format, 0, ptr::null(), 0);
let content = io::buf_content(tmp);
let len = io::buf_length(tmp);
if !content.is_null() && len > 0 {
io::output_buffer_write(out, len, content as *const c_char);
}
io::buf_free(tmp);
let ret = io::output_buffer_close(out);
if ret < 0 {
-1
} else {
ret
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlDocDumpFormatMemoryEnc(
out_doc: *mut _xmlDoc,
doc_txt_ptr: *mut *mut xmlChar,
doc_txt_len: *mut c_int,
txt_encoding: *const c_char,
format: c_int,
) {
if !doc_txt_len.is_null() {
unsafe { *doc_txt_len = 0 };
}
if doc_txt_ptr.is_null() {
return;
}
unsafe { *doc_txt_ptr = ptr::null_mut() };
if out_doc.is_null() {
return;
}
let buf = io::buf_create(-1);
if buf.is_null() {
return;
}
if !txt_encoding.is_null() {
write_xml_declaration(buf, out_doc, txt_encoding as *const xmlChar);
serialize_node_opts(out_doc as *mut _xmlNode, buf, format, 0, ptr::null(), 1);
} else {
serialize_node_opts(out_doc as *mut _xmlNode, buf, format, 0, ptr::null(), 0);
}
let content = io::buf_content(buf);
let len = io::buf_length(buf);
if !content.is_null() && len > 0 {
let result = xmlMallocImpl((len + 1) as usize) as *mut xmlChar;
if !result.is_null() {
ptr::copy_nonoverlapping(content, result, len as usize);
*result.add(len as usize) = 0;
unsafe {
*doc_txt_ptr = result;
if !doc_txt_len.is_null() {
*doc_txt_len = len;
}
}
}
}
io::buf_free(buf);
}
unsafe fn write_xml_declaration(buf: *mut _xmlBuffer, doc: *mut _xmlDoc, encoding: *const xmlChar) {
let d = unsafe { &*doc };
io::buf_add(buf, b"<?xml version=\"" as *const u8, 15);
if !d.version.is_null() {
io::buf_cat(buf, d.version);
} else {
io::buf_add(buf, b"1.0" as *const u8, 3);
}
io::buf_ccat(buf, b'"');
if !encoding.is_null() {
io::buf_add(buf, b" encoding=\"" as *const u8, 11);
io::buf_cat(buf, encoding);
io::buf_ccat(buf, b'"');
}
match d.standalone {
0 => {
io::buf_add(buf, b" standalone=\"no\"" as *const u8, 16);
}
1 => {
io::buf_add(buf, b" standalone=\"yes\"" as *const u8, 17);
}
_ => {}
}
io::buf_add(buf, b"?>\n" as *const u8, 3);
}
#[no_mangle]
pub unsafe extern "C" fn xmlDocDumpMemoryEnc(
out_doc: *mut _xmlDoc,
doc_txt_ptr: *mut *mut xmlChar,
doc_txt_len: *mut c_int,
txt_encoding: *const c_char,
) {
xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len, txt_encoding, 0)
}
unsafe fn debug_err(f: *mut _IO_FILE, errors: &mut c_int, code: c_int, msg: *const c_char) {
*errors += 1;
libc::fprintf(f, c"ERROR %d: %s".as_ptr() as *const c_char, code, msg);
}
unsafe fn debug_err_str(
f: *mut _IO_FILE,
errors: &mut c_int,
code: c_int,
msg: *const c_char,
extra: *const c_char,
) {
*errors += 1;
libc::fprintf(f, c"ERROR %d: ".as_ptr() as *const c_char, code);
libc::fprintf(f, msg, extra);
}
unsafe fn debug_err_int(
f: *mut _IO_FILE,
errors: &mut c_int,
code: c_int,
msg: *const c_char,
extra: c_int,
) {
*errors += 1;
libc::fprintf(f, c"ERROR %d: ".as_ptr() as *const c_char, code);
libc::fprintf(f, msg, extra);
}
unsafe fn ns_check_scope(node: *mut _xmlNode, ns: *mut _xmlNs) -> c_int {
if node.is_null() || ns.is_null() {
return -1;
}
unsafe {
let t = (*node).type_;
if t != XML_ELEMENT_NODE as c_int
&& t != XML_ATTRIBUTE_NODE as c_int
&& t != XML_DOCUMENT_NODE as c_int
&& t != XML_TEXT_NODE as c_int
&& t != XML_HTML_DOCUMENT_NODE as c_int
&& t != XML_XINCLUDE_START as c_int
{
return -2;
}
let mut cur_node = node;
while !cur_node.is_null()
&& ((*cur_node).type_ == XML_ELEMENT_NODE as c_int
|| (*cur_node).type_ == XML_ATTRIBUTE_NODE as c_int
|| (*cur_node).type_ == XML_TEXT_NODE as c_int
|| (*cur_node).type_ == XML_XINCLUDE_START as c_int)
{
if (*cur_node).type_ == XML_ELEMENT_NODE as c_int
|| (*cur_node).type_ == XML_XINCLUDE_START as c_int
{
let mut cur = (*cur_node).nsDef;
while !cur.is_null() {
if cur == ns {
return 1;
}
if crate::abi::exports_xml2::xmlStrEqual((*cur).prefix, (*ns).prefix) != 0 {
return -2;
}
cur = (*cur).next;
}
}
cur_node = (*cur_node).parent;
}
if !cur_node.is_null()
&& ((*cur_node).type_ == XML_DOCUMENT_NODE as c_int
|| (*cur_node).type_ == XML_HTML_DOCUMENT_NODE as c_int)
{
let old_ns = (*(cur_node as *mut _xmlDoc)).oldNs;
if old_ns == ns {
return 1;
}
}
}
-3
}
unsafe fn ns_check_scope_report(
f: *mut _IO_FILE,
errors: &mut c_int,
node: *mut _xmlNode,
ns: *mut _xmlNs,
) {
let ret = ns_check_scope(node, ns);
if ret == -2 {
if unsafe { (*ns).prefix.is_null() } {
debug_err(
f,
errors,
XML_CHECK_NS_SCOPE,
c"Reference to default namespace not in scope\n".as_ptr() as *const c_char,
);
} else {
debug_err_str(
f,
errors,
XML_CHECK_NS_SCOPE,
c"Reference to namespace '%s' not in scope\n".as_ptr() as *const c_char,
unsafe { (*ns).prefix } as *const c_char,
);
}
}
if ret == -3 {
if unsafe { (*ns).prefix.is_null() } {
debug_err(
f,
errors,
XML_CHECK_NS_ANCESTOR,
c"Reference to default namespace not on ancestor\n".as_ptr() as *const c_char,
);
} else {
debug_err_str(
f,
errors,
XML_CHECK_NS_ANCESTOR,
c"Reference to namespace '%s' not on ancestor\n".as_ptr() as *const c_char,
unsafe { (*ns).prefix } as *const c_char,
);
}
}
}
unsafe fn check_string(f: *mut _IO_FILE, errors: &mut c_int, str: *const xmlChar) {
if str.is_null() {
return;
}
if check_utf8(str) == 0 {
debug_err_str(
f,
errors,
XML_CHECK_NOT_UTF8,
c"String is not UTF-8 %s".as_ptr() as *const c_char,
str as *const c_char,
);
}
}
unsafe fn check_name(f: *mut _IO_FILE, errors: &mut c_int, name: *const xmlChar) {
if name.is_null() {
debug_err(
f,
errors,
XML_CHECK_NO_NAME,
c"Name is NULL".as_ptr() as *const c_char,
);
return;
}
if crate::xml::validation::validate_name_space(name, 0) != 0 {
debug_err_str(
f,
errors,
XML_CHECK_NOT_NCNAME,
c"Name is not an NCName '%s'".as_ptr() as *const c_char,
name as *const c_char,
);
}
}
unsafe fn generic_node_check(f: *mut _IO_FILE, errors: &mut c_int, node: *mut _xmlNode) {
unsafe {
let doc = (*node).doc;
if (*node).parent.is_null() {
debug_err(
f,
errors,
XML_CHECK_NO_PARENT,
c"Node has no parent\n".as_ptr() as *const c_char,
);
}
if (*node).doc.is_null() {
debug_err(
f,
errors,
XML_CHECK_NO_DOC,
c"Node has no doc\n".as_ptr() as *const c_char,
);
}
if !(*node).parent.is_null()
&& (*node).doc != (*(*node).parent).doc
&& !c_str_eq_bytes((*node).name, b"pseudoroot")
{
debug_err(
f,
errors,
XML_CHECK_WRONG_DOC,
c"Node doc differs from parent's one\n".as_ptr() as *const c_char,
);
}
if (*node).prev.is_null() {
if (*node).type_ == XML_ATTRIBUTE_NODE as c_int {
if !(*node).parent.is_null()
&& node != (*(*node).parent).properties as *mut _xmlNode
{
debug_err(
f,
errors,
XML_CHECK_NO_PREV,
c"Attr has no prev and not first of attr list\n".as_ptr() as *const c_char,
);
}
} else if !(*node).parent.is_null() && (*(*node).parent).children != node {
debug_err(
f,
errors,
XML_CHECK_NO_PREV,
c"Node has no prev and not first of parent list\n".as_ptr() as *const c_char,
);
}
} else if (*(*node).prev).next != node {
debug_err(
f,
errors,
XML_CHECK_WRONG_PREV,
c"Node prev->next : back link wrong\n".as_ptr() as *const c_char,
);
}
if (*node).next.is_null() {
if !(*node).parent.is_null()
&& (*node).type_ != XML_ATTRIBUTE_NODE as c_int
&& (*(*node).parent).last != node
&& (*(*node).parent).type_ == XML_ELEMENT_NODE as c_int
{
debug_err(
f,
errors,
XML_CHECK_NO_NEXT,
c"Node has no next and not last of parent list\n".as_ptr() as *const c_char,
);
}
} else {
if (*(*node).next).prev != node {
debug_err(
f,
errors,
XML_CHECK_WRONG_NEXT,
c"Node next->prev : forward link wrong\n".as_ptr() as *const c_char,
);
}
if (*(*node).next).parent != (*node).parent {
debug_err(
f,
errors,
XML_CHECK_WRONG_PARENT,
c"Node next->prev : forward link wrong\n".as_ptr() as *const c_char,
);
}
}
if (*node).type_ == XML_ELEMENT_NODE as c_int {
let mut ns = (*node).nsDef;
while !ns.is_null() {
ns_check_scope_report(f, errors, node, ns);
ns = (*ns).next;
}
if !(*node).ns.is_null() {
ns_check_scope_report(f, errors, node, (*node).ns);
}
} else if (*node).type_ == XML_ATTRIBUTE_NODE as c_int && !(*node).ns.is_null() {
ns_check_scope_report(f, errors, node, (*node).ns);
}
if (*node).type_ != XML_ELEMENT_NODE as c_int
&& (*node).type_ != XML_ATTRIBUTE_NODE as c_int
&& (*node).type_ != XML_ELEMENT_DECL as c_int
&& (*node).type_ != XML_ATTRIBUTE_DECL as c_int
&& (*node).type_ != XML_DTD_NODE as c_int
&& (*node).type_ != XML_HTML_DOCUMENT_NODE as c_int
&& (*node).type_ != XML_DOCUMENT_NODE as c_int
&& !(*node).content.is_null()
{
check_string(f, errors, (*node).content);
}
let _ = doc;
if (*node).type_ == XML_ELEMENT_NODE as c_int
|| (*node).type_ == XML_ATTRIBUTE_NODE as c_int
{
check_name(f, errors, (*node).name);
} else if (*node).type_ == XML_TEXT_NODE as c_int {
if !c_str_eq_bytes((*node).name, b"text") && !c_str_eq_bytes((*node).name, b"textnoenc")
{
debug_err_str(
f,
errors,
XML_CHECK_WRONG_NAME,
c"Text node has wrong name '%s'".as_ptr() as *const c_char,
(*node).name as *const c_char,
);
}
} else if (*node).type_ == XML_COMMENT_NODE as c_int {
if !c_str_eq_bytes((*node).name, b"comment") {
debug_err_str(
f,
errors,
XML_CHECK_WRONG_NAME,
c"Comment node has wrong name '%s'".as_ptr() as *const c_char,
(*node).name as *const c_char,
);
}
} else if (*node).type_ == XML_PI_NODE as c_int {
check_name(f, errors, (*node).name);
} else if (*node).type_ == XML_CDATA_SECTION_NODE as c_int && !(*node).name.is_null() {
debug_err_str(
f,
errors,
XML_CHECK_NAME_NOT_NULL,
c"CData section has non NULL name '%s'".as_ptr() as *const c_char,
(*node).name as *const c_char,
);
}
}
}
unsafe fn dump_doc_head(f: *mut _IO_FILE, errors: &mut c_int, doc: *mut _xmlDoc, check: c_int) {
unsafe {
match (*doc).type_ {
t if t == XML_ELEMENT_NODE as c_int => {
debug_err(
f,
errors,
XML_CHECK_FOUND_ELEMENT,
c"Misplaced ELEMENT node\n".as_ptr() as *const c_char,
);
}
t if t == XML_ATTRIBUTE_NODE as c_int => {
debug_err(
f,
errors,
XML_CHECK_FOUND_ATTRIBUTE,
c"Misplaced ATTRIBUTE node\n".as_ptr() as *const c_char,
);
}
t if t == XML_TEXT_NODE as c_int => {
debug_err(
f,
errors,
XML_CHECK_FOUND_TEXT,
c"Misplaced TEXT node\n".as_ptr() as *const c_char,
);
}
t if t == XML_CDATA_SECTION_NODE as c_int => {
debug_err(
f,
errors,
XML_CHECK_FOUND_CDATA,
c"Misplaced CDATA node\n".as_ptr() as *const c_char,
);
}
t if t == XML_ENTITY_REF_NODE as c_int => {
debug_err(
f,
errors,
XML_CHECK_FOUND_ENTITYREF,
c"Misplaced ENTITYREF node\n".as_ptr() as *const c_char,
);
}
t if t == XML_ENTITY_NODE as c_int => {
debug_err(
f,
errors,
XML_CHECK_FOUND_ENTITY,
c"Misplaced ENTITY node\n".as_ptr() as *const c_char,
);
}
t if t == XML_PI_NODE as c_int => {
debug_err(
f,
errors,
XML_CHECK_FOUND_PI,
c"Misplaced PI node\n".as_ptr() as *const c_char,
);
}
t if t == XML_COMMENT_NODE as c_int => {
debug_err(
f,
errors,
XML_CHECK_FOUND_COMMENT,
c"Misplaced COMMENT node\n".as_ptr() as *const c_char,
);
}
t if t == XML_DOCUMENT_NODE as c_int => {
if check == 0 {
libc::fprintf(f, c"DOCUMENT\n".as_ptr() as *const c_char);
}
}
t if t == XML_HTML_DOCUMENT_NODE as c_int => {
if check == 0 {
libc::fprintf(f, c"HTML DOCUMENT\n".as_ptr() as *const c_char);
}
}
t if t == XML_DOCUMENT_TYPE_NODE as c_int => {
debug_err(
f,
errors,
XML_CHECK_FOUND_DOCTYPE,
c"Misplaced DOCTYPE node\n".as_ptr() as *const c_char,
);
}
t if t == XML_DOCUMENT_FRAG_NODE as c_int => {
debug_err(
f,
errors,
XML_CHECK_FOUND_FRAGMENT,
c"Misplaced FRAGMENT node\n".as_ptr() as *const c_char,
);
}
t if t == XML_NOTATION_NODE as c_int => {
debug_err(
f,
errors,
XML_CHECK_FOUND_NOTATION,
c"Misplaced NOTATION node\n".as_ptr() as *const c_char,
);
}
_ => {
debug_err_int(
f,
errors,
XML_CHECK_UNKNOWN_NODE,
c"Unknown node type %d\n".as_ptr() as *const c_char,
(*doc).type_ as c_int,
);
}
}
}
}
unsafe extern "C" fn dump_entity_callback(
payload: *mut c_void,
data: *mut c_void,
_name: *const xmlChar,
) {
if payload.is_null() {
return;
}
let cur = payload as *mut _xmlEntity;
let f = data as *mut _IO_FILE;
let mut errors: c_int = 0;
unsafe {
libc::fprintf(f, c"%s : ".as_ptr() as *const c_char, (*cur).name);
match (*cur).etype {
t if t == XML_INTERNAL_GENERAL_ENTITY as c_int => {
libc::fprintf(f, c"INTERNAL GENERAL, ".as_ptr() as *const c_char);
}
t if t == XML_EXTERNAL_GENERAL_PARSED_ENTITY as c_int => {
libc::fprintf(f, c"EXTERNAL PARSED, ".as_ptr() as *const c_char);
}
t if t == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY as c_int => {
libc::fprintf(f, c"EXTERNAL UNPARSED, ".as_ptr() as *const c_char);
}
t if t == XML_INTERNAL_PARAMETER_ENTITY as c_int => {
libc::fprintf(f, c"INTERNAL PARAMETER, ".as_ptr() as *const c_char);
}
t if t == XML_EXTERNAL_PARAMETER_ENTITY as c_int => {
libc::fprintf(f, c"EXTERNAL PARAMETER, ".as_ptr() as *const c_char);
}
_ => {
debug_err_int(
f,
&mut errors,
XML_CHECK_ENTITY_TYPE,
c"Unknown entity type %d\n".as_ptr() as *const c_char,
(*cur).etype as c_int,
);
}
}
if !(*cur).ExternalID.is_null() {
libc::fprintf(f, c"ID \"%s\"".as_ptr() as *const c_char, (*cur).ExternalID);
}
if !(*cur).SystemID.is_null() {
libc::fprintf(
f,
c"SYSTEM \"%s\"".as_ptr() as *const c_char,
(*cur).SystemID,
);
}
if !(*cur).orig.is_null() {
libc::fprintf(f, c"\n orig \"%s\"".as_ptr() as *const c_char, (*cur).orig);
}
if (*cur).type_ != XML_ELEMENT_NODE as c_int && !(*cur).content.is_null() {
libc::fprintf(
f,
c"\n content \"%s\"".as_ptr() as *const c_char,
(*cur).content,
);
}
libc::fprintf(f, c"\n".as_ptr() as *const c_char);
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlDebugDumpEntities(output: *mut _IO_FILE, doc: *mut _xmlDoc) {
if output.is_null() || doc.is_null() {
return;
}
let mut errors: c_int = 0;
dump_doc_head(output, &mut errors, doc, 0);
unsafe {
let int_subset = (*doc).intSubset;
let ext_subset = (*doc).extSubset;
if !int_subset.is_null()
&& !(*int_subset).entities.is_null()
&& crate::xml::hash::hash_size(
(*int_subset).entities as *mut crate::xml::hash::HashTable,
) > 0
{
libc::fprintf(
output,
c"Entities in internal subset\n".as_ptr() as *const c_char,
);
crate::xml::hash::hash_scan(
(*int_subset).entities as *mut crate::xml::hash::HashTable,
Some(dump_entity_callback),
output as *mut c_void,
);
} else {
libc::fprintf(
output,
c"No entities in internal subset\n".as_ptr() as *const c_char,
);
}
if !ext_subset.is_null()
&& !(*ext_subset).entities.is_null()
&& crate::xml::hash::hash_size(
(*ext_subset).entities as *mut crate::xml::hash::HashTable,
) > 0
{
libc::fprintf(
output,
c"Entities in external subset\n".as_ptr() as *const c_char,
);
crate::xml::hash::hash_scan(
(*ext_subset).entities as *mut crate::xml::hash::HashTable,
Some(dump_entity_callback),
output as *mut c_void,
);
} else {
libc::fprintf(
output,
c"No entities in external subset\n".as_ptr() as *const c_char,
);
}
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlDebugDumpDTD(output: *mut _IO_FILE, dtd: *mut _xmlDtd) {
let output = if output.is_null() {
unsafe { stdout as *mut _IO_FILE }
} else {
output
};
if dtd.is_null() {
libc::fprintf(output, c"DTD is NULL\n".as_ptr() as *const c_char);
return;
}
unsafe {
if !(*dtd).name.is_null() {
libc::fprintf(output, c"DTD(%s)".as_ptr() as *const c_char, (*dtd).name);
} else {
libc::fprintf(output, c"DTD".as_ptr() as *const c_char);
}
if !(*dtd).ExternalID.is_null() {
libc::fprintf(
output,
c", PUBLIC %s".as_ptr() as *const c_char,
(*dtd).ExternalID,
);
}
if !(*dtd).SystemID.is_null() {
libc::fprintf(
output,
c", SYSTEM %s".as_ptr() as *const c_char,
(*dtd).SystemID,
);
}
libc::fprintf(output, c"\n".as_ptr() as *const c_char);
if (*dtd).children.is_null() {
libc::fprintf(output, c" DTD is empty\n".as_ptr() as *const c_char);
} else {
crate::xml::debug::xmlDebugDumpNodeList(output, (*dtd).children, 1);
}
}
}
unsafe fn dump_one_node_check(f: *mut _IO_FILE, errors: &mut c_int, node: *mut _xmlNode) {
if node.is_null() {
return;
}
unsafe {
match (*node).type_ {
t if t == XML_ATTRIBUTE_NODE as c_int => {
libc::fprintf(
f,
c"Error, ATTRIBUTE found here\n".as_ptr() as *const c_char,
);
generic_node_check(f, errors, node);
return;
}
t if t == XML_DOCUMENT_NODE as c_int || t == XML_HTML_DOCUMENT_NODE as c_int => {
libc::fprintf(f, c"Error, DOCUMENT found here\n".as_ptr() as *const c_char);
generic_node_check(f, errors, node);
return;
}
t if t == XML_DTD_NODE as c_int => {
if (*node).type_ != XML_DTD_NODE as c_int {
debug_err(
f,
errors,
XML_CHECK_NOT_DTD,
c"Node is not a DTD".as_ptr() as *const c_char,
);
}
generic_node_check(f, errors, node);
return;
}
t if t == XML_ELEMENT_DECL as c_int => {
let elem = node as *mut _xmlElement;
if (*elem).type_ != XML_ELEMENT_DECL as c_int {
debug_err(
f,
errors,
XML_CHECK_NOT_ELEM_DECL,
c"Node is not an element declaration".as_ptr() as *const c_char,
);
}
if (*elem).name.is_null() {
debug_err(
f,
errors,
XML_CHECK_NO_NAME,
c"Element declaration has no name".as_ptr() as *const c_char,
);
}
generic_node_check(f, errors, node);
return;
}
t if t == XML_ATTRIBUTE_DECL as c_int => {
let attr = node as *mut _xmlAttribute;
if (*attr).type_ != XML_ATTRIBUTE_DECL as c_int {
debug_err(
f,
errors,
XML_CHECK_NOT_ATTR_DECL,
c"Node is not an attribute declaration".as_ptr() as *const c_char,
);
}
if (*attr).name.is_null() {
debug_err(
f,
errors,
XML_CHECK_NO_NAME,
c"Node attribute declaration has no name".as_ptr() as *const c_char,
);
}
if (*attr).elem.is_null() {
debug_err(
f,
errors,
XML_CHECK_NO_ELEM,
c"Node attribute declaration has no element name".as_ptr() as *const c_char,
);
}
generic_node_check(f, errors, node);
return;
}
t if t == XML_ENTITY_DECL as c_int => {
let ent = node as *mut _xmlEntity;
if (*ent).type_ != XML_ENTITY_DECL as c_int {
debug_err(
f,
errors,
XML_CHECK_NOT_ENTITY_DECL,
c"Node is not an entity declaration".as_ptr() as *const c_char,
);
}
if (*ent).name.is_null() {
debug_err(
f,
errors,
XML_CHECK_NO_NAME,
c"Entity declaration has no name".as_ptr() as *const c_char,
);
}
generic_node_check(f, errors, node);
return;
}
t if t == XML_NAMESPACE_DECL as c_int => {
let ns = node as *mut _xmlNs;
if (*ns).type_ != XML_NAMESPACE_DECL as c_int {
debug_err(
f,
errors,
XML_CHECK_NOT_NS_DECL,
c"Node is not a namespace declaration".as_ptr() as *const c_char,
);
}
if (*ns).href.is_null() {
if !(*ns).prefix.is_null() {
debug_err_str(
f,
errors,
XML_CHECK_NO_HREF,
c"Incomplete namespace %s href=NULL\n".as_ptr() as *const c_char,
(*ns).prefix as *const c_char,
);
} else {
debug_err(
f,
errors,
XML_CHECK_NO_HREF,
c"Incomplete default namespace href=NULL\n".as_ptr() as *const c_char,
);
}
}
return;
}
t if t == XML_XINCLUDE_START as c_int || t == XML_XINCLUDE_END as c_int => {
return;
}
_ => {}
}
if (*node).doc.is_null() {
libc::fprintf(f, c"PBM: doc == NULL !!!\n".as_ptr() as *const c_char);
}
generic_node_check(f, errors, node);
}
}
unsafe fn dump_node_list_check(
f: *mut _IO_FILE,
errors: &mut c_int,
node: *mut _xmlNode,
depth: c_int,
) {
let mut cur = node;
while !cur.is_null() {
dump_node_check(f, errors, cur, depth);
unsafe {
cur = (*cur).next;
}
}
}
unsafe fn dump_node_check(f: *mut _IO_FILE, errors: &mut c_int, node: *mut _xmlNode, depth: c_int) {
let _ = depth;
if node.is_null() {
return;
}
dump_one_node_check(f, errors, node);
unsafe {
let t = (*node).type_;
if t != XML_NAMESPACE_DECL as c_int
&& !(*node).children.is_null()
&& t != XML_ENTITY_REF_NODE as c_int
{
dump_node_list_check(f, errors, (*node).children, depth + 1);
}
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlDebugCheckDocument(output: *mut _IO_FILE, doc: *mut _xmlDoc) -> c_int {
let output = if output.is_null() {
unsafe { stdout as *mut _IO_FILE }
} else {
output
};
let mut errors: c_int = 0;
if doc.is_null() {
return errors;
}
dump_doc_head(output, &mut errors, doc, 1);
unsafe {
let t = (*doc).type_;
if (t == XML_DOCUMENT_NODE as c_int || t == XML_HTML_DOCUMENT_NODE as c_int)
&& !(*doc).children.is_null()
{
dump_node_list_check(output, &mut errors, (*doc).children, 1);
}
}
errors
}