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]
455pub static xsltLibxmlVersion: c_int = 21501;
456
457#[no_mangle]
462pub static xsltLibxsltVersion: c_int = 10145;
463
464#[no_mangle]
470pub static mut xsltEngineVersion: *const c_char = {
471 static S: [u8; 17] = *b"10145-GITv1.1.45\0";
472 S.as_ptr() as *const c_char
473};
474
475#[no_mangle]
479pub static mut exsltLibraryVersion: *const c_char = {
480 static S: [u8; 15] = *b"825-GITv1.1.45\0";
481 S.as_ptr() as *const c_char
482};
483
484#[no_mangle]
487pub static exsltLibexsltVersion: c_int = 825;
488
489#[no_mangle]
492pub static exsltLibxmlVersion: c_int = 21501;
493
494#[no_mangle]
497pub static exsltLibxsltVersion: c_int = 10145;
498
499#[no_mangle]
504pub static mut xslDebugStatus: c_int = 0;
505
506#[cfg(target_arch = "x86_64")]
511#[no_mangle]
512pub static mut xsltGenericError: Option<xmlGenericErrorFunc> = Some(XSLT_GENERIC_ERROR_DEFAULT);
513
514#[cfg(not(target_arch = "x86_64"))]
515#[no_mangle]
516pub static mut xsltGenericError: Option<xmlGenericErrorFunc> = None;
517
518#[no_mangle]
520pub static mut xsltGenericErrorContext: *mut c_void = core::ptr::null_mut();
521
522#[no_mangle]
524pub static mut xsltGenericDebugContext: *mut c_void = core::ptr::null_mut();
525
526#[no_mangle]
529pub static xsltExtMarker: [xmlChar; 1] = [0];
530
531#[no_mangle]
536pub static mut xsltDocDefaultLoader: Option<
537 unsafe extern "C" fn(
538 *const xmlChar,
539 *mut c_void,
540 c_int,
541 *mut crate::abi::structs::_xsltStylesheet,
542 *mut crate::abi::structs::_xsltTransformContext,
543 ) -> *mut crate::abi::structs::_xmlDoc,
544> = None;
545
546#[no_mangle]
552pub static mut xmlParserInputBufferCreateFilenameValue: Option<
553 unsafe extern "C" fn(*const c_char, c_int) -> *mut crate::abi::structs::_xmlParserInputBuffer,
554> = None;
555
556#[no_mangle]
558pub static mut xmlOutputBufferCreateFilenameValue: Option<
559 unsafe extern "C" fn(
560 *const c_char,
561 crate::abi::structs::xmlCharEncodingHandlerPtr,
562 c_int,
563 ) -> *mut crate::abi::structs::_xmlOutputBuffer,
564> = None;
565
566#[no_mangle]
578pub static xmlDefaultSAXHandler: crate::abi::structs::_xmlSAXHandlerV1 =
579 crate::abi::structs::_xmlSAXHandlerV1 {
580 internalSubset: Some(crate::abi::exports_xml2::xmlSAX2InternalSubset),
581 isStandalone: Some(crate::abi::exports_xml2::xmlSAX2IsStandalone),
582 hasInternalSubset: Some(crate::abi::exports_xml2::xmlSAX2HasInternalSubset),
583 hasExternalSubset: Some(crate::abi::exports_xml2::xmlSAX2HasExternalSubset),
584 resolveEntity: Some(crate::abi::exports_xml2::xmlSAX2ResolveEntity),
585 getEntity: Some(crate::abi::exports_xml2::xmlSAX2GetEntity),
586 entityDecl: Some(crate::abi::exports_xml2::xmlSAX2EntityDecl),
587 notationDecl: Some(crate::abi::exports_xml2::xmlSAX2NotationDecl),
588 attributeDecl: Some(crate::abi::exports_xml2::xmlSAX2AttributeDecl),
589 elementDecl: Some(crate::abi::exports_xml2::xmlSAX2ElementDecl),
590 unparsedEntityDecl: Some(crate::abi::exports_xml2::xmlSAX2UnparsedEntityDecl),
591 setDocumentLocator: Some(crate::abi::exports_xml2::xmlSAX2SetDocumentLocator),
592 startDocument: Some(crate::abi::exports_xml2::xmlSAX2StartDocument),
593 endDocument: Some(crate::abi::exports_xml2::xmlSAX2EndDocument),
594 startElement: Some(crate::abi::exports_xml2::xmlSAX2StartElement),
595 endElement: Some(crate::abi::exports_xml2::xmlSAX2EndElement),
596 reference: Some(crate::abi::exports_xml2::xmlSAX2Reference),
597 characters: Some(crate::abi::exports_xml2::xmlSAX2Characters),
598 ignorableWhitespace: Some(crate::abi::exports_xml2::xmlSAX2IgnorableWhitespace),
599 processingInstruction: Some(crate::abi::exports_xml2::xmlSAX2ProcessingInstruction),
600 comment: Some(crate::abi::exports_xml2::xmlSAX2Comment),
601 warning: Some(crate::xml::errors::xmlParserWarning),
602 error: Some(crate::xml::errors::xmlParserError),
603 fatalError: Some(crate::xml::errors::xmlParserError),
604 getParameterEntity: Some(crate::abi::exports_xml2::xmlSAX2GetParameterEntity),
605 cdataBlock: Some(crate::abi::exports_xml2::xmlSAX2CDataBlock),
606 externalSubset: Some(crate::abi::exports_xml2::xmlSAX2ExternalSubset),
607 initialized: 1,
608 };
609
610#[no_mangle]
612pub static htmlDefaultSAXHandler: crate::abi::structs::_xmlSAXHandlerV1 =
613 crate::abi::structs::_xmlSAXHandlerV1 {
614 internalSubset: Some(crate::abi::exports_xml2::xmlSAX2InternalSubset),
615 isStandalone: None,
616 hasInternalSubset: None,
617 hasExternalSubset: None,
618 resolveEntity: None,
619 getEntity: Some(crate::abi::exports_xml2::xmlSAX2GetEntity),
620 entityDecl: None,
621 notationDecl: None,
622 attributeDecl: None,
623 elementDecl: None,
624 unparsedEntityDecl: None,
625 setDocumentLocator: Some(crate::abi::exports_xml2::xmlSAX2SetDocumentLocator),
626 startDocument: Some(crate::abi::exports_xml2::xmlSAX2StartDocument),
627 endDocument: Some(crate::abi::exports_xml2::xmlSAX2EndDocument),
628 startElement: Some(crate::abi::exports_xml2::xmlSAX2StartElement),
629 endElement: Some(crate::abi::exports_xml2::xmlSAX2EndElement),
630 reference: None,
631 characters: Some(crate::abi::exports_xml2::xmlSAX2Characters),
632 ignorableWhitespace: Some(crate::abi::exports_xml2::xmlSAX2IgnorableWhitespace),
633 processingInstruction: Some(crate::abi::exports_xml2::xmlSAX2ProcessingInstruction),
634 comment: Some(crate::abi::exports_xml2::xmlSAX2Comment),
635 warning: Some(crate::xml::errors::xmlParserWarning),
636 error: Some(crate::xml::errors::xmlParserError),
637 fatalError: Some(crate::xml::errors::xmlParserError),
638 getParameterEntity: None,
639 cdataBlock: Some(crate::abi::exports_xml2::xmlSAX2CDataBlock),
640 externalSubset: None,
641 initialized: 1,
642 };
643
644#[no_mangle]
646pub static xmlDefaultSAXLocator: crate::abi::callbacks::_xmlSAXLocator =
647 crate::abi::callbacks::_xmlSAXLocator {
648 getPublicId: Some(crate::abi::exports_xml2::xmlSAX2GetPublicId),
649 getSystemId: Some(crate::abi::exports_xml2::xmlSAX2GetSystemId),
650 getLineNumber: Some(crate::abi::exports_xml2::xmlSAX2GetLineNumber),
651 getColumnNumber: Some(crate::abi::exports_xml2::xmlSAX2GetColumnNumber),
652 };
653
654#[no_mangle]
666pub static mut xmlLastError: crate::abi::structs::_xmlError = crate::abi::structs::_xmlError {
667 domain: 0,
668 code: 0,
669 message: core::ptr::null_mut(),
670 level: 0,
671 file: core::ptr::null_mut(),
672 line: 0,
673 str1: core::ptr::null_mut(),
674 str2: core::ptr::null_mut(),
675 str3: core::ptr::null_mut(),
676 int1: 0,
677 int2: 0,
678 ctxt: core::ptr::null_mut(),
679 node: core::ptr::null_mut(),
680};
681
682pub unsafe fn sync_xml_last_error(err: *const crate::abi::structs::_xmlError) {
693 if err.is_null() {
694 return;
695 }
696 let _guard = LAST_ERROR_MIRROR_LOCK.lock();
697 unsafe { sync_xml_last_error_locked(err) };
698}
699
700unsafe fn sync_xml_last_error_locked(err: *const crate::abi::structs::_xmlError) {
702 unsafe {
703 reset_xml_last_error_locked();
704 let src = &*err;
705 let dst = core::ptr::addr_of_mut!(xmlLastError);
706 (*dst).domain = src.domain;
707 (*dst).code = src.code;
708 (*dst).level = src.level;
709 (*dst).line = src.line;
710 (*dst).int1 = src.int1;
711 (*dst).int2 = src.int2;
712 (*dst).ctxt = src.ctxt;
713 (*dst).node = src.node;
714 (*dst).message = dup_cstr(src.message as *const u8);
715 (*dst).file = dup_cstr(src.file as *const u8);
716 (*dst).str1 = dup_cstr(src.str1 as *const u8);
717 (*dst).str2 = dup_cstr(src.str2 as *const u8);
718 (*dst).str3 = dup_cstr(src.str3 as *const u8);
719 }
720}
721
722pub unsafe fn reset_xml_last_error() {
730 let _guard = LAST_ERROR_MIRROR_LOCK.lock();
731 unsafe { reset_xml_last_error_locked() };
732}
733
734unsafe fn reset_xml_last_error_locked() {
736 unsafe {
737 let dst = core::ptr::addr_of_mut!(xmlLastError);
738 if !(*dst).message.is_null() {
739 libc::free((*dst).message as *mut libc::c_void);
740 }
741 if !(*dst).file.is_null() {
742 libc::free((*dst).file as *mut libc::c_void);
743 }
744 if !(*dst).str1.is_null() {
745 libc::free((*dst).str1 as *mut libc::c_void);
746 }
747 if !(*dst).str2.is_null() {
748 libc::free((*dst).str2 as *mut libc::c_void);
749 }
750 if !(*dst).str3.is_null() {
751 libc::free((*dst).str3 as *mut libc::c_void);
752 }
753 *dst = crate::abi::structs::_xmlError {
754 domain: 0,
755 code: 0,
756 message: core::ptr::null_mut(),
757 level: 0,
758 file: core::ptr::null_mut(),
759 line: 0,
760 str1: core::ptr::null_mut(),
761 str2: core::ptr::null_mut(),
762 str3: core::ptr::null_mut(),
763 int1: 0,
764 int2: 0,
765 ctxt: core::ptr::null_mut(),
766 node: core::ptr::null_mut(),
767 };
768 }
769}
770
771unsafe fn dup_cstr(s: *const u8) -> *mut c_char {
773 if s.is_null() {
774 return core::ptr::null_mut();
775 }
776 unsafe {
777 let len = libc::strlen(s as *const libc::c_char) as usize;
778 let p = libc::malloc(len + 1) as *mut u8;
779 if p.is_null() {
780 return core::ptr::null_mut();
781 }
782 libc::memcpy(p as *mut libc::c_void, s as *const libc::c_void, len + 1);
783 p as *mut c_char
784 }
785}
786
787#[no_mangle]
798pub unsafe extern "C" fn xmlKeepBlanksDefault(v: c_int) -> c_int {
799 unsafe {
800 if v != 0 {
801 xmlKeepBlanksDefaultValue = v;
802 }
803 xmlKeepBlanksDefaultValue
804 }
805}
806
807#[no_mangle]
809pub unsafe extern "C" fn xmlLineNumbersDefault(v: c_int) -> c_int {
810 unsafe {
811 if v != 0 {
812 xmlLineNumbersDefaultValue = v;
813 }
814 xmlLineNumbersDefaultValue
815 }
816}
817
818#[no_mangle]
820pub unsafe extern "C" fn xmlSubstituteEntitiesDefault(v: c_int) -> c_int {
821 unsafe {
822 if v != 0 {
823 xmlSubstituteEntitiesDefaultValue = v;
824 }
825 xmlSubstituteEntitiesDefaultValue
826 }
827}
828
829#[no_mangle]
831pub unsafe extern "C" fn xmlPedanticParserDefault(v: c_int) -> c_int {
832 unsafe {
833 if v != 0 {
834 xmlPedanticParserDefaultValue = v;
835 }
836 xmlPedanticParserDefaultValue
837 }
838}
839
840#[no_mangle]
846pub unsafe extern "C" fn xmlRegisterNodeDefault(
847 func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
848) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
849 unsafe {
850 XML_REGISTER_CALLBACKS.store(true, core::sync::atomic::Ordering::Relaxed);
853 if func.is_some() {
854 xmlRegisterNodeDefaultValue = func;
855 }
856 xmlRegisterNodeDefaultValue
857 }
858}
859
860#[no_mangle]
862pub unsafe extern "C" fn xmlDeregisterNodeDefault(
863 func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
864) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
865 unsafe {
866 XML_REGISTER_CALLBACKS.store(true, core::sync::atomic::Ordering::Relaxed);
869 if func.is_some() {
870 xmlDeregisterNodeDefaultValue = func;
871 }
872 xmlDeregisterNodeDefaultValue
873 }
874}
875
876#[no_mangle]
879pub unsafe extern "C" fn __xmlIndentTreeOutput() -> *mut c_int {
880 unsafe { core::ptr::addr_of_mut!(xmlIndentTreeOutput) }
881}
882
883#[no_mangle]
886pub unsafe extern "C" fn __xmlSaveNoEmptyTags() -> *mut c_int {
887 unsafe { core::ptr::addr_of_mut!(xmlSaveNoEmptyTags) }
888}
889
890#[no_mangle]
893pub unsafe extern "C" fn __xmlTreeIndentString() -> *mut *const xmlChar {
894 unsafe { core::ptr::addr_of_mut!(xmlTreeIndentString) }
895}
896
897#[no_mangle]
909pub unsafe extern "C" fn xmlThrDefDoValidityCheckingDefaultValue(v: c_int) -> c_int {
910 unsafe {
911 if v != 0 {
912 xmlDoValidityCheckingDefaultValue = v;
913 }
914 xmlDoValidityCheckingDefaultValue
915 }
916}
917
918#[no_mangle]
920pub unsafe extern "C" fn xmlThrDefGetWarningsDefaultValue(v: c_int) -> c_int {
921 unsafe {
922 if v != 0 {
923 xmlGetWarningsDefaultValue = v;
924 }
925 xmlGetWarningsDefaultValue
926 }
927}
928
929#[no_mangle]
931pub unsafe extern "C" fn xmlThrDefLoadExtDtdDefaultValue(v: c_int) -> c_int {
932 unsafe {
933 if v != 0 {
934 xmlLoadExtDtdDefaultValue = v;
935 }
936 xmlLoadExtDtdDefaultValue
937 }
938}
939
940#[no_mangle]
942pub unsafe extern "C" fn xmlThrDefPedanticParserDefaultValue(v: c_int) -> c_int {
943 unsafe {
944 if v != 0 {
945 xmlPedanticParserDefaultValue = v;
946 }
947 xmlPedanticParserDefaultValue
948 }
949}
950
951#[no_mangle]
953pub unsafe extern "C" fn xmlThrDefLineNumbersDefaultValue(v: c_int) -> c_int {
954 unsafe {
955 if v != 0 {
956 xmlLineNumbersDefaultValue = v;
957 }
958 xmlLineNumbersDefaultValue
959 }
960}
961
962#[no_mangle]
964pub unsafe extern "C" fn xmlThrDefKeepBlanksDefaultValue(v: c_int) -> c_int {
965 unsafe {
966 if v != 0 {
967 xmlKeepBlanksDefaultValue = v;
968 }
969 xmlKeepBlanksDefaultValue
970 }
971}
972
973#[no_mangle]
975pub unsafe extern "C" fn xmlThrDefSubstituteEntitiesDefaultValue(v: c_int) -> c_int {
976 unsafe {
977 if v != 0 {
978 xmlSubstituteEntitiesDefaultValue = v;
979 }
980 xmlSubstituteEntitiesDefaultValue
981 }
982}
983
984#[no_mangle]
986pub unsafe extern "C" fn xmlThrDefParserDebugEntities(v: c_int) -> c_int {
987 unsafe {
988 if v != 0 {
989 xmlParserDebugEntities = v;
990 }
991 xmlParserDebugEntities
992 }
993}
994
995#[no_mangle]
997pub unsafe extern "C" fn xmlThrDefIndentTreeOutput(v: c_int) -> c_int {
998 unsafe {
999 if v != 0 {
1000 xmlIndentTreeOutput = v;
1001 }
1002 xmlIndentTreeOutput
1003 }
1004}
1005
1006#[no_mangle]
1009pub unsafe extern "C" fn xmlThrDefTreeIndentString(v: *const c_char) -> *const c_char {
1010 unsafe {
1011 if !v.is_null() {
1012 xmlTreeIndentString = v as *const xmlChar;
1013 }
1014 xmlTreeIndentString as *const c_char
1015 }
1016}
1017
1018#[no_mangle]
1020pub unsafe extern "C" fn xmlThrDefSaveNoEmptyTags(v: c_int) -> c_int {
1021 unsafe {
1022 if v != 0 {
1023 xmlSaveNoEmptyTags = v;
1024 }
1025 xmlSaveNoEmptyTags
1026 }
1027}
1028
1029#[no_mangle]
1031pub unsafe extern "C" fn xmlThrDefRegisterNodeDefault(
1032 func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
1033) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
1034 unsafe {
1035 if func.is_some() {
1036 xmlRegisterNodeDefaultValue = func;
1037 }
1038 xmlRegisterNodeDefaultValue
1039 }
1040}
1041
1042#[no_mangle]
1044pub unsafe extern "C" fn xmlThrDefDeregisterNodeDefault(
1045 func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
1046) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
1047 unsafe {
1048 if func.is_some() {
1049 xmlDeregisterNodeDefaultValue = func;
1050 }
1051 xmlDeregisterNodeDefaultValue
1052 }
1053}
1054
1055#[no_mangle]
1057pub unsafe extern "C" fn xmlThrDefSetGenericErrorFunc(
1058 ctx: *mut c_void,
1059 func: Option<xmlGenericErrorFunc>,
1060) {
1061 unsafe {
1062 xmlGenericErrorContext = ctx;
1063 xmlGenericError = func;
1064 }
1065}
1066
1067#[no_mangle]
1069pub unsafe extern "C" fn xmlThrDefSetStructuredErrorFunc(
1070 ctx: *mut c_void,
1071 func: Option<xmlStructuredErrorFunc>,
1072) {
1073 unsafe {
1074 xmlStructuredErrorContext = ctx;
1075 xmlStructuredError = func;
1076 }
1077}
1078
1079#[no_mangle]
1081pub unsafe extern "C" fn xmlThrDefDefaultBufferSize(v: c_int) -> c_int {
1082 unsafe {
1083 if v != 0 {
1084 xmlDefaultBufferSize = v;
1085 }
1086 xmlDefaultBufferSize
1087 }
1088}
1089
1090#[no_mangle]
1092pub unsafe extern "C" fn xmlThrDefBufferAllocScheme(v: c_int) -> c_int {
1093 unsafe {
1094 if v != 0 {
1095 xmlBufferAllocScheme = v;
1096 }
1097 xmlBufferAllocScheme
1098 }
1099}
1100
1101#[no_mangle]
1103pub unsafe extern "C" fn xmlThrDefParserInputBufferCreateFilenameDefault(
1104 func: Option<
1105 unsafe extern "C" fn(
1106 *const c_char,
1107 c_int,
1108 ) -> *mut crate::abi::structs::_xmlParserInputBuffer,
1109 >,
1110) -> Option<
1111 unsafe extern "C" fn(*const c_char, c_int) -> *mut crate::abi::structs::_xmlParserInputBuffer,
1112> {
1113 unsafe {
1114 if func.is_some() {
1115 xmlParserInputBufferCreateFilenameValue = func;
1116 }
1117 xmlParserInputBufferCreateFilenameValue
1118 }
1119}
1120
1121#[no_mangle]
1123pub unsafe extern "C" fn xmlThrDefOutputBufferCreateFilenameDefault(
1124 func: Option<
1125 unsafe extern "C" fn(
1126 *const c_char,
1127 crate::abi::structs::xmlCharEncodingHandlerPtr,
1128 c_int,
1129 ) -> *mut crate::abi::structs::_xmlOutputBuffer,
1130 >,
1131) -> Option<
1132 unsafe extern "C" fn(
1133 *const c_char,
1134 crate::abi::structs::xmlCharEncodingHandlerPtr,
1135 c_int,
1136 ) -> *mut crate::abi::structs::_xmlOutputBuffer,
1137> {
1138 unsafe {
1139 if func.is_some() {
1140 xmlOutputBufferCreateFilenameValue = func;
1141 }
1142 xmlOutputBufferCreateFilenameValue
1143 }
1144}
1145
1146#[no_mangle]
1154pub unsafe extern "C" fn __xmlBufferAllocScheme() -> *mut c_int {
1155 unsafe { core::ptr::addr_of_mut!(xmlBufferAllocScheme) }
1158}
1159
1160#[no_mangle]
1162pub unsafe extern "C" fn __xmlDefaultBufferSize() -> *mut c_int {
1163 unsafe { core::ptr::addr_of_mut!(xmlDefaultBufferSize) }
1166}
1167
1168#[no_mangle]
1170pub unsafe extern "C" fn __xmlDeregisterNodeDefaultValue(
1171) -> *mut Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
1172 unsafe { core::ptr::addr_of_mut!(xmlDeregisterNodeDefaultValue) }
1175}
1176
1177#[no_mangle]
1179pub unsafe extern "C" fn __xmlDoValidityCheckingDefaultValue() -> *mut c_int {
1180 unsafe { core::ptr::addr_of_mut!(xmlDoValidityCheckingDefaultValue) }
1183}
1184
1185#[no_mangle]
1187pub unsafe extern "C" fn __xmlGenericError() -> *mut Option<xmlGenericErrorFunc> {
1188 unsafe { core::ptr::addr_of_mut!(xmlGenericError) }
1191}
1192
1193#[no_mangle]
1195pub unsafe extern "C" fn __xmlGenericErrorContext() -> *mut *mut c_void {
1196 unsafe { core::ptr::addr_of_mut!(xmlGenericErrorContext) }
1199}
1200
1201#[no_mangle]
1203pub unsafe extern "C" fn __xmlGetWarningsDefaultValue() -> *mut c_int {
1204 unsafe { core::ptr::addr_of_mut!(xmlGetWarningsDefaultValue) }
1207}
1208
1209#[no_mangle]
1211pub unsafe extern "C" fn __xmlKeepBlanksDefaultValue() -> *mut c_int {
1212 unsafe { core::ptr::addr_of_mut!(xmlKeepBlanksDefaultValue) }
1215}
1216
1217#[no_mangle]
1219pub unsafe extern "C" fn __xmlLineNumbersDefaultValue() -> *mut c_int {
1220 unsafe { core::ptr::addr_of_mut!(xmlLineNumbersDefaultValue) }
1223}
1224
1225#[no_mangle]
1227pub unsafe extern "C" fn __xmlLoadExtDtdDefaultValue() -> *mut c_int {
1228 unsafe { core::ptr::addr_of_mut!(xmlLoadExtDtdDefaultValue) }
1231}
1232
1233#[no_mangle]
1235pub unsafe extern "C" fn __xmlOutputBufferCreateFilenameValue() -> *mut Option<
1236 unsafe extern "C" fn(
1237 *const c_char,
1238 crate::abi::structs::xmlCharEncodingHandlerPtr,
1239 c_int,
1240 ) -> *mut crate::abi::structs::_xmlOutputBuffer,
1241> {
1242 unsafe { core::ptr::addr_of_mut!(xmlOutputBufferCreateFilenameValue) }
1245}
1246
1247#[no_mangle]
1249pub unsafe extern "C" fn __xmlParserDebugEntities() -> *mut c_int {
1250 unsafe { core::ptr::addr_of_mut!(xmlParserDebugEntities) }
1253}
1254
1255#[no_mangle]
1257pub unsafe extern "C" fn __xmlParserInputBufferCreateFilenameValue() -> *mut Option<
1258 unsafe extern "C" fn(*const c_char, c_int) -> *mut crate::abi::structs::_xmlParserInputBuffer,
1259> {
1260 unsafe { core::ptr::addr_of_mut!(xmlParserInputBufferCreateFilenameValue) }
1263}
1264
1265#[no_mangle]
1267pub unsafe extern "C" fn __xmlParserVersion() -> *mut *const c_char {
1268 unsafe { core::ptr::addr_of_mut!(xmlParserVersion) }
1271}
1272
1273#[no_mangle]
1275pub unsafe extern "C" fn __xmlPedanticParserDefaultValue() -> *mut c_int {
1276 unsafe { core::ptr::addr_of_mut!(xmlPedanticParserDefaultValue) }
1279}
1280
1281#[no_mangle]
1283pub unsafe extern "C" fn __xmlRegisterNodeDefaultValue(
1284) -> *mut Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
1285 unsafe { core::ptr::addr_of_mut!(xmlRegisterNodeDefaultValue) }
1288}
1289
1290#[no_mangle]
1292pub unsafe extern "C" fn __xmlStructuredError() -> *mut Option<xmlStructuredErrorFunc> {
1293 unsafe { core::ptr::addr_of_mut!(xmlStructuredError) }
1296}
1297
1298#[no_mangle]
1300pub unsafe extern "C" fn __xmlStructuredErrorContext() -> *mut *mut c_void {
1301 unsafe { core::ptr::addr_of_mut!(xmlStructuredErrorContext) }
1304}
1305
1306#[no_mangle]
1308pub unsafe extern "C" fn __xmlSubstituteEntitiesDefaultValue() -> *mut c_int {
1309 unsafe { core::ptr::addr_of_mut!(xmlSubstituteEntitiesDefaultValue) }
1312}
1313
1314#[cfg(test)]
1327mod tests {
1328 use super::*;
1329 use crate::abi::allocator::xmlMallocImpl;
1330 use crate::abi::structs::_xmlError;
1331 use crate::xml::globals;
1332 use core::ptr;
1333
1334 unsafe fn alloc_cstr(s: &str) -> *mut c_char {
1337 let bytes = s.as_bytes();
1338 let p = unsafe { xmlMallocImpl(bytes.len() + 1) as *mut c_char };
1339 assert!(!p.is_null(), "alloc_cstr: xmlMallocImpl failed");
1340 unsafe {
1341 ptr::copy_nonoverlapping(bytes.as_ptr(), p as *mut u8, bytes.len());
1342 *((p as *mut u8).add(bytes.len())) = 0;
1343 }
1344 p
1345 }
1346
1347 unsafe fn build_error(tag: &str) -> _xmlError {
1349 _xmlError {
1350 domain: 1,
1351 code: 2,
1352 message: unsafe { alloc_cstr(&format!("msg {tag}")) },
1353 level: 3,
1354 file: unsafe { alloc_cstr(&format!("file {tag}")) },
1355 line: 4,
1356 str1: unsafe { alloc_cstr(&format!("str1 {tag}")) },
1357 str2: ptr::null_mut(),
1358 str3: ptr::null_mut(),
1359 int1: 0,
1360 int2: 0,
1361 ctxt: ptr::null_mut(),
1362 node: ptr::null_mut(),
1363 }
1364 }
1365
1366 #[test]
1370 fn test_last_error_mirror_concurrent_sync_reset() {
1371 let sync = std::thread::spawn(|| {
1372 for i in 0..400 {
1373 unsafe { globals::set_last_error(build_error(&format!("sync {i}"))) };
1374 }
1375 });
1376 let reset = std::thread::spawn(|| {
1377 for _ in 0..400 {
1378 globals::reset_last_error();
1379 }
1380 });
1381 sync.join().unwrap();
1382 reset.join().unwrap();
1383 globals::reset_last_error();
1387 }
1388
1389 #[test]
1392 fn test_last_error_mirror_many_threads() {
1393 let mut handles = Vec::new();
1394 for t in 0..8 {
1395 handles.push(std::thread::spawn(move || {
1396 for i in 0..150 {
1397 unsafe { globals::set_last_error(build_error(&format!("t{t} i{i}"))) };
1398 if i % 7 == 0 {
1399 globals::reset_last_error();
1400 }
1401 }
1402 }));
1403 }
1404 for h in handles {
1405 h.join().unwrap();
1406 }
1407 globals::reset_last_error();
1408 }
1409}