1use crate::abi::allocator::xmlFreeImpl;
9use crate::abi::structs::{_xmlAttr, _xmlDoc, _xmlNode, _xmlNs};
10use core::ffi::{c_char, c_int, c_void};
11use core::ptr;
12
13const MAX_DEPTH: c_int = 100;
15
16fn is_xinclude_node(node: *mut _xmlNode) -> bool {
20 if node.is_null() {
21 return false;
22 }
23 unsafe {
24 let ns = (*node).ns;
25 if ns.is_null() {
26 return false;
27 }
28 let ns_href = (*ns).href;
29 let ns_prefix = (*ns).prefix;
30 if ns_href.is_null() {
31 return false;
32 }
33 let href = core::slice::from_raw_parts(ns_href as *const u8, 30);
35 let xi_ns = b"http://www.w3.org/2001/XInclude\0";
36 let mut matches = true;
37 for i in 0..30 {
38 if i >= href.len() || href[i] != xi_ns[i] {
39 matches = false;
40 break;
41 }
42 }
43 if !matches {
44 return false;
45 }
46 let name_bytes = if !(*node).name.is_null() {
48 core::slice::from_raw_parts((*node).name as *const u8, 8)
49 } else {
50 return false;
51 };
52 name_bytes.len() >= 7 && &name_bytes[..7] == b"include"
53 }
54}
55
56#[no_mangle]
60pub unsafe extern "C" fn xmlBoolToText(boolval: c_int) -> *const c_char {
61 if boolval != 0 {
62 b"true\0".as_ptr() as *const c_char
63 } else {
64 b"false\0".as_ptr() as *const c_char
65 }
66}
67
68#[no_mangle]
73pub unsafe extern "C" fn xmlDebugDumpString(output: *mut _IO_FILE, str_val: *const u8) {
74 if output.is_null() {
75 return;
76 }
77 if str_val.is_null() {
78 unsafe {
79 libc::fprintf(output, b"(NULL)\0".as_ptr() as *const c_char);
80 }
81 return;
82 }
83 unsafe {
84 let mut i = 0;
88 while i < 40 {
89 let c = *str_val.add(i);
90 if c == 0 {
91 return;
92 }
93 if c == b' ' || c == b'\t' || c == b'\n' || c == b'\r' {
94 libc::fprintf(output, b" \0".as_ptr() as *const c_char);
95 } else if c >= 0x80 {
96 libc::fprintf(output, b"#%X\0".as_ptr() as *const c_char, c as c_int);
97 } else {
98 libc::fprintf(output, b"%c\0".as_ptr() as *const c_char, c as c_int);
99 }
100 i += 1;
101 }
102 libc::fprintf(output, b"...\0".as_ptr() as *const c_char);
103 }
104}
105
106#[no_mangle]
110pub unsafe extern "C" fn xmlDebugDumpAttr(
111 output: *mut _IO_FILE,
112 attr: *mut _xmlAttr,
113 depth: c_int,
114) {
115 if output.is_null() || attr.is_null() {
116 return;
117 }
118 unsafe {
119 for _ in 0..depth {
120 libc::fprintf(output, b" \0".as_ptr() as *const c_char);
121 }
122 libc::fprintf(output, b"ATTRIBUTE \0".as_ptr() as *const c_char);
123 xmlDebugDumpString(output, (*attr).name as *const u8);
124 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
125 xmlDebugDumpNode(output, (*attr).children, depth + 1);
127 }
128}
129
130#[no_mangle]
134pub unsafe extern "C" fn xmlDebugDumpAttrList(
135 output: *mut _IO_FILE,
136 attr: *mut _xmlAttr,
137 depth: c_int,
138) {
139 if output.is_null() {
140 return;
141 }
142 let mut cur = attr;
143 while !cur.is_null() {
144 unsafe {
145 xmlDebugDumpAttr(output, cur, depth);
146 cur = (*cur).next;
147 }
148 }
149}
150
151#[no_mangle]
155pub unsafe extern "C" fn xmlDebugDumpOneNode(
156 output: *mut _IO_FILE,
157 node: *mut _xmlNode,
158 depth: c_int,
159) {
160 if output.is_null() || node.is_null() {
161 return;
162 }
163 unsafe {
164 for _ in 0..depth {
166 libc::fprintf(output, b" \0".as_ptr() as *const c_char);
167 }
168
169 match (*node).type_ {
171 1 => {
172 libc::fprintf(output, b"ELEMENT \0".as_ptr() as *const c_char);
174 if !(*node).ns.is_null() && !(*(*node).ns).prefix.is_null() {
176 libc::fprintf(
177 output,
178 b"%s:\0".as_ptr() as *const c_char,
179 (*(*node).ns).prefix,
180 );
181 }
182 xmlDebugDumpString(output, (*node).name as *const u8);
183 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
184
185 if !(*node).nsDef.is_null() {
188 let mut ns = (*node).nsDef;
189 while !ns.is_null() {
190 for _ in 0..(depth + 1) {
191 libc::fprintf(output, b" \0".as_ptr() as *const c_char);
192 }
193 libc::fprintf(output, b"namespace \0".as_ptr() as *const c_char);
194 if (*ns).prefix.is_null() {
195 libc::fprintf(output, b" \0".as_ptr() as *const c_char);
196 } else {
197 libc::fprintf(output, b"%s\0".as_ptr() as *const c_char, (*ns).prefix);
198 }
199 libc::fprintf(output, b" href=\0".as_ptr() as *const c_char);
200 libc::fprintf(output, b"%s\n\0".as_ptr() as *const c_char, (*ns).href);
201 ns = (*ns).next;
202 }
203 }
204
205 if !(*node).properties.is_null() {
207 xmlDebugDumpAttrList(output, (*node).properties, depth + 1);
208 }
209 }
210 2 => {
211 libc::fprintf(output, b"ATTRIBUTE \0".as_ptr() as *const c_char);
213 xmlDebugDumpString(output, (*node).name as *const u8);
214 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
215 }
216 3 => {
217 libc::fprintf(output, b"TEXT\0".as_ptr() as *const c_char);
219 let inline_addr = std::ptr::addr_of_mut!((*node).properties) as *const c_void;
222 if (*node).content as *const c_void == inline_addr {
223 libc::fprintf(output, b" compact\0".as_ptr() as *const c_char);
224 }
225 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
226 for _ in 0..(depth + 1) {
227 libc::fprintf(output, b" \0".as_ptr() as *const c_char);
228 }
229 libc::fprintf(output, b"content=\0".as_ptr() as *const c_char);
230 if !(*node).content.is_null() {
231 xmlDebugDumpString(output, (*node).content as *const u8);
232 } else {
233 let c = crate::xml::tree::node_get_content(node);
234 if !c.is_null() {
235 libc::fprintf(output, b"%s\0".as_ptr() as *const c_char, c);
236 crate::abi::allocator::xmlFreeImpl(c as *mut c_void);
237 }
238 }
239 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
240 }
241 4 => {
242 libc::fprintf(output, b"CDATA_SECTION\n\0".as_ptr() as *const c_char);
244 for _ in 0..(depth + 1) {
245 libc::fprintf(output, b" \0".as_ptr() as *const c_char);
246 }
247 libc::fprintf(output, b"content=\0".as_ptr() as *const c_char);
248 xmlDebugDumpString(output, (*node).content as *const u8);
249 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
250 }
251 5 => {
252 libc::fprintf(output, b"ENTITY_REF(\0".as_ptr() as *const c_char);
254 xmlDebugDumpString(output, (*node).name as *const u8);
255 libc::fprintf(output, b")\n\0".as_ptr() as *const c_char);
256 let doc = (*node).doc;
258 let ent = if doc.is_null() {
259 ptr::null_mut()
260 } else {
261 crate::xml::entities::get_entity(doc, (*node).name)
262 };
263 if !ent.is_null() {
264 for _ in 0..(depth + 1) {
265 libc::fprintf(output, b" \0".as_ptr() as *const c_char);
266 }
267 let etype = (*ent).etype;
268 let etype_name = entity_type_name(etype);
269 libc::fprintf(
270 output,
271 b"%s \0".as_ptr() as *const c_char,
272 etype_name.as_ptr() as *const c_char,
273 );
274 libc::fprintf(output, b"%s\n\0".as_ptr() as *const c_char, (*ent).name);
275 for _ in 0..(depth + 1) {
276 libc::fprintf(output, b" \0".as_ptr() as *const c_char);
277 }
278 libc::fprintf(output, b"content=\0".as_ptr() as *const c_char);
279 if !(*ent).content.is_null() {
280 xmlDebugDumpString(output, (*ent).content as *const u8);
281 }
282 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
283 }
284 }
285 6 => {
286 libc::fprintf(output, b"ENTITYDECL(\0".as_ptr() as *const c_char);
288 xmlDebugDumpString(output, (*node).name as *const u8);
289 libc::fprintf(output, b")\0".as_ptr() as *const c_char);
290 if !(*node).content.is_null() {
291 libc::fprintf(output, b", internal\n \0".as_ptr() as *const c_char);
292 libc::fprintf(output, b"content=\0".as_ptr() as *const c_char);
293 xmlDebugDumpString(output, (*node).content as *const u8);
294 }
295 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
296 }
297 7 => {
298 libc::fprintf(output, b"PI \0".as_ptr() as *const c_char);
300 xmlDebugDumpString(output, (*node).name as *const u8);
301 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
302 if !(*node).content.is_null() {
303 for _ in 0..(depth + 1) {
304 libc::fprintf(output, b" \0".as_ptr() as *const c_char);
305 }
306 libc::fprintf(output, b"content=\0".as_ptr() as *const c_char);
307 xmlDebugDumpString(output, (*node).content as *const u8);
308 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
309 }
310 }
311 8 => {
312 libc::fprintf(output, b"COMMENT\n\0".as_ptr() as *const c_char);
314 for _ in 0..(depth + 1) {
315 libc::fprintf(output, b" \0".as_ptr() as *const c_char);
316 }
317 libc::fprintf(output, b"content=\0".as_ptr() as *const c_char);
318 xmlDebugDumpString(output, (*node).content as *const u8);
319 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
320 }
321 9 => {
322 libc::fprintf(output, b"DOCUMENT\0".as_ptr() as *const c_char);
324 }
325 10 => {
326 libc::fprintf(output, b"DOCTYPE\0".as_ptr() as *const c_char);
328 }
329 14 => {
330 libc::fprintf(output, b"DTD(\0".as_ptr() as *const c_char);
334 xmlDebugDumpString(output, (*node).name as *const u8);
335 libc::fprintf(output, b")\0".as_ptr() as *const c_char);
336 let dtd = node as *mut crate::abi::structs::_xmlDtd;
337 if !(*dtd).ExternalID.is_null() {
338 libc::fprintf(output, b", PUBLIC \0".as_ptr() as *const c_char);
339 libc::fprintf(output, b"%s\0".as_ptr() as *const c_char, (*dtd).ExternalID);
340 }
341 if !(*dtd).SystemID.is_null() {
342 libc::fprintf(output, b", SYSTEM \0".as_ptr() as *const c_char);
343 libc::fprintf(output, b"%s\0".as_ptr() as *const c_char, (*dtd).SystemID);
344 }
345 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
346 let dtd = node as *mut crate::abi::structs::_xmlDtd;
348 if !(*dtd).elements.is_null() {
349 let ctx = DtdDumpCtx {
350 output,
351 depth: depth + 1,
352 };
353 crate::xml::hash::hash_scan(
354 (*dtd).elements as *mut crate::xml::hash::HashTable,
355 Some(dump_elemscan_cb),
356 &ctx as *const DtdDumpCtx as *mut c_void,
357 );
358 }
359 if !(*dtd).entities.is_null() {
361 let ctx = DtdDumpCtx {
362 output,
363 depth: depth + 1,
364 };
365 crate::xml::hash::hash_scan(
366 (*dtd).entities as *mut crate::xml::hash::HashTable,
367 Some(dump_entityscan_cb),
368 &ctx as *const DtdDumpCtx as *mut c_void,
369 );
370 }
371 }
372 13 => {
373 libc::fprintf(output, b"HTML DOCUMENT\0".as_ptr() as *const c_char);
375 }
376 18 => {
377 libc::fprintf(output, b"NAMESPACE\0".as_ptr() as *const c_char);
379 if !(*node).ns.is_null() && !(*(*node).ns).prefix.is_null() {
380 libc::fprintf(
381 output,
382 b" %s=%s\0".as_ptr() as *const c_char,
383 (*(*node).ns).prefix,
384 (*(*node).ns).href,
385 );
386 }
387 }
388 19 => {
389 if is_xinclude_node(node) {
391 libc::fprintf(output, b"XINCLUDE\0".as_ptr() as *const c_char);
392 } else {
393 libc::fprintf(output, b"XINCLUDE_START\0".as_ptr() as *const c_char);
394 }
395 }
396 20 => {
397 libc::fprintf(output, b"XINCLUDE_END\0".as_ptr() as *const c_char);
399 }
400 _ => {
401 libc::fprintf(
402 output,
403 b"UNKNOWN (%d)\0".as_ptr() as *const c_char,
404 (*node).type_ as c_int,
405 );
406 }
407 }
408 }
409}
410
411fn entity_type_name(etype: c_int) -> Vec<u8> {
413 use crate::abi::types::xmlEntityType::*;
414 match etype {
415 t if t == XML_INTERNAL_GENERAL_ENTITY as c_int => b"INTERNAL_GENERAL_ENTITY\0".to_vec(),
416 t if t == XML_INTERNAL_PARAMETER_ENTITY as c_int => b"INTERNAL_PARAMETER_ENTITY\0".to_vec(),
417 t if t == XML_EXTERNAL_GENERAL_PARSED_ENTITY as c_int => {
418 b"EXTERNAL_GENERAL_PARSED_ENTITY\0".to_vec()
419 }
420 t if t == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY as c_int => {
421 b"EXTERNAL_GENERAL_UNPARSED_ENTITY\0".to_vec()
422 }
423 t if t == XML_EXTERNAL_PARAMETER_ENTITY as c_int => b"EXTERNAL_PARAMETER_ENTITY\0".to_vec(),
424 t if t == XML_INTERNAL_PREDEFINED_ENTITY as c_int => {
425 b"INTERNAL_PREDEFINED_ENTITY\0".to_vec()
426 }
427 _ => b"UNKNOWN_ENTITY\0".to_vec(),
428 }
429}
430
431#[repr(C)]
433struct DtdDumpCtx {
434 output: *mut _IO_FILE,
435 depth: c_int,
436}
437
438unsafe extern "C" fn dump_elemscan_cb(payload: *mut c_void, data: *mut c_void, _name: *const u8) {
440 if payload.is_null() || data.is_null() {
441 return;
442 }
443 let ctx = unsafe { &*(data as *const DtdDumpCtx) };
444 let elem = unsafe { &*(payload as *mut crate::abi::structs::_xmlElement) };
445 unsafe {
446 for _ in 0..ctx.depth {
447 libc::fprintf(ctx.output, b" \0".as_ptr() as *const c_char);
448 }
449 libc::fprintf(ctx.output, b"ELEMDECL(\0".as_ptr() as *const c_char);
450 if !elem.name.is_null() {
451 libc::fprintf(ctx.output, b"%s\0".as_ptr() as *const c_char, elem.name);
452 }
453 libc::fprintf(ctx.output, b")\0".as_ptr() as *const c_char);
454 match elem.type_ {
458 t if t == crate::abi::types::xmlElementTypeVal::XML_ELEMENT_TYPE_EMPTY as c_int => {
459 libc::fprintf(ctx.output, b", EMPTY\n\0".as_ptr() as *const c_char);
460 }
461 t if t == crate::abi::types::xmlElementTypeVal::XML_ELEMENT_TYPE_ANY as c_int => {
462 libc::fprintf(ctx.output, b", ANY\n\0".as_ptr() as *const c_char);
463 }
464 _ => {
465 libc::fprintf(ctx.output, b", MIXED \0".as_ptr() as *const c_char);
466 dump_debug_content_model(ctx.output, elem.content);
467 libc::fprintf(ctx.output, b"\n\0".as_ptr() as *const c_char);
468 }
469 }
470 }
471}
472
473unsafe fn dump_debug_content_model(
476 output: *mut _IO_FILE,
477 content: *mut crate::abi::structs::_xmlElementContent,
478) {
479 use crate::abi::types::xmlElementContentOccur::*;
480 use crate::abi::types::xmlElementContentType::*;
481 if content.is_null() {
482 return;
483 }
484 unsafe {
485 let c = &*content;
486 match c.type_ {
487 t if t == XML_ELEMENT_CONTENT_PCDATA as c_int => {
488 libc::fprintf(output, b"(#PCDATA)\0".as_ptr() as *const c_char);
489 }
490 t if t == XML_ELEMENT_CONTENT_ELEMENT as c_int => {
491 if !c.prefix.is_null() {
492 libc::fprintf(output, b"%s:\0".as_ptr() as *const c_char, c.prefix);
493 }
494 libc::fprintf(output, b"%s\0".as_ptr() as *const c_char, c.name);
495 }
496 _ => {
497 let sep = if c.type_ == XML_ELEMENT_CONTENT_SEQ as c_int {
498 b" , \0".as_ptr() as *const c_char
499 } else {
500 b" | \0".as_ptr() as *const c_char
501 };
502 libc::fprintf(output, b"(\0".as_ptr() as *const c_char);
503 let mut parts: Vec<*mut crate::abi::structs::_xmlElementContent> = Vec::new();
504 flatten_chain(c as *const _ as *mut _, c.type_, &mut parts);
505 for (i, &p) in parts.iter().enumerate() {
506 if i > 0 {
507 libc::fprintf(output, b"%s\0".as_ptr() as *const c_char, sep);
508 }
509 let pc = &*p;
510 if pc.type_ == XML_ELEMENT_CONTENT_PCDATA as c_int {
511 libc::fprintf(output, b"#PCDATA\0".as_ptr() as *const c_char);
512 } else if pc.type_ == XML_ELEMENT_CONTENT_ELEMENT as c_int {
513 if !pc.prefix.is_null() {
514 libc::fprintf(output, b"%s:\0".as_ptr() as *const c_char, pc.prefix);
515 }
516 libc::fprintf(output, b"%s\0".as_ptr() as *const c_char, pc.name);
517 } else {
518 dump_debug_content_model(output, p);
519 }
520 dump_debug_occurrence(output, pc.ocur);
521 }
522 libc::fprintf(output, b")\0".as_ptr() as *const c_char);
523 }
524 }
525 dump_debug_occurrence(output, c.ocur);
526 }
527}
528
529fn flatten_chain(
531 node: *mut crate::abi::structs::_xmlElementContent,
532 chain_type: c_int,
533 parts: &mut Vec<*mut crate::abi::structs::_xmlElementContent>,
534) {
535 unsafe {
536 let c = &*node;
537 if c.type_ == chain_type && !c.c1.is_null() {
538 flatten_chain(c.c1, chain_type, parts);
539 if !c.c2.is_null() {
540 flatten_chain(c.c2, chain_type, parts);
541 }
542 } else {
543 parts.push(node);
544 }
545 }
546}
547
548unsafe fn dump_debug_occurrence(output: *mut _IO_FILE, ocur: c_int) {
550 use crate::abi::types::xmlElementContentOccur::*;
551 let s = match ocur {
552 t if t == XML_ELEMENT_CONTENT_OPT as c_int => b"?\0".as_ptr() as *const c_char,
553 t if t == XML_ELEMENT_CONTENT_MULT as c_int => b"*\0".as_ptr() as *const c_char,
554 t if t == XML_ELEMENT_CONTENT_PLUS as c_int => b"+\0".as_ptr() as *const c_char,
555 _ => return,
556 };
557 unsafe {
558 libc::fprintf(output, b"%s\0".as_ptr() as *const c_char, s);
559 }
560}
561
562unsafe fn contains_markup(s: *const crate::abi::types::xmlChar) -> bool {
565 if s.is_null() {
566 return false;
567 }
568 unsafe {
569 let mut i = 0usize;
570 while *s.add(i) != 0 {
571 let c = *s.add(i);
572 if c == b'<' || c == b'&' {
573 return true;
574 }
575 i += 1;
576 }
577 }
578 false
579}
580
581unsafe extern "C" fn dump_entityscan_cb(payload: *mut c_void, data: *mut c_void, _name: *const u8) {
583 if payload.is_null() || data.is_null() {
584 return;
585 }
586 let ctx = unsafe { &*(data as *const DtdDumpCtx) };
587 let ent = unsafe { &*(payload as *mut crate::abi::structs::_xmlEntity) };
588 unsafe {
589 for _ in 0..ctx.depth {
590 libc::fprintf(ctx.output, b" \0".as_ptr() as *const c_char);
591 }
592 libc::fprintf(ctx.output, b"ENTITYDECL(\0".as_ptr() as *const c_char);
593 if !ent.name.is_null() {
594 libc::fprintf(ctx.output, b"%s\0".as_ptr() as *const c_char, ent.name);
595 }
596 if ent.etype == crate::abi::types::xmlEntityType::XML_INTERNAL_GENERAL_ENTITY as c_int {
597 libc::fprintf(ctx.output, b"), internal\n\0".as_ptr() as *const c_char);
598 for _ in 0..ctx.depth {
601 libc::fprintf(ctx.output, b" \0".as_ptr() as *const c_char);
602 }
603 libc::fprintf(ctx.output, b" content=\0".as_ptr() as *const c_char);
604 if !ent.content.is_null() {
605 xmlDebugDumpString(ctx.output, ent.content as *const u8);
606 }
607 libc::fprintf(ctx.output, b"\n\0".as_ptr() as *const c_char);
608 if !ent.content.is_null() && !contains_markup(ent.content) && ent.children.is_null() {
615 for _ in 0..(ctx.depth + 1) {
616 libc::fprintf(ctx.output, b" \0".as_ptr() as *const c_char);
617 }
618 libc::fprintf(ctx.output, b"TEXT compact\n\0".as_ptr() as *const c_char);
619 for _ in 0..(ctx.depth + 2) {
620 libc::fprintf(ctx.output, b" \0".as_ptr() as *const c_char);
621 }
622 libc::fprintf(ctx.output, b"content=\0".as_ptr() as *const c_char);
623 xmlDebugDumpString(ctx.output, ent.content as *const u8);
624 libc::fprintf(ctx.output, b"\n\0".as_ptr() as *const c_char);
625 }
626 } else {
627 libc::fprintf(ctx.output, b")\n\0".as_ptr() as *const c_char);
628 }
629 }
630}
631
632#[no_mangle]
636pub unsafe extern "C" fn xmlDebugDumpNode(
637 output: *mut _IO_FILE,
638 node: *mut _xmlNode,
639 depth: c_int,
640) {
641 if output.is_null() || node.is_null() || depth > MAX_DEPTH {
642 return;
643 }
644 unsafe {
645 xmlDebugDumpOneNode(output, node, depth);
646
647 let t = (*node).type_;
650 let recurse = t == 1 || t == 9 || t == 13 || t == 11 || t == 14; if recurse && !(*node).children.is_null() {
656 let mut child = (*node).children;
657 while !child.is_null() {
658 xmlDebugDumpNode(output, child, depth + 1);
659 child = (*child).next;
660 }
661 }
662 }
663}
664
665#[no_mangle]
669pub unsafe extern "C" fn xmlDebugDumpNodeList(
670 output: *mut _IO_FILE,
671 node: *mut _xmlNode,
672 depth: c_int,
673) {
674 if output.is_null() {
675 return;
676 }
677 let mut cur = node;
678 while !cur.is_null() {
679 unsafe {
680 xmlDebugDumpNode(output, cur, depth);
681 cur = (*cur).next;
682 }
683 }
684}
685
686#[no_mangle]
690pub unsafe extern "C" fn xmlDebugDumpDocument(output: *mut _IO_FILE, doc: *mut _xmlDoc) {
691 if output.is_null() || doc.is_null() {
692 return;
693 }
694 unsafe {
695 if (*doc).type_ == crate::abi::types::xmlElementType::XML_HTML_DOCUMENT_NODE as c_int {
698 libc::fprintf(output, b"HTML DOCUMENT\n\0".as_ptr() as *const c_char);
699 } else {
700 libc::fprintf(output, b"DOCUMENT\n\0".as_ptr() as *const c_char);
701 }
702 if !(*doc).version.is_null() {
703 libc::fprintf(output, b"version=\0".as_ptr() as *const c_char);
704 xmlDebugDumpString(output, (*doc).version as *const u8);
705 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
706 }
707 if !(*doc).URL.is_null() {
708 libc::fprintf(output, b"URL=\0".as_ptr() as *const c_char);
709 xmlDebugDumpString(output, (*doc).URL as *const u8);
712 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
713 }
714 if (*doc).standalone != 0 {
718 libc::fprintf(output, b"standalone=true\n\0".as_ptr() as *const c_char);
719 }
720
721 if !(*doc).oldNs.is_null() {
724 let mut ns = (*doc).oldNs;
725 while !ns.is_null() {
726 libc::fprintf(output, b"namespace \0".as_ptr() as *const c_char);
727 if (*ns).prefix.is_null() {
728 libc::fprintf(output, b" \0".as_ptr() as *const c_char);
729 } else {
730 libc::fprintf(output, b"%s\0".as_ptr() as *const c_char, (*ns).prefix);
731 }
732 libc::fprintf(
733 output,
734 b" href=%s\n\0".as_ptr() as *const c_char,
735 (*ns).href,
736 );
737 ns = (*ns).next;
738 }
739 }
740
741 if !(*doc).intSubset.is_null() {
744 xmlDebugDumpNode(output, (*doc).intSubset as *mut _xmlNode, 1);
745 }
746
747 if !(*doc).children.is_null() {
749 let mut child = (*doc).children;
750 while !child.is_null() {
751 xmlDebugDumpNode(output, child, 1);
752 child = (*child).next;
753 }
754 }
755 }
756}
757
758#[no_mangle]
762pub unsafe extern "C" fn xmlDebugDumpDocumentHead(output: *mut _IO_FILE, doc: *mut _xmlDoc) {
763 if output.is_null() || doc.is_null() {
764 return;
765 }
766 unsafe {
767 xmlDebugDumpDocument(output, doc);
768 }
769}
770
771#[no_mangle]
775pub unsafe extern "C" fn xmlLsCountNode(node: *mut _xmlNode) -> c_int {
776 if node.is_null() {
777 return 0;
778 }
779 let mut count: c_int = 0;
780 let mut cur = node;
781 while !cur.is_null() {
782 count += 1;
783 unsafe {
784 cur = (*cur).next;
785 }
786 }
787 count
788}
789
790#[no_mangle]
794pub unsafe extern "C" fn xmlLsOneNode(output: *mut _IO_FILE, node: *mut _xmlNode) {
795 if output.is_null() || node.is_null() {
796 return;
797 }
798 unsafe {
799 match (*node).type_ {
800 1 => {
801 libc::fprintf(output, b"E \0".as_ptr() as *const c_char);
803 if !(*node).ns.is_null() && !(*(*node).ns).prefix.is_null() {
804 libc::fprintf(
805 output,
806 b"%s:\0".as_ptr() as *const c_char,
807 (*(*node).ns).prefix,
808 );
809 }
810 xmlDebugDumpString(output, (*node).name as *const u8);
811 }
812 2 => {
813 libc::fprintf(output, b"A \0".as_ptr() as *const c_char);
814 xmlDebugDumpString(output, (*node).name as *const u8);
815 }
816 3 => {
817 libc::fprintf(output, b"T \0".as_ptr() as *const c_char);
818 if !(*node).content.is_null() {
819 xmlDebugDumpString(output, (*node).content as *const u8);
820 }
821 }
822 4 => {
823 libc::fprintf(output, b"C \0".as_ptr() as *const c_char);
824 }
825 5 => {
826 libc::fprintf(output, b"E \0".as_ptr() as *const c_char);
827 xmlDebugDumpString(output, (*node).name as *const u8);
828 }
829 6 => {
830 libc::fprintf(output, b"E \0".as_ptr() as *const c_char);
831 xmlDebugDumpString(output, (*node).name as *const u8);
832 }
833 7 => {
834 libc::fprintf(output, b"PI \0".as_ptr() as *const c_char);
835 xmlDebugDumpString(output, (*node).name as *const u8);
836 }
837 8 => {
838 libc::fprintf(output, b"C \0".as_ptr() as *const c_char);
839 }
840 9 => {
841 libc::fprintf(output, b"D \0".as_ptr() as *const c_char);
842 }
843 10 => {
844 libc::fprintf(output, b"DTD \0".as_ptr() as *const c_char);
845 }
846 14 => {
847 libc::fprintf(output, b"X \0".as_ptr() as *const c_char);
848 }
849 _ => {
850 libc::fprintf(
851 output,
852 b"? (%d)\0".as_ptr() as *const c_char,
853 (*node).type_ as c_int,
854 );
855 }
856 }
857 libc::fprintf(output, b"\n\0".as_ptr() as *const c_char);
858 }
859}
860
861pub type _IO_FILE = libc::FILE;
866
867#[cfg(test)]
872mod tests {
873 use super::*;
874 use crate::abi::allocator::xmlMallocImpl;
875 use crate::abi::structs::*;
876 use crate::abi::types::xmlChar;
877 use crate::xml::tree::*;
878
879 unsafe fn create_test_doc() -> *mut _xmlDoc {
881 let doc = new_doc(b"1.0\0".as_ptr() as *const xmlChar);
882 let root = new_node(ptr::null_mut(), b"root\0".as_ptr() as *const xmlChar);
883 doc_set_root_element(doc, root);
884 let child = new_child(root, ptr::null_mut(), b"child\0".as_ptr() as *const xmlChar);
885 set_prop(
887 child,
888 b"attr1\0".as_ptr() as *const xmlChar,
889 b"value1\0".as_ptr() as *const xmlChar,
890 );
891 doc
892 }
893
894 #[test]
895 fn test_xml_bool_to_text() {
896 unsafe {
897 let t = xmlBoolToText(1);
898 assert!(!t.is_null());
899 let f = xmlBoolToText(0);
900 assert!(!f.is_null());
901 assert_eq!(*t as u8, b't');
903 assert_eq!(*f as u8, b'f');
904 }
905 }
906
907 #[test]
908 fn test_debug_dump_string_null() {
909 unsafe {
910 xmlDebugDumpString(ptr::null_mut(), ptr::null());
912 let f = libc::fmemopen(ptr::null_mut(), 0, b"w\0".as_ptr() as *const c_char);
914 if !f.is_null() {
915 xmlDebugDumpString(f, ptr::null());
916 libc::fclose(f);
917 }
918 }
919 }
920
921 #[test]
922 fn test_debug_dump_document_null() {
923 unsafe {
924 xmlDebugDumpDocument(ptr::null_mut(), ptr::null_mut());
925 let f = libc::fmemopen(ptr::null_mut(), 0, b"w\0".as_ptr() as *const c_char);
926 if !f.is_null() {
927 xmlDebugDumpDocument(f, ptr::null_mut());
928 libc::fclose(f);
929 }
930 }
931 }
932
933 #[test]
934 fn test_debug_dump_node_null() {
935 unsafe {
936 xmlDebugDumpNode(ptr::null_mut(), ptr::null_mut(), 0);
937 let f = libc::fmemopen(ptr::null_mut(), 0, b"w\0".as_ptr() as *const c_char);
938 if !f.is_null() {
939 xmlDebugDumpNode(f, ptr::null_mut(), 0);
940 libc::fclose(f);
941 }
942 }
943 }
944
945 #[test]
946 fn test_ls_count_node() {
947 unsafe {
948 let node = new_node(ptr::null_mut(), b"test\0".as_ptr() as *const xmlChar);
949 assert!(!node.is_null());
950 let count = xmlLsCountNode(node);
951 assert_eq!(count, 1);
952
953 let sibling = new_node(ptr::null_mut(), b"sibling\0".as_ptr() as *const xmlChar);
955 add_sibling(node, sibling);
956 let count = xmlLsCountNode(node);
957 assert_eq!(count, 2);
958
959 free_node(node);
960 }
961 }
962
963 #[test]
964 fn test_debug_dump_attr_null() {
965 unsafe {
966 xmlDebugDumpAttr(ptr::null_mut(), ptr::null_mut(), 0);
967 let f = libc::fmemopen(ptr::null_mut(), 0, b"w\0".as_ptr() as *const c_char);
968 if !f.is_null() {
969 xmlDebugDumpAttr(f, ptr::null_mut(), 0);
970 libc::fclose(f);
971 }
972 }
973 }
974
975 #[test]
976 fn test_debug_dump_attr_list_null() {
977 unsafe {
978 xmlDebugDumpAttrList(ptr::null_mut(), ptr::null_mut(), 0);
979 }
980 }
981
982 #[test]
983 fn test_debug_dump_node_list_null() {
984 unsafe {
985 xmlDebugDumpNodeList(ptr::null_mut(), ptr::null_mut(), 0);
986 }
987 }
988
989 #[test]
990 fn test_ls_one_node_null() {
991 unsafe {
992 xmlLsOneNode(ptr::null_mut(), ptr::null_mut());
993 let f = libc::fmemopen(ptr::null_mut(), 0, b"w\0".as_ptr() as *const c_char);
994 if !f.is_null() {
995 xmlLsOneNode(f, ptr::null_mut());
996 libc::fclose(f);
997 }
998 }
999 }
1000
1001 #[test]
1002 fn test_dump_document_head_null() {
1003 unsafe {
1004 xmlDebugDumpDocumentHead(ptr::null_mut(), ptr::null_mut());
1005 }
1006 }
1007
1008 #[test]
1009 fn test_ls_count_node_null() {
1010 assert_eq!(unsafe { xmlLsCountNode(ptr::null_mut()) }, 0);
1011 }
1012}