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;
23use std::os::raw::c_int;
24
25use crate::abi::callbacks::{xmlGenericErrorFunc, xmlStructuredErrorFunc};
26use crate::abi::types::xmlChar;
27
28// ═══════════════════════════════════════════════════════════════════════════════
29// Parser defaults (upstream globals.c)
30// ═══════════════════════════════════════════════════════════════════════════════
31
32/// `int xmlDoValidityCheckingDefaultValue` (default 0)
33#[no_mangle]
34pub static mut xmlDoValidityCheckingDefaultValue: c_int = 0;
35
36/// `int xmlGetWarningsDefaultValue` (default 1)
37#[no_mangle]
38pub static mut xmlGetWarningsDefaultValue: c_int = 1;
39
40/// `int xmlLoadExtDtdDefaultValue` (default 0)
41#[no_mangle]
42pub static mut xmlLoadExtDtdDefaultValue: c_int = 0;
43
44/// `int xmlPedanticParserDefaultValue` (default 0)
45#[no_mangle]
46pub static mut xmlPedanticParserDefaultValue: c_int = 0;
47
48/// `int xmlLineNumbersDefaultValue` (default 0)
49#[no_mangle]
50pub static mut xmlLineNumbersDefaultValue: c_int = 0;
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 0)
65#[no_mangle]
66pub static mut xmlIndentTreeOutput: c_int = 0;
67
68/// `const xmlChar *xmlTreeIndentString` (default NULL)
69#[no_mangle]
70pub static mut xmlTreeIndentString: *const xmlChar = core::ptr::null();
71
72/// `int xmlSaveNoEmptyTags` (default 0)
73#[no_mangle]
74pub static mut xmlSaveNoEmptyTags: c_int = 0;
75
76/// `xmlRegisterNodeFunc xmlRegisterNodeDefaultValue` (default NULL)
77#[no_mangle]
78pub static mut xmlRegisterNodeDefaultValue: Option<
79    unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode),
80> = None;
81
82/// `xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue` (default NULL)
83#[no_mangle]
84pub static mut xmlDeregisterNodeDefaultValue: Option<
85    unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode),
86> = None;
87
88/// `const char *xmlParserVersion` (default "21503" — upstream LIBXML_VERSION_STRING)
89///
90/// SAFETY: the pointed-to string is a static, immutable, null-terminated
91/// literal; `static mut` is used because C raw pointers are not `Sync`.
92/// Reads/writes of the pointer itself are racy only if C code mutates it
93/// (upstream treats it as a constant).
94#[no_mangle]
95pub static mut xmlParserVersion: *const c_char = {
96    const S: &[u8] = b"21503\0";
97    S.as_ptr() as *const c_char
98};
99
100/// `int xmlParserMaxDepth` (default 256)
101#[no_mangle]
102pub static mut xmlParserMaxDepth: c_int = 256;
103
104// ═══════════════════════════════════════════════════════════════════════════════
105// Buffer globals (upstream tree.h / xmlIO.c)
106// ═══════════════════════════════════════════════════════════════════════════════
107
108/// `int xmlDefaultBufferSize` (default 4096)
109#[no_mangle]
110pub static mut xmlDefaultBufferSize: c_int = 4096;
111
112/// `xmlBufferAllocationScheme xmlBufferAllocScheme` (default XML_BUFFER_ALLOC_EXACT = 0)
113#[no_mangle]
114pub static mut xmlBufferAllocScheme: c_int = 0;
115
116// ═══════════════════════════════════════════════════════════════════════════════
117// Error callback globals (upstream xmlerror.h)
118// ═══════════════════════════════════════════════════════════════════════════════
119
120/// `xmlGenericErrorFunc xmlGenericError` — the generic error callback.
121#[no_mangle]
122pub static mut xmlGenericError: Option<xmlGenericErrorFunc> = None;
123
124/// `void *xmlGenericErrorContext` — context for the generic error callback.
125#[no_mangle]
126pub static mut xmlGenericErrorContext: *mut c_void = core::ptr::null_mut();
127
128/// `xmlStructuredErrorFunc xmlStructuredError` — the structured error callback.
129#[no_mangle]
130pub static mut xmlStructuredError: Option<xmlStructuredErrorFunc> = None;
131
132/// `void *xmlStructuredErrorContext` — context for the structured callback.
133#[no_mangle]
134pub static mut xmlStructuredErrorContext: *mut c_void = core::ptr::null_mut();
135
136// ═══════════════════════════════════════════════════════════════════════════════
137// Static strings (upstream xmlstring.h / tree.c)
138// ═══════════════════════════════════════════════════════════════════════════════
139
140/// `const xmlChar xmlStringText[]` — "text"
141#[no_mangle]
142pub static xmlStringText: [xmlChar; 5] = [b't', b'e', b'x', b't', 0];
143
144/// `const xmlChar xmlStringTextNoenc[]` — "textnoenc"
145#[no_mangle]
146pub static xmlStringTextNoenc: [xmlChar; 9] =
147    [b't', b'e', b'x', b't', b'n', b'o', b'e', b'n', b'c'];
148
149/// `const xmlChar xmlStringComment[]` — "comment"
150#[no_mangle]
151pub static xmlStringComment: [xmlChar; 8] = [b'c', b'o', b'm', b'm', b'e', b'n', b't', 0];
152
153// ═══════════════════════════════════════════════════════════════════════════════
154// XPath numeric constants (upstream xpath.c)
155// ═══════════════════════════════════════════════════════════════════════════════
156
157/// `double xmlXPathNAN` — NaN
158#[no_mangle]
159pub static xmlXPathNAN: f64 = f64::NAN;
160
161/// `double xmlXPathPINF` — +infinity
162#[no_mangle]
163pub static xmlXPathPINF: f64 = f64::INFINITY;
164
165/// `double xmlXPathNINF` — -infinity
166#[no_mangle]
167pub static xmlXPathNINF: f64 = f64::NEG_INFINITY;
168
169// ═══════════════════════════════════════════════════════════════════════════════
170// libxslt globals (upstream xslt.c / xsltutils.c / documents.c / xslt.h)
171// ═══════════════════════════════════════════════════════════════════════════════
172// xsltMaxDepth / xsltMaxVars are exported from src/xslt/transform/mod.rs
173// (they are read by the transform engine).
174
175/// `const int xsltLibxmlVersion` = LIBXML_VERSION (21503) — the libxml2
176/// version libxslt was built against (upstream xslt.c).
177#[no_mangle]
178pub static xsltLibxmlVersion: c_int = 21503;
179
180/// `xmlGenericErrorFunc xsltGenericError` — the libxslt error callback.
181/// Upstream defaults to `xsltGenericErrorDefaultFunc` (a variadic stderr
182/// printer); the candidate defaults to NULL and the XSLT error paths fall
183/// back to the generic error handler — documented safe divergence
184/// (residual R-000135), since stable Rust cannot define variadic extern
185/// functions.
186#[no_mangle]
187pub static mut xsltGenericError: Option<xmlGenericErrorFunc> = None;
188
189/// `void *xsltGenericErrorContext` (default NULL)
190#[no_mangle]
191pub static mut xsltGenericErrorContext: *mut c_void = core::ptr::null_mut();
192
193/// `void *xsltGenericDebugContext` (default NULL)
194#[no_mangle]
195pub static mut xsltGenericDebugContext: *mut c_void = core::ptr::null_mut();
196
197/// `const xmlChar xsltExtMarker[]` — empty string used to mark extension
198/// nodes (upstream transform.c).
199#[no_mangle]
200pub static xsltExtMarker: [xmlChar; 1] = [0];
201
202/// `xsltDocLoaderFunc xsltDocDefaultLoader` — the document loader callback.
203/// Upstream defaults to `xsltDocDefaultLoaderFunc`; the candidate defaults
204/// to NULL and its internal loader path is used — documented safe
205/// divergence (residual R-000135).
206#[no_mangle]
207pub static mut xsltDocDefaultLoader: Option<
208    unsafe extern "C" fn(
209        *const xmlChar,
210        *mut c_void,
211        c_int,
212        *mut crate::abi::structs::_xsltStylesheet,
213        *mut crate::abi::structs::_xsltTransformContext,
214    ) -> *mut crate::abi::structs::_xmlDoc,
215> = None;
216
217// ═══════════════════════════════════════════════════════════════════════════════
218// I/O filename callback globals (upstream xmlIO.h)
219// ═══════════════════════════════════════════════════════════════════════════════
220
221/// `xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValue`
222#[no_mangle]
223pub static mut xmlParserInputBufferCreateFilenameValue: Option<
224    unsafe extern "C" fn(*const c_char, c_int) -> *mut crate::abi::structs::_xmlParserInputBuffer,
225> = None;
226
227/// `xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValue`
228#[no_mangle]
229pub static mut xmlOutputBufferCreateFilenameValue: Option<
230    unsafe extern "C" fn(
231        *const c_char,
232        crate::abi::structs::xmlCharEncodingHandlerPtr,
233        c_int,
234    ) -> *mut crate::abi::structs::_xmlOutputBuffer,
235> = None;
236
237// ═══════════════════════════════════════════════════════════════════════════════
238// Default SAX v1 handler structs + locator (upstream globals.c 2.15.3)
239// ═══════════════════════════════════════════════════════════════════════════════
240//
241// `const xmlSAXHandlerV1 xmlDefaultSAXHandler` and `htmlDefaultSAXHandler`
242// (parser.h / HTMLparser.h), plus `const xmlSAXLocator xmlDefaultSAXLocator`.
243// The handler instances reproduce the upstream initializer lists exactly
244// (globals.c); every referenced xmlSAX2* entry point is a real candidate
245// export.
246
247/// `const xmlSAXHandlerV1 xmlDefaultSAXHandler` (globals.c 2.15.3).
248#[no_mangle]
249pub static xmlDefaultSAXHandler: crate::abi::structs::_xmlSAXHandlerV1 =
250    crate::abi::structs::_xmlSAXHandlerV1 {
251        internalSubset: Some(crate::abi::exports_xml2::xmlSAX2InternalSubset),
252        isStandalone: Some(crate::abi::exports_xml2::xmlSAX2IsStandalone),
253        hasInternalSubset: Some(crate::abi::exports_xml2::xmlSAX2HasInternalSubset),
254        hasExternalSubset: Some(crate::abi::exports_xml2::xmlSAX2HasExternalSubset),
255        resolveEntity: Some(crate::abi::exports_xml2::xmlSAX2ResolveEntity),
256        getEntity: Some(crate::abi::exports_xml2::xmlSAX2GetEntity),
257        entityDecl: Some(crate::abi::exports_xml2::xmlSAX2EntityDecl),
258        notationDecl: Some(crate::abi::exports_xml2::xmlSAX2NotationDecl),
259        attributeDecl: Some(crate::abi::exports_xml2::xmlSAX2AttributeDecl),
260        elementDecl: Some(crate::abi::exports_xml2::xmlSAX2ElementDecl),
261        unparsedEntityDecl: Some(crate::abi::exports_xml2::xmlSAX2UnparsedEntityDecl),
262        setDocumentLocator: Some(crate::abi::exports_xml2::xmlSAX2SetDocumentLocator),
263        startDocument: Some(crate::abi::exports_xml2::xmlSAX2StartDocument),
264        endDocument: Some(crate::abi::exports_xml2::xmlSAX2EndDocument),
265        startElement: Some(crate::abi::exports_xml2::xmlSAX2StartElement),
266        endElement: Some(crate::abi::exports_xml2::xmlSAX2EndElement),
267        reference: Some(crate::abi::exports_xml2::xmlSAX2Reference),
268        characters: Some(crate::abi::exports_xml2::xmlSAX2Characters),
269        ignorableWhitespace: Some(crate::abi::exports_xml2::xmlSAX2IgnorableWhitespace),
270        processingInstruction: Some(crate::abi::exports_xml2::xmlSAX2ProcessingInstruction),
271        comment: Some(crate::abi::exports_xml2::xmlSAX2Comment),
272        warning: Some(crate::xml::errors::xmlParserWarning),
273        error: Some(crate::xml::errors::xmlParserError),
274        fatalError: Some(crate::xml::errors::xmlParserError),
275        getParameterEntity: Some(crate::abi::exports_xml2::xmlSAX2GetParameterEntity),
276        cdataBlock: Some(crate::abi::exports_xml2::xmlSAX2CDataBlock),
277        externalSubset: Some(crate::abi::exports_xml2::xmlSAX2ExternalSubset),
278        initialized: 1,
279    };
280
281/// `const xmlSAXHandlerV1 htmlDefaultSAXHandler` (globals.c 2.15.3).
282#[no_mangle]
283pub static htmlDefaultSAXHandler: crate::abi::structs::_xmlSAXHandlerV1 =
284    crate::abi::structs::_xmlSAXHandlerV1 {
285        internalSubset: Some(crate::abi::exports_xml2::xmlSAX2InternalSubset),
286        isStandalone: None,
287        hasInternalSubset: None,
288        hasExternalSubset: None,
289        resolveEntity: None,
290        getEntity: Some(crate::abi::exports_xml2::xmlSAX2GetEntity),
291        entityDecl: None,
292        notationDecl: None,
293        attributeDecl: None,
294        elementDecl: None,
295        unparsedEntityDecl: None,
296        setDocumentLocator: Some(crate::abi::exports_xml2::xmlSAX2SetDocumentLocator),
297        startDocument: Some(crate::abi::exports_xml2::xmlSAX2StartDocument),
298        endDocument: Some(crate::abi::exports_xml2::xmlSAX2EndDocument),
299        startElement: Some(crate::abi::exports_xml2::xmlSAX2StartElement),
300        endElement: Some(crate::abi::exports_xml2::xmlSAX2EndElement),
301        reference: None,
302        characters: Some(crate::abi::exports_xml2::xmlSAX2Characters),
303        ignorableWhitespace: Some(crate::abi::exports_xml2::xmlSAX2IgnorableWhitespace),
304        processingInstruction: Some(crate::abi::exports_xml2::xmlSAX2ProcessingInstruction),
305        comment: Some(crate::abi::exports_xml2::xmlSAX2Comment),
306        warning: Some(crate::xml::errors::xmlParserWarning),
307        error: Some(crate::xml::errors::xmlParserError),
308        fatalError: Some(crate::xml::errors::xmlParserError),
309        getParameterEntity: None,
310        cdataBlock: Some(crate::abi::exports_xml2::xmlSAX2CDataBlock),
311        externalSubset: None,
312        initialized: 1,
313    };
314
315/// `const xmlSAXLocator xmlDefaultSAXLocator` (globals.c 2.15.3).
316#[no_mangle]
317pub static xmlDefaultSAXLocator: crate::abi::callbacks::_xmlSAXLocator =
318    crate::abi::callbacks::_xmlSAXLocator {
319        getPublicId: Some(crate::abi::exports_xml2::xmlSAX2GetPublicId),
320        getSystemId: Some(crate::abi::exports_xml2::xmlSAX2GetSystemId),
321        getLineNumber: Some(crate::abi::exports_xml2::xmlSAX2GetLineNumber),
322        getColumnNumber: Some(crate::abi::exports_xml2::xmlSAX2GetColumnNumber),
323    };
324
325// ═══════════════════════════════════════════════════════════════════════════════
326// xmlLastError — the exported C global mirror of the thread-local error state
327// ═══════════════════════════════════════════════════════════════════════════════
328//
329// Upstream `XMLPUBVAR xmlError xmlLastError` (xmlerror.h). The candidate's
330// internal error state is thread-local (safe divergence, more correct than
331// upstream's racy global); this mirror is deep-copied on every error raise
332// and freed on reset, so C consumers observe upstream-equivalent lifetime
333// semantics. Residual R-000135.
334
335/// `xmlError xmlLastError` — most recent error (mirror).
336#[no_mangle]
337pub static mut xmlLastError: crate::abi::structs::_xmlError = crate::abi::structs::_xmlError {
338    domain: 0,
339    code: 0,
340    message: core::ptr::null_mut(),
341    level: 0,
342    file: core::ptr::null_mut(),
343    line: 0,
344    str1: core::ptr::null_mut(),
345    str2: core::ptr::null_mut(),
346    str3: core::ptr::null_mut(),
347    int1: 0,
348    int2: 0,
349    ctxt: core::ptr::null_mut(),
350    node: core::ptr::null_mut(),
351};
352
353/// Deep-copy `err` into the exported `xmlLastError` global.
354///
355/// The string fields are copied with `libc::malloc`/`memcpy` so the mirror
356/// owns them (previous mirror strings are freed first — upstream
357/// xmlResetError semantics).
358///
359/// # SAFETY
360///
361/// - `err` must point to a valid `_xmlError` whose string fields are
362///   NUL-terminated or NULL.
363pub unsafe fn sync_xml_last_error(err: *const crate::abi::structs::_xmlError) {
364    if err.is_null() {
365        return;
366    }
367    unsafe {
368        reset_xml_last_error();
369        let src = &*err;
370        let dst = core::ptr::addr_of_mut!(xmlLastError);
371        (*dst).domain = src.domain;
372        (*dst).code = src.code;
373        (*dst).level = src.level;
374        (*dst).line = src.line;
375        (*dst).int1 = src.int1;
376        (*dst).int2 = src.int2;
377        (*dst).ctxt = src.ctxt;
378        (*dst).node = src.node;
379        (*dst).message = dup_cstr(src.message as *const u8);
380        (*dst).file = dup_cstr(src.file as *const u8);
381        (*dst).str1 = dup_cstr(src.str1 as *const u8);
382        (*dst).str2 = dup_cstr(src.str2 as *const u8);
383        (*dst).str3 = dup_cstr(src.str3 as *const u8);
384    }
385}
386
387/// Reset the exported `xmlLastError` global, freeing owned strings
388/// (upstream xmlResetError).
389///
390/// # SAFETY
391///
392/// Only call while no other thread is reading the global (upstream has the
393/// same race; documented).
394pub unsafe fn reset_xml_last_error() {
395    unsafe {
396        let dst = core::ptr::addr_of_mut!(xmlLastError);
397        if !(*dst).message.is_null() {
398            libc::free((*dst).message as *mut libc::c_void);
399        }
400        if !(*dst).file.is_null() {
401            libc::free((*dst).file as *mut libc::c_void);
402        }
403        if !(*dst).str1.is_null() {
404            libc::free((*dst).str1 as *mut libc::c_void);
405        }
406        if !(*dst).str2.is_null() {
407            libc::free((*dst).str2 as *mut libc::c_void);
408        }
409        if !(*dst).str3.is_null() {
410            libc::free((*dst).str3 as *mut libc::c_void);
411        }
412        *dst = crate::abi::structs::_xmlError {
413            domain: 0,
414            code: 0,
415            message: core::ptr::null_mut(),
416            level: 0,
417            file: core::ptr::null_mut(),
418            line: 0,
419            str1: core::ptr::null_mut(),
420            str2: core::ptr::null_mut(),
421            str3: core::ptr::null_mut(),
422            int1: 0,
423            int2: 0,
424            ctxt: core::ptr::null_mut(),
425            node: core::ptr::null_mut(),
426        };
427    }
428}
429
430/// Heap-copy a NUL-terminated string (NULL-safe).
431unsafe fn dup_cstr(s: *const u8) -> *mut c_char {
432    if s.is_null() {
433        return core::ptr::null_mut();
434    }
435    unsafe {
436        let len = libc::strlen(s as *const libc::c_char) as usize;
437        let p = libc::malloc(len + 1) as *mut u8;
438        if p.is_null() {
439            return core::ptr::null_mut();
440        }
441        libc::memcpy(p as *mut libc::c_void, s as *const libc::c_void, len + 1);
442        p as *mut c_char
443    }
444}
445
446// ═══════════════════════════════════════════════════════════════════════════════
447// Default accessor functions (upstream parser.h / tree.h / xmlsave.h)
448// ═══════════════════════════════════════════════════════════════════════════════
449//
450// The deprecated `xmlXxxDefault(v)` accessors set the corresponding global
451// when `v != 0` and return the (new) value — upstream semantics (they
452// predate the plain globals; the modern behavior is conditional-set-and-
453// return, see upstream globals.c / parser.c).
454
455/// Upstream `xmlKeepBlanksDefault(int v)`.
456#[no_mangle]
457pub unsafe extern "C" fn xmlKeepBlanksDefault(v: c_int) -> c_int {
458    unsafe {
459        if v != 0 {
460            xmlKeepBlanksDefaultValue = v;
461        }
462        xmlKeepBlanksDefaultValue
463    }
464}
465
466/// Upstream `xmlLineNumbersDefault(int v)`.
467#[no_mangle]
468pub unsafe extern "C" fn xmlLineNumbersDefault(v: c_int) -> c_int {
469    unsafe {
470        if v != 0 {
471            xmlLineNumbersDefaultValue = v;
472        }
473        xmlLineNumbersDefaultValue
474    }
475}
476
477/// Upstream `xmlSubstituteEntitiesDefault(int v)`.
478#[no_mangle]
479pub unsafe extern "C" fn xmlSubstituteEntitiesDefault(v: c_int) -> c_int {
480    unsafe {
481        if v != 0 {
482            xmlSubstituteEntitiesDefaultValue = v;
483        }
484        xmlSubstituteEntitiesDefaultValue
485    }
486}
487
488/// Upstream `xmlPedanticParserDefault(int v)`.
489#[no_mangle]
490pub unsafe extern "C" fn xmlPedanticParserDefault(v: c_int) -> c_int {
491    unsafe {
492        if v != 0 {
493            xmlPedanticParserDefaultValue = v;
494        }
495        xmlPedanticParserDefaultValue
496    }
497}
498
499/// Upstream `xmlDoValidityCheckingDefaultValue` accessor is the global
500/// itself; `xmlGetWarningsDefaultValue` likewise (no accessor functions
501/// exist for those in upstream 2.15).
502
503/// Upstream `xmlRegisterNodeDefault(xmlRegisterNodeFunc func)`.
504#[no_mangle]
505pub unsafe extern "C" fn xmlRegisterNodeDefault(
506    func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
507) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
508    unsafe {
509        if func.is_some() {
510            xmlRegisterNodeDefaultValue = func;
511        }
512        xmlRegisterNodeDefaultValue
513    }
514}
515
516/// Upstream `xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func)`.
517#[no_mangle]
518pub unsafe extern "C" fn xmlDeregisterNodeDefault(
519    func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
520) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
521    unsafe {
522        if func.is_some() {
523            xmlDeregisterNodeDefaultValue = func;
524        }
525        xmlDeregisterNodeDefaultValue
526    }
527}
528
529/// Upstream `__xmlIndentTreeOutput(void)` (parser.h) — returns a pointer to
530/// the `xmlIndentTreeOutput` global.
531#[no_mangle]
532pub unsafe extern "C" fn __xmlIndentTreeOutput() -> *mut c_int {
533    unsafe { core::ptr::addr_of_mut!(xmlIndentTreeOutput) }
534}
535
536/// Upstream `__xmlSaveNoEmptyTags(void)` (parser.h) — returns a pointer to
537/// the `xmlSaveNoEmptyTags` global.
538#[no_mangle]
539pub unsafe extern "C" fn __xmlSaveNoEmptyTags() -> *mut c_int {
540    unsafe { core::ptr::addr_of_mut!(xmlSaveNoEmptyTags) }
541}
542
543/// Upstream `__xmlTreeIndentString(void)` (parser.h) — returns a pointer to
544/// the `xmlTreeIndentString` global.
545#[no_mangle]
546pub unsafe extern "C" fn __xmlTreeIndentString() -> *mut *const xmlChar {
547    unsafe { core::ptr::addr_of_mut!(xmlTreeIndentString) }
548}
549
550// ═══════════════════════════════════════════════════════════════════════════════
551// xmlThrDef* accessors (upstream threads.c / globals.c)
552// ═══════════════════════════════════════════════════════════════════════════════
553//
554// The deprecated `xmlThrDef*` family reads/writes the public globals with
555// the upstream semantics: when `v != 0` the global is set, and the (new)
556// value is returned. In upstream these were thread-local definitions before
557// the globals became plain variables; the modern behavior is exactly this
558// conditional-set-and-return on the global (see upstream globals.c).
559
560/// Upstream `xmlThrDefDoValidityCheckingDefaultValue(int v)`.
561#[no_mangle]
562pub unsafe extern "C" fn xmlThrDefDoValidityCheckingDefaultValue(v: c_int) -> c_int {
563    unsafe {
564        if v != 0 {
565            xmlDoValidityCheckingDefaultValue = v;
566        }
567        xmlDoValidityCheckingDefaultValue
568    }
569}
570
571/// Upstream `xmlThrDefGetWarningsDefaultValue(int v)`.
572#[no_mangle]
573pub unsafe extern "C" fn xmlThrDefGetWarningsDefaultValue(v: c_int) -> c_int {
574    unsafe {
575        if v != 0 {
576            xmlGetWarningsDefaultValue = v;
577        }
578        xmlGetWarningsDefaultValue
579    }
580}
581
582/// Upstream `xmlThrDefLoadExtDtdDefaultValue(int v)`.
583#[no_mangle]
584pub unsafe extern "C" fn xmlThrDefLoadExtDtdDefaultValue(v: c_int) -> c_int {
585    unsafe {
586        if v != 0 {
587            xmlLoadExtDtdDefaultValue = v;
588        }
589        xmlLoadExtDtdDefaultValue
590    }
591}
592
593/// Upstream `xmlThrDefPedanticParserDefaultValue(int v)`.
594#[no_mangle]
595pub unsafe extern "C" fn xmlThrDefPedanticParserDefaultValue(v: c_int) -> c_int {
596    unsafe {
597        if v != 0 {
598            xmlPedanticParserDefaultValue = v;
599        }
600        xmlPedanticParserDefaultValue
601    }
602}
603
604/// Upstream `xmlThrDefLineNumbersDefaultValue(int v)`.
605#[no_mangle]
606pub unsafe extern "C" fn xmlThrDefLineNumbersDefaultValue(v: c_int) -> c_int {
607    unsafe {
608        if v != 0 {
609            xmlLineNumbersDefaultValue = v;
610        }
611        xmlLineNumbersDefaultValue
612    }
613}
614
615/// Upstream `xmlThrDefKeepBlanksDefaultValue(int v)`.
616#[no_mangle]
617pub unsafe extern "C" fn xmlThrDefKeepBlanksDefaultValue(v: c_int) -> c_int {
618    unsafe {
619        if v != 0 {
620            xmlKeepBlanksDefaultValue = v;
621        }
622        xmlKeepBlanksDefaultValue
623    }
624}
625
626/// Upstream `xmlThrDefSubstituteEntitiesDefaultValue(int v)`.
627#[no_mangle]
628pub unsafe extern "C" fn xmlThrDefSubstituteEntitiesDefaultValue(v: c_int) -> c_int {
629    unsafe {
630        if v != 0 {
631            xmlSubstituteEntitiesDefaultValue = v;
632        }
633        xmlSubstituteEntitiesDefaultValue
634    }
635}
636
637/// Upstream `xmlThrDefParserDebugEntities(int v)`.
638#[no_mangle]
639pub unsafe extern "C" fn xmlThrDefParserDebugEntities(v: c_int) -> c_int {
640    unsafe {
641        if v != 0 {
642            xmlParserDebugEntities = v;
643        }
644        xmlParserDebugEntities
645    }
646}
647
648/// Upstream `xmlThrDefIndentTreeOutput(int v)`.
649#[no_mangle]
650pub unsafe extern "C" fn xmlThrDefIndentTreeOutput(v: c_int) -> c_int {
651    unsafe {
652        if v != 0 {
653            xmlIndentTreeOutput = v;
654        }
655        xmlIndentTreeOutput
656    }
657}
658
659/// Upstream `xmlThrDefTreeIndentString(const char *v)` — sets the indent
660/// string when non-NULL and returns the current pointer.
661#[no_mangle]
662pub unsafe extern "C" fn xmlThrDefTreeIndentString(v: *const c_char) -> *const c_char {
663    unsafe {
664        if !v.is_null() {
665            xmlTreeIndentString = v as *const xmlChar;
666        }
667        xmlTreeIndentString as *const c_char
668    }
669}
670
671/// Upstream `xmlThrDefSaveNoEmptyTags(int v)`.
672#[no_mangle]
673pub unsafe extern "C" fn xmlThrDefSaveNoEmptyTags(v: c_int) -> c_int {
674    unsafe {
675        if v != 0 {
676            xmlSaveNoEmptyTags = v;
677        }
678        xmlSaveNoEmptyTags
679    }
680}
681
682/// Upstream `xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func)`.
683#[no_mangle]
684pub unsafe extern "C" fn xmlThrDefRegisterNodeDefault(
685    func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
686) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
687    unsafe {
688        if func.is_some() {
689            xmlRegisterNodeDefaultValue = func;
690        }
691        xmlRegisterNodeDefaultValue
692    }
693}
694
695/// Upstream `xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func)`.
696#[no_mangle]
697pub unsafe extern "C" fn xmlThrDefDeregisterNodeDefault(
698    func: Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)>,
699) -> Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
700    unsafe {
701        if func.is_some() {
702            xmlDeregisterNodeDefaultValue = func;
703        }
704        xmlDeregisterNodeDefaultValue
705    }
706}
707
708/// Upstream `xmlThrDefSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc func)`.
709#[no_mangle]
710pub unsafe extern "C" fn xmlThrDefSetGenericErrorFunc(
711    ctx: *mut c_void,
712    func: Option<xmlGenericErrorFunc>,
713) {
714    unsafe {
715        xmlGenericErrorContext = ctx;
716        xmlGenericError = func;
717    }
718}
719
720/// Upstream `xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc func)`.
721#[no_mangle]
722pub unsafe extern "C" fn xmlThrDefSetStructuredErrorFunc(
723    ctx: *mut c_void,
724    func: Option<xmlStructuredErrorFunc>,
725) {
726    unsafe {
727        xmlStructuredErrorContext = ctx;
728        xmlStructuredError = func;
729    }
730}
731
732/// Upstream `xmlThrDefDefaultBufferSize(int v)`.
733#[no_mangle]
734pub unsafe extern "C" fn xmlThrDefDefaultBufferSize(v: c_int) -> c_int {
735    unsafe {
736        if v != 0 {
737            xmlDefaultBufferSize = v;
738        }
739        xmlDefaultBufferSize
740    }
741}
742
743/// Upstream `xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v)`.
744#[no_mangle]
745pub unsafe extern "C" fn xmlThrDefBufferAllocScheme(v: c_int) -> c_int {
746    unsafe {
747        if v != 0 {
748            xmlBufferAllocScheme = v;
749        }
750        xmlBufferAllocScheme
751    }
752}
753
754/// Upstream `xmlThrDefParserInputBufferCreateFilenameDefault(...)`.
755#[no_mangle]
756pub unsafe extern "C" fn xmlThrDefParserInputBufferCreateFilenameDefault(
757    func: Option<
758        unsafe extern "C" fn(
759            *const c_char,
760            c_int,
761        ) -> *mut crate::abi::structs::_xmlParserInputBuffer,
762    >,
763) -> Option<
764    unsafe extern "C" fn(*const c_char, c_int) -> *mut crate::abi::structs::_xmlParserInputBuffer,
765> {
766    unsafe {
767        if func.is_some() {
768            xmlParserInputBufferCreateFilenameValue = func;
769        }
770        xmlParserInputBufferCreateFilenameValue
771    }
772}
773
774/// Upstream `xmlThrDefOutputBufferCreateFilenameDefault(...)`.
775#[no_mangle]
776pub unsafe extern "C" fn xmlThrDefOutputBufferCreateFilenameDefault(
777    func: Option<
778        unsafe extern "C" fn(
779            *const c_char,
780            crate::abi::structs::xmlCharEncodingHandlerPtr,
781            c_int,
782        ) -> *mut crate::abi::structs::_xmlOutputBuffer,
783    >,
784) -> Option<
785    unsafe extern "C" fn(
786        *const c_char,
787        crate::abi::structs::xmlCharEncodingHandlerPtr,
788        c_int,
789    ) -> *mut crate::abi::structs::_xmlOutputBuffer,
790> {
791    unsafe {
792        if func.is_some() {
793            xmlOutputBufferCreateFilenameValue = func;
794        }
795        xmlOutputBufferCreateFilenameValue
796    }
797}
798
799// ═══════════════════════════════════════════════════════════════════════════════
800// __xmlXxx() pointer accessors (upstream threads.c / globals.c)
801// ═══════════════════════════════════════════════════════════════════════════════
802// The deprecated thread-local API exports one `__xmlXxx(void)` accessor per
803// global; each returns a pointer to the global so callers can read/write it.
804
805/// Upstream `__xmlBufferAllocScheme(void)` — returns a pointer to `xmlBufferAllocScheme`.
806#[no_mangle]
807pub unsafe extern "C" fn __xmlBufferAllocScheme() -> *mut c_int {
808    // SAFETY: returning a pointer to an exported static; the caller may
809    // read/write it exactly as with upstream's deprecated accessor.
810    unsafe { core::ptr::addr_of_mut!(xmlBufferAllocScheme) }
811}
812
813/// Upstream `__xmlDefaultBufferSize(void)` — returns a pointer to `xmlDefaultBufferSize`.
814#[no_mangle]
815pub unsafe extern "C" fn __xmlDefaultBufferSize() -> *mut c_int {
816    // SAFETY: returning a pointer to an exported static; the caller may
817    // read/write it exactly as with upstream's deprecated accessor.
818    unsafe { core::ptr::addr_of_mut!(xmlDefaultBufferSize) }
819}
820
821/// Upstream `__xmlDeregisterNodeDefaultValue(void)` — returns a pointer to `xmlDeregisterNodeDefaultValue`.
822#[no_mangle]
823pub unsafe extern "C" fn __xmlDeregisterNodeDefaultValue(
824) -> *mut Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
825    // SAFETY: returning a pointer to an exported static; the caller may
826    // read/write it exactly as with upstream's deprecated accessor.
827    unsafe { core::ptr::addr_of_mut!(xmlDeregisterNodeDefaultValue) }
828}
829
830/// Upstream `__xmlDoValidityCheckingDefaultValue(void)` — returns a pointer to `xmlDoValidityCheckingDefaultValue`.
831#[no_mangle]
832pub unsafe extern "C" fn __xmlDoValidityCheckingDefaultValue() -> *mut c_int {
833    // SAFETY: returning a pointer to an exported static; the caller may
834    // read/write it exactly as with upstream's deprecated accessor.
835    unsafe { core::ptr::addr_of_mut!(xmlDoValidityCheckingDefaultValue) }
836}
837
838/// Upstream `__xmlGenericError(void)` — returns a pointer to `xmlGenericError`.
839#[no_mangle]
840pub unsafe extern "C" fn __xmlGenericError() -> *mut Option<xmlGenericErrorFunc> {
841    // SAFETY: returning a pointer to an exported static; the caller may
842    // read/write it exactly as with upstream's deprecated accessor.
843    unsafe { core::ptr::addr_of_mut!(xmlGenericError) }
844}
845
846/// Upstream `__xmlGenericErrorContext(void)` — returns a pointer to `xmlGenericErrorContext`.
847#[no_mangle]
848pub unsafe extern "C" fn __xmlGenericErrorContext() -> *mut *mut c_void {
849    // SAFETY: returning a pointer to an exported static; the caller may
850    // read/write it exactly as with upstream's deprecated accessor.
851    unsafe { core::ptr::addr_of_mut!(xmlGenericErrorContext) }
852}
853
854/// Upstream `__xmlGetWarningsDefaultValue(void)` — returns a pointer to `xmlGetWarningsDefaultValue`.
855#[no_mangle]
856pub unsafe extern "C" fn __xmlGetWarningsDefaultValue() -> *mut c_int {
857    // SAFETY: returning a pointer to an exported static; the caller may
858    // read/write it exactly as with upstream's deprecated accessor.
859    unsafe { core::ptr::addr_of_mut!(xmlGetWarningsDefaultValue) }
860}
861
862/// Upstream `__xmlKeepBlanksDefaultValue(void)` — returns a pointer to `xmlKeepBlanksDefaultValue`.
863#[no_mangle]
864pub unsafe extern "C" fn __xmlKeepBlanksDefaultValue() -> *mut c_int {
865    // SAFETY: returning a pointer to an exported static; the caller may
866    // read/write it exactly as with upstream's deprecated accessor.
867    unsafe { core::ptr::addr_of_mut!(xmlKeepBlanksDefaultValue) }
868}
869
870/// Upstream `__xmlLineNumbersDefaultValue(void)` — returns a pointer to `xmlLineNumbersDefaultValue`.
871#[no_mangle]
872pub unsafe extern "C" fn __xmlLineNumbersDefaultValue() -> *mut c_int {
873    // SAFETY: returning a pointer to an exported static; the caller may
874    // read/write it exactly as with upstream's deprecated accessor.
875    unsafe { core::ptr::addr_of_mut!(xmlLineNumbersDefaultValue) }
876}
877
878/// Upstream `__xmlLoadExtDtdDefaultValue(void)` — returns a pointer to `xmlLoadExtDtdDefaultValue`.
879#[no_mangle]
880pub unsafe extern "C" fn __xmlLoadExtDtdDefaultValue() -> *mut c_int {
881    // SAFETY: returning a pointer to an exported static; the caller may
882    // read/write it exactly as with upstream's deprecated accessor.
883    unsafe { core::ptr::addr_of_mut!(xmlLoadExtDtdDefaultValue) }
884}
885
886/// Upstream `__xmlOutputBufferCreateFilenameValue(void)` — returns a pointer to `xmlOutputBufferCreateFilenameValue`.
887#[no_mangle]
888pub unsafe extern "C" fn __xmlOutputBufferCreateFilenameValue() -> *mut Option<
889    unsafe extern "C" fn(
890        *const c_char,
891        crate::abi::structs::xmlCharEncodingHandlerPtr,
892        c_int,
893    ) -> *mut crate::abi::structs::_xmlOutputBuffer,
894> {
895    // SAFETY: returning a pointer to an exported static; the caller may
896    // read/write it exactly as with upstream's deprecated accessor.
897    unsafe { core::ptr::addr_of_mut!(xmlOutputBufferCreateFilenameValue) }
898}
899
900/// Upstream `__xmlParserDebugEntities(void)` — returns a pointer to `xmlParserDebugEntities`.
901#[no_mangle]
902pub unsafe extern "C" fn __xmlParserDebugEntities() -> *mut c_int {
903    // SAFETY: returning a pointer to an exported static; the caller may
904    // read/write it exactly as with upstream's deprecated accessor.
905    unsafe { core::ptr::addr_of_mut!(xmlParserDebugEntities) }
906}
907
908/// Upstream `__xmlParserInputBufferCreateFilenameValue(void)` — returns a pointer to `xmlParserInputBufferCreateFilenameValue`.
909#[no_mangle]
910pub unsafe extern "C" fn __xmlParserInputBufferCreateFilenameValue() -> *mut Option<
911    unsafe extern "C" fn(*const c_char, c_int) -> *mut crate::abi::structs::_xmlParserInputBuffer,
912> {
913    // SAFETY: returning a pointer to an exported static; the caller may
914    // read/write it exactly as with upstream's deprecated accessor.
915    unsafe { core::ptr::addr_of_mut!(xmlParserInputBufferCreateFilenameValue) }
916}
917
918/// Upstream `__xmlParserVersion(void)` — returns a pointer to `xmlParserVersion`.
919#[no_mangle]
920pub unsafe extern "C" fn __xmlParserVersion() -> *mut *const c_char {
921    // SAFETY: returning a pointer to an exported static; the caller may
922    // read/write it exactly as with upstream's deprecated accessor.
923    unsafe { core::ptr::addr_of_mut!(xmlParserVersion) }
924}
925
926/// Upstream `__xmlPedanticParserDefaultValue(void)` — returns a pointer to `xmlPedanticParserDefaultValue`.
927#[no_mangle]
928pub unsafe extern "C" fn __xmlPedanticParserDefaultValue() -> *mut c_int {
929    // SAFETY: returning a pointer to an exported static; the caller may
930    // read/write it exactly as with upstream's deprecated accessor.
931    unsafe { core::ptr::addr_of_mut!(xmlPedanticParserDefaultValue) }
932}
933
934/// Upstream `__xmlRegisterNodeDefaultValue(void)` — returns a pointer to `xmlRegisterNodeDefaultValue`.
935#[no_mangle]
936pub unsafe extern "C" fn __xmlRegisterNodeDefaultValue(
937) -> *mut Option<unsafe extern "C" fn(*mut crate::abi::structs::_xmlNode)> {
938    // SAFETY: returning a pointer to an exported static; the caller may
939    // read/write it exactly as with upstream's deprecated accessor.
940    unsafe { core::ptr::addr_of_mut!(xmlRegisterNodeDefaultValue) }
941}
942
943/// Upstream `__xmlStructuredError(void)` — returns a pointer to `xmlStructuredError`.
944#[no_mangle]
945pub unsafe extern "C" fn __xmlStructuredError() -> *mut Option<xmlStructuredErrorFunc> {
946    // SAFETY: returning a pointer to an exported static; the caller may
947    // read/write it exactly as with upstream's deprecated accessor.
948    unsafe { core::ptr::addr_of_mut!(xmlStructuredError) }
949}
950
951/// Upstream `__xmlStructuredErrorContext(void)` — returns a pointer to `xmlStructuredErrorContext`.
952#[no_mangle]
953pub unsafe extern "C" fn __xmlStructuredErrorContext() -> *mut *mut c_void {
954    // SAFETY: returning a pointer to an exported static; the caller may
955    // read/write it exactly as with upstream's deprecated accessor.
956    unsafe { core::ptr::addr_of_mut!(xmlStructuredErrorContext) }
957}
958
959/// Upstream `__xmlSubstituteEntitiesDefaultValue(void)` — returns a pointer to `xmlSubstituteEntitiesDefaultValue`.
960#[no_mangle]
961pub unsafe extern "C" fn __xmlSubstituteEntitiesDefaultValue() -> *mut c_int {
962    // SAFETY: returning a pointer to an exported static; the caller may
963    // read/write it exactly as with upstream's deprecated accessor.
964    unsafe { core::ptr::addr_of_mut!(xmlSubstituteEntitiesDefaultValue) }
965}