1use crate::abi::structs::{_xmlAttr, _xmlDoc, _xmlNode};
9use core::ffi::{c_char, c_int, c_void};
10use core::ptr;
11
12const MAX_DEPTH: c_int = 100;
14
15fn is_xinclude_node(node: *mut _xmlNode) -> bool {
19 if node.is_null() {
20 return false;
21 }
22 unsafe {
23 let ns = (*node).ns;
24 if ns.is_null() {
25 return false;
26 }
27 let ns_href = (*ns).href;
28 let _ns_prefix = (*ns).prefix;
29 if ns_href.is_null() {
30 return false;
31 }
32 let href = core::slice::from_raw_parts(ns_href, 30);
34 let xi_ns = b"http://www.w3.org/2001/XInclude\0";
35 let mut matches = true;
36 for i in 0..30 {
37 if i >= href.len() || href[i] != xi_ns[i] {
38 matches = false;
39 break;
40 }
41 }
42 if !matches {
43 return false;
44 }
45 let name_bytes = if !(*node).name.is_null() {
47 core::slice::from_raw_parts((*node).name, 8)
48 } else {
49 return false;
50 };
51 name_bytes.len() >= 7 && &name_bytes[..7] == b"include"
52 }
53}
54
55#[no_mangle]
69pub const unsafe extern "C" fn xmlBoolToText(boolval: c_int) -> *const c_char {
70 if boolval != 0 {
71 c"true".as_ptr() as *const c_char
72 } else {
73 c"false".as_ptr() as *const c_char
74 }
75}
76
77#[no_mangle]
97pub unsafe extern "C" fn xmlDebugDumpString(output: *mut _IO_FILE, str_val: *const u8) {
98 if output.is_null() {
99 return;
100 }
101 if str_val.is_null() {
102 unsafe {
103 libc::fprintf(output, c"(NULL)".as_ptr() as *const c_char);
104 }
105 return;
106 }
107 unsafe {
108 let mut i = 0;
112 while i < 40 {
113 let c = *str_val.add(i);
114 if c == 0 {
115 return;
116 }
117 if c == b' ' || c == b'\t' || c == b'\n' || c == b'\r' {
118 libc::fprintf(output, c" ".as_ptr() as *const c_char);
119 } else if c >= 0x80 {
120 libc::fprintf(output, c"#%X".as_ptr() as *const c_char, c as c_int);
121 } else {
122 libc::fprintf(output, c"%c".as_ptr() as *const c_char, c as c_int);
123 }
124 i += 1;
125 }
126 libc::fprintf(output, c"...".as_ptr() as *const c_char);
127 }
128}
129
130#[no_mangle]
149pub unsafe extern "C" fn xmlDebugDumpAttr(
150 output: *mut _IO_FILE,
151 attr: *mut _xmlAttr,
152 depth: c_int,
153) {
154 if output.is_null() || attr.is_null() {
155 return;
156 }
157 unsafe {
158 for _ in 0..depth {
159 libc::fprintf(output, c" ".as_ptr() as *const c_char);
160 }
161 libc::fprintf(output, c"ATTRIBUTE ".as_ptr() as *const c_char);
162 xmlDebugDumpString(output, (*attr).name);
163 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
164 xmlDebugDumpNode(output, (*attr).children, depth + 1);
166 }
167}
168
169#[no_mangle]
188pub unsafe extern "C" fn xmlDebugDumpAttrList(
189 output: *mut _IO_FILE,
190 attr: *mut _xmlAttr,
191 depth: c_int,
192) {
193 if output.is_null() {
194 return;
195 }
196 let mut cur = attr;
197 while !cur.is_null() {
198 unsafe {
199 xmlDebugDumpAttr(output, cur, depth);
200 cur = (*cur).next;
201 }
202 }
203}
204
205#[no_mangle]
224pub unsafe extern "C" fn xmlDebugDumpOneNode(
225 output: *mut _IO_FILE,
226 node: *mut _xmlNode,
227 depth: c_int,
228) {
229 if output.is_null() || node.is_null() {
230 return;
231 }
232 unsafe {
233 for _ in 0..depth {
235 libc::fprintf(output, c" ".as_ptr() as *const c_char);
236 }
237
238 match (*node).type_ {
240 1 => {
241 libc::fprintf(output, c"ELEMENT ".as_ptr() as *const c_char);
243 if !(*node).ns.is_null() && !(*(*node).ns).prefix.is_null() {
245 libc::fprintf(
246 output,
247 c"%s:".as_ptr() as *const c_char,
248 (*(*node).ns).prefix,
249 );
250 }
251 xmlDebugDumpString(output, (*node).name);
252 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
253
254 if !(*node).nsDef.is_null() {
257 let mut ns = (*node).nsDef;
258 while !ns.is_null() {
259 for _ in 0..(depth + 1) {
260 libc::fprintf(output, c" ".as_ptr() as *const c_char);
261 }
262 libc::fprintf(output, c"namespace ".as_ptr() as *const c_char);
263 if (*ns).prefix.is_null() {
264 libc::fprintf(output, c" ".as_ptr() as *const c_char);
265 } else {
266 libc::fprintf(output, c"%s".as_ptr() as *const c_char, (*ns).prefix);
267 }
268 libc::fprintf(output, c" href=".as_ptr() as *const c_char);
269 libc::fprintf(output, c"%s\n".as_ptr() as *const c_char, (*ns).href);
270 ns = (*ns).next;
271 }
272 }
273
274 if !(*node).properties.is_null() {
276 xmlDebugDumpAttrList(output, (*node).properties, depth + 1);
277 }
278 }
279 2 => {
280 libc::fprintf(output, c"ATTRIBUTE ".as_ptr() as *const c_char);
282 xmlDebugDumpString(output, (*node).name);
283 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
284 }
285 3 => {
286 libc::fprintf(output, c"TEXT".as_ptr() as *const c_char);
288 let inline_addr = std::ptr::addr_of_mut!((*node).properties) as *const c_void;
291 if (*node).content as *const c_void == inline_addr {
292 libc::fprintf(output, c" compact".as_ptr() as *const c_char);
293 }
294 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
295 for _ in 0..(depth + 1) {
296 libc::fprintf(output, c" ".as_ptr() as *const c_char);
297 }
298 libc::fprintf(output, c"content=".as_ptr() as *const c_char);
299 if !(*node).content.is_null() {
300 xmlDebugDumpString(output, (*node).content as *const u8);
301 } else {
302 let c = crate::xml::tree::node_get_content(node);
303 if !c.is_null() {
304 libc::fprintf(output, c"%s".as_ptr() as *const c_char, c);
305 crate::abi::allocator::xmlFreeImpl(c as *mut c_void);
306 }
307 }
308 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
309 }
310 4 => {
311 libc::fprintf(output, c"CDATA_SECTION\n".as_ptr() as *const c_char);
313 for _ in 0..(depth + 1) {
314 libc::fprintf(output, c" ".as_ptr() as *const c_char);
315 }
316 libc::fprintf(output, c"content=".as_ptr() as *const c_char);
317 xmlDebugDumpString(output, (*node).content as *const u8);
318 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
319 }
320 5 => {
321 libc::fprintf(output, c"ENTITY_REF(".as_ptr() as *const c_char);
323 xmlDebugDumpString(output, (*node).name);
324 libc::fprintf(output, c")\n".as_ptr() as *const c_char);
325 let doc = (*node).doc;
327 let ent = if doc.is_null() {
328 ptr::null_mut()
329 } else {
330 crate::xml::entities::get_entity(doc, (*node).name)
331 };
332 if !ent.is_null() {
333 for _ in 0..(depth + 1) {
334 libc::fprintf(output, c" ".as_ptr() as *const c_char);
335 }
336 let etype = (*ent).etype;
337 let etype_name = entity_type_name(etype);
338 libc::fprintf(
339 output,
340 c"%s ".as_ptr() as *const c_char,
341 etype_name.as_ptr() as *const c_char,
342 );
343 libc::fprintf(output, c"%s\n".as_ptr() as *const c_char, (*ent).name);
344 for _ in 0..(depth + 1) {
345 libc::fprintf(output, c" ".as_ptr() as *const c_char);
346 }
347 libc::fprintf(output, c"content=".as_ptr() as *const c_char);
348 if !(*ent).content.is_null() {
349 xmlDebugDumpString(output, (*ent).content as *const u8);
350 }
351 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
352 }
353 }
354 6 => {
355 libc::fprintf(output, c"ENTITYDECL(".as_ptr() as *const c_char);
357 xmlDebugDumpString(output, (*node).name);
358 libc::fprintf(output, c")".as_ptr() as *const c_char);
359 if !(*node).content.is_null() {
360 libc::fprintf(output, c", internal\n ".as_ptr() as *const c_char);
361 libc::fprintf(output, c"content=".as_ptr() as *const c_char);
362 xmlDebugDumpString(output, (*node).content as *const u8);
363 }
364 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
365 }
366 7 => {
367 libc::fprintf(output, c"PI ".as_ptr() as *const c_char);
369 xmlDebugDumpString(output, (*node).name);
370 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
371 if !(*node).content.is_null() {
372 for _ in 0..(depth + 1) {
373 libc::fprintf(output, c" ".as_ptr() as *const c_char);
374 }
375 libc::fprintf(output, c"content=".as_ptr() as *const c_char);
376 xmlDebugDumpString(output, (*node).content as *const u8);
377 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
378 }
379 }
380 8 => {
381 libc::fprintf(output, c"COMMENT\n".as_ptr() as *const c_char);
383 for _ in 0..(depth + 1) {
384 libc::fprintf(output, c" ".as_ptr() as *const c_char);
385 }
386 libc::fprintf(output, c"content=".as_ptr() as *const c_char);
387 xmlDebugDumpString(output, (*node).content as *const u8);
388 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
389 }
390 9 => {
391 libc::fprintf(output, c"DOCUMENT".as_ptr() as *const c_char);
393 }
394 10 => {
395 libc::fprintf(output, c"DOCTYPE".as_ptr() as *const c_char);
397 }
398 14 => {
399 libc::fprintf(output, c"DTD(".as_ptr() as *const c_char);
403 xmlDebugDumpString(output, (*node).name);
404 libc::fprintf(output, c")".as_ptr() as *const c_char);
405 let dtd = node as *mut crate::abi::structs::_xmlDtd;
406 if !(*dtd).ExternalID.is_null() {
407 libc::fprintf(output, c", PUBLIC ".as_ptr() as *const c_char);
408 libc::fprintf(output, c"%s".as_ptr() as *const c_char, (*dtd).ExternalID);
409 }
410 if !(*dtd).SystemID.is_null() {
411 libc::fprintf(output, c", SYSTEM ".as_ptr() as *const c_char);
412 libc::fprintf(output, c"%s".as_ptr() as *const c_char, (*dtd).SystemID);
413 }
414 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
415 let dtd = node as *mut crate::abi::structs::_xmlDtd;
417 if !(*dtd).elements.is_null() {
418 let ctx = DtdDumpCtx {
419 output,
420 depth: depth + 1,
421 };
422 crate::xml::hash::hash_scan(
423 (*dtd).elements as *mut crate::xml::hash::HashTable,
424 Some(dump_elemscan_cb),
425 &ctx as *const DtdDumpCtx as *mut c_void,
426 );
427 }
428 if !(*dtd).entities.is_null() {
430 let ctx = DtdDumpCtx {
431 output,
432 depth: depth + 1,
433 };
434 crate::xml::hash::hash_scan(
435 (*dtd).entities as *mut crate::xml::hash::HashTable,
436 Some(dump_entityscan_cb),
437 &ctx as *const DtdDumpCtx as *mut c_void,
438 );
439 }
440 }
441 13 => {
442 libc::fprintf(output, c"HTML DOCUMENT".as_ptr() as *const c_char);
444 }
445 18 => {
446 libc::fprintf(output, c"NAMESPACE".as_ptr() as *const c_char);
448 if !(*node).ns.is_null() && !(*(*node).ns).prefix.is_null() {
449 libc::fprintf(
450 output,
451 c" %s=%s".as_ptr() as *const c_char,
452 (*(*node).ns).prefix,
453 (*(*node).ns).href,
454 );
455 }
456 }
457 19 => {
458 if is_xinclude_node(node) {
460 libc::fprintf(output, c"XINCLUDE".as_ptr() as *const c_char);
461 } else {
462 libc::fprintf(output, c"XINCLUDE_START".as_ptr() as *const c_char);
463 }
464 }
465 20 => {
466 libc::fprintf(output, c"XINCLUDE_END".as_ptr() as *const c_char);
468 }
469 _ => {
470 libc::fprintf(
471 output,
472 c"UNKNOWN (%d)".as_ptr() as *const c_char,
473 (*node).type_ as c_int,
474 );
475 }
476 }
477 }
478}
479
480fn entity_type_name(etype: c_int) -> Vec<u8> {
482 use crate::abi::types::xmlEntityType::*;
483 match etype {
484 t if t == XML_INTERNAL_GENERAL_ENTITY as c_int => b"INTERNAL_GENERAL_ENTITY\0".to_vec(),
485 t if t == XML_INTERNAL_PARAMETER_ENTITY as c_int => b"INTERNAL_PARAMETER_ENTITY\0".to_vec(),
486 t if t == XML_EXTERNAL_GENERAL_PARSED_ENTITY as c_int => {
487 b"EXTERNAL_GENERAL_PARSED_ENTITY\0".to_vec()
488 }
489 t if t == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY as c_int => {
490 b"EXTERNAL_GENERAL_UNPARSED_ENTITY\0".to_vec()
491 }
492 t if t == XML_EXTERNAL_PARAMETER_ENTITY as c_int => b"EXTERNAL_PARAMETER_ENTITY\0".to_vec(),
493 t if t == XML_INTERNAL_PREDEFINED_ENTITY as c_int => {
494 b"INTERNAL_PREDEFINED_ENTITY\0".to_vec()
495 }
496 _ => b"UNKNOWN_ENTITY\0".to_vec(),
497 }
498}
499
500#[repr(C)]
502struct DtdDumpCtx {
503 output: *mut _IO_FILE,
504 depth: c_int,
505}
506
507unsafe extern "C" fn dump_elemscan_cb(payload: *mut c_void, data: *mut c_void, _name: *const u8) {
509 if payload.is_null() || data.is_null() {
510 return;
511 }
512 let ctx = unsafe { &*(data as *const DtdDumpCtx) };
513 let elem = unsafe { &*(payload as *mut crate::abi::structs::_xmlElement) };
514 unsafe {
515 for _ in 0..ctx.depth {
516 libc::fprintf(ctx.output, c" ".as_ptr() as *const c_char);
517 }
518 libc::fprintf(ctx.output, c"ELEMDECL(".as_ptr() as *const c_char);
519 if !elem.name.is_null() {
520 libc::fprintf(ctx.output, c"%s".as_ptr() as *const c_char, elem.name);
521 }
522 libc::fprintf(ctx.output, c")".as_ptr() as *const c_char);
523 match elem.type_ {
527 t if t == crate::abi::types::xmlElementTypeVal::XML_ELEMENT_TYPE_EMPTY as c_int => {
528 libc::fprintf(ctx.output, c", EMPTY\n".as_ptr() as *const c_char);
529 }
530 t if t == crate::abi::types::xmlElementTypeVal::XML_ELEMENT_TYPE_ANY as c_int => {
531 libc::fprintf(ctx.output, c", ANY\n".as_ptr() as *const c_char);
532 }
533 _ => {
534 libc::fprintf(ctx.output, c", MIXED ".as_ptr() as *const c_char);
535 dump_debug_content_model(ctx.output, elem.content);
536 libc::fprintf(ctx.output, c"\n".as_ptr() as *const c_char);
537 }
538 }
539 }
540}
541
542unsafe fn dump_debug_content_model(
545 output: *mut _IO_FILE,
546 content: *mut crate::abi::structs::_xmlElementContent,
547) {
548 use crate::abi::types::xmlElementContentType::*;
549 if content.is_null() {
550 return;
551 }
552 unsafe {
553 let c = &*content;
554 match c.type_ {
555 t if t == XML_ELEMENT_CONTENT_PCDATA as c_int => {
556 libc::fprintf(output, c"(#PCDATA)".as_ptr() as *const c_char);
557 }
558 t if t == XML_ELEMENT_CONTENT_ELEMENT as c_int => {
559 if !c.prefix.is_null() {
560 libc::fprintf(output, c"%s:".as_ptr() as *const c_char, c.prefix);
561 }
562 libc::fprintf(output, c"%s".as_ptr() as *const c_char, c.name);
563 }
564 _ => {
565 let sep = if c.type_ == XML_ELEMENT_CONTENT_SEQ as c_int {
566 c" , ".as_ptr() as *const c_char
567 } else {
568 c" | ".as_ptr() as *const c_char
569 };
570 libc::fprintf(output, c"(".as_ptr() as *const c_char);
571 let mut parts: Vec<*mut crate::abi::structs::_xmlElementContent> = Vec::new();
572 flatten_chain(c as *const _ as *mut _, c.type_, &mut parts);
573 for (i, &p) in parts.iter().enumerate() {
574 if i > 0 {
575 libc::fprintf(output, c"%s".as_ptr() as *const c_char, sep);
576 }
577 let pc = &*p;
578 if pc.type_ == XML_ELEMENT_CONTENT_PCDATA as c_int {
579 libc::fprintf(output, c"#PCDATA".as_ptr() as *const c_char);
580 } else if pc.type_ == XML_ELEMENT_CONTENT_ELEMENT as c_int {
581 if !pc.prefix.is_null() {
582 libc::fprintf(output, c"%s:".as_ptr() as *const c_char, pc.prefix);
583 }
584 libc::fprintf(output, c"%s".as_ptr() as *const c_char, pc.name);
585 } else {
586 dump_debug_content_model(output, p);
587 }
588 dump_debug_occurrence(output, pc.ocur);
589 }
590 libc::fprintf(output, c")".as_ptr() as *const c_char);
591 }
592 }
593 dump_debug_occurrence(output, c.ocur);
594 }
595}
596
597fn flatten_chain(
599 node: *mut crate::abi::structs::_xmlElementContent,
600 chain_type: c_int,
601 parts: &mut Vec<*mut crate::abi::structs::_xmlElementContent>,
602) {
603 unsafe {
604 let c = &*node;
605 if c.type_ == chain_type && !c.c1.is_null() {
606 flatten_chain(c.c1, chain_type, parts);
607 if !c.c2.is_null() {
608 flatten_chain(c.c2, chain_type, parts);
609 }
610 } else {
611 parts.push(node);
612 }
613 }
614}
615
616unsafe fn dump_debug_occurrence(output: *mut _IO_FILE, ocur: c_int) {
618 use crate::abi::types::xmlElementContentOccur::*;
619 let s = match ocur {
620 t if t == XML_ELEMENT_CONTENT_OPT as c_int => c"?".as_ptr() as *const c_char,
621 t if t == XML_ELEMENT_CONTENT_MULT as c_int => c"*".as_ptr() as *const c_char,
622 t if t == XML_ELEMENT_CONTENT_PLUS as c_int => c"+".as_ptr() as *const c_char,
623 _ => return,
624 };
625 unsafe {
626 libc::fprintf(output, c"%s".as_ptr() as *const c_char, s);
627 }
628}
629
630const unsafe fn contains_markup(s: *const crate::abi::types::xmlChar) -> bool {
633 if s.is_null() {
634 return false;
635 }
636 unsafe {
637 let mut i = 0usize;
638 while *s.add(i) != 0 {
639 let c = *s.add(i);
640 if c == b'<' || c == b'&' {
641 return true;
642 }
643 i += 1;
644 }
645 }
646 false
647}
648
649unsafe extern "C" fn dump_entityscan_cb(payload: *mut c_void, data: *mut c_void, _name: *const u8) {
651 if payload.is_null() || data.is_null() {
652 return;
653 }
654 let ctx = unsafe { &*(data as *const DtdDumpCtx) };
655 let ent = unsafe { &*(payload as *mut crate::abi::structs::_xmlEntity) };
656 unsafe {
657 for _ in 0..ctx.depth {
658 libc::fprintf(ctx.output, c" ".as_ptr() as *const c_char);
659 }
660 libc::fprintf(ctx.output, c"ENTITYDECL(".as_ptr() as *const c_char);
661 if !ent.name.is_null() {
662 libc::fprintf(ctx.output, c"%s".as_ptr() as *const c_char, ent.name);
663 }
664 if ent.etype == crate::abi::types::xmlEntityType::XML_INTERNAL_GENERAL_ENTITY as c_int {
665 libc::fprintf(ctx.output, c"), internal\n".as_ptr() as *const c_char);
666 for _ in 0..ctx.depth {
669 libc::fprintf(ctx.output, c" ".as_ptr() as *const c_char);
670 }
671 libc::fprintf(ctx.output, c" content=".as_ptr() as *const c_char);
672 if !ent.content.is_null() {
673 xmlDebugDumpString(ctx.output, ent.content as *const u8);
674 }
675 libc::fprintf(ctx.output, c"\n".as_ptr() as *const c_char);
676 if !ent.children.is_null() {
682 let mut c = ent.children;
683 while !c.is_null() {
684 xmlDebugDumpNode(ctx.output, c, (ctx.depth + 1) as c_int);
685 c = (*c).next;
686 }
687 } else if !ent.content.is_null() && !contains_markup(ent.content) {
688 for _ in 0..(ctx.depth + 1) {
689 libc::fprintf(ctx.output, c" ".as_ptr() as *const c_char);
690 }
691 libc::fprintf(ctx.output, c"TEXT compact\n".as_ptr() as *const c_char);
692 for _ in 0..(ctx.depth + 2) {
693 libc::fprintf(ctx.output, c" ".as_ptr() as *const c_char);
694 }
695 libc::fprintf(ctx.output, c"content=".as_ptr() as *const c_char);
696 xmlDebugDumpString(ctx.output, ent.content as *const u8);
697 libc::fprintf(ctx.output, c"\n".as_ptr() as *const c_char);
698 }
699 } else {
700 libc::fprintf(ctx.output, c")\n".as_ptr() as *const c_char);
701 }
702 }
703}
704
705#[no_mangle]
724pub unsafe extern "C" fn xmlDebugDumpNode(
725 output: *mut _IO_FILE,
726 node: *mut _xmlNode,
727 depth: c_int,
728) {
729 if output.is_null() || node.is_null() || depth > MAX_DEPTH {
730 return;
731 }
732 unsafe {
733 xmlDebugDumpOneNode(output, node, depth);
734
735 let t = (*node).type_;
743 let recurse = t == 1 || t == 9 || t == 13 || t == 11; if recurse && !(*node).children.is_null() {
748 let mut child = (*node).children;
749 while !child.is_null() {
750 xmlDebugDumpNode(output, child, depth + 1);
751 child = (*child).next;
752 }
753 }
754 }
755}
756
757#[no_mangle]
776pub unsafe extern "C" fn xmlDebugDumpNodeList(
777 output: *mut _IO_FILE,
778 node: *mut _xmlNode,
779 depth: c_int,
780) {
781 if output.is_null() {
782 return;
783 }
784 let mut cur = node;
785 while !cur.is_null() {
786 unsafe {
787 xmlDebugDumpNode(output, cur, depth);
788 cur = (*cur).next;
789 }
790 }
791}
792
793#[no_mangle]
812pub unsafe extern "C" fn xmlDebugDumpDocument(output: *mut _IO_FILE, doc: *mut _xmlDoc) {
813 if output.is_null() || doc.is_null() {
814 return;
815 }
816 unsafe {
817 if (*doc).type_ == crate::abi::types::xmlElementType::XML_HTML_DOCUMENT_NODE as c_int {
820 libc::fprintf(output, c"HTML DOCUMENT\n".as_ptr() as *const c_char);
821 } else {
822 libc::fprintf(output, c"DOCUMENT\n".as_ptr() as *const c_char);
823 }
824 if !(*doc).version.is_null() {
825 libc::fprintf(output, c"version=".as_ptr() as *const c_char);
826 xmlDebugDumpString(output, (*doc).version as *const u8);
827 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
828 }
829 if !(*doc).URL.is_null() {
830 libc::fprintf(output, c"URL=".as_ptr() as *const c_char);
831 xmlDebugDumpString(output, (*doc).URL as *const u8);
834 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
835 }
836 if (*doc).standalone != 0 {
840 libc::fprintf(output, c"standalone=true\n".as_ptr() as *const c_char);
841 }
842
843 if !(*doc).oldNs.is_null() {
846 let mut ns = (*doc).oldNs;
847 while !ns.is_null() {
848 libc::fprintf(output, c"namespace ".as_ptr() as *const c_char);
849 if (*ns).prefix.is_null() {
850 libc::fprintf(output, c" ".as_ptr() as *const c_char);
851 } else {
852 libc::fprintf(output, c"%s".as_ptr() as *const c_char, (*ns).prefix);
853 }
854 libc::fprintf(output, c" href=%s\n".as_ptr() as *const c_char, (*ns).href);
855 ns = (*ns).next;
856 }
857 }
858
859 if !(*doc).intSubset.is_null() {
865 let mut in_chain = false;
866 let mut c = (*doc).children;
867 while !c.is_null() {
868 if c as *mut c_void == (*doc).intSubset as *mut c_void {
869 in_chain = true;
870 break;
871 }
872 c = (*c).next;
873 }
874 if !in_chain {
875 xmlDebugDumpNode(output, (*doc).intSubset as *mut _xmlNode, 1);
876 }
877 }
878
879 if !(*doc).children.is_null() {
881 let mut child = (*doc).children;
882 while !child.is_null() {
883 xmlDebugDumpNode(output, child, 1);
884 child = (*child).next;
885 }
886 }
887 }
888}
889
890#[no_mangle]
909pub unsafe extern "C" fn xmlDebugDumpDocumentHead(output: *mut _IO_FILE, doc: *mut _xmlDoc) {
910 if output.is_null() || doc.is_null() {
911 return;
912 }
913 unsafe {
914 xmlDebugDumpDocument(output, doc);
915 }
916}
917
918#[no_mangle]
937pub unsafe extern "C" fn xmlLsCountNode(node: *mut _xmlNode) -> c_int {
938 if node.is_null() {
939 return 0;
940 }
941 let mut count: c_int = 0;
942 let mut cur = node;
943 while !cur.is_null() {
944 count += 1;
945 unsafe {
946 cur = (*cur).next;
947 }
948 }
949 count
950}
951
952#[no_mangle]
971pub unsafe extern "C" fn xmlLsOneNode(output: *mut _IO_FILE, node: *mut _xmlNode) {
972 if output.is_null() || node.is_null() {
973 return;
974 }
975 unsafe {
976 match (*node).type_ {
977 1 => {
978 libc::fprintf(output, c"E ".as_ptr() as *const c_char);
980 if !(*node).ns.is_null() && !(*(*node).ns).prefix.is_null() {
981 libc::fprintf(
982 output,
983 c"%s:".as_ptr() as *const c_char,
984 (*(*node).ns).prefix,
985 );
986 }
987 xmlDebugDumpString(output, (*node).name);
988 }
989 2 => {
990 libc::fprintf(output, c"A ".as_ptr() as *const c_char);
991 xmlDebugDumpString(output, (*node).name);
992 }
993 3 => {
994 libc::fprintf(output, c"T ".as_ptr() as *const c_char);
995 if !(*node).content.is_null() {
996 xmlDebugDumpString(output, (*node).content as *const u8);
997 }
998 }
999 4 => {
1000 libc::fprintf(output, c"C ".as_ptr() as *const c_char);
1001 }
1002 5 => {
1003 libc::fprintf(output, c"E ".as_ptr() as *const c_char);
1004 xmlDebugDumpString(output, (*node).name);
1005 }
1006 6 => {
1007 libc::fprintf(output, c"E ".as_ptr() as *const c_char);
1008 xmlDebugDumpString(output, (*node).name);
1009 }
1010 7 => {
1011 libc::fprintf(output, c"PI ".as_ptr() as *const c_char);
1012 xmlDebugDumpString(output, (*node).name);
1013 }
1014 8 => {
1015 libc::fprintf(output, c"C ".as_ptr() as *const c_char);
1016 }
1017 9 => {
1018 libc::fprintf(output, c"D ".as_ptr() as *const c_char);
1019 }
1020 10 => {
1021 libc::fprintf(output, c"DTD ".as_ptr() as *const c_char);
1022 }
1023 14 => {
1024 libc::fprintf(output, c"X ".as_ptr() as *const c_char);
1025 }
1026 _ => {
1027 libc::fprintf(
1028 output,
1029 c"? (%d)".as_ptr() as *const c_char,
1030 (*node).type_ as c_int,
1031 );
1032 }
1033 }
1034 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
1035 }
1036}
1037
1038pub type _IO_FILE = libc::FILE;
1043
1044#[cfg(test)]
1049mod tests {
1050 use super::*;
1051
1052 use crate::abi::types::xmlChar;
1053 use crate::xml::tree::*;
1054
1055 #[allow(dead_code)]
1057 unsafe fn create_test_doc() -> *mut _xmlDoc {
1058 let doc = new_doc(c"1.0".as_ptr() as *const xmlChar);
1059 let root = new_node(ptr::null_mut(), c"root".as_ptr() as *const xmlChar);
1060 doc_set_root_element(doc, root);
1061 let child = new_child(root, ptr::null_mut(), c"child".as_ptr() as *const xmlChar);
1062 set_prop(
1064 child,
1065 c"attr1".as_ptr() as *const xmlChar,
1066 c"value1".as_ptr() as *const xmlChar,
1067 );
1068 doc
1069 }
1070
1071 #[test]
1072 fn test_xml_bool_to_text() {
1073 unsafe {
1074 let t = xmlBoolToText(1);
1075 assert!(!t.is_null());
1076 let f = xmlBoolToText(0);
1077 assert!(!f.is_null());
1078 assert_eq!(*t as u8, b't');
1080 assert_eq!(*f as u8, b'f');
1081 }
1082 }
1083
1084 #[test]
1085 fn test_debug_dump_string_null() {
1086 unsafe {
1087 xmlDebugDumpString(ptr::null_mut(), ptr::null());
1089 let f = libc::fmemopen(ptr::null_mut(), 0, c"w".as_ptr() as *const c_char);
1091 if !f.is_null() {
1092 xmlDebugDumpString(f, ptr::null());
1093 libc::fclose(f);
1094 }
1095 }
1096 }
1097
1098 #[test]
1099 fn test_debug_dump_document_null() {
1100 unsafe {
1101 xmlDebugDumpDocument(ptr::null_mut(), ptr::null_mut());
1102 let f = libc::fmemopen(ptr::null_mut(), 0, c"w".as_ptr() as *const c_char);
1103 if !f.is_null() {
1104 xmlDebugDumpDocument(f, ptr::null_mut());
1105 libc::fclose(f);
1106 }
1107 }
1108 }
1109
1110 #[test]
1111 fn test_debug_dump_node_null() {
1112 unsafe {
1113 xmlDebugDumpNode(ptr::null_mut(), ptr::null_mut(), 0);
1114 let f = libc::fmemopen(ptr::null_mut(), 0, c"w".as_ptr() as *const c_char);
1115 if !f.is_null() {
1116 xmlDebugDumpNode(f, ptr::null_mut(), 0);
1117 libc::fclose(f);
1118 }
1119 }
1120 }
1121
1122 #[test]
1123 fn test_ls_count_node() {
1124 unsafe {
1125 let node = new_node(ptr::null_mut(), c"test".as_ptr() as *const xmlChar);
1126 assert!(!node.is_null());
1127 let count = xmlLsCountNode(node);
1128 assert_eq!(count, 1);
1129
1130 let sibling = new_node(ptr::null_mut(), c"sibling".as_ptr() as *const xmlChar);
1132 add_sibling(node, sibling);
1133 let count = xmlLsCountNode(node);
1134 assert_eq!(count, 2);
1135
1136 free_node(node);
1137 }
1138 }
1139
1140 #[test]
1141 fn test_debug_dump_attr_null() {
1142 unsafe {
1143 xmlDebugDumpAttr(ptr::null_mut(), ptr::null_mut(), 0);
1144 let f = libc::fmemopen(ptr::null_mut(), 0, c"w".as_ptr() as *const c_char);
1145 if !f.is_null() {
1146 xmlDebugDumpAttr(f, ptr::null_mut(), 0);
1147 libc::fclose(f);
1148 }
1149 }
1150 }
1151
1152 #[test]
1153 fn test_debug_dump_attr_list_null() {
1154 unsafe {
1155 xmlDebugDumpAttrList(ptr::null_mut(), ptr::null_mut(), 0);
1156 }
1157 }
1158
1159 #[test]
1160 fn test_debug_dump_node_list_null() {
1161 unsafe {
1162 xmlDebugDumpNodeList(ptr::null_mut(), ptr::null_mut(), 0);
1163 }
1164 }
1165
1166 #[test]
1167 fn test_ls_one_node_null() {
1168 unsafe {
1169 xmlLsOneNode(ptr::null_mut(), ptr::null_mut());
1170 let f = libc::fmemopen(ptr::null_mut(), 0, c"w".as_ptr() as *const c_char);
1171 if !f.is_null() {
1172 xmlLsOneNode(f, ptr::null_mut());
1173 libc::fclose(f);
1174 }
1175 }
1176 }
1177
1178 #[test]
1179 fn test_dump_document_head_null() {
1180 unsafe {
1181 xmlDebugDumpDocumentHead(ptr::null_mut(), ptr::null_mut());
1182 }
1183 }
1184
1185 #[test]
1186 fn test_ls_count_node_null() {
1187 assert_eq!(unsafe { xmlLsCountNode(ptr::null_mut()) }, 0);
1188 }
1189}