1use crate::abi::structs::{_xmlAttr, _xmlDoc, _xmlNode};
59use core::ffi::{c_char, c_int, c_void};
60use core::ptr;
61
62const MAX_DEPTH: c_int = 100;
64
65fn is_xinclude_node(node: *mut _xmlNode) -> bool {
69 if node.is_null() {
70 return false;
71 }
72 unsafe {
73 let ns = (*node).ns;
74 if ns.is_null() {
75 return false;
76 }
77 let ns_href = (*ns).href;
78 let _ns_prefix = (*ns).prefix;
79 if ns_href.is_null() {
80 return false;
81 }
82 let href = core::slice::from_raw_parts(ns_href, 30);
84 let xi_ns = b"http://www.w3.org/2001/XInclude\0";
85 let mut matches = true;
86 for i in 0..30 {
87 if i >= href.len() || href[i] != xi_ns[i] {
88 matches = false;
89 break;
90 }
91 }
92 if !matches {
93 return false;
94 }
95 let name_bytes = if !(*node).name.is_null() {
97 core::slice::from_raw_parts((*node).name, 8)
98 } else {
99 return false;
100 };
101 name_bytes.len() >= 7 && &name_bytes[..7] == b"include"
102 }
103}
104
105#[no_mangle]
119pub const unsafe extern "C" fn xmlBoolToText(boolval: c_int) -> *const c_char {
120 if boolval != 0 {
121 c"true".as_ptr() as *const c_char
122 } else {
123 c"false".as_ptr() as *const c_char
124 }
125}
126
127#[no_mangle]
147pub unsafe extern "C" fn xmlDebugDumpString(output: *mut _IO_FILE, str_val: *const u8) {
148 if output.is_null() {
149 return;
150 }
151 if str_val.is_null() {
152 unsafe {
153 libc::fprintf(output, c"(NULL)".as_ptr() as *const c_char);
154 }
155 return;
156 }
157 unsafe {
158 let mut i = 0;
162 while i < 40 {
163 let c = *str_val.add(i);
164 if c == 0 {
165 return;
166 }
167 if c == b' ' || c == b'\t' || c == b'\n' || c == b'\r' {
168 libc::fprintf(output, c" ".as_ptr() as *const c_char);
169 } else if c >= 0x80 {
170 libc::fprintf(output, c"#%X".as_ptr() as *const c_char, c as c_int);
171 } else {
172 libc::fprintf(output, c"%c".as_ptr() as *const c_char, c as c_int);
173 }
174 i += 1;
175 }
176 libc::fprintf(output, c"...".as_ptr() as *const c_char);
177 }
178}
179
180#[no_mangle]
199pub unsafe extern "C" fn xmlDebugDumpAttr(
200 output: *mut _IO_FILE,
201 attr: *mut _xmlAttr,
202 depth: c_int,
203) {
204 if output.is_null() || attr.is_null() {
205 return;
206 }
207 unsafe {
208 for _ in 0..depth {
209 libc::fprintf(output, c" ".as_ptr() as *const c_char);
210 }
211 libc::fprintf(output, c"ATTRIBUTE ".as_ptr() as *const c_char);
212 xmlDebugDumpString(output, (*attr).name);
213 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
214 xmlDebugDumpNode(output, (*attr).children, depth + 1);
216 }
217}
218
219#[no_mangle]
238pub unsafe extern "C" fn xmlDebugDumpAttrList(
239 output: *mut _IO_FILE,
240 attr: *mut _xmlAttr,
241 depth: c_int,
242) {
243 if output.is_null() {
244 return;
245 }
246 let mut cur = attr;
247 while !cur.is_null() {
248 unsafe {
249 xmlDebugDumpAttr(output, cur, depth);
250 cur = (*cur).next;
251 }
252 }
253}
254
255#[no_mangle]
274pub unsafe extern "C" fn xmlDebugDumpOneNode(
275 output: *mut _IO_FILE,
276 node: *mut _xmlNode,
277 depth: c_int,
278) {
279 if output.is_null() || node.is_null() {
280 return;
281 }
282 unsafe {
283 for _ in 0..depth {
285 libc::fprintf(output, c" ".as_ptr() as *const c_char);
286 }
287
288 match (*node).type_ {
290 1 => {
291 libc::fprintf(output, c"ELEMENT ".as_ptr() as *const c_char);
293 if !(*node).ns.is_null() && !(*(*node).ns).prefix.is_null() {
295 libc::fprintf(
296 output,
297 c"%s:".as_ptr() as *const c_char,
298 (*(*node).ns).prefix,
299 );
300 }
301 xmlDebugDumpString(output, (*node).name);
302 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
303
304 if !(*node).nsDef.is_null() {
307 let mut ns = (*node).nsDef;
308 while !ns.is_null() {
309 for _ in 0..(depth + 1) {
310 libc::fprintf(output, c" ".as_ptr() as *const c_char);
311 }
312 libc::fprintf(output, c"namespace ".as_ptr() as *const c_char);
313 if (*ns).prefix.is_null() {
314 libc::fprintf(output, c" ".as_ptr() as *const c_char);
315 } else {
316 libc::fprintf(output, c"%s".as_ptr() as *const c_char, (*ns).prefix);
317 }
318 libc::fprintf(output, c" href=".as_ptr() as *const c_char);
319 libc::fprintf(output, c"%s\n".as_ptr() as *const c_char, (*ns).href);
320 ns = (*ns).next;
321 }
322 }
323
324 if !(*node).properties.is_null() {
326 xmlDebugDumpAttrList(output, (*node).properties, depth + 1);
327 }
328 }
329 2 => {
330 libc::fprintf(output, c"ATTRIBUTE ".as_ptr() as *const c_char);
332 xmlDebugDumpString(output, (*node).name);
333 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
334 }
335 3 => {
336 libc::fprintf(output, c"TEXT".as_ptr() as *const c_char);
338 let inline_addr = std::ptr::addr_of_mut!((*node).properties) as *const c_void;
341 if (*node).content as *const c_void == inline_addr {
342 libc::fprintf(output, c" compact".as_ptr() as *const c_char);
343 }
344 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
345 for _ in 0..(depth + 1) {
346 libc::fprintf(output, c" ".as_ptr() as *const c_char);
347 }
348 libc::fprintf(output, c"content=".as_ptr() as *const c_char);
349 if !(*node).content.is_null() {
350 xmlDebugDumpString(output, (*node).content as *const u8);
351 } else {
352 let c = crate::xml::tree::node_get_content(node);
353 if !c.is_null() {
354 libc::fprintf(output, c"%s".as_ptr() as *const c_char, c);
355 crate::abi::allocator::xmlFreeImpl(c as *mut c_void);
356 }
357 }
358 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
359 }
360 4 => {
361 libc::fprintf(output, c"CDATA_SECTION\n".as_ptr() as *const c_char);
363 for _ in 0..(depth + 1) {
364 libc::fprintf(output, c" ".as_ptr() as *const c_char);
365 }
366 libc::fprintf(output, c"content=".as_ptr() as *const c_char);
367 xmlDebugDumpString(output, (*node).content as *const u8);
368 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
369 }
370 5 => {
371 libc::fprintf(output, c"ENTITY_REF(".as_ptr() as *const c_char);
373 xmlDebugDumpString(output, (*node).name);
374 libc::fprintf(output, c")\n".as_ptr() as *const c_char);
375 let doc = (*node).doc;
377 let ent = if doc.is_null() {
378 ptr::null_mut()
379 } else {
380 crate::xml::entities::get_entity(doc, (*node).name)
381 };
382 if !ent.is_null() {
383 for _ in 0..(depth + 1) {
384 libc::fprintf(output, c" ".as_ptr() as *const c_char);
385 }
386 let etype = (*ent).etype;
387 let etype_name = entity_type_name(etype);
388 libc::fprintf(
389 output,
390 c"%s ".as_ptr() as *const c_char,
391 etype_name.as_ptr() as *const c_char,
392 );
393 libc::fprintf(output, c"%s\n".as_ptr() as *const c_char, (*ent).name);
394 for _ in 0..(depth + 1) {
395 libc::fprintf(output, c" ".as_ptr() as *const c_char);
396 }
397 libc::fprintf(output, c"content=".as_ptr() as *const c_char);
398 if !(*ent).content.is_null() {
399 xmlDebugDumpString(output, (*ent).content as *const u8);
400 }
401 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
402 }
403 }
404 6 => {
405 libc::fprintf(output, c"ENTITYDECL(".as_ptr() as *const c_char);
407 xmlDebugDumpString(output, (*node).name);
408 libc::fprintf(output, c")".as_ptr() as *const c_char);
409 if !(*node).content.is_null() {
410 libc::fprintf(output, c", internal\n ".as_ptr() as *const c_char);
411 libc::fprintf(output, c"content=".as_ptr() as *const c_char);
412 xmlDebugDumpString(output, (*node).content as *const u8);
413 }
414 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
415 }
416 7 => {
417 libc::fprintf(output, c"PI ".as_ptr() as *const c_char);
419 xmlDebugDumpString(output, (*node).name);
420 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
421 if !(*node).content.is_null() {
422 for _ in 0..(depth + 1) {
423 libc::fprintf(output, c" ".as_ptr() as *const c_char);
424 }
425 libc::fprintf(output, c"content=".as_ptr() as *const c_char);
426 xmlDebugDumpString(output, (*node).content as *const u8);
427 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
428 }
429 }
430 8 => {
431 libc::fprintf(output, c"COMMENT\n".as_ptr() as *const c_char);
433 for _ in 0..(depth + 1) {
434 libc::fprintf(output, c" ".as_ptr() as *const c_char);
435 }
436 libc::fprintf(output, c"content=".as_ptr() as *const c_char);
437 xmlDebugDumpString(output, (*node).content as *const u8);
438 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
439 }
440 9 => {
441 libc::fprintf(output, c"DOCUMENT".as_ptr() as *const c_char);
443 }
444 10 => {
445 libc::fprintf(output, c"DOCTYPE".as_ptr() as *const c_char);
447 }
448 14 => {
449 libc::fprintf(output, c"DTD(".as_ptr() as *const c_char);
453 xmlDebugDumpString(output, (*node).name);
454 libc::fprintf(output, c")".as_ptr() as *const c_char);
455 let dtd = node as *mut crate::abi::structs::_xmlDtd;
456 if !(*dtd).ExternalID.is_null() {
457 libc::fprintf(output, c", PUBLIC ".as_ptr() as *const c_char);
458 libc::fprintf(output, c"%s".as_ptr() as *const c_char, (*dtd).ExternalID);
459 }
460 if !(*dtd).SystemID.is_null() {
461 libc::fprintf(output, c", SYSTEM ".as_ptr() as *const c_char);
462 libc::fprintf(output, c"%s".as_ptr() as *const c_char, (*dtd).SystemID);
463 }
464 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
465 let dtd = node as *mut crate::abi::structs::_xmlDtd;
467 if !(*dtd).elements.is_null() {
468 let ctx = DtdDumpCtx {
469 output,
470 depth: depth + 1,
471 };
472 crate::xml::hash::hash_scan(
473 (*dtd).elements as *mut crate::xml::hash::HashTable,
474 Some(dump_elemscan_cb),
475 &ctx as *const DtdDumpCtx as *mut c_void,
476 );
477 }
478 if !(*dtd).entities.is_null() {
480 let ctx = DtdDumpCtx {
481 output,
482 depth: depth + 1,
483 };
484 crate::xml::hash::hash_scan(
485 (*dtd).entities as *mut crate::xml::hash::HashTable,
486 Some(dump_entityscan_cb),
487 &ctx as *const DtdDumpCtx as *mut c_void,
488 );
489 }
490 }
491 13 => {
492 libc::fprintf(output, c"HTML DOCUMENT".as_ptr() as *const c_char);
494 }
495 18 => {
496 libc::fprintf(output, c"NAMESPACE".as_ptr() as *const c_char);
498 if !(*node).ns.is_null() && !(*(*node).ns).prefix.is_null() {
499 libc::fprintf(
500 output,
501 c" %s=%s".as_ptr() as *const c_char,
502 (*(*node).ns).prefix,
503 (*(*node).ns).href,
504 );
505 }
506 }
507 19 => {
508 if is_xinclude_node(node) {
510 libc::fprintf(output, c"XINCLUDE".as_ptr() as *const c_char);
511 } else {
512 libc::fprintf(output, c"XINCLUDE_START".as_ptr() as *const c_char);
513 }
514 }
515 20 => {
516 libc::fprintf(output, c"XINCLUDE_END".as_ptr() as *const c_char);
518 }
519 _ => {
520 libc::fprintf(
521 output,
522 c"UNKNOWN (%d)".as_ptr() as *const c_char,
523 (*node).type_ as c_int,
524 );
525 }
526 }
527 }
528}
529
530fn entity_type_name(etype: c_int) -> Vec<u8> {
532 use crate::abi::types::xmlEntityType::*;
533 match etype {
534 t if t == XML_INTERNAL_GENERAL_ENTITY as c_int => b"INTERNAL_GENERAL_ENTITY\0".to_vec(),
535 t if t == XML_INTERNAL_PARAMETER_ENTITY as c_int => b"INTERNAL_PARAMETER_ENTITY\0".to_vec(),
536 t if t == XML_EXTERNAL_GENERAL_PARSED_ENTITY as c_int => {
537 b"EXTERNAL_GENERAL_PARSED_ENTITY\0".to_vec()
538 }
539 t if t == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY as c_int => {
540 b"EXTERNAL_GENERAL_UNPARSED_ENTITY\0".to_vec()
541 }
542 t if t == XML_EXTERNAL_PARAMETER_ENTITY as c_int => b"EXTERNAL_PARAMETER_ENTITY\0".to_vec(),
543 t if t == XML_INTERNAL_PREDEFINED_ENTITY as c_int => {
544 b"INTERNAL_PREDEFINED_ENTITY\0".to_vec()
545 }
546 _ => b"UNKNOWN_ENTITY\0".to_vec(),
547 }
548}
549
550#[repr(C)]
552struct DtdDumpCtx {
553 output: *mut _IO_FILE,
554 depth: c_int,
555}
556
557unsafe extern "C" fn dump_elemscan_cb(payload: *mut c_void, data: *mut c_void, _name: *const u8) {
559 if payload.is_null() || data.is_null() {
560 return;
561 }
562 let ctx = unsafe { &*(data as *const DtdDumpCtx) };
563 let elem = unsafe { &*(payload as *mut crate::abi::structs::_xmlElement) };
564 unsafe {
565 for _ in 0..ctx.depth {
566 libc::fprintf(ctx.output, c" ".as_ptr() as *const c_char);
567 }
568 libc::fprintf(ctx.output, c"ELEMDECL(".as_ptr() as *const c_char);
569 if !elem.name.is_null() {
570 libc::fprintf(ctx.output, c"%s".as_ptr() as *const c_char, elem.name);
571 }
572 libc::fprintf(ctx.output, c")".as_ptr() as *const c_char);
573 match elem.type_ {
577 t if t == crate::abi::types::xmlElementTypeVal::XML_ELEMENT_TYPE_EMPTY as c_int => {
578 libc::fprintf(ctx.output, c", EMPTY\n".as_ptr() as *const c_char);
579 }
580 t if t == crate::abi::types::xmlElementTypeVal::XML_ELEMENT_TYPE_ANY as c_int => {
581 libc::fprintf(ctx.output, c", ANY\n".as_ptr() as *const c_char);
582 }
583 _ => {
584 libc::fprintf(ctx.output, c", MIXED ".as_ptr() as *const c_char);
585 dump_debug_content_model(ctx.output, elem.content);
586 libc::fprintf(ctx.output, c"\n".as_ptr() as *const c_char);
587 }
588 }
589 }
590}
591
592unsafe fn dump_debug_content_model(
595 output: *mut _IO_FILE,
596 content: *mut crate::abi::structs::_xmlElementContent,
597) {
598 use crate::abi::types::xmlElementContentType::*;
599 if content.is_null() {
600 return;
601 }
602 unsafe {
603 let c = &*content;
604 match c.type_ {
605 t if t == XML_ELEMENT_CONTENT_PCDATA as c_int => {
606 libc::fprintf(output, c"(#PCDATA)".as_ptr() as *const c_char);
607 }
608 t if t == XML_ELEMENT_CONTENT_ELEMENT as c_int => {
609 if !c.prefix.is_null() {
610 libc::fprintf(output, c"%s:".as_ptr() as *const c_char, c.prefix);
611 }
612 libc::fprintf(output, c"%s".as_ptr() as *const c_char, c.name);
613 }
614 _ => {
615 let sep = if c.type_ == XML_ELEMENT_CONTENT_SEQ as c_int {
616 c" , ".as_ptr() as *const c_char
617 } else {
618 c" | ".as_ptr() as *const c_char
619 };
620 libc::fprintf(output, c"(".as_ptr() as *const c_char);
621 let mut parts: Vec<*mut crate::abi::structs::_xmlElementContent> = Vec::new();
622 flatten_chain(c as *const _ as *mut _, c.type_, &mut parts);
623 for (i, &p) in parts.iter().enumerate() {
624 if i > 0 {
625 libc::fprintf(output, c"%s".as_ptr() as *const c_char, sep);
626 }
627 let pc = &*p;
628 if pc.type_ == XML_ELEMENT_CONTENT_PCDATA as c_int {
629 libc::fprintf(output, c"#PCDATA".as_ptr() as *const c_char);
630 } else if pc.type_ == XML_ELEMENT_CONTENT_ELEMENT as c_int {
631 if !pc.prefix.is_null() {
632 libc::fprintf(output, c"%s:".as_ptr() as *const c_char, pc.prefix);
633 }
634 libc::fprintf(output, c"%s".as_ptr() as *const c_char, pc.name);
635 } else {
636 dump_debug_content_model(output, p);
637 }
638 dump_debug_occurrence(output, pc.ocur);
639 }
640 libc::fprintf(output, c")".as_ptr() as *const c_char);
641 }
642 }
643 dump_debug_occurrence(output, c.ocur);
644 }
645}
646
647fn flatten_chain(
649 node: *mut crate::abi::structs::_xmlElementContent,
650 chain_type: c_int,
651 parts: &mut Vec<*mut crate::abi::structs::_xmlElementContent>,
652) {
653 unsafe {
654 let c = &*node;
655 if c.type_ == chain_type && !c.c1.is_null() {
656 flatten_chain(c.c1, chain_type, parts);
657 if !c.c2.is_null() {
658 flatten_chain(c.c2, chain_type, parts);
659 }
660 } else {
661 parts.push(node);
662 }
663 }
664}
665
666unsafe fn dump_debug_occurrence(output: *mut _IO_FILE, ocur: c_int) {
668 use crate::abi::types::xmlElementContentOccur::*;
669 let s = match ocur {
670 t if t == XML_ELEMENT_CONTENT_OPT as c_int => c"?".as_ptr() as *const c_char,
671 t if t == XML_ELEMENT_CONTENT_MULT as c_int => c"*".as_ptr() as *const c_char,
672 t if t == XML_ELEMENT_CONTENT_PLUS as c_int => c"+".as_ptr() as *const c_char,
673 _ => return,
674 };
675 unsafe {
676 libc::fprintf(output, c"%s".as_ptr() as *const c_char, s);
677 }
678}
679
680const unsafe fn contains_markup(s: *const crate::abi::types::xmlChar) -> bool {
683 if s.is_null() {
684 return false;
685 }
686 unsafe {
687 let mut i = 0usize;
688 while *s.add(i) != 0 {
689 let c = *s.add(i);
690 if c == b'<' || c == b'&' {
691 return true;
692 }
693 i += 1;
694 }
695 }
696 false
697}
698
699unsafe extern "C" fn dump_entityscan_cb(payload: *mut c_void, data: *mut c_void, _name: *const u8) {
701 if payload.is_null() || data.is_null() {
702 return;
703 }
704 let ctx = unsafe { &*(data as *const DtdDumpCtx) };
705 let ent = unsafe { &*(payload as *mut crate::abi::structs::_xmlEntity) };
706 unsafe {
707 for _ in 0..ctx.depth {
708 libc::fprintf(ctx.output, c" ".as_ptr() as *const c_char);
709 }
710 libc::fprintf(ctx.output, c"ENTITYDECL(".as_ptr() as *const c_char);
711 if !ent.name.is_null() {
712 libc::fprintf(ctx.output, c"%s".as_ptr() as *const c_char, ent.name);
713 }
714 if ent.etype == crate::abi::types::xmlEntityType::XML_INTERNAL_GENERAL_ENTITY as c_int {
715 libc::fprintf(ctx.output, c"), internal\n".as_ptr() as *const c_char);
716 for _ in 0..ctx.depth {
719 libc::fprintf(ctx.output, c" ".as_ptr() as *const c_char);
720 }
721 libc::fprintf(ctx.output, c" content=".as_ptr() as *const c_char);
722 if !ent.content.is_null() {
723 xmlDebugDumpString(ctx.output, ent.content as *const u8);
724 }
725 libc::fprintf(ctx.output, c"\n".as_ptr() as *const c_char);
726 if !ent.children.is_null() {
732 let mut c = ent.children;
733 while !c.is_null() {
734 xmlDebugDumpNode(ctx.output, c, (ctx.depth + 1) as c_int);
735 c = (*c).next;
736 }
737 } else if !ent.content.is_null() && !contains_markup(ent.content) {
738 for _ in 0..(ctx.depth + 1) {
739 libc::fprintf(ctx.output, c" ".as_ptr() as *const c_char);
740 }
741 libc::fprintf(ctx.output, c"TEXT compact\n".as_ptr() as *const c_char);
742 for _ in 0..(ctx.depth + 2) {
743 libc::fprintf(ctx.output, c" ".as_ptr() as *const c_char);
744 }
745 libc::fprintf(ctx.output, c"content=".as_ptr() as *const c_char);
746 xmlDebugDumpString(ctx.output, ent.content as *const u8);
747 libc::fprintf(ctx.output, c"\n".as_ptr() as *const c_char);
748 }
749 } else {
750 libc::fprintf(ctx.output, c")\n".as_ptr() as *const c_char);
751 }
752 }
753}
754
755#[no_mangle]
774pub unsafe extern "C" fn xmlDebugDumpNode(
775 output: *mut _IO_FILE,
776 node: *mut _xmlNode,
777 depth: c_int,
778) {
779 if output.is_null() || node.is_null() || depth > MAX_DEPTH {
780 return;
781 }
782 unsafe {
783 xmlDebugDumpOneNode(output, node, depth);
784
785 let t = (*node).type_;
793 let recurse = t == 1 || t == 9 || t == 13 || t == 11; if recurse && !(*node).children.is_null() {
798 let mut child = (*node).children;
799 while !child.is_null() {
800 xmlDebugDumpNode(output, child, depth + 1);
801 child = (*child).next;
802 }
803 }
804 }
805}
806
807#[no_mangle]
826pub unsafe extern "C" fn xmlDebugDumpNodeList(
827 output: *mut _IO_FILE,
828 node: *mut _xmlNode,
829 depth: c_int,
830) {
831 if output.is_null() {
832 return;
833 }
834 let mut cur = node;
835 while !cur.is_null() {
836 unsafe {
837 xmlDebugDumpNode(output, cur, depth);
838 cur = (*cur).next;
839 }
840 }
841}
842
843#[no_mangle]
862pub unsafe extern "C" fn xmlDebugDumpDocument(output: *mut _IO_FILE, doc: *mut _xmlDoc) {
863 if output.is_null() || doc.is_null() {
864 return;
865 }
866 unsafe {
867 if (*doc).type_ == crate::abi::types::xmlElementType::XML_HTML_DOCUMENT_NODE as c_int {
870 libc::fprintf(output, c"HTML DOCUMENT\n".as_ptr() as *const c_char);
871 } else {
872 libc::fprintf(output, c"DOCUMENT\n".as_ptr() as *const c_char);
873 }
874 if !(*doc).version.is_null() {
875 libc::fprintf(output, c"version=".as_ptr() as *const c_char);
876 xmlDebugDumpString(output, (*doc).version as *const u8);
877 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
878 }
879 if !(*doc).URL.is_null() {
880 libc::fprintf(output, c"URL=".as_ptr() as *const c_char);
881 xmlDebugDumpString(output, (*doc).URL as *const u8);
884 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
885 }
886 if (*doc).standalone != 0 {
890 libc::fprintf(output, c"standalone=true\n".as_ptr() as *const c_char);
891 }
892
893 if !(*doc).oldNs.is_null() {
896 let mut ns = (*doc).oldNs;
897 while !ns.is_null() {
898 libc::fprintf(output, c"namespace ".as_ptr() as *const c_char);
899 if (*ns).prefix.is_null() {
900 libc::fprintf(output, c" ".as_ptr() as *const c_char);
901 } else {
902 libc::fprintf(output, c"%s".as_ptr() as *const c_char, (*ns).prefix);
903 }
904 libc::fprintf(output, c" href=%s\n".as_ptr() as *const c_char, (*ns).href);
905 ns = (*ns).next;
906 }
907 }
908
909 if !(*doc).intSubset.is_null() {
915 let mut in_chain = false;
916 let mut c = (*doc).children;
917 while !c.is_null() {
918 if c as *mut c_void == (*doc).intSubset as *mut c_void {
919 in_chain = true;
920 break;
921 }
922 c = (*c).next;
923 }
924 if !in_chain {
925 xmlDebugDumpNode(output, (*doc).intSubset as *mut _xmlNode, 1);
926 }
927 }
928
929 if !(*doc).children.is_null() {
931 let mut child = (*doc).children;
932 while !child.is_null() {
933 xmlDebugDumpNode(output, child, 1);
934 child = (*child).next;
935 }
936 }
937 }
938}
939
940#[no_mangle]
959pub unsafe extern "C" fn xmlDebugDumpDocumentHead(output: *mut _IO_FILE, doc: *mut _xmlDoc) {
960 if output.is_null() || doc.is_null() {
961 return;
962 }
963 unsafe {
964 xmlDebugDumpDocument(output, doc);
965 }
966}
967
968#[no_mangle]
987pub unsafe extern "C" fn xmlLsCountNode(node: *mut _xmlNode) -> c_int {
988 if node.is_null() {
989 return 0;
990 }
991 let mut count: c_int = 0;
992 let mut cur = node;
993 while !cur.is_null() {
994 count += 1;
995 unsafe {
996 cur = (*cur).next;
997 }
998 }
999 count
1000}
1001
1002#[no_mangle]
1021pub unsafe extern "C" fn xmlLsOneNode(output: *mut _IO_FILE, node: *mut _xmlNode) {
1022 if output.is_null() || node.is_null() {
1023 return;
1024 }
1025 unsafe {
1026 match (*node).type_ {
1027 1 => {
1028 libc::fprintf(output, c"E ".as_ptr() as *const c_char);
1030 if !(*node).ns.is_null() && !(*(*node).ns).prefix.is_null() {
1031 libc::fprintf(
1032 output,
1033 c"%s:".as_ptr() as *const c_char,
1034 (*(*node).ns).prefix,
1035 );
1036 }
1037 xmlDebugDumpString(output, (*node).name);
1038 }
1039 2 => {
1040 libc::fprintf(output, c"A ".as_ptr() as *const c_char);
1041 xmlDebugDumpString(output, (*node).name);
1042 }
1043 3 => {
1044 libc::fprintf(output, c"T ".as_ptr() as *const c_char);
1045 if !(*node).content.is_null() {
1046 xmlDebugDumpString(output, (*node).content as *const u8);
1047 }
1048 }
1049 4 => {
1050 libc::fprintf(output, c"C ".as_ptr() as *const c_char);
1051 }
1052 5 => {
1053 libc::fprintf(output, c"E ".as_ptr() as *const c_char);
1054 xmlDebugDumpString(output, (*node).name);
1055 }
1056 6 => {
1057 libc::fprintf(output, c"E ".as_ptr() as *const c_char);
1058 xmlDebugDumpString(output, (*node).name);
1059 }
1060 7 => {
1061 libc::fprintf(output, c"PI ".as_ptr() as *const c_char);
1062 xmlDebugDumpString(output, (*node).name);
1063 }
1064 8 => {
1065 libc::fprintf(output, c"C ".as_ptr() as *const c_char);
1066 }
1067 9 => {
1068 libc::fprintf(output, c"D ".as_ptr() as *const c_char);
1069 }
1070 10 => {
1071 libc::fprintf(output, c"DTD ".as_ptr() as *const c_char);
1072 }
1073 14 => {
1074 libc::fprintf(output, c"X ".as_ptr() as *const c_char);
1075 }
1076 _ => {
1077 libc::fprintf(
1078 output,
1079 c"? (%d)".as_ptr() as *const c_char,
1080 (*node).type_ as c_int,
1081 );
1082 }
1083 }
1084 libc::fprintf(output, c"\n".as_ptr() as *const c_char);
1085 }
1086}
1087
1088pub type _IO_FILE = libc::FILE;
1093
1094#[cfg(test)]
1099mod tests {
1100 use super::*;
1101
1102 use crate::abi::types::xmlChar;
1103 use crate::xml::tree::*;
1104
1105 #[allow(dead_code)]
1107 unsafe fn create_test_doc() -> *mut _xmlDoc {
1108 let doc = new_doc(c"1.0".as_ptr() as *const xmlChar);
1109 let root = new_node(ptr::null_mut(), c"root".as_ptr() as *const xmlChar);
1110 doc_set_root_element(doc, root);
1111 let child = new_child(root, ptr::null_mut(), c"child".as_ptr() as *const xmlChar);
1112 set_prop(
1114 child,
1115 c"attr1".as_ptr() as *const xmlChar,
1116 c"value1".as_ptr() as *const xmlChar,
1117 );
1118 doc
1119 }
1120
1121 #[test]
1122 fn test_xml_bool_to_text() {
1123 unsafe {
1124 let t = xmlBoolToText(1);
1125 assert!(!t.is_null());
1126 let f = xmlBoolToText(0);
1127 assert!(!f.is_null());
1128 assert_eq!(*t as u8, b't');
1130 assert_eq!(*f as u8, b'f');
1131 }
1132 }
1133
1134 #[test]
1135 fn test_debug_dump_string_null() {
1136 unsafe {
1137 xmlDebugDumpString(ptr::null_mut(), ptr::null());
1139 let f = libc::fmemopen(ptr::null_mut(), 0, c"w".as_ptr() as *const c_char);
1141 if !f.is_null() {
1142 xmlDebugDumpString(f, ptr::null());
1143 libc::fclose(f);
1144 }
1145 }
1146 }
1147
1148 #[test]
1149 fn test_debug_dump_document_null() {
1150 unsafe {
1151 xmlDebugDumpDocument(ptr::null_mut(), ptr::null_mut());
1152 let f = libc::fmemopen(ptr::null_mut(), 0, c"w".as_ptr() as *const c_char);
1153 if !f.is_null() {
1154 xmlDebugDumpDocument(f, ptr::null_mut());
1155 libc::fclose(f);
1156 }
1157 }
1158 }
1159
1160 #[test]
1161 fn test_debug_dump_node_null() {
1162 unsafe {
1163 xmlDebugDumpNode(ptr::null_mut(), ptr::null_mut(), 0);
1164 let f = libc::fmemopen(ptr::null_mut(), 0, c"w".as_ptr() as *const c_char);
1165 if !f.is_null() {
1166 xmlDebugDumpNode(f, ptr::null_mut(), 0);
1167 libc::fclose(f);
1168 }
1169 }
1170 }
1171
1172 #[test]
1173 fn test_ls_count_node() {
1174 unsafe {
1175 let node = new_node(ptr::null_mut(), c"test".as_ptr() as *const xmlChar);
1176 assert!(!node.is_null());
1177 let count = xmlLsCountNode(node);
1178 assert_eq!(count, 1);
1179
1180 let sibling = new_node(ptr::null_mut(), c"sibling".as_ptr() as *const xmlChar);
1182 add_sibling(node, sibling);
1183 let count = xmlLsCountNode(node);
1184 assert_eq!(count, 2);
1185
1186 free_node(node);
1187 }
1188 }
1189
1190 #[test]
1191 fn test_debug_dump_attr_null() {
1192 unsafe {
1193 xmlDebugDumpAttr(ptr::null_mut(), ptr::null_mut(), 0);
1194 let f = libc::fmemopen(ptr::null_mut(), 0, c"w".as_ptr() as *const c_char);
1195 if !f.is_null() {
1196 xmlDebugDumpAttr(f, ptr::null_mut(), 0);
1197 libc::fclose(f);
1198 }
1199 }
1200 }
1201
1202 #[test]
1203 fn test_debug_dump_attr_list_null() {
1204 unsafe {
1205 xmlDebugDumpAttrList(ptr::null_mut(), ptr::null_mut(), 0);
1206 }
1207 }
1208
1209 #[test]
1210 fn test_debug_dump_node_list_null() {
1211 unsafe {
1212 xmlDebugDumpNodeList(ptr::null_mut(), ptr::null_mut(), 0);
1213 }
1214 }
1215
1216 #[test]
1217 fn test_ls_one_node_null() {
1218 unsafe {
1219 xmlLsOneNode(ptr::null_mut(), ptr::null_mut());
1220 let f = libc::fmemopen(ptr::null_mut(), 0, c"w".as_ptr() as *const c_char);
1221 if !f.is_null() {
1222 xmlLsOneNode(f, ptr::null_mut());
1223 libc::fclose(f);
1224 }
1225 }
1226 }
1227
1228 #[test]
1229 fn test_dump_document_head_null() {
1230 unsafe {
1231 xmlDebugDumpDocumentHead(ptr::null_mut(), ptr::null_mut());
1232 }
1233 }
1234
1235 #[test]
1236 fn test_ls_count_node_null() {
1237 assert_eq!(unsafe { xmlLsCountNode(ptr::null_mut()) }, 0);
1238 }
1239}