1use core::ffi::c_void;
22use std::os::raw::{c_char, c_int, c_uint};
23
24use crate::abi::callbacks::{xmlGenericErrorFunc, xmlStructuredErrorFunc};
25use crate::abi::types::xmlChar;
26
27static LAST_ERROR_MIRROR_LOCK: parking_lot::Mutex<()> = parking_lot::Mutex::new(());
38
39#[no_mangle]
45pub static mut xmlDoValidityCheckingDefaultValue: c_int = 0;
46
47#[no_mangle]
49pub static mut xmlGetWarningsDefaultValue: c_int = 1;
50
51#[no_mangle]
53pub static mut xmlLoadExtDtdDefaultValue: c_int = 0;
54
55#[no_mangle]
57pub static mut xmlPedanticParserDefaultValue: c_int = 0;
58
59#[no_mangle]
62pub static mut xmlLineNumbersDefaultValue: c_int = 1;
63
64#[no_mangle]
66pub static mut xmlKeepBlanksDefaultValue: c_int = 1;
67
68#[no_mangle]
70pub static mut xmlSubstituteEntitiesDefaultValue: c_int = 0;
71
72#[no_mangle]
74pub static mut xmlParserDebugEntities: c_int = 0;
75
76#[no_mangle]
79pub static mut xmlIndentTreeOutput: c_int = 1;
80
81#[no_mangle]
84pub static mut xmlTreeIndentString: *const xmlChar = {
85 static S: [u8; 3] = *b" \0";
86 S.as_ptr()
87};
88
89#[no_mangle]
91pub static mut xmlSaveNoEmptyTags: c_int = 0;
92
93#[no_mangle]
95pub static mut xmlRegisterNodeDefaultValue: Option<
96 unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode),
97> = None;
98
99pub static XML_REGISTER_CALLBACKS: core::sync::atomic::AtomicBool =
102 core::sync::atomic::AtomicBool::new(false);
103
104pub fn register_node_hook(node: *mut crate::abi::structs::_xmlNode) {
111 if !XML_REGISTER_CALLBACKS.load(core::sync::atomic::Ordering::Relaxed) {
112 return;
113 }
114 let hook = unsafe { xmlRegisterNodeDefaultValue };
115 if let Some(h) = hook {
116 if !node.is_null() {
117 unsafe { h(node) };
119 }
120 }
121}
122
123pub fn deregister_node_hook(node: *mut crate::abi::structs::_xmlNode) {
130 if !XML_REGISTER_CALLBACKS.load(core::sync::atomic::Ordering::Relaxed) {
131 return;
132 }
133 let hook = unsafe { xmlDeregisterNodeDefaultValue };
134 if let Some(h) = hook {
135 if !node.is_null() {
136 unsafe { h(node) };
138 }
139 }
140}
141
142#[no_mangle]
144pub static mut xmlDeregisterNodeDefaultValue: Option<
145 unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode),
146> = None;
147
148#[no_mangle]
157pub static mut xmlParserVersion: *const c_char = {
158 static V: [u8; 17] = *b"21503-GITv2.15.3\0";
159 V.as_ptr() as *const c_char
160};
161
162#[no_mangle]
164pub static mut xmlParserMaxDepth: c_int = 256;
165
166#[no_mangle]
172pub static mut xmlDefaultBufferSize: c_int = 4096;
173
174#[no_mangle]
177pub static mut xmlBufferAllocScheme: c_int = 1;
178
179#[cfg(target_arch = "x86_64")]
189#[no_mangle]
190pub static mut xmlGenericError: Option<xmlGenericErrorFunc> = Some(XML_GENERIC_ERROR_DEFAULT);
191
192#[cfg(not(target_arch = "x86_64"))]
193#[no_mangle]
194pub static mut xmlGenericError: Option<xmlGenericErrorFunc> = None;
195
196#[no_mangle]
198pub static mut xmlGenericErrorContext: *mut c_void = core::ptr::null_mut();
199
200#[no_mangle]
202pub static mut xmlStructuredError: Option<xmlStructuredErrorFunc> = None;
203
204#[no_mangle]
206pub static mut xmlStructuredErrorContext: *mut c_void = core::ptr::null_mut();
207
208#[cfg(target_arch = "x86_64")]
225#[repr(C)]
226#[derive(Clone, Copy)]
227struct VaListTag {
228 gp_offset: c_uint,
229 fp_offset: c_uint,
230 overflow_arg_area: *mut c_void,
231 reg_save_area: *mut c_void,
232}
233
234#[cfg(target_arch = "x86_64")]
235unsafe extern "C" {
236 fn vfprintf(stream: *mut c_void, format: *const c_char, ap: *mut VaListTag) -> c_int;
237}
238
239#[cfg(target_arch = "x86_64")]
247unsafe fn stderr_file() -> *mut c_void {
248 extern "C" {
249 static stderr: *mut c_void;
250 }
251 unsafe { stderr }
252}
253
254#[cfg(target_arch = "x86_64")]
257#[no_mangle]
258pub unsafe extern "C" fn xmlGenericErrorDefaultFuncV(
259 _ctx: *mut c_void,
260 msg: *const c_char,
261 ap: *mut VaListTag,
262) -> c_int {
263 unsafe {
264 if crate::abi::data_globals::xmlGenericErrorContext.is_null() {
265 crate::abi::data_globals::xmlGenericErrorContext = stderr_file();
266 }
267 let stream = crate::abi::data_globals::xmlGenericErrorContext;
268 if msg.is_null() || stream.is_null() {
269 return 0;
270 }
271 vfprintf(stream, msg, ap)
272 }
273}
274
275#[cfg(target_arch = "x86_64")]
282pub unsafe extern "C" fn xmlGenericErrorDefaultFunc() -> c_int {
283 unsafe {
284 core::arch::asm!(
285 "sub rsp, 240",
286 "mov [rsp+0], rdi",
287 "mov [rsp+8], rsi",
288 "mov [rsp+16], rdx",
289 "mov [rsp+24], rcx",
290 "mov [rsp+32], r8",
291 "mov [rsp+40], r9",
292 "movaps [rsp+48], xmm0",
293 "movaps [rsp+64], xmm1",
294 "movaps [rsp+80], xmm2",
295 "movaps [rsp+96], xmm3",
296 "movaps [rsp+112], xmm4",
297 "movaps [rsp+128], xmm5",
298 "movaps [rsp+144], xmm6",
299 "movaps [rsp+160], xmm7",
300 "mov dword ptr [rsp+176], 16",
301 "mov dword ptr [rsp+180], 48",
302 "lea rax, [rsp+256]",
303 "mov [rsp+184], rax",
304 "lea rax, [rsp]",
305 "mov [rsp+192], rax",
306 "lea rdx, [rsp+176]",
307 "call xmlGenericErrorDefaultFuncV",
308 "add rsp, 240",
309 "add rsp, 8",
310 "ret",
311 options(noreturn),
312 );
313 }
314}
315
316#[cfg(target_arch = "x86_64")]
318const XML_GENERIC_ERROR_DEFAULT: xmlGenericErrorFunc = unsafe {
319 core::mem::transmute::<
323 unsafe extern "C" fn() -> c_int,
324 unsafe extern "C" fn(*mut c_void, *const c_char),
325 >(xmlGenericErrorDefaultFunc)
326};
327
328#[cfg(target_arch = "x86_64")]
331#[no_mangle]
332pub unsafe extern "C" fn xsltGenericErrorDefaultFuncV(
333 _ctx: *mut c_void,
334 msg: *const c_char,
335 ap: *mut VaListTag,
336) -> c_int {
337 unsafe {
338 if crate::abi::data_globals::xsltGenericErrorContext.is_null() {
339 crate::abi::data_globals::xsltGenericErrorContext = stderr_file();
340 }
341 let stream = crate::abi::data_globals::xsltGenericErrorContext;
342 if msg.is_null() || stream.is_null() {
343 return 0;
344 }
345 vfprintf(stream, msg, ap)
346 }
347}
348
349#[cfg(target_arch = "x86_64")]
352pub unsafe extern "C" fn xsltGenericErrorDefaultFunc() -> c_int {
353 unsafe {
354 core::arch::asm!(
355 "sub rsp, 240",
356 "mov [rsp+0], rdi",
357 "mov [rsp+8], rsi",
358 "mov [rsp+16], rdx",
359 "mov [rsp+24], rcx",
360 "mov [rsp+32], r8",
361 "mov [rsp+40], r9",
362 "movaps [rsp+48], xmm0",
363 "movaps [rsp+64], xmm1",
364 "movaps [rsp+80], xmm2",
365 "movaps [rsp+96], xmm3",
366 "movaps [rsp+112], xmm4",
367 "movaps [rsp+128], xmm5",
368 "movaps [rsp+144], xmm6",
369 "movaps [rsp+160], xmm7",
370 "mov dword ptr [rsp+176], 16",
371 "mov dword ptr [rsp+180], 48",
372 "lea rax, [rsp+256]",
373 "mov [rsp+184], rax",
374 "lea rax, [rsp]",
375 "mov [rsp+192], rax",
376 "lea rdx, [rsp+176]",
377 "call xsltGenericErrorDefaultFuncV",
378 "add rsp, 240",
379 "add rsp, 8",
380 "ret",
381 options(noreturn),
382 );
383 }
384}
385
386#[cfg(target_arch = "x86_64")]
388const XSLT_GENERIC_ERROR_DEFAULT: xmlGenericErrorFunc = unsafe {
389 core::mem::transmute::<
391 unsafe extern "C" fn() -> c_int,
392 unsafe extern "C" fn(*mut c_void, *const c_char),
393 >(xsltGenericErrorDefaultFunc)
394};
395
396pub fn default_generic_error_func() -> Option<xmlGenericErrorFunc> {
401 #[cfg(target_arch = "x86_64")]
402 {
403 Some(XML_GENERIC_ERROR_DEFAULT)
404 }
405 #[cfg(not(target_arch = "x86_64"))]
406 {
407 None
408 }
409}
410
411#[no_mangle]
417pub static xmlStringText: [xmlChar; 5] = [b't', b'e', b'x', b't', 0];
418
419#[no_mangle]
421pub static xmlStringTextNoenc: [xmlChar; 9] =
422 [b't', b'e', b'x', b't', b'n', b'o', b'e', b'n', b'c'];
423
424#[no_mangle]
426pub static xmlStringComment: [xmlChar; 8] = [b'c', b'o', b'm', b'm', b'e', b'n', b't', 0];
427
428#[no_mangle]
434pub static xmlXPathNAN: f64 = f64::NAN;
435
436#[no_mangle]
438pub static xmlXPathPINF: f64 = f64::INFINITY;
439
440#[no_mangle]
442pub static xmlXPathNINF: f64 = f64::NEG_INFINITY;
443
444#[no_mangle]
453pub static xsltLibxmlVersion: c_int = 21503;
454
455#[cfg(target_arch = "x86_64")]
460#[no_mangle]
461pub static mut xsltGenericError: Option<xmlGenericErrorFunc> = Some(XSLT_GENERIC_ERROR_DEFAULT);
462
463#[cfg(not(target_arch = "x86_64"))]
464#[no_mangle]
465pub static mut xsltGenericError: Option<xmlGenericErrorFunc> = None;
466
467#[no_mangle]
469pub static mut xsltGenericErrorContext: *mut c_void = core::ptr::null_mut();
470
471#[no_mangle]
473pub static mut xsltGenericDebugContext: *mut c_void = core::ptr::null_mut();
474
475#[no_mangle]
478pub static xsltExtMarker: [xmlChar; 1] = [0];
479
480#[no_mangle]
485pub static mut xsltDocDefaultLoader: Option<
486 unsafe extern "C" fn(
487 *const xmlChar,
488 *mut c_void,
489 c_int,
490 *mut crate::abi::structs::_xsltStylesheet,
491 *mut crate::abi::structs::_xsltTransformContext,
492 ) -> *mut crate::abi::structs::_xmlDoc,
493> = None;
494
495#[no_mangle]
501pub static mut xmlParserInputBufferCreateFilenameValue: Option<
502 unsafe extern "C" fn(*const c_char, c_int) -> *mut crate::abi::structs::_xmlParserInputBuffer,
503> = None;
504
505#[no_mangle]
507pub static mut xmlOutputBufferCreateFilenameValue: Option<
508 unsafe extern "C" fn(
509 *const c_char,
510 crate::abi::structs::xmlCharEncodingHandlerPtr,
511 c_int,
512 ) -> *mut crate::abi::structs::_xmlOutputBuffer,
513> = None;
514
515#[no_mangle]
527pub static xmlDefaultSAXHandler: crate::abi::structs::_xmlSAXHandlerV1 =
528 crate::abi::structs::_xmlSAXHandlerV1 {
529 internalSubset: Some(crate::abi::exports_xml2::xmlSAX2InternalSubset),
530 isStandalone: Some(crate::abi::exports_xml2::xmlSAX2IsStandalone),
531 hasInternalSubset: Some(crate::abi::exports_xml2::xmlSAX2HasInternalSubset),
532 hasExternalSubset: Some(crate::abi::exports_xml2::xmlSAX2HasExternalSubset),
533 resolveEntity: Some(crate::abi::exports_xml2::xmlSAX2ResolveEntity),
534 getEntity: Some(crate::abi::exports_xml2::xmlSAX2GetEntity),
535 entityDecl: Some(crate::abi::exports_xml2::xmlSAX2EntityDecl),
536 notationDecl: Some(crate::abi::exports_xml2::xmlSAX2NotationDecl),
537 attributeDecl: Some(crate::abi::exports_xml2::xmlSAX2AttributeDecl),
538 elementDecl: Some(crate::abi::exports_xml2::xmlSAX2ElementDecl),
539 unparsedEntityDecl: Some(crate::abi::exports_xml2::xmlSAX2UnparsedEntityDecl),
540 setDocumentLocator: Some(crate::abi::exports_xml2::xmlSAX2SetDocumentLocator),
541 startDocument: Some(crate::abi::exports_xml2::xmlSAX2StartDocument),
542 endDocument: Some(crate::abi::exports_xml2::xmlSAX2EndDocument),
543 startElement: Some(crate::abi::exports_xml2::xmlSAX2StartElement),
544 endElement: Some(crate::abi::exports_xml2::xmlSAX2EndElement),
545 reference: Some(crate::abi::exports_xml2::xmlSAX2Reference),
546 characters: Some(crate::abi::exports_xml2::xmlSAX2Characters),
547 ignorableWhitespace: Some(crate::abi::exports_xml2::xmlSAX2IgnorableWhitespace),
548 processingInstruction: Some(crate::abi::exports_xml2::xmlSAX2ProcessingInstruction),
549 comment: Some(crate::abi::exports_xml2::xmlSAX2Comment),
550 warning: Some(crate::xml::errors::xmlParserWarning),
551 error: Some(crate::xml::errors::xmlParserError),
552 fatalError: Some(crate::xml::errors::xmlParserError),
553 getParameterEntity: Some(crate::abi::exports_xml2::xmlSAX2GetParameterEntity),
554 cdataBlock: Some(crate::abi::exports_xml2::xmlSAX2CDataBlock),
555 externalSubset: Some(crate::abi::exports_xml2::xmlSAX2ExternalSubset),
556 initialized: 1,
557 };
558
559#[no_mangle]
561pub static htmlDefaultSAXHandler: crate::abi::structs::_xmlSAXHandlerV1 =
562 crate::abi::structs::_xmlSAXHandlerV1 {
563 internalSubset: Some(crate::abi::exports_xml2::xmlSAX2InternalSubset),
564 isStandalone: None,
565 hasInternalSubset: None,
566 hasExternalSubset: None,
567 resolveEntity: None,
568 getEntity: Some(crate::abi::exports_xml2::xmlSAX2GetEntity),
569 entityDecl: None,
570 notationDecl: None,
571 attributeDecl: None,
572 elementDecl: None,
573 unparsedEntityDecl: None,
574 setDocumentLocator: Some(crate::abi::exports_xml2::xmlSAX2SetDocumentLocator),
575 startDocument: Some(crate::abi::exports_xml2::xmlSAX2StartDocument),
576 endDocument: Some(crate::abi::exports_xml2::xmlSAX2EndDocument),
577 startElement: Some(crate::abi::exports_xml2::xmlSAX2StartElement),
578 endElement: Some(crate::abi::exports_xml2::xmlSAX2EndElement),
579 reference: None,
580 characters: Some(crate::abi::exports_xml2::xmlSAX2Characters),
581 ignorableWhitespace: Some(crate::abi::exports_xml2::xmlSAX2IgnorableWhitespace),
582 processingInstruction: Some(crate::abi::exports_xml2::xmlSAX2ProcessingInstruction),
583 comment: Some(crate::abi::exports_xml2::xmlSAX2Comment),
584 warning: Some(crate::xml::errors::xmlParserWarning),
585 error: Some(crate::xml::errors::xmlParserError),
586 fatalError: Some(crate::xml::errors::xmlParserError),
587 getParameterEntity: None,
588 cdataBlock: Some(crate::abi::exports_xml2::xmlSAX2CDataBlock),
589 externalSubset: None,
590 initialized: 1,
591 };
592
593#[no_mangle]
595pub static xmlDefaultSAXLocator: crate::abi::callbacks::_xmlSAXLocator =
596 crate::abi::callbacks::_xmlSAXLocator {
597 getPublicId: Some(crate::abi::exports_xml2::xmlSAX2GetPublicId),
598 getSystemId: Some(crate::abi::exports_xml2::xmlSAX2GetSystemId),
599 getLineNumber: Some(crate::abi::exports_xml2::xmlSAX2GetLineNumber),
600 getColumnNumber: Some(crate::abi::exports_xml2::xmlSAX2GetColumnNumber),
601 };
602
603#[no_mangle]
615pub static mut xmlLastError: crate::abi::structs::_xmlError = crate::abi::structs::_xmlError {
616 domain: 0,
617 code: 0,
618 message: core::ptr::null_mut(),
619 level: 0,
620 file: core::ptr::null_mut(),
621 line: 0,
622 str1: core::ptr::null_mut(),
623 str2: core::ptr::null_mut(),
624 str3: core::ptr::null_mut(),
625 int1: 0,
626 int2: 0,
627 ctxt: core::ptr::null_mut(),
628 node: core::ptr::null_mut(),
629};
630
631pub unsafe fn sync_xml_last_error(err: *const crate::abi::structs::_xmlError) {
642 if err.is_null() {
643 return;
644 }
645 let _guard = LAST_ERROR_MIRROR_LOCK.lock();
646 unsafe { sync_xml_last_error_locked(err) };
647}
648
649unsafe fn sync_xml_last_error_locked(err: *const crate::abi::structs::_xmlError) {
651 unsafe {
652 reset_xml_last_error_locked();
653 let src = &*err;
654 let dst = core::ptr::addr_of_mut!(xmlLastError);
655 (*dst).domain = src.domain;
656 (*dst).code = src.code;
657 (*dst).level = src.level;
658 (*dst).line = src.line;
659 (*dst).int1 = src.int1;
660 (*dst).int2 = src.int2;
661 (*dst).ctxt = src.ctxt;
662 (*dst).node = src.node;
663 (*dst).message = dup_cstr(src.message as *const u8);
664 (*dst).file = dup_cstr(src.file as *const u8);
665 (*dst).str1 = dup_cstr(src.str1 as *const u8);
666 (*dst).str2 = dup_cstr(src.str2 as *const u8);
667 (*dst).str3 = dup_cstr(src.str3 as *const u8);
668 }
669}
670
671pub unsafe fn reset_xml_last_error() {
679 let _guard = LAST_ERROR_MIRROR_LOCK.lock();
680 unsafe { reset_xml_last_error_locked() };
681}
682
683unsafe fn reset_xml_last_error_locked() {
685 unsafe {
686 let dst = core::ptr::addr_of_mut!(xmlLastError);
687 if !(*dst).message.is_null() {
688 libc::free((*dst).message as *mut libc::c_void);
689 }
690 if !(*dst).file.is_null() {
691 libc::free((*dst).file as *mut libc::c_void);
692 }
693 if !(*dst).str1.is_null() {
694 libc::free((*dst).str1 as *mut libc::c_void);
695 }
696 if !(*dst).str2.is_null() {
697 libc::free((*dst).str2 as *mut libc::c_void);
698 }
699 if !(*dst).str3.is_null() {
700 libc::free((*dst).str3 as *mut libc::c_void);
701 }
702 *dst = crate::abi::structs::_xmlError {
703 domain: 0,
704 code: 0,
705 message: core::ptr::null_mut(),
706 level: 0,
707 file: core::ptr::null_mut(),
708 line: 0,
709 str1: core::ptr::null_mut(),
710 str2: core::ptr::null_mut(),
711 str3: core::ptr::null_mut(),
712 int1: 0,
713 int2: 0,
714 ctxt: core::ptr::null_mut(),
715 node: core::ptr::null_mut(),
716 };
717 }
718}
719
720unsafe fn dup_cstr(s: *const u8) -> *mut c_char {
722 if s.is_null() {
723 return core::ptr::null_mut();
724 }
725 unsafe {
726 let len = libc::strlen(s as *const libc::c_char) as usize;
727 let p = libc::malloc(len + 1) as *mut u8;
728 if p.is_null() {
729 return core::ptr::null_mut();
730 }
731 libc::memcpy(p as *mut libc::c_void, s as *const libc::c_void, len + 1);
732 p as *mut c_char
733 }
734}
735
736#[no_mangle]
747pub unsafe extern "C" fn xmlKeepBlanksDefault(v: c_int) -> c_int {
748 unsafe {
749 if v != 0 {
750 xmlKeepBlanksDefaultValue = v;
751 }
752 xmlKeepBlanksDefaultValue
753 }
754}
755
756#[no_mangle]
758pub unsafe extern "C" fn xmlLineNumbersDefault(v: c_int) -> c_int {
759 unsafe {
760 if v != 0 {
761 xmlLineNumbersDefaultValue = v;
762 }
763 xmlLineNumbersDefaultValue
764 }
765}
766
767#[no_mangle]
769pub unsafe extern "C" fn xmlSubstituteEntitiesDefault(v: c_int) -> c_int {
770 unsafe {
771 if v != 0 {
772 xmlSubstituteEntitiesDefaultValue = v;
773 }
774 xmlSubstituteEntitiesDefaultValue
775 }
776}
777
778#[no_mangle]
780pub unsafe extern "C" fn xmlPedanticParserDefault(v: c_int) -> c_int {
781 unsafe {
782 if v != 0 {
783 xmlPedanticParserDefaultValue = v;
784 }
785 xmlPedanticParserDefaultValue
786 }
787}
788
789#[no_mangle]
795pub unsafe extern "C" fn xmlRegisterNodeDefault(
796 func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
797) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
798 unsafe {
799 XML_REGISTER_CALLBACKS.store(true, core::sync::atomic::Ordering::Relaxed);
802 if func.is_some() {
803 xmlRegisterNodeDefaultValue = func;
804 }
805 xmlRegisterNodeDefaultValue
806 }
807}
808
809#[no_mangle]
811pub unsafe extern "C" fn xmlDeregisterNodeDefault(
812 func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
813) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
814 unsafe {
815 XML_REGISTER_CALLBACKS.store(true, core::sync::atomic::Ordering::Relaxed);
818 if func.is_some() {
819 xmlDeregisterNodeDefaultValue = func;
820 }
821 xmlDeregisterNodeDefaultValue
822 }
823}
824
825#[no_mangle]
828pub unsafe extern "C" fn __xmlIndentTreeOutput() -> *mut c_int {
829 unsafe { core::ptr::addr_of_mut!(xmlIndentTreeOutput) }
830}
831
832#[no_mangle]
835pub unsafe extern "C" fn __xmlSaveNoEmptyTags() -> *mut c_int {
836 unsafe { core::ptr::addr_of_mut!(xmlSaveNoEmptyTags) }
837}
838
839#[no_mangle]
842pub unsafe extern "C" fn __xmlTreeIndentString() -> *mut *const xmlChar {
843 unsafe { core::ptr::addr_of_mut!(xmlTreeIndentString) }
844}
845
846#[no_mangle]
858pub unsafe extern "C" fn xmlThrDefDoValidityCheckingDefaultValue(v: c_int) -> c_int {
859 unsafe {
860 if v != 0 {
861 xmlDoValidityCheckingDefaultValue = v;
862 }
863 xmlDoValidityCheckingDefaultValue
864 }
865}
866
867#[no_mangle]
869pub unsafe extern "C" fn xmlThrDefGetWarningsDefaultValue(v: c_int) -> c_int {
870 unsafe {
871 if v != 0 {
872 xmlGetWarningsDefaultValue = v;
873 }
874 xmlGetWarningsDefaultValue
875 }
876}
877
878#[no_mangle]
880pub unsafe extern "C" fn xmlThrDefLoadExtDtdDefaultValue(v: c_int) -> c_int {
881 unsafe {
882 if v != 0 {
883 xmlLoadExtDtdDefaultValue = v;
884 }
885 xmlLoadExtDtdDefaultValue
886 }
887}
888
889#[no_mangle]
891pub unsafe extern "C" fn xmlThrDefPedanticParserDefaultValue(v: c_int) -> c_int {
892 unsafe {
893 if v != 0 {
894 xmlPedanticParserDefaultValue = v;
895 }
896 xmlPedanticParserDefaultValue
897 }
898}
899
900#[no_mangle]
902pub unsafe extern "C" fn xmlThrDefLineNumbersDefaultValue(v: c_int) -> c_int {
903 unsafe {
904 if v != 0 {
905 xmlLineNumbersDefaultValue = v;
906 }
907 xmlLineNumbersDefaultValue
908 }
909}
910
911#[no_mangle]
913pub unsafe extern "C" fn xmlThrDefKeepBlanksDefaultValue(v: c_int) -> c_int {
914 unsafe {
915 if v != 0 {
916 xmlKeepBlanksDefaultValue = v;
917 }
918 xmlKeepBlanksDefaultValue
919 }
920}
921
922#[no_mangle]
924pub unsafe extern "C" fn xmlThrDefSubstituteEntitiesDefaultValue(v: c_int) -> c_int {
925 unsafe {
926 if v != 0 {
927 xmlSubstituteEntitiesDefaultValue = v;
928 }
929 xmlSubstituteEntitiesDefaultValue
930 }
931}
932
933#[no_mangle]
935pub unsafe extern "C" fn xmlThrDefParserDebugEntities(v: c_int) -> c_int {
936 unsafe {
937 if v != 0 {
938 xmlParserDebugEntities = v;
939 }
940 xmlParserDebugEntities
941 }
942}
943
944#[no_mangle]
946pub unsafe extern "C" fn xmlThrDefIndentTreeOutput(v: c_int) -> c_int {
947 unsafe {
948 if v != 0 {
949 xmlIndentTreeOutput = v;
950 }
951 xmlIndentTreeOutput
952 }
953}
954
955#[no_mangle]
958pub unsafe extern "C" fn xmlThrDefTreeIndentString(v: *const c_char) -> *const c_char {
959 unsafe {
960 if !v.is_null() {
961 xmlTreeIndentString = v as *const xmlChar;
962 }
963 xmlTreeIndentString as *const c_char
964 }
965}
966
967#[no_mangle]
969pub unsafe extern "C" fn xmlThrDefSaveNoEmptyTags(v: c_int) -> c_int {
970 unsafe {
971 if v != 0 {
972 xmlSaveNoEmptyTags = v;
973 }
974 xmlSaveNoEmptyTags
975 }
976}
977
978#[no_mangle]
980pub unsafe extern "C" fn xmlThrDefRegisterNodeDefault(
981 func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
982) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
983 unsafe {
984 if func.is_some() {
985 xmlRegisterNodeDefaultValue = func;
986 }
987 xmlRegisterNodeDefaultValue
988 }
989}
990
991#[no_mangle]
993pub unsafe extern "C" fn xmlThrDefDeregisterNodeDefault(
994 func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
995) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
996 unsafe {
997 if func.is_some() {
998 xmlDeregisterNodeDefaultValue = func;
999 }
1000 xmlDeregisterNodeDefaultValue
1001 }
1002}
1003
1004#[no_mangle]
1006pub unsafe extern "C" fn xmlThrDefSetGenericErrorFunc(
1007 ctx: *mut c_void,
1008 func: Option<xmlGenericErrorFunc>,
1009) {
1010 unsafe {
1011 xmlGenericErrorContext = ctx;
1012 xmlGenericError = func;
1013 }
1014}
1015
1016#[no_mangle]
1018pub unsafe extern "C" fn xmlThrDefSetStructuredErrorFunc(
1019 ctx: *mut c_void,
1020 func: Option<xmlStructuredErrorFunc>,
1021) {
1022 unsafe {
1023 xmlStructuredErrorContext = ctx;
1024 xmlStructuredError = func;
1025 }
1026}
1027
1028#[no_mangle]
1030pub unsafe extern "C" fn xmlThrDefDefaultBufferSize(v: c_int) -> c_int {
1031 unsafe {
1032 if v != 0 {
1033 xmlDefaultBufferSize = v;
1034 }
1035 xmlDefaultBufferSize
1036 }
1037}
1038
1039#[no_mangle]
1041pub unsafe extern "C" fn xmlThrDefBufferAllocScheme(v: c_int) -> c_int {
1042 unsafe {
1043 if v != 0 {
1044 xmlBufferAllocScheme = v;
1045 }
1046 xmlBufferAllocScheme
1047 }
1048}
1049
1050#[no_mangle]
1052pub unsafe extern "C" fn xmlThrDefParserInputBufferCreateFilenameDefault(
1053 func: Option<
1054 unsafe extern "C" fn(
1055 *const c_char,
1056 c_int,
1057 ) -> *mut crate::abi::structs::_xmlParserInputBuffer,
1058 >,
1059) -> Option<
1060 unsafe extern "C" fn(*const c_char, c_int) -> *mut crate::abi::structs::_xmlParserInputBuffer,
1061> {
1062 unsafe {
1063 if func.is_some() {
1064 xmlParserInputBufferCreateFilenameValue = func;
1065 }
1066 xmlParserInputBufferCreateFilenameValue
1067 }
1068}
1069
1070#[no_mangle]
1072pub unsafe extern "C" fn xmlThrDefOutputBufferCreateFilenameDefault(
1073 func: Option<
1074 unsafe extern "C" fn(
1075 *const c_char,
1076 crate::abi::structs::xmlCharEncodingHandlerPtr,
1077 c_int,
1078 ) -> *mut crate::abi::structs::_xmlOutputBuffer,
1079 >,
1080) -> Option<
1081 unsafe extern "C" fn(
1082 *const c_char,
1083 crate::abi::structs::xmlCharEncodingHandlerPtr,
1084 c_int,
1085 ) -> *mut crate::abi::structs::_xmlOutputBuffer,
1086> {
1087 unsafe {
1088 if func.is_some() {
1089 xmlOutputBufferCreateFilenameValue = func;
1090 }
1091 xmlOutputBufferCreateFilenameValue
1092 }
1093}
1094
1095#[no_mangle]
1103pub unsafe extern "C" fn __xmlBufferAllocScheme() -> *mut c_int {
1104 unsafe { core::ptr::addr_of_mut!(xmlBufferAllocScheme) }
1107}
1108
1109#[no_mangle]
1111pub unsafe extern "C" fn __xmlDefaultBufferSize() -> *mut c_int {
1112 unsafe { core::ptr::addr_of_mut!(xmlDefaultBufferSize) }
1115}
1116
1117#[no_mangle]
1119pub unsafe extern "C" fn __xmlDeregisterNodeDefaultValue(
1120) -> *mut Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
1121 unsafe { core::ptr::addr_of_mut!(xmlDeregisterNodeDefaultValue) }
1124}
1125
1126#[no_mangle]
1128pub unsafe extern "C" fn __xmlDoValidityCheckingDefaultValue() -> *mut c_int {
1129 unsafe { core::ptr::addr_of_mut!(xmlDoValidityCheckingDefaultValue) }
1132}
1133
1134#[no_mangle]
1136pub unsafe extern "C" fn __xmlGenericError() -> *mut Option<xmlGenericErrorFunc> {
1137 unsafe { core::ptr::addr_of_mut!(xmlGenericError) }
1140}
1141
1142#[no_mangle]
1144pub unsafe extern "C" fn __xmlGenericErrorContext() -> *mut *mut c_void {
1145 unsafe { core::ptr::addr_of_mut!(xmlGenericErrorContext) }
1148}
1149
1150#[no_mangle]
1152pub unsafe extern "C" fn __xmlGetWarningsDefaultValue() -> *mut c_int {
1153 unsafe { core::ptr::addr_of_mut!(xmlGetWarningsDefaultValue) }
1156}
1157
1158#[no_mangle]
1160pub unsafe extern "C" fn __xmlKeepBlanksDefaultValue() -> *mut c_int {
1161 unsafe { core::ptr::addr_of_mut!(xmlKeepBlanksDefaultValue) }
1164}
1165
1166#[no_mangle]
1168pub unsafe extern "C" fn __xmlLineNumbersDefaultValue() -> *mut c_int {
1169 unsafe { core::ptr::addr_of_mut!(xmlLineNumbersDefaultValue) }
1172}
1173
1174#[no_mangle]
1176pub unsafe extern "C" fn __xmlLoadExtDtdDefaultValue() -> *mut c_int {
1177 unsafe { core::ptr::addr_of_mut!(xmlLoadExtDtdDefaultValue) }
1180}
1181
1182#[no_mangle]
1184pub unsafe extern "C" fn __xmlOutputBufferCreateFilenameValue() -> *mut Option<
1185 unsafe extern "C" fn(
1186 *const c_char,
1187 crate::abi::structs::xmlCharEncodingHandlerPtr,
1188 c_int,
1189 ) -> *mut crate::abi::structs::_xmlOutputBuffer,
1190> {
1191 unsafe { core::ptr::addr_of_mut!(xmlOutputBufferCreateFilenameValue) }
1194}
1195
1196#[no_mangle]
1198pub unsafe extern "C" fn __xmlParserDebugEntities() -> *mut c_int {
1199 unsafe { core::ptr::addr_of_mut!(xmlParserDebugEntities) }
1202}
1203
1204#[no_mangle]
1206pub unsafe extern "C" fn __xmlParserInputBufferCreateFilenameValue() -> *mut Option<
1207 unsafe extern "C" fn(*const c_char, c_int) -> *mut crate::abi::structs::_xmlParserInputBuffer,
1208> {
1209 unsafe { core::ptr::addr_of_mut!(xmlParserInputBufferCreateFilenameValue) }
1212}
1213
1214#[no_mangle]
1216pub unsafe extern "C" fn __xmlParserVersion() -> *mut *const c_char {
1217 unsafe { core::ptr::addr_of_mut!(xmlParserVersion) }
1220}
1221
1222#[no_mangle]
1224pub unsafe extern "C" fn __xmlPedanticParserDefaultValue() -> *mut c_int {
1225 unsafe { core::ptr::addr_of_mut!(xmlPedanticParserDefaultValue) }
1228}
1229
1230#[no_mangle]
1232pub unsafe extern "C" fn __xmlRegisterNodeDefaultValue(
1233) -> *mut Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
1234 unsafe { core::ptr::addr_of_mut!(xmlRegisterNodeDefaultValue) }
1237}
1238
1239#[no_mangle]
1241pub unsafe extern "C" fn __xmlStructuredError() -> *mut Option<xmlStructuredErrorFunc> {
1242 unsafe { core::ptr::addr_of_mut!(xmlStructuredError) }
1245}
1246
1247#[no_mangle]
1249pub unsafe extern "C" fn __xmlStructuredErrorContext() -> *mut *mut c_void {
1250 unsafe { core::ptr::addr_of_mut!(xmlStructuredErrorContext) }
1253}
1254
1255#[no_mangle]
1257pub unsafe extern "C" fn __xmlSubstituteEntitiesDefaultValue() -> *mut c_int {
1258 unsafe { core::ptr::addr_of_mut!(xmlSubstituteEntitiesDefaultValue) }
1261}
1262
1263#[cfg(test)]
1276mod tests {
1277 use super::*;
1278 use crate::abi::allocator::xmlMallocImpl;
1279 use crate::abi::structs::_xmlError;
1280 use crate::xml::globals;
1281 use core::ptr;
1282
1283 unsafe fn alloc_cstr(s: &str) -> *mut c_char {
1286 let bytes = s.as_bytes();
1287 let p = unsafe { xmlMallocImpl(bytes.len() + 1) as *mut c_char };
1288 assert!(!p.is_null(), "alloc_cstr: xmlMallocImpl failed");
1289 unsafe {
1290 ptr::copy_nonoverlapping(bytes.as_ptr(), p as *mut u8, bytes.len());
1291 *((p as *mut u8).add(bytes.len())) = 0;
1292 }
1293 p
1294 }
1295
1296 unsafe fn build_error(tag: &str) -> _xmlError {
1298 _xmlError {
1299 domain: 1,
1300 code: 2,
1301 message: unsafe { alloc_cstr(&format!("msg {tag}")) },
1302 level: 3,
1303 file: unsafe { alloc_cstr(&format!("file {tag}")) },
1304 line: 4,
1305 str1: unsafe { alloc_cstr(&format!("str1 {tag}")) },
1306 str2: ptr::null_mut(),
1307 str3: ptr::null_mut(),
1308 int1: 0,
1309 int2: 0,
1310 ctxt: ptr::null_mut(),
1311 node: ptr::null_mut(),
1312 }
1313 }
1314
1315 #[test]
1319 fn test_last_error_mirror_concurrent_sync_reset() {
1320 let sync = std::thread::spawn(|| {
1321 for i in 0..400 {
1322 unsafe { globals::set_last_error(build_error(&format!("sync {i}"))) };
1323 }
1324 });
1325 let reset = std::thread::spawn(|| {
1326 for _ in 0..400 {
1327 globals::reset_last_error();
1328 }
1329 });
1330 sync.join().unwrap();
1331 reset.join().unwrap();
1332 globals::reset_last_error();
1336 }
1337
1338 #[test]
1341 fn test_last_error_mirror_many_threads() {
1342 let mut handles = Vec::new();
1343 for t in 0..8 {
1344 handles.push(std::thread::spawn(move || {
1345 for i in 0..150 {
1346 unsafe { globals::set_last_error(build_error(&format!("t{t} i{i}"))) };
1347 if i % 7 == 0 {
1348 globals::reset_last_error();
1349 }
1350 }
1351 }));
1352 }
1353 for h in handles {
1354 h.join().unwrap();
1355 }
1356 globals::reset_last_error();
1357 }
1358}