Skip to main content

libxml_rs/abi/
data_globals.rs

1//! Exported C data globals — the classic libxml2/libxslt public variables
2//! (11.1-G data-ABI closure, residual R-000135).
3//!
4//! Downstream C code reads and writes these symbols directly
5//! (e.g. `xmlDoValidityCheckingDefaultValue = 1;`), so they must exist with
6//! upstream names, types and defaults. The parser-default accessors in
7//! `src/xml/globals/mod.rs` read and write the SAME statics (single source
8//! of truth): a C write is immediately observable by the candidate parser.
9//!
10//! Defaults match upstream `globals.c` (libxml2 2.15.3) and `xslt.c`
11//! (libxslt 1.1.45).
12//!
13//! # SAFETY
14//!
15//! `static mut` globals are unsafe to touch from Rust; every access goes
16//! through the accessor functions in `crate::xml::globals` (or directly
17//! here with an explicit safety note). C accesses are inherently racy in
18//! upstream too — upstream documents these globals as deprecated and
19//! not thread-safe.
20
21use 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
27// ═══════════════════════════════════════════════════════════════════════════════
28// Parser defaults (upstream globals.c)
29// ═══════════════════════════════════════════════════════════════════════════════
30
31/// `int xmlDoValidityCheckingDefaultValue` (default 0)
32#[no_mangle]
33pub static mut xmlDoValidityCheckingDefaultValue: c_int = 0;
34
35/// `int xmlGetWarningsDefaultValue` (default 1)
36#[no_mangle]
37pub static mut xmlGetWarningsDefaultValue: c_int = 1;
38
39/// `int xmlLoadExtDtdDefaultValue` (default 0)
40#[no_mangle]
41pub static mut xmlLoadExtDtdDefaultValue: c_int = 0;
42
43/// `int xmlPedanticParserDefaultValue` (default 0)
44#[no_mangle]
45pub static mut xmlPedanticParserDefaultValue: c_int = 0;
46
47/// `int xmlLineNumbersDefaultValue` (default 1 — upstream globals.c
48/// `xmlLineNumbersDefaultValueThrDef = 1`)
49#[no_mangle]
50pub static mut xmlLineNumbersDefaultValue: c_int = 1;
51
52/// `int xmlKeepBlanksDefaultValue` (default 1)
53#[no_mangle]
54pub static mut xmlKeepBlanksDefaultValue: c_int = 1;
55
56/// `int xmlSubstituteEntitiesDefaultValue` (default 0)
57#[no_mangle]
58pub static mut xmlSubstituteEntitiesDefaultValue: c_int = 0;
59
60/// `int xmlParserDebugEntities` (default 0)
61#[no_mangle]
62pub static mut xmlParserDebugEntities: c_int = 0;
63
64/// `int xmlIndentTreeOutput` (default 1 — upstream globals.c
65/// `xmlIndentTreeOutputThrDef = 1`)
66#[no_mangle]
67pub static mut xmlIndentTreeOutput: c_int = 1;
68
69/// `const xmlChar *xmlTreeIndentString` (default "  " — upstream globals.c
70/// `xmlTreeIndentStringThrDef = "  "`)
71#[no_mangle]
72pub static mut xmlTreeIndentString: *const xmlChar = {
73    static S: [u8; 3] = *b"  \0";
74    S.as_ptr()
75};
76
77/// `int xmlSaveNoEmptyTags` (default 0)
78#[no_mangle]
79pub static mut xmlSaveNoEmptyTags: c_int = 0;
80
81/// Upstream `xmlRegisterNodeFunc xmlRegisterNodeDefaultValue` (default NULL)
82#[no_mangle]
83pub static mut xmlRegisterNodeDefaultValue: Option<
84    unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode),
85> = None;
86
87/// Upstream static `xmlRegisterCallbacks` (tree.c): the gate that arms the
88/// node register/deregister hooks once a callback has been registered.
89pub static XML_REGISTER_CALLBACKS: core::sync::atomic::AtomicBool =
90    core::sync::atomic::AtomicBool::new(false);
91
92/// Upstream `xmlRegisterNodeCallback(node)` — invoke the registered node
93/// hook, gated by `xmlRegisterCallbacks` (tree.c).
94///
95/// # SAFETY
96///
97/// - `node` must be a valid, fully-initialised node or NULL.
98pub fn register_node_hook(node: *mut crate::abi::structs::_xmlNode) {
99    if !XML_REGISTER_CALLBACKS.load(core::sync::atomic::Ordering::Relaxed) {
100        return;
101    }
102    let hook = unsafe { xmlRegisterNodeDefaultValue };
103    if let Some(h) = hook {
104        if !node.is_null() {
105            // SAFETY: the hook is a valid C callback registered by the user.
106            unsafe { h(node) };
107        }
108    }
109}
110
111/// Upstream `xmlDeregisterNodeCallback(node)` — invoke the registered node
112/// deregister hook, gated by `xmlRegisterCallbacks` (tree.c).
113///
114/// # SAFETY
115///
116/// - `node` must be a valid node about to be freed, or NULL.
117pub fn deregister_node_hook(node: *mut crate::abi::structs::_xmlNode) {
118    if !XML_REGISTER_CALLBACKS.load(core::sync::atomic::Ordering::Relaxed) {
119        return;
120    }
121    let hook = unsafe { xmlDeregisterNodeDefaultValue };
122    if let Some(h) = hook {
123        if !node.is_null() {
124            // SAFETY: the hook is a valid C callback registered by the user.
125            unsafe { h(node) };
126        }
127    }
128}
129
130/// `xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue` (default NULL)
131#[no_mangle]
132pub static mut xmlDeregisterNodeDefaultValue: Option<
133    unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode),
134> = None;
135
136/// `const char *xmlParserVersion` — matched to the system oracle build
137/// (libxml2 2.15.3 GIT build: LIBXML_VERSION_STRING "21503" plus the
138/// upstream version extra "-GITv2.15.3").
139///
140/// SAFETY: the pointed-to string is a static, immutable, null-terminated
141/// literal; `static mut` is used because C raw pointers are not `Sync`.
142/// Reads/writes of the pointer itself are racy only if C code mutates it
143/// (upstream treats it as a constant).
144#[no_mangle]
145pub static mut xmlParserVersion: *const c_char = {
146    static V: [u8; 17] = *b"21503-GITv2.15.3\0";
147    V.as_ptr() as *const c_char
148};
149
150/// `int xmlParserMaxDepth` (default 256)
151#[no_mangle]
152pub static mut xmlParserMaxDepth: c_int = 256;
153
154// ═══════════════════════════════════════════════════════════════════════════════
155// Buffer globals (upstream tree.h / xmlIO.c)
156// ═══════════════════════════════════════════════════════════════════════════════
157
158/// `int xmlDefaultBufferSize` (default 4096)
159#[no_mangle]
160pub static mut xmlDefaultBufferSize: c_int = 4096;
161
162/// `xmlBufferAllocationScheme xmlBufferAllocScheme` (default XML_BUFFER_ALLOC_EXACT = 1;
163/// upstream globals.c `xmlBufferAllocSchemeThrDef = XML_BUFFER_ALLOC_EXACT`)
164#[no_mangle]
165pub static mut xmlBufferAllocScheme: c_int = 1;
166
167// ═══════════════════════════════════════════════════════════════════════════════
168// Error callback globals (upstream xmlerror.h)
169// ═══════════════════════════════════════════════════════════════════════════════
170
171/// `xmlGenericErrorFunc xmlGenericError` — the generic error callback.
172///
173/// Upstream defaults to `xmlGenericErrorDefaultFunc` (a variadic stderr
174/// printer, error.c); the candidate's shim below reproduces it, so a
175/// freshly-initialized library routes errors to stderr exactly like upstream.
176#[cfg(target_arch = "x86_64")]
177#[no_mangle]
178pub static mut xmlGenericError: Option<xmlGenericErrorFunc> = Some(XML_GENERIC_ERROR_DEFAULT);
179
180#[cfg(not(target_arch = "x86_64"))]
181#[no_mangle]
182pub static mut xmlGenericError: Option<xmlGenericErrorFunc> = None;
183
184/// `void *xmlGenericErrorContext` — context for the generic error callback.
185#[no_mangle]
186pub static mut xmlGenericErrorContext: *mut c_void = core::ptr::null_mut();
187
188/// `xmlStructuredErrorFunc xmlStructuredError` — the structured error callback.
189#[no_mangle]
190pub static mut xmlStructuredError: Option<xmlStructuredErrorFunc> = None;
191
192/// `void *xmlStructuredErrorContext` — context for the structured callback.
193#[no_mangle]
194pub static mut xmlStructuredErrorContext: *mut c_void = core::ptr::null_mut();
195
196// ═══════════════════════════════════════════════════════════════════════════════
197// Variadic default error handlers (upstream error.c / xsltutils.c)
198// ═══════════════════════════════════════════════════════════════════════════════
199//
200// Upstream `xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...)`
201// prints the formatted message to `xmlGenericErrorContext` (stderr when
202// NULL). Stable Rust cannot define a variadic extern fn body, so the ABI
203// entry is an x86_64 SysV inline-asm shim that materialises the caller's
204// register/stack arguments into a `va_list` and forwards to a non-variadic
205// receiver — the same pattern as `xsltTransformError`
206// (exports_xslt_util.rs) and the writer's `vfmt_shim!`. Neither default
207// function is a dynamic export upstream (both are internal); the exported
208// data globals merely point at them.
209
210/// System V AMD64 `__va_list_tag` (24 bytes) — same layout as the writer's
211/// shims and `exports_xslt_util.rs`.
212#[cfg(target_arch = "x86_64")]
213#[repr(C)]
214#[derive(Clone, Copy)]
215struct VaListTag {
216    gp_offset: c_uint,
217    fp_offset: c_uint,
218    overflow_arg_area: *mut c_void,
219    reg_save_area: *mut c_void,
220}
221
222#[cfg(target_arch = "x86_64")]
223unsafe extern "C" {
224    fn vfprintf(stream: *mut c_void, format: *const c_char, ap: *mut VaListTag) -> c_int;
225}
226
227/// The `stderr` FILE* — glibc exports the `stderr` data object, an
228/// 8-byte pointer variable whose value is `&_IO_2_1_stderr_`. Upstream
229/// `xmlGenericErrorDefaultFunc` defaults the error context to `stderr`;
230/// using the real stdio object (unbuffered, fd-2 relative) keeps writes
231/// byte-exact and honors fd-2 redirection, unlike a private `fdopen(2)`
232/// FILE* which is fully buffered and lands at exit on whatever fd 2 then
233/// points to.
234#[cfg(target_arch = "x86_64")]
235unsafe fn stderr_file() -> *mut c_void {
236    extern "C" {
237        static stderr: *mut c_void;
238    }
239    unsafe { stderr }
240}
241
242/// Variadic receiver for the `xmlGenericErrorDefaultFunc` shim (upstream
243/// error.c semantics: default the context to stderr, then `vfprintf`).
244#[cfg(target_arch = "x86_64")]
245#[no_mangle]
246pub unsafe extern "C" fn xmlGenericErrorDefaultFuncV(
247    _ctx: *mut c_void,
248    msg: *const c_char,
249    ap: *mut VaListTag,
250) -> c_int {
251    unsafe {
252        if crate::abi::data_globals::xmlGenericErrorContext.is_null() {
253            crate::abi::data_globals::xmlGenericErrorContext = stderr_file();
254        }
255        let stream = crate::abi::data_globals::xmlGenericErrorContext;
256        if msg.is_null() || stream.is_null() {
257            return 0;
258        }
259        vfprintf(stream, msg, ap)
260    }
261}
262
263/// `xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...)` — the
264/// upstream default generic error handler. Not exported dynamically (matches
265/// upstream, where the symbol is internal).
266///
267/// 2 fixed args (ctx=rdi, msg=rsi) → `gp_offset` 16; the va_list pointer is
268/// passed as the 3rd arg (rdx) of the receiver.
269#[cfg(target_arch = "x86_64")]
270pub unsafe extern "C" fn xmlGenericErrorDefaultFunc() -> c_int {
271    unsafe {
272        core::arch::asm!(
273            "sub rsp, 240",
274            "mov [rsp+0], rdi",
275            "mov [rsp+8], rsi",
276            "mov [rsp+16], rdx",
277            "mov [rsp+24], rcx",
278            "mov [rsp+32], r8",
279            "mov [rsp+40], r9",
280            "movaps [rsp+48], xmm0",
281            "movaps [rsp+64], xmm1",
282            "movaps [rsp+80], xmm2",
283            "movaps [rsp+96], xmm3",
284            "movaps [rsp+112], xmm4",
285            "movaps [rsp+128], xmm5",
286            "movaps [rsp+144], xmm6",
287            "movaps [rsp+160], xmm7",
288            "mov dword ptr [rsp+176], 16",
289            "mov dword ptr [rsp+180], 48",
290            "lea rax, [rsp+256]",
291            "mov [rsp+184], rax",
292            "lea rax, [rsp]",
293            "mov [rsp+192], rax",
294            "lea rdx, [rsp+176]",
295            "call xmlGenericErrorDefaultFuncV",
296            "add rsp, 240",
297            "add rsp, 8",
298            "ret",
299            options(noreturn),
300        );
301    }
302}
303
304/// Default value of the exported `xmlGenericError` data global.
305#[cfg(target_arch = "x86_64")]
306const XML_GENERIC_ERROR_DEFAULT: xmlGenericErrorFunc = unsafe {
307    // SAFETY: the shim and the function-pointer type have identical ABI
308    // (a code pointer); the declared arity is a Rust-side fiction required
309    // to store a variadic entry in the non-variadic pointer type.
310    core::mem::transmute::<
311        unsafe extern "C" fn() -> c_int,
312        unsafe extern "C" fn(*mut c_void, *const c_char),
313    >(xmlGenericErrorDefaultFunc)
314};
315
316/// Variadic receiver for the `xsltGenericErrorDefaultFunc` shim (upstream
317/// xsltutils.c semantics: default the context to stderr, then `vfprintf`).
318#[cfg(target_arch = "x86_64")]
319#[no_mangle]
320pub unsafe extern "C" fn xsltGenericErrorDefaultFuncV(
321    _ctx: *mut c_void,
322    msg: *const c_char,
323    ap: *mut VaListTag,
324) -> c_int {
325    unsafe {
326        if crate::abi::data_globals::xsltGenericErrorContext.is_null() {
327            crate::abi::data_globals::xsltGenericErrorContext = stderr_file();
328        }
329        let stream = crate::abi::data_globals::xsltGenericErrorContext;
330        if msg.is_null() || stream.is_null() {
331            return 0;
332        }
333        vfprintf(stream, msg, ap)
334    }
335}
336
337/// `xsltGenericErrorDefaultFunc(void *ctx, const char *msg, ...)` — the
338/// upstream default XSLT error handler (xsltutils.c).
339#[cfg(target_arch = "x86_64")]
340pub unsafe extern "C" fn xsltGenericErrorDefaultFunc() -> c_int {
341    unsafe {
342        core::arch::asm!(
343            "sub rsp, 240",
344            "mov [rsp+0], rdi",
345            "mov [rsp+8], rsi",
346            "mov [rsp+16], rdx",
347            "mov [rsp+24], rcx",
348            "mov [rsp+32], r8",
349            "mov [rsp+40], r9",
350            "movaps [rsp+48], xmm0",
351            "movaps [rsp+64], xmm1",
352            "movaps [rsp+80], xmm2",
353            "movaps [rsp+96], xmm3",
354            "movaps [rsp+112], xmm4",
355            "movaps [rsp+128], xmm5",
356            "movaps [rsp+144], xmm6",
357            "movaps [rsp+160], xmm7",
358            "mov dword ptr [rsp+176], 16",
359            "mov dword ptr [rsp+180], 48",
360            "lea rax, [rsp+256]",
361            "mov [rsp+184], rax",
362            "lea rax, [rsp]",
363            "mov [rsp+192], rax",
364            "lea rdx, [rsp+176]",
365            "call xsltGenericErrorDefaultFuncV",
366            "add rsp, 240",
367            "add rsp, 8",
368            "ret",
369            options(noreturn),
370        );
371    }
372}
373
374/// Default value of the exported `xsltGenericError` data global.
375#[cfg(target_arch = "x86_64")]
376const XSLT_GENERIC_ERROR_DEFAULT: xmlGenericErrorFunc = unsafe {
377    // SAFETY: as above — ABI-identical code pointer.
378    core::mem::transmute::<
379        unsafe extern "C" fn() -> c_int,
380        unsafe extern "C" fn(*mut c_void, *const c_char),
381    >(xsltGenericErrorDefaultFunc)
382};
383
384/// The built-in default generic error handler (upstream
385/// `xmlGenericErrorDefaultFunc`), for use when a caller resets the handler
386/// with NULL. Only available on x86_64 (the variadic shim is SysV-specific);
387/// on other targets there is no default (resets leave the handler unset).
388pub fn default_generic_error_func() -> Option<xmlGenericErrorFunc> {
389    #[cfg(target_arch = "x86_64")]
390    {
391        Some(XML_GENERIC_ERROR_DEFAULT)
392    }
393    #[cfg(not(target_arch = "x86_64"))]
394    {
395        None
396    }
397}
398
399// ═══════════════════════════════════════════════════════════════════════════════
400// Static strings (upstream xmlstring.h / tree.c)
401// ═══════════════════════════════════════════════════════════════════════════════
402
403/// `const xmlChar xmlStringText[]` — "text"
404#[no_mangle]
405pub static xmlStringText: [xmlChar; 5] = [b't', b'e', b'x', b't', 0];
406
407/// `const xmlChar xmlStringTextNoenc[]` — "textnoenc"
408#[no_mangle]
409pub static xmlStringTextNoenc: [xmlChar; 9] =
410    [b't', b'e', b'x', b't', b'n', b'o', b'e', b'n', b'c'];
411
412/// `const xmlChar xmlStringComment[]` — "comment"
413#[no_mangle]
414pub static xmlStringComment: [xmlChar; 8] = [b'c', b'o', b'm', b'm', b'e', b'n', b't', 0];
415
416// ═══════════════════════════════════════════════════════════════════════════════
417// XPath numeric constants (upstream xpath.c)
418// ═══════════════════════════════════════════════════════════════════════════════
419
420/// `double xmlXPathNAN` — NaN
421#[no_mangle]
422pub static xmlXPathNAN: f64 = f64::NAN;
423
424/// `double xmlXPathPINF` — +infinity
425#[no_mangle]
426pub static xmlXPathPINF: f64 = f64::INFINITY;
427
428/// `double xmlXPathNINF` — -infinity
429#[no_mangle]
430pub static xmlXPathNINF: f64 = f64::NEG_INFINITY;
431
432// ═══════════════════════════════════════════════════════════════════════════════
433// libxslt globals (upstream xslt.c / xsltutils.c / documents.c / xslt.h)
434// ═══════════════════════════════════════════════════════════════════════════════
435// xsltMaxDepth / xsltMaxVars are exported from src/xslt/transform/mod.rs
436// (they are read by the transform engine).
437
438/// `const int xsltLibxmlVersion` = LIBXML_VERSION (21503) — the libxml2
439/// version libxslt was built against (upstream xslt.c).
440#[no_mangle]
441pub static xsltLibxmlVersion: c_int = 21503;
442
443/// `xmlGenericErrorFunc xsltGenericError` — the libxslt error callback.
444/// Upstream defaults to `xsltGenericErrorDefaultFunc` (xsltutils.c, a variadic
445/// stderr printer); the candidate's shim below reproduces it (R-000135
446/// divergence now closed).
447#[cfg(target_arch = "x86_64")]
448#[no_mangle]
449pub static mut xsltGenericError: Option<xmlGenericErrorFunc> = Some(XSLT_GENERIC_ERROR_DEFAULT);
450
451#[cfg(not(target_arch = "x86_64"))]
452#[no_mangle]
453pub static mut xsltGenericError: Option<xmlGenericErrorFunc> = None;
454
455/// `void *xsltGenericErrorContext` (default NULL)
456#[no_mangle]
457pub static mut xsltGenericErrorContext: *mut c_void = core::ptr::null_mut();
458
459/// `void *xsltGenericDebugContext` (default NULL)
460#[no_mangle]
461pub static mut xsltGenericDebugContext: *mut c_void = core::ptr::null_mut();
462
463/// `const xmlChar xsltExtMarker[]` — empty string used to mark extension
464/// nodes (upstream transform.c).
465#[no_mangle]
466pub static xsltExtMarker: [xmlChar; 1] = [0];
467
468/// `xsltDocLoaderFunc xsltDocDefaultLoader` — the document loader callback.
469/// Upstream defaults to `xsltDocDefaultLoaderFunc`; the candidate defaults
470/// to NULL and its internal loader path is used — documented safe
471/// divergence (residual R-000135).
472#[no_mangle]
473pub static mut xsltDocDefaultLoader: Option<
474    unsafe extern "C" fn(
475        *const xmlChar,
476        *mut c_void,
477        c_int,
478        *mut crate::abi::structs::_xsltStylesheet,
479        *mut crate::abi::structs::_xsltTransformContext,
480    ) -> *mut crate::abi::structs::_xmlDoc,
481> = None;
482
483// ═══════════════════════════════════════════════════════════════════════════════
484// I/O filename callback globals (upstream xmlIO.h)
485// ═══════════════════════════════════════════════════════════════════════════════
486
487/// `xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValue`
488#[no_mangle]
489pub static mut xmlParserInputBufferCreateFilenameValue: Option<
490    unsafe extern "C" fn(*const c_char, c_int) -> *mut crate::abi::structs::_xmlParserInputBuffer,
491> = None;
492
493/// `xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValue`
494#[no_mangle]
495pub static mut xmlOutputBufferCreateFilenameValue: Option<
496    unsafe extern "C" fn(
497        *const c_char,
498        crate::abi::structs::xmlCharEncodingHandlerPtr,
499        c_int,
500    ) -> *mut crate::abi::structs::_xmlOutputBuffer,
501> = None;
502
503// ═══════════════════════════════════════════════════════════════════════════════
504// Default SAX v1 handler structs + locator (upstream globals.c 2.15.3)
505// ═══════════════════════════════════════════════════════════════════════════════
506//
507// `const xmlSAXHandlerV1 xmlDefaultSAXHandler` and `htmlDefaultSAXHandler`
508// (parser.h / HTMLparser.h), plus `const xmlSAXLocator xmlDefaultSAXLocator`.
509// The handler instances reproduce the upstream initializer lists exactly
510// (globals.c); every referenced xmlSAX2* entry point is a real candidate
511// export.
512
513/// `const xmlSAXHandlerV1 xmlDefaultSAXHandler` (globals.c 2.15.3).
514#[no_mangle]
515pub static xmlDefaultSAXHandler: crate::abi::structs::_xmlSAXHandlerV1 =
516    crate::abi::structs::_xmlSAXHandlerV1 {
517        internalSubset: Some(crate::abi::exports_xml2::xmlSAX2InternalSubset),
518        isStandalone: Some(crate::abi::exports_xml2::xmlSAX2IsStandalone),
519        hasInternalSubset: Some(crate::abi::exports_xml2::xmlSAX2HasInternalSubset),
520        hasExternalSubset: Some(crate::abi::exports_xml2::xmlSAX2HasExternalSubset),
521        resolveEntity: Some(crate::abi::exports_xml2::xmlSAX2ResolveEntity),
522        getEntity: Some(crate::abi::exports_xml2::xmlSAX2GetEntity),
523        entityDecl: Some(crate::abi::exports_xml2::xmlSAX2EntityDecl),
524        notationDecl: Some(crate::abi::exports_xml2::xmlSAX2NotationDecl),
525        attributeDecl: Some(crate::abi::exports_xml2::xmlSAX2AttributeDecl),
526        elementDecl: Some(crate::abi::exports_xml2::xmlSAX2ElementDecl),
527        unparsedEntityDecl: Some(crate::abi::exports_xml2::xmlSAX2UnparsedEntityDecl),
528        setDocumentLocator: Some(crate::abi::exports_xml2::xmlSAX2SetDocumentLocator),
529        startDocument: Some(crate::abi::exports_xml2::xmlSAX2StartDocument),
530        endDocument: Some(crate::abi::exports_xml2::xmlSAX2EndDocument),
531        startElement: Some(crate::abi::exports_xml2::xmlSAX2StartElement),
532        endElement: Some(crate::abi::exports_xml2::xmlSAX2EndElement),
533        reference: Some(crate::abi::exports_xml2::xmlSAX2Reference),
534        characters: Some(crate::abi::exports_xml2::xmlSAX2Characters),
535        ignorableWhitespace: Some(crate::abi::exports_xml2::xmlSAX2IgnorableWhitespace),
536        processingInstruction: Some(crate::abi::exports_xml2::xmlSAX2ProcessingInstruction),
537        comment: Some(crate::abi::exports_xml2::xmlSAX2Comment),
538        warning: Some(crate::xml::errors::xmlParserWarning),
539        error: Some(crate::xml::errors::xmlParserError),
540        fatalError: Some(crate::xml::errors::xmlParserError),
541        getParameterEntity: Some(crate::abi::exports_xml2::xmlSAX2GetParameterEntity),
542        cdataBlock: Some(crate::abi::exports_xml2::xmlSAX2CDataBlock),
543        externalSubset: Some(crate::abi::exports_xml2::xmlSAX2ExternalSubset),
544        initialized: 1,
545    };
546
547/// `const xmlSAXHandlerV1 htmlDefaultSAXHandler` (globals.c 2.15.3).
548#[no_mangle]
549pub static htmlDefaultSAXHandler: crate::abi::structs::_xmlSAXHandlerV1 =
550    crate::abi::structs::_xmlSAXHandlerV1 {
551        internalSubset: Some(crate::abi::exports_xml2::xmlSAX2InternalSubset),
552        isStandalone: None,
553        hasInternalSubset: None,
554        hasExternalSubset: None,
555        resolveEntity: None,
556        getEntity: Some(crate::abi::exports_xml2::xmlSAX2GetEntity),
557        entityDecl: None,
558        notationDecl: None,
559        attributeDecl: None,
560        elementDecl: None,
561        unparsedEntityDecl: None,
562        setDocumentLocator: Some(crate::abi::exports_xml2::xmlSAX2SetDocumentLocator),
563        startDocument: Some(crate::abi::exports_xml2::xmlSAX2StartDocument),
564        endDocument: Some(crate::abi::exports_xml2::xmlSAX2EndDocument),
565        startElement: Some(crate::abi::exports_xml2::xmlSAX2StartElement),
566        endElement: Some(crate::abi::exports_xml2::xmlSAX2EndElement),
567        reference: None,
568        characters: Some(crate::abi::exports_xml2::xmlSAX2Characters),
569        ignorableWhitespace: Some(crate::abi::exports_xml2::xmlSAX2IgnorableWhitespace),
570        processingInstruction: Some(crate::abi::exports_xml2::xmlSAX2ProcessingInstruction),
571        comment: Some(crate::abi::exports_xml2::xmlSAX2Comment),
572        warning: Some(crate::xml::errors::xmlParserWarning),
573        error: Some(crate::xml::errors::xmlParserError),
574        fatalError: Some(crate::xml::errors::xmlParserError),
575        getParameterEntity: None,
576        cdataBlock: Some(crate::abi::exports_xml2::xmlSAX2CDataBlock),
577        externalSubset: None,
578        initialized: 1,
579    };
580
581/// `const xmlSAXLocator xmlDefaultSAXLocator` (globals.c 2.15.3).
582#[no_mangle]
583pub static xmlDefaultSAXLocator: crate::abi::callbacks::_xmlSAXLocator =
584    crate::abi::callbacks::_xmlSAXLocator {
585        getPublicId: Some(crate::abi::exports_xml2::xmlSAX2GetPublicId),
586        getSystemId: Some(crate::abi::exports_xml2::xmlSAX2GetSystemId),
587        getLineNumber: Some(crate::abi::exports_xml2::xmlSAX2GetLineNumber),
588        getColumnNumber: Some(crate::abi::exports_xml2::xmlSAX2GetColumnNumber),
589    };
590
591// ═══════════════════════════════════════════════════════════════════════════════
592// xmlLastError — the exported C global mirror of the thread-local error state
593// ═══════════════════════════════════════════════════════════════════════════════
594//
595// Upstream `XMLPUBVAR xmlError xmlLastError` (xmlerror.h). The candidate's
596// internal error state is thread-local (safe divergence, more correct than
597// upstream's racy global); this mirror is deep-copied on every error raise
598// and freed on reset, so C consumers observe upstream-equivalent lifetime
599// semantics. Residual R-000135.
600
601/// `xmlError xmlLastError` — most recent error (mirror).
602#[no_mangle]
603pub static mut xmlLastError: crate::abi::structs::_xmlError = crate::abi::structs::_xmlError {
604    domain: 0,
605    code: 0,
606    message: core::ptr::null_mut(),
607    level: 0,
608    file: core::ptr::null_mut(),
609    line: 0,
610    str1: core::ptr::null_mut(),
611    str2: core::ptr::null_mut(),
612    str3: core::ptr::null_mut(),
613    int1: 0,
614    int2: 0,
615    ctxt: core::ptr::null_mut(),
616    node: core::ptr::null_mut(),
617};
618
619/// Deep-copy `err` into the exported `xmlLastError` global.
620///
621/// The string fields are copied with `libc::malloc`/`memcpy` so the mirror
622/// owns them (previous mirror strings are freed first — upstream
623/// xmlResetError semantics).
624///
625/// # SAFETY
626///
627/// - `err` must point to a valid `_xmlError` whose string fields are
628///   NUL-terminated or NULL.
629pub unsafe fn sync_xml_last_error(err: *const crate::abi::structs::_xmlError) {
630    if err.is_null() {
631        return;
632    }
633    unsafe {
634        reset_xml_last_error();
635        let src = &*err;
636        let dst = core::ptr::addr_of_mut!(xmlLastError);
637        (*dst).domain = src.domain;
638        (*dst).code = src.code;
639        (*dst).level = src.level;
640        (*dst).line = src.line;
641        (*dst).int1 = src.int1;
642        (*dst).int2 = src.int2;
643        (*dst).ctxt = src.ctxt;
644        (*dst).node = src.node;
645        (*dst).message = dup_cstr(src.message as *const u8);
646        (*dst).file = dup_cstr(src.file as *const u8);
647        (*dst).str1 = dup_cstr(src.str1 as *const u8);
648        (*dst).str2 = dup_cstr(src.str2 as *const u8);
649        (*dst).str3 = dup_cstr(src.str3 as *const u8);
650    }
651}
652
653/// Reset the exported `xmlLastError` global, freeing owned strings
654/// (upstream xmlResetError).
655///
656/// # SAFETY
657///
658/// Only call while no other thread is reading the global (upstream has the
659/// same race; documented).
660pub unsafe fn reset_xml_last_error() {
661    unsafe {
662        let dst = core::ptr::addr_of_mut!(xmlLastError);
663        if !(*dst).message.is_null() {
664            libc::free((*dst).message as *mut libc::c_void);
665        }
666        if !(*dst).file.is_null() {
667            libc::free((*dst).file as *mut libc::c_void);
668        }
669        if !(*dst).str1.is_null() {
670            libc::free((*dst).str1 as *mut libc::c_void);
671        }
672        if !(*dst).str2.is_null() {
673            libc::free((*dst).str2 as *mut libc::c_void);
674        }
675        if !(*dst).str3.is_null() {
676            libc::free((*dst).str3 as *mut libc::c_void);
677        }
678        *dst = crate::abi::structs::_xmlError {
679            domain: 0,
680            code: 0,
681            message: core::ptr::null_mut(),
682            level: 0,
683            file: core::ptr::null_mut(),
684            line: 0,
685            str1: core::ptr::null_mut(),
686            str2: core::ptr::null_mut(),
687            str3: core::ptr::null_mut(),
688            int1: 0,
689            int2: 0,
690            ctxt: core::ptr::null_mut(),
691            node: core::ptr::null_mut(),
692        };
693    }
694}
695
696/// Heap-copy a NUL-terminated string (NULL-safe).
697unsafe fn dup_cstr(s: *const u8) -> *mut c_char {
698    if s.is_null() {
699        return core::ptr::null_mut();
700    }
701    unsafe {
702        let len = libc::strlen(s as *const libc::c_char) as usize;
703        let p = libc::malloc(len + 1) as *mut u8;
704        if p.is_null() {
705            return core::ptr::null_mut();
706        }
707        libc::memcpy(p as *mut libc::c_void, s as *const libc::c_void, len + 1);
708        p as *mut c_char
709    }
710}
711
712// ═══════════════════════════════════════════════════════════════════════════════
713// Default accessor functions (upstream parser.h / tree.h / xmlsave.h)
714// ═══════════════════════════════════════════════════════════════════════════════
715//
716// The deprecated `xmlXxxDefault(v)` accessors set the corresponding global
717// when `v != 0` and return the (new) value — upstream semantics (they
718// predate the plain globals; the modern behavior is conditional-set-and-
719// return, see upstream globals.c / parser.c).
720
721/// Upstream `xmlKeepBlanksDefault(int v)`.
722#[no_mangle]
723pub unsafe extern "C" fn xmlKeepBlanksDefault(v: c_int) -> c_int {
724    unsafe {
725        if v != 0 {
726            xmlKeepBlanksDefaultValue = v;
727        }
728        xmlKeepBlanksDefaultValue
729    }
730}
731
732/// Upstream `xmlLineNumbersDefault(int v)`.
733#[no_mangle]
734pub unsafe extern "C" fn xmlLineNumbersDefault(v: c_int) -> c_int {
735    unsafe {
736        if v != 0 {
737            xmlLineNumbersDefaultValue = v;
738        }
739        xmlLineNumbersDefaultValue
740    }
741}
742
743/// Upstream `xmlSubstituteEntitiesDefault(int v)`.
744#[no_mangle]
745pub unsafe extern "C" fn xmlSubstituteEntitiesDefault(v: c_int) -> c_int {
746    unsafe {
747        if v != 0 {
748            xmlSubstituteEntitiesDefaultValue = v;
749        }
750        xmlSubstituteEntitiesDefaultValue
751    }
752}
753
754/// Upstream `xmlPedanticParserDefault(int v)`.
755#[no_mangle]
756pub unsafe extern "C" fn xmlPedanticParserDefault(v: c_int) -> c_int {
757    unsafe {
758        if v != 0 {
759            xmlPedanticParserDefaultValue = v;
760        }
761        xmlPedanticParserDefaultValue
762    }
763}
764
765/// Upstream `xmlDoValidityCheckingDefaultValue` accessor is the global
766/// itself; `xmlGetWarningsDefaultValue` likewise (no accessor functions
767/// exist for those in upstream 2.15).
768
769/// Upstream `xmlRegisterNodeDefault(xmlRegisterNodeFunc func)`.
770#[no_mangle]
771pub unsafe extern "C" fn xmlRegisterNodeDefault(
772    func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
773) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
774    unsafe {
775        // UPSTREAM-PARITY (tree.c): registering any callback arms the
776        // xmlRegisterCallbacks gate.
777        XML_REGISTER_CALLBACKS.store(true, core::sync::atomic::Ordering::Relaxed);
778        if func.is_some() {
779            xmlRegisterNodeDefaultValue = func;
780        }
781        xmlRegisterNodeDefaultValue
782    }
783}
784
785/// Upstream `xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func)`.
786#[no_mangle]
787pub unsafe extern "C" fn xmlDeregisterNodeDefault(
788    func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
789) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
790    unsafe {
791        // UPSTREAM-PARITY (tree.c): registering any callback arms the
792        // xmlRegisterCallbacks gate.
793        XML_REGISTER_CALLBACKS.store(true, core::sync::atomic::Ordering::Relaxed);
794        if func.is_some() {
795            xmlDeregisterNodeDefaultValue = func;
796        }
797        xmlDeregisterNodeDefaultValue
798    }
799}
800
801/// Upstream `__xmlIndentTreeOutput(void)` (parser.h) — returns a pointer to
802/// the `xmlIndentTreeOutput` global.
803#[no_mangle]
804pub unsafe extern "C" fn __xmlIndentTreeOutput() -> *mut c_int {
805    unsafe { core::ptr::addr_of_mut!(xmlIndentTreeOutput) }
806}
807
808/// Upstream `__xmlSaveNoEmptyTags(void)` (parser.h) — returns a pointer to
809/// the `xmlSaveNoEmptyTags` global.
810#[no_mangle]
811pub unsafe extern "C" fn __xmlSaveNoEmptyTags() -> *mut c_int {
812    unsafe { core::ptr::addr_of_mut!(xmlSaveNoEmptyTags) }
813}
814
815/// Upstream `__xmlTreeIndentString(void)` (parser.h) — returns a pointer to
816/// the `xmlTreeIndentString` global.
817#[no_mangle]
818pub unsafe extern "C" fn __xmlTreeIndentString() -> *mut *const xmlChar {
819    unsafe { core::ptr::addr_of_mut!(xmlTreeIndentString) }
820}
821
822// ═══════════════════════════════════════════════════════════════════════════════
823// xmlThrDef* accessors (upstream threads.c / globals.c)
824// ═══════════════════════════════════════════════════════════════════════════════
825//
826// The deprecated `xmlThrDef*` family reads/writes the public globals with
827// the upstream semantics: when `v != 0` the global is set, and the (new)
828// value is returned. In upstream these were thread-local definitions before
829// the globals became plain variables; the modern behavior is exactly this
830// conditional-set-and-return on the global (see upstream globals.c).
831
832/// Upstream `xmlThrDefDoValidityCheckingDefaultValue(int v)`.
833#[no_mangle]
834pub unsafe extern "C" fn xmlThrDefDoValidityCheckingDefaultValue(v: c_int) -> c_int {
835    unsafe {
836        if v != 0 {
837            xmlDoValidityCheckingDefaultValue = v;
838        }
839        xmlDoValidityCheckingDefaultValue
840    }
841}
842
843/// Upstream `xmlThrDefGetWarningsDefaultValue(int v)`.
844#[no_mangle]
845pub unsafe extern "C" fn xmlThrDefGetWarningsDefaultValue(v: c_int) -> c_int {
846    unsafe {
847        if v != 0 {
848            xmlGetWarningsDefaultValue = v;
849        }
850        xmlGetWarningsDefaultValue
851    }
852}
853
854/// Upstream `xmlThrDefLoadExtDtdDefaultValue(int v)`.
855#[no_mangle]
856pub unsafe extern "C" fn xmlThrDefLoadExtDtdDefaultValue(v: c_int) -> c_int {
857    unsafe {
858        if v != 0 {
859            xmlLoadExtDtdDefaultValue = v;
860        }
861        xmlLoadExtDtdDefaultValue
862    }
863}
864
865/// Upstream `xmlThrDefPedanticParserDefaultValue(int v)`.
866#[no_mangle]
867pub unsafe extern "C" fn xmlThrDefPedanticParserDefaultValue(v: c_int) -> c_int {
868    unsafe {
869        if v != 0 {
870            xmlPedanticParserDefaultValue = v;
871        }
872        xmlPedanticParserDefaultValue
873    }
874}
875
876/// Upstream `xmlThrDefLineNumbersDefaultValue(int v)`.
877#[no_mangle]
878pub unsafe extern "C" fn xmlThrDefLineNumbersDefaultValue(v: c_int) -> c_int {
879    unsafe {
880        if v != 0 {
881            xmlLineNumbersDefaultValue = v;
882        }
883        xmlLineNumbersDefaultValue
884    }
885}
886
887/// Upstream `xmlThrDefKeepBlanksDefaultValue(int v)`.
888#[no_mangle]
889pub unsafe extern "C" fn xmlThrDefKeepBlanksDefaultValue(v: c_int) -> c_int {
890    unsafe {
891        if v != 0 {
892            xmlKeepBlanksDefaultValue = v;
893        }
894        xmlKeepBlanksDefaultValue
895    }
896}
897
898/// Upstream `xmlThrDefSubstituteEntitiesDefaultValue(int v)`.
899#[no_mangle]
900pub unsafe extern "C" fn xmlThrDefSubstituteEntitiesDefaultValue(v: c_int) -> c_int {
901    unsafe {
902        if v != 0 {
903            xmlSubstituteEntitiesDefaultValue = v;
904        }
905        xmlSubstituteEntitiesDefaultValue
906    }
907}
908
909/// Upstream `xmlThrDefParserDebugEntities(int v)`.
910#[no_mangle]
911pub unsafe extern "C" fn xmlThrDefParserDebugEntities(v: c_int) -> c_int {
912    unsafe {
913        if v != 0 {
914            xmlParserDebugEntities = v;
915        }
916        xmlParserDebugEntities
917    }
918}
919
920/// Upstream `xmlThrDefIndentTreeOutput(int v)`.
921#[no_mangle]
922pub unsafe extern "C" fn xmlThrDefIndentTreeOutput(v: c_int) -> c_int {
923    unsafe {
924        if v != 0 {
925            xmlIndentTreeOutput = v;
926        }
927        xmlIndentTreeOutput
928    }
929}
930
931/// Upstream `xmlThrDefTreeIndentString(const char *v)` — sets the indent
932/// string when non-NULL and returns the current pointer.
933#[no_mangle]
934pub unsafe extern "C" fn xmlThrDefTreeIndentString(v: *const c_char) -> *const c_char {
935    unsafe {
936        if !v.is_null() {
937            xmlTreeIndentString = v as *const xmlChar;
938        }
939        xmlTreeIndentString as *const c_char
940    }
941}
942
943/// Upstream `xmlThrDefSaveNoEmptyTags(int v)`.
944#[no_mangle]
945pub unsafe extern "C" fn xmlThrDefSaveNoEmptyTags(v: c_int) -> c_int {
946    unsafe {
947        if v != 0 {
948            xmlSaveNoEmptyTags = v;
949        }
950        xmlSaveNoEmptyTags
951    }
952}
953
954/// Upstream `xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func)`.
955#[no_mangle]
956pub unsafe extern "C" fn xmlThrDefRegisterNodeDefault(
957    func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
958) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
959    unsafe {
960        if func.is_some() {
961            xmlRegisterNodeDefaultValue = func;
962        }
963        xmlRegisterNodeDefaultValue
964    }
965}
966
967/// Upstream `xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func)`.
968#[no_mangle]
969pub unsafe extern "C" fn xmlThrDefDeregisterNodeDefault(
970    func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
971) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
972    unsafe {
973        if func.is_some() {
974            xmlDeregisterNodeDefaultValue = func;
975        }
976        xmlDeregisterNodeDefaultValue
977    }
978}
979
980/// Upstream `xmlThrDefSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc func)`.
981#[no_mangle]
982pub unsafe extern "C" fn xmlThrDefSetGenericErrorFunc(
983    ctx: *mut c_void,
984    func: Option<xmlGenericErrorFunc>,
985) {
986    unsafe {
987        xmlGenericErrorContext = ctx;
988        xmlGenericError = func;
989    }
990}
991
992/// Upstream `xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc func)`.
993#[no_mangle]
994pub unsafe extern "C" fn xmlThrDefSetStructuredErrorFunc(
995    ctx: *mut c_void,
996    func: Option<xmlStructuredErrorFunc>,
997) {
998    unsafe {
999        xmlStructuredErrorContext = ctx;
1000        xmlStructuredError = func;
1001    }
1002}
1003
1004/// Upstream `xmlThrDefDefaultBufferSize(int v)`.
1005#[no_mangle]
1006pub unsafe extern "C" fn xmlThrDefDefaultBufferSize(v: c_int) -> c_int {
1007    unsafe {
1008        if v != 0 {
1009            xmlDefaultBufferSize = v;
1010        }
1011        xmlDefaultBufferSize
1012    }
1013}
1014
1015/// Upstream `xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v)`.
1016#[no_mangle]
1017pub unsafe extern "C" fn xmlThrDefBufferAllocScheme(v: c_int) -> c_int {
1018    unsafe {
1019        if v != 0 {
1020            xmlBufferAllocScheme = v;
1021        }
1022        xmlBufferAllocScheme
1023    }
1024}
1025
1026/// Upstream `xmlThrDefParserInputBufferCreateFilenameDefault(...)`.
1027#[no_mangle]
1028pub unsafe extern "C" fn xmlThrDefParserInputBufferCreateFilenameDefault(
1029    func: Option<
1030        unsafe extern "C" fn(
1031            *const c_char,
1032            c_int,
1033        ) -> *mut crate::abi::structs::_xmlParserInputBuffer,
1034    >,
1035) -> Option<
1036    unsafe extern "C" fn(*const c_char, c_int) -> *mut crate::abi::structs::_xmlParserInputBuffer,
1037> {
1038    unsafe {
1039        if func.is_some() {
1040            xmlParserInputBufferCreateFilenameValue = func;
1041        }
1042        xmlParserInputBufferCreateFilenameValue
1043    }
1044}
1045
1046/// Upstream `xmlThrDefOutputBufferCreateFilenameDefault(...)`.
1047#[no_mangle]
1048pub unsafe extern "C" fn xmlThrDefOutputBufferCreateFilenameDefault(
1049    func: Option<
1050        unsafe extern "C" fn(
1051            *const c_char,
1052            crate::abi::structs::xmlCharEncodingHandlerPtr,
1053            c_int,
1054        ) -> *mut crate::abi::structs::_xmlOutputBuffer,
1055    >,
1056) -> Option<
1057    unsafe extern "C" fn(
1058        *const c_char,
1059        crate::abi::structs::xmlCharEncodingHandlerPtr,
1060        c_int,
1061    ) -> *mut crate::abi::structs::_xmlOutputBuffer,
1062> {
1063    unsafe {
1064        if func.is_some() {
1065            xmlOutputBufferCreateFilenameValue = func;
1066        }
1067        xmlOutputBufferCreateFilenameValue
1068    }
1069}
1070
1071// ═══════════════════════════════════════════════════════════════════════════════
1072// __xmlXxx() pointer accessors (upstream threads.c / globals.c)
1073// ═══════════════════════════════════════════════════════════════════════════════
1074// The deprecated thread-local API exports one `__xmlXxx(void)` accessor per
1075// global; each returns a pointer to the global so callers can read/write it.
1076
1077/// Upstream `__xmlBufferAllocScheme(void)` — returns a pointer to `xmlBufferAllocScheme`.
1078#[no_mangle]
1079pub unsafe extern "C" fn __xmlBufferAllocScheme() -> *mut c_int {
1080    // SAFETY: returning a pointer to an exported static; the caller may
1081    // read/write it exactly as with upstream's deprecated accessor.
1082    unsafe { core::ptr::addr_of_mut!(xmlBufferAllocScheme) }
1083}
1084
1085/// Upstream `__xmlDefaultBufferSize(void)` — returns a pointer to `xmlDefaultBufferSize`.
1086#[no_mangle]
1087pub unsafe extern "C" fn __xmlDefaultBufferSize() -> *mut c_int {
1088    // SAFETY: returning a pointer to an exported static; the caller may
1089    // read/write it exactly as with upstream's deprecated accessor.
1090    unsafe { core::ptr::addr_of_mut!(xmlDefaultBufferSize) }
1091}
1092
1093/// Upstream `__xmlDeregisterNodeDefaultValue(void)` — returns a pointer to `xmlDeregisterNodeDefaultValue`.
1094#[no_mangle]
1095pub unsafe extern "C" fn __xmlDeregisterNodeDefaultValue(
1096) -> *mut Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
1097    // SAFETY: returning a pointer to an exported static; the caller may
1098    // read/write it exactly as with upstream's deprecated accessor.
1099    unsafe { core::ptr::addr_of_mut!(xmlDeregisterNodeDefaultValue) }
1100}
1101
1102/// Upstream `__xmlDoValidityCheckingDefaultValue(void)` — returns a pointer to `xmlDoValidityCheckingDefaultValue`.
1103#[no_mangle]
1104pub unsafe extern "C" fn __xmlDoValidityCheckingDefaultValue() -> *mut c_int {
1105    // SAFETY: returning a pointer to an exported static; the caller may
1106    // read/write it exactly as with upstream's deprecated accessor.
1107    unsafe { core::ptr::addr_of_mut!(xmlDoValidityCheckingDefaultValue) }
1108}
1109
1110/// Upstream `__xmlGenericError(void)` — returns a pointer to `xmlGenericError`.
1111#[no_mangle]
1112pub unsafe extern "C" fn __xmlGenericError() -> *mut Option<xmlGenericErrorFunc> {
1113    // SAFETY: returning a pointer to an exported static; the caller may
1114    // read/write it exactly as with upstream's deprecated accessor.
1115    unsafe { core::ptr::addr_of_mut!(xmlGenericError) }
1116}
1117
1118/// Upstream `__xmlGenericErrorContext(void)` — returns a pointer to `xmlGenericErrorContext`.
1119#[no_mangle]
1120pub unsafe extern "C" fn __xmlGenericErrorContext() -> *mut *mut c_void {
1121    // SAFETY: returning a pointer to an exported static; the caller may
1122    // read/write it exactly as with upstream's deprecated accessor.
1123    unsafe { core::ptr::addr_of_mut!(xmlGenericErrorContext) }
1124}
1125
1126/// Upstream `__xmlGetWarningsDefaultValue(void)` — returns a pointer to `xmlGetWarningsDefaultValue`.
1127#[no_mangle]
1128pub unsafe extern "C" fn __xmlGetWarningsDefaultValue() -> *mut c_int {
1129    // SAFETY: returning a pointer to an exported static; the caller may
1130    // read/write it exactly as with upstream's deprecated accessor.
1131    unsafe { core::ptr::addr_of_mut!(xmlGetWarningsDefaultValue) }
1132}
1133
1134/// Upstream `__xmlKeepBlanksDefaultValue(void)` — returns a pointer to `xmlKeepBlanksDefaultValue`.
1135#[no_mangle]
1136pub unsafe extern "C" fn __xmlKeepBlanksDefaultValue() -> *mut c_int {
1137    // SAFETY: returning a pointer to an exported static; the caller may
1138    // read/write it exactly as with upstream's deprecated accessor.
1139    unsafe { core::ptr::addr_of_mut!(xmlKeepBlanksDefaultValue) }
1140}
1141
1142/// Upstream `__xmlLineNumbersDefaultValue(void)` — returns a pointer to `xmlLineNumbersDefaultValue`.
1143#[no_mangle]
1144pub unsafe extern "C" fn __xmlLineNumbersDefaultValue() -> *mut c_int {
1145    // SAFETY: returning a pointer to an exported static; the caller may
1146    // read/write it exactly as with upstream's deprecated accessor.
1147    unsafe { core::ptr::addr_of_mut!(xmlLineNumbersDefaultValue) }
1148}
1149
1150/// Upstream `__xmlLoadExtDtdDefaultValue(void)` — returns a pointer to `xmlLoadExtDtdDefaultValue`.
1151#[no_mangle]
1152pub unsafe extern "C" fn __xmlLoadExtDtdDefaultValue() -> *mut c_int {
1153    // SAFETY: returning a pointer to an exported static; the caller may
1154    // read/write it exactly as with upstream's deprecated accessor.
1155    unsafe { core::ptr::addr_of_mut!(xmlLoadExtDtdDefaultValue) }
1156}
1157
1158/// Upstream `__xmlOutputBufferCreateFilenameValue(void)` — returns a pointer to `xmlOutputBufferCreateFilenameValue`.
1159#[no_mangle]
1160pub unsafe extern "C" fn __xmlOutputBufferCreateFilenameValue() -> *mut Option<
1161    unsafe extern "C" fn(
1162        *const c_char,
1163        crate::abi::structs::xmlCharEncodingHandlerPtr,
1164        c_int,
1165    ) -> *mut crate::abi::structs::_xmlOutputBuffer,
1166> {
1167    // SAFETY: returning a pointer to an exported static; the caller may
1168    // read/write it exactly as with upstream's deprecated accessor.
1169    unsafe { core::ptr::addr_of_mut!(xmlOutputBufferCreateFilenameValue) }
1170}
1171
1172/// Upstream `__xmlParserDebugEntities(void)` — returns a pointer to `xmlParserDebugEntities`.
1173#[no_mangle]
1174pub unsafe extern "C" fn __xmlParserDebugEntities() -> *mut c_int {
1175    // SAFETY: returning a pointer to an exported static; the caller may
1176    // read/write it exactly as with upstream's deprecated accessor.
1177    unsafe { core::ptr::addr_of_mut!(xmlParserDebugEntities) }
1178}
1179
1180/// Upstream `__xmlParserInputBufferCreateFilenameValue(void)` — returns a pointer to `xmlParserInputBufferCreateFilenameValue`.
1181#[no_mangle]
1182pub unsafe extern "C" fn __xmlParserInputBufferCreateFilenameValue() -> *mut Option<
1183    unsafe extern "C" fn(*const c_char, c_int) -> *mut crate::abi::structs::_xmlParserInputBuffer,
1184> {
1185    // SAFETY: returning a pointer to an exported static; the caller may
1186    // read/write it exactly as with upstream's deprecated accessor.
1187    unsafe { core::ptr::addr_of_mut!(xmlParserInputBufferCreateFilenameValue) }
1188}
1189
1190/// Upstream `__xmlParserVersion(void)` — returns a pointer to `xmlParserVersion`.
1191#[no_mangle]
1192pub unsafe extern "C" fn __xmlParserVersion() -> *mut *const c_char {
1193    // SAFETY: returning a pointer to an exported static; the caller may
1194    // read/write it exactly as with upstream's deprecated accessor.
1195    unsafe { core::ptr::addr_of_mut!(xmlParserVersion) }
1196}
1197
1198/// Upstream `__xmlPedanticParserDefaultValue(void)` — returns a pointer to `xmlPedanticParserDefaultValue`.
1199#[no_mangle]
1200pub unsafe extern "C" fn __xmlPedanticParserDefaultValue() -> *mut c_int {
1201    // SAFETY: returning a pointer to an exported static; the caller may
1202    // read/write it exactly as with upstream's deprecated accessor.
1203    unsafe { core::ptr::addr_of_mut!(xmlPedanticParserDefaultValue) }
1204}
1205
1206/// Upstream `__xmlRegisterNodeDefaultValue(void)` — returns a pointer to `xmlRegisterNodeDefaultValue`.
1207#[no_mangle]
1208pub unsafe extern "C" fn __xmlRegisterNodeDefaultValue(
1209) -> *mut Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
1210    // SAFETY: returning a pointer to an exported static; the caller may
1211    // read/write it exactly as with upstream's deprecated accessor.
1212    unsafe { core::ptr::addr_of_mut!(xmlRegisterNodeDefaultValue) }
1213}
1214
1215/// Upstream `__xmlStructuredError(void)` — returns a pointer to `xmlStructuredError`.
1216#[no_mangle]
1217pub unsafe extern "C" fn __xmlStructuredError() -> *mut Option<xmlStructuredErrorFunc> {
1218    // SAFETY: returning a pointer to an exported static; the caller may
1219    // read/write it exactly as with upstream's deprecated accessor.
1220    unsafe { core::ptr::addr_of_mut!(xmlStructuredError) }
1221}
1222
1223/// Upstream `__xmlStructuredErrorContext(void)` — returns a pointer to `xmlStructuredErrorContext`.
1224#[no_mangle]
1225pub unsafe extern "C" fn __xmlStructuredErrorContext() -> *mut *mut c_void {
1226    // SAFETY: returning a pointer to an exported static; the caller may
1227    // read/write it exactly as with upstream's deprecated accessor.
1228    unsafe { core::ptr::addr_of_mut!(xmlStructuredErrorContext) }
1229}
1230
1231/// Upstream `__xmlSubstituteEntitiesDefaultValue(void)` — returns a pointer to `xmlSubstituteEntitiesDefaultValue`.
1232#[no_mangle]
1233pub unsafe extern "C" fn __xmlSubstituteEntitiesDefaultValue() -> *mut c_int {
1234    // SAFETY: returning a pointer to an exported static; the caller may
1235    // read/write it exactly as with upstream's deprecated accessor.
1236    unsafe { core::ptr::addr_of_mut!(xmlSubstituteEntitiesDefaultValue) }
1237}