libxml_rs/abi/exports_xml2.rs
1//! C ABI exports for libxml2.so.2 — no_mangle extern "C" functions (§1, §16).
2//!
3//! This module contains all `#[no_mangle] pub extern "C"` function definitions
4//! that form the public ABI of libxml2.so.2. Every function here corresponds to
5//! a function in the upstream libxml2 headers.
6//!
7//! # Phase 1 status
8//!
9//! Complete — all major ABI entry points are implemented. Functions that require
10//! modules not yet implemented (tree, parser, etc.) call into those modules,
11//! which will be filled in as Phase 1 continues.
12//!
13//! # Organization
14//!
15//! Exports are grouped by subsystem in the order they appear in upstream headers:
16//!
17//! 1. Initialization / Cleanup
18//! 2. Version
19//! 3. Memory / Allocator
20//! 4. Error handling
21//! 5. String utilities
22//! 6. Tree (document, node, attribute, namespace, DTD, entity)
23//! 7. Parser (SAX, DOM, push, reader)
24//! 8. I/O
25//! 9. Dictionary
26//! 10. Hash table
27//! 11. List
28//! 12. Buffer
29//! 13. Encoding
30//! 14. XPath
31//! 15. XInclude
32//! 16. Catalog
33//! 17. HTML
34//! 18. Debug/misc
35
36#![allow(non_snake_case)]
37#![allow(unused_variables)]
38#![allow(clippy::missing_safety_doc)]
39#![allow(clippy::not_unsafe_ptr_arg_deref)]
40
41use core::ffi::c_void;
42use core::ptr;
43use std::mem::size_of;
44use std::os::raw::{c_char, c_int, c_uint};
45
46use crate::abi::allocator::*;
47use crate::abi::callbacks::*;
48use crate::abi::ownership::*;
49use crate::abi::structs::*;
50use crate::abi::types::xmlAttributeType::XML_ATTRIBUTE_CDATA;
51use crate::abi::types::xmlElementType::*;
52use crate::abi::types::xmlErrorLevel::XML_ERR_NONE;
53use crate::abi::types::*;
54use crate::abi::versioning::*;
55
56// ═══════════════════════════════════════════════════════════════════════════════
57// 1. Initialization / Cleanup
58// ═══════════════════════════════════════════════════════════════════════════════
59
60/// Initialize the parser library.
61///
62/// Must be called before any other libxml2 functions.
63/// Safe to call multiple times (reference-counted in modern libxml2).
64///
65/// # UPSTREAM-PARITY
66///
67/// ```c
68/// void xmlInitParser(void);
69/// ```
70#[no_mangle]
71pub unsafe extern "C" fn xmlInitParser() {
72 crate::internal::globals::init_parser();
73}
74
75/// Clean up the parser library.
76///
77/// Should be called when the library is no longer needed.
78///
79/// # UPSTREAM-PARITY
80///
81/// ```c
82/// void xmlCleanupParser(void);
83/// ```
84#[no_mangle]
85pub unsafe extern "C" fn xmlCleanupParser() {
86 crate::internal::globals::cleanup_parser();
87}
88
89/// Initialize threading support.
90///
91/// # UPSTREAM-PARITY
92///
93/// ```c
94/// int xmlInitThreads(void);
95/// ```
96///
97/// Returns 0 on success.
98#[no_mangle]
99pub unsafe extern "C" fn xmlInitThreads() -> c_int {
100 crate::internal::globals::init_threads()
101}
102
103/// Clean up threading support.
104///
105/// # UPSTREAM-PARITY
106///
107/// ```c
108/// void xmlCleanupThreads(void);
109/// ```
110#[no_mangle]
111pub unsafe extern "C" fn xmlCleanupThreads() {
112 crate::xml::threads::cleanup_threads();
113}
114
115/// Check whether the library has been initialized.
116///
117/// # UPSTREAM-PARITY
118///
119/// ```c
120/// int xmlIsInitialized(void);
121/// ```
122#[no_mangle]
123pub extern "C" fn xmlIsInitialized() -> c_int {
124 if crate::abi::versioning::is_initialized() {
125 1
126 } else {
127 0
128 }
129}
130
131/// Initialize a set of threads (libxml2 compat).
132///
133/// # UPSTREAM-PARITY
134///
135/// ```c
136/// int xmlInitThreads(void);
137/// ```
138/// This is an alias.
139#[no_mangle]
140pub unsafe extern "C" fn xmlLockLibrary() {
141 crate::xml::threads::lock_library();
142}
143
144/// Unlock the library (libxml2 compat).
145///
146/// # UPSTREAM-PARITY
147///
148/// ```c
149/// void xmlUnlockLibrary(void);
150/// ```
151#[no_mangle]
152pub unsafe extern "C" fn xmlUnlockLibrary() {
153 crate::xml::threads::unlock_library();
154}
155
156// ═══════════════════════════════════════════════════════════════════════════════
157// 4. Error Handling
158// ═══════════════════════════════════════════════════════════════════════════════
159
160/// Set the generic error handler.
161///
162/// # UPSTREAM-PARITY
163///
164/// ```c
165/// void xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler);
166/// ```
167///
168/// # SAFETY
169///
170/// - `handler` must be a valid function pointer or NULL (to reset to default).
171/// - If non-NULL, the handler may be called at any time with `ctx`.
172#[no_mangle]
173pub unsafe extern "C" fn xmlSetGenericErrorFunc(
174 ctx: *mut c_void,
175 handler: Option<xmlGenericErrorFunc>,
176) {
177 // SAFETY: Delegates to xml::errors with same safety contract.
178 unsafe { crate::xml::errors::set_generic_error_func(ctx, handler) };
179}
180
181/// Set the structured error handler.
182///
183/// # UPSTREAM-PARITY
184///
185/// ```c
186/// void xmlSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler);
187/// ```
188///
189/// # SAFETY
190///
191/// - `handler` must be a valid function pointer or NULL.
192#[no_mangle]
193pub unsafe extern "C" fn xmlSetStructuredErrorFunc(
194 ctx: *mut c_void,
195 handler: Option<xmlStructuredErrorFunc>,
196) {
197 // SAFETY: Delegates to xml::errors with same safety contract.
198 unsafe { crate::xml::errors::set_structured_error_func(ctx, handler) };
199}
200
201/// Get the last error for the current thread.
202///
203/// # UPSTREAM-PARITY
204///
205/// ```c
206/// xmlErrorPtr xmlGetLastError(void);
207/// ```
208///
209/// Returns a pointer to the last error, or NULL if no error occurred.
210/// The returned pointer is valid until the next libxml2 call in this thread.
211#[no_mangle]
212pub extern "C" fn xmlGetLastError() -> *mut _xmlError {
213 crate::xml::errors::get_last_error()
214}
215
216/// Get a copy of the last error for the current thread.
217///
218/// # UPSTREAM-PARITY
219///
220/// ```c
221/// xmlErrorPtr xmlCopyError(xmlErrorPtr from, xmlErrorPtr to);
222/// ```
223///
224/// Copies `from` into `to`. Returns 0 on success, -1 on error.
225///
226/// # SAFETY
227///
228/// - `from` and `to` must be valid pointers to `_xmlError` structs, or NULL.
229#[no_mangle]
230pub unsafe extern "C" fn xmlCopyError(from: *const _xmlError, to: *mut _xmlError) -> c_int {
231 // SAFETY: Delegates to xml::errors with same safety contract.
232 unsafe { crate::xml::errors::copy_error(from, to) }
233}
234
235/// Reset an error structure.
236///
237/// # UPSTREAM-PARITY
238///
239/// ```c
240/// void xmlResetError(xmlErrorPtr err);
241/// ```
242///
243/// # SAFETY
244///
245/// - `err` must be a valid pointer to `_xmlError`, or NULL.
246#[no_mangle]
247pub unsafe extern "C" fn xmlResetError(err: *mut _xmlError) {
248 // SAFETY: Delegates to xml::errors with same safety contract.
249 unsafe { crate::xml::errors::reset_error(err) };
250}
251
252/// Raise a structured error.
253///
254/// This is called internally when an error occurs. It updates the last error
255/// and invokes the structured error handler if one is set.
256///
257/// # SAFETY
258///
259/// - `ctxt` may be NULL (context of the error).
260/// - `domain`, `code`, `level`: valid error codes.
261/// - `msg` must be a valid C string or NULL.
262/// - `file` must be a valid C string or NULL.
263/// - `str1`, `str2`, `str3`: error-related strings (may be NULL).
264#[no_mangle]
265pub unsafe extern "C" fn xmlRaiseError(
266 ctxt: *mut c_void,
267 ctxt2: *mut c_void,
268 ctxt3: *mut c_void,
269 ctxt4: *mut c_void,
270 ctxt5: *mut c_void,
271 domain: c_int,
272 code: c_int,
273 level: c_int,
274 file: *const c_char,
275 line: c_int,
276 str1: *const c_char,
277 str2: *const c_char,
278 str3: *const c_char,
279 int1: c_int,
280 int2: c_int,
281 msg: *const c_char,
282) {
283 // SAFETY: Delegates to xml::errors with same safety contract.
284 unsafe {
285 crate::xml::errors::raise_error(
286 ctxt, ctxt2, ctxt3, ctxt4, ctxt5, domain, code, level, file, line, str1, str2, str3,
287 int1, int2, msg,
288 );
289 }
290}
291
292/// Remove any error from the last error stack.
293///
294/// # UPSTREAM-PARITY
295///
296/// ```c
297/// void xmlResetLastError(void);
298/// ```
299#[no_mangle]
300pub extern "C" fn xmlResetLastError() {
301 crate::xml::errors::reset_last_error();
302}
303
304// ═══════════════════════════════════════════════════════════════════════════════
305// 5. String Utilities
306// ═══════════════════════════════════════════════════════════════════════════════
307
308/// Duplicate a string using xmlChar.
309///
310/// # UPSTREAM-PARITY
311///
312/// ```c
313/// xmlChar *xmlStrdup(const xmlChar *cur);
314/// ```
315///
316/// # SAFETY
317///
318/// - `cur` must be a valid null-terminated xmlChar string or NULL.
319#[no_mangle]
320pub unsafe extern "C" fn xmlStrdup(cur: *const xmlChar) -> *mut xmlChar {
321 if cur.is_null() {
322 return ptr::null_mut();
323 }
324 let len = unsafe { xmlStrlen(cur) };
325 let size = len + 1;
326 let new_ptr = unsafe { xmlMalloc(size as usize) };
327 if new_ptr.is_null() {
328 return ptr::null_mut();
329 }
330 unsafe {
331 ptr::copy_nonoverlapping(cur as *const u8, new_ptr as *mut u8, size as usize);
332 }
333 new_ptr as *mut xmlChar
334}
335
336/// Duplicate a substring.
337///
338/// # UPSTREAM-PARITY
339///
340/// ```c
341/// xmlChar *xmlStrndup(const xmlChar *cur, int len);
342/// ```
343///
344/// # SAFETY
345///
346/// - `cur` must be a valid pointer or NULL.
347#[no_mangle]
348pub unsafe extern "C" fn xmlStrndup(cur: *const xmlChar, len: c_int) -> *mut xmlChar {
349 if cur.is_null() || len <= 0 {
350 return ptr::null_mut();
351 }
352 let size = len as usize + 1;
353 let new_ptr = unsafe { xmlMalloc(size) };
354 if new_ptr.is_null() {
355 return ptr::null_mut();
356 }
357 unsafe {
358 ptr::copy_nonoverlapping(cur as *const u8, new_ptr as *mut u8, len as usize);
359 *(new_ptr.add(len as usize) as *mut u8) = 0;
360 }
361 new_ptr as *mut xmlChar
362}
363
364/// Get the length of an xmlChar string.
365///
366/// # UPSTREAM-PARITY
367///
368/// ```c
369/// int xmlStrlen(const xmlChar *str);
370/// ```
371///
372/// # SAFETY
373///
374/// - `str` must be a valid null-terminated string or NULL (returns 0).
375#[no_mangle]
376pub unsafe extern "C" fn xmlStrlen(str: *const xmlChar) -> c_int {
377 if str.is_null() {
378 return 0;
379 }
380 unsafe { libc::strlen(str as *const c_char) as c_int }
381}
382
383/// Compare two xmlChar strings.
384///
385/// # UPSTREAM-PARITY
386///
387/// ```c
388/// int xmlStrcmp(const xmlChar *str1, const xmlChar *str2);
389/// ```
390///
391/// Returns 0 if equal, <0 if str1 < str2, >0 if str1 > str2.
392/// NULL-safe: NULL sorts before any non-NULL string.
393#[no_mangle]
394pub unsafe extern "C" fn xmlStrcmp(str1: *const xmlChar, str2: *const xmlChar) -> c_int {
395 if str1.is_null() && str2.is_null() {
396 return 0;
397 }
398 if str1.is_null() {
399 return -1;
400 }
401 if str2.is_null() {
402 return 1;
403 }
404 unsafe { libc::strcmp(str1 as *const c_char, str2 as *const c_char) as c_int }
405}
406
407/// Compare two xmlChar strings up to a given length.
408///
409/// # UPSTREAM-PARITY
410///
411/// ```c
412/// int xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len);
413/// ```
414#[no_mangle]
415pub unsafe extern "C" fn xmlStrncmp(
416 str1: *const xmlChar,
417 str2: *const xmlChar,
418 len: c_int,
419) -> c_int {
420 if len <= 0 {
421 return 0;
422 }
423 if str1.is_null() && str2.is_null() {
424 return 0;
425 }
426 if str1.is_null() {
427 return -1;
428 }
429 if str2.is_null() {
430 return 1;
431 }
432 unsafe { libc::strncmp(str1 as *const c_char, str2 as *const c_char, len as usize) as c_int }
433}
434
435/// Case-insensitive comparison of two xmlChar strings.
436///
437/// # UPSTREAM-PARITY
438///
439/// ```c
440/// int xmlStrcasecmp(const xmlChar *str1, const xmlChar *str2);
441/// ```
442#[no_mangle]
443pub unsafe extern "C" fn xmlStrcasecmp(str1: *const xmlChar, str2: *const xmlChar) -> c_int {
444 if str1.is_null() && str2.is_null() {
445 return 0;
446 }
447 if str1.is_null() {
448 return -1;
449 }
450 if str2.is_null() {
451 return 1;
452 }
453 unsafe { libc::strcasecmp(str1 as *const c_char, str2 as *const c_char) as c_int }
454}
455
456/// Case-insensitive comparison with length limit.
457///
458/// # UPSTREAM-PARITY
459///
460/// ```c
461/// int xmlStrncasecmp(const xmlChar *str1, const xmlChar *str2, int len);
462/// ```
463#[no_mangle]
464pub unsafe extern "C" fn xmlStrncasecmp(
465 str1: *const xmlChar,
466 str2: *const xmlChar,
467 len: c_int,
468) -> c_int {
469 if len <= 0 {
470 return 0;
471 }
472 if str1.is_null() && str2.is_null() {
473 return 0;
474 }
475 if str1.is_null() {
476 return -1;
477 }
478 if str2.is_null() {
479 return 1;
480 }
481 unsafe {
482 libc::strncasecmp(str1 as *const c_char, str2 as *const c_char, len as usize) as c_int
483 }
484}
485
486/// Check if two xmlChar strings are equal.
487///
488/// # UPSTREAM-PARITY
489///
490/// ```c
491/// int xmlStrEqual(const xmlChar *str1, const xmlChar *str2);
492/// ```
493///
494/// Returns 1 if equal, 0 if not. NULL-safe.
495#[no_mangle]
496pub unsafe extern "C" fn xmlStrEqual(str1: *const xmlChar, str2: *const xmlChar) -> c_int {
497 if str1.is_null() && str2.is_null() {
498 return 1;
499 }
500 if str1.is_null() || str2.is_null() {
501 return 0;
502 }
503 unsafe { (libc::strcmp(str1 as *const c_char, str2 as *const c_char) == 0) as c_int }
504}
505
506/// Check if an xmlChar string equals a qualified name.
507///
508/// # UPSTREAM-PARITY
509///
510/// ```c
511/// int xmlStrQEqual(const xmlChar *pref, const xmlChar *name, const xmlChar *str);
512/// ```
513///
514/// Returns 1 if `pref:name` equals `str`, 0 otherwise.
515/// `pref` may be NULL (compares only name).
516#[no_mangle]
517pub unsafe extern "C" fn xmlStrQEqual(
518 pref: *const xmlChar,
519 name: *const xmlChar,
520 str: *const xmlChar,
521) -> c_int {
522 if name.is_null() || str.is_null() {
523 return 0;
524 }
525 if pref.is_null() {
526 return unsafe { xmlStrEqual(name, str) };
527 }
528 // Compare "pref:name" with str
529 let pref_len = unsafe { xmlStrlen(pref) };
530 let name_len = unsafe { xmlStrlen(name) };
531 let total_len = pref_len + 1 + name_len;
532 let str_len = unsafe { xmlStrlen(str) };
533 if total_len != str_len {
534 return 0;
535 }
536 // Compare prefix part
537 if unsafe {
538 libc::strncmp(
539 pref as *const c_char,
540 str as *const c_char,
541 pref_len as usize,
542 )
543 } != 0
544 {
545 return 0;
546 }
547 // Check colon
548 if unsafe { *str.add(pref_len as usize) } != b':' as xmlChar {
549 return 0;
550 }
551 // Compare name part
552 (unsafe {
553 libc::strncmp(
554 name as *const c_char,
555 str.add((pref_len + 1) as usize) as *const c_char,
556 name_len as usize,
557 ) == 0
558 }) as c_int
559}
560
561/// Concatenate two strings.
562///
563/// # UPSTREAM-PARITY
564///
565/// ```c
566/// xmlChar *xmlStrcat(xmlChar *cur, const xmlChar *add);
567/// ```
568///
569/// # SAFETY
570///
571/// - `cur` must be a valid xmlMalloc'd string or NULL.
572/// - `add` must be a valid string or NULL.
573/// - If `cur` is NULL, behaves like xmlStrdup(add).
574#[no_mangle]
575pub unsafe extern "C" fn xmlStrcat(cur: *mut xmlChar, add: *const xmlChar) -> *mut xmlChar {
576 if add.is_null() {
577 return cur;
578 }
579 if cur.is_null() {
580 return unsafe { xmlStrdup(add) };
581 }
582 let cur_len = unsafe { xmlStrlen(cur) } as usize;
583 let add_len = unsafe { xmlStrlen(add) } as usize;
584 let new_size = cur_len + add_len + 1;
585 let new_ptr = unsafe { xmlRealloc(cur as *mut c_void, new_size) };
586 if new_ptr.is_null() {
587 return ptr::null_mut();
588 }
589 unsafe {
590 ptr::copy_nonoverlapping(add as *const u8, (new_ptr as *mut u8).add(cur_len), add_len);
591 *((new_ptr as *mut u8).add(cur_len + add_len)) = 0;
592 }
593 new_ptr as *mut xmlChar
594}
595
596/// Concatenate up to `len` characters.
597///
598/// # UPSTREAM-PARITY
599///
600/// ```c
601/// xmlChar *xmlStrncat(xmlChar *cur, const xmlChar *add, int len);
602/// ```
603///
604/// # SAFETY
605///
606/// Same as xmlStrcat, but only copies up to `len` characters from `add`.
607#[no_mangle]
608pub unsafe extern "C" fn xmlStrncat(
609 cur: *mut xmlChar,
610 add: *const xmlChar,
611 len: c_int,
612) -> *mut xmlChar {
613 if add.is_null() || len <= 0 {
614 return cur;
615 }
616 let len = len as usize;
617 if cur.is_null() {
618 return unsafe { xmlStrndup(add, len as c_int) };
619 }
620 let cur_len = unsafe { xmlStrlen(cur) } as usize;
621 let new_size = cur_len + len + 1;
622 let new_ptr = unsafe { xmlRealloc(cur as *mut c_void, new_size) };
623 if new_ptr.is_null() {
624 return ptr::null_mut();
625 }
626 unsafe {
627 ptr::copy_nonoverlapping(add as *const u8, (new_ptr as *mut u8).add(cur_len), len);
628 *((new_ptr as *mut u8).add(cur_len + len)) = 0;
629 }
630 new_ptr as *mut xmlChar
631}
632
633/// Create a new string by concatenating up to `len` characters.
634///
635/// # UPSTREAM-PARITY
636///
637/// ```c
638/// xmlChar *xmlStrncatNew(const xmlChar *str1, const xmlChar *str2, int len);
639/// ```
640#[no_mangle]
641pub unsafe extern "C" fn xmlStrncatNew(
642 str1: *const xmlChar,
643 str2: *const xmlChar,
644 len: c_int,
645) -> *mut xmlChar {
646 let mut result: *mut xmlChar = ptr::null_mut();
647 if !str1.is_null() {
648 result = unsafe { xmlStrdup(str1) };
649 }
650 if !str2.is_null() && len > 0 {
651 result = unsafe { xmlStrncat(result, str2, len) };
652 }
653 result
654}
655
656/// Copy a string.
657///
658/// # UPSTREAM-PARITY
659///
660/// ```c
661/// xmlChar *xmlStrcpy(xmlChar *dst, const xmlChar *src);
662/// ```
663///
664/// # SAFETY
665///
666/// - `dst` must be a valid xmlMalloc'd buffer large enough to hold `src`.
667/// - `src` must be a valid string.
668#[no_mangle]
669pub unsafe extern "C" fn xmlStrcpy(dst: *mut xmlChar, src: *const xmlChar) -> *mut xmlChar {
670 if dst.is_null() || src.is_null() {
671 return dst;
672 }
673 let len = unsafe { xmlStrlen(src) } as usize + 1;
674 unsafe {
675 ptr::copy_nonoverlapping(src as *const u8, dst as *mut u8, len);
676 }
677 dst
678}
679
680/// Copy up to `len` characters.
681///
682/// # UPSTREAM-PARITY
683///
684/// ```c
685/// xmlChar *xmlStrncpy(xmlChar *dst, const xmlChar *src, int len);
686/// ```
687#[no_mangle]
688pub unsafe extern "C" fn xmlStrncpy(
689 dst: *mut xmlChar,
690 src: *const xmlChar,
691 len: c_int,
692) -> *mut xmlChar {
693 if dst.is_null() || src.is_null() || len <= 0 {
694 return dst;
695 }
696 let len = len as usize;
697 let src_len = unsafe { xmlStrlen(src) } as usize;
698 let copy_len = if src_len < len { src_len } else { len - 1 };
699 unsafe {
700 ptr::copy_nonoverlapping(src as *const u8, dst as *mut u8, copy_len);
701 *dst.add(copy_len) = 0;
702 }
703 dst
704}
705
706/// Extract a substring.
707///
708/// # UPSTREAM-PARITY
709///
710/// ```c
711/// xmlChar *xmlStrsub(const xmlChar *str, int start, int len);
712/// ```
713///
714/// Returns a newly allocated substring, or NULL on error.
715#[no_mangle]
716pub unsafe extern "C" fn xmlStrsub(str: *const xmlChar, start: c_int, len: c_int) -> *mut xmlChar {
717 if str.is_null() || start < 0 || len < 0 {
718 return ptr::null_mut();
719 }
720 let str_len = unsafe { xmlStrlen(str) };
721 if start >= str_len {
722 return unsafe { xmlStrdup(b"\0" as *const u8 as *const xmlChar) };
723 }
724 let actual_len = if start + len > str_len {
725 str_len - start
726 } else {
727 len
728 };
729 unsafe { xmlStrndup(str.add(start as usize), actual_len) }
730}
731
732// ═══════════════════════════════════════════════════════════════════════════════
733// 6. Tree — Document, Node, Attribute, Namespace, DTD, Entity
734// ═══════════════════════════════════════════════════════════════════════════════
735
736/// Create a new document.
737///
738/// # UPSTREAM-PARITY
739///
740/// ```c
741/// xmlDocPtr xmlNewDoc(const xmlChar *version);
742/// ```
743///
744/// # SAFETY
745///
746/// - `version` must be a valid string or NULL (defaults to "1.0").
747/// - Returns a newly allocated document. Caller must free with `xmlFreeDoc`.
748#[no_mangle]
749pub unsafe extern "C" fn xmlNewDoc(version: *const xmlChar) -> *mut _xmlDoc {
750 crate::xml::tree::new_doc(version)
751}
752
753/// Free a document.
754///
755/// # UPSTREAM-PARITY
756///
757/// ```c
758/// void xmlFreeDoc(xmlDocPtr doc);
759/// ```
760///
761/// # SAFETY
762///
763/// - `doc` must be a valid document pointer or NULL.
764#[no_mangle]
765pub unsafe extern "C" fn xmlFreeDoc(doc: *mut _xmlDoc) {
766 crate::xml::tree::free_doc(doc);
767}
768
769/// Create a new node.
770///
771/// # UPSTREAM-PARITY
772///
773/// ```c
774/// xmlNodePtr xmlNewNode(xmlNsPtr ns, const xmlChar *name);
775/// ```
776///
777/// # SAFETY
778///
779/// - `ns` may be NULL.
780/// - `name` must be a valid string.
781/// - Returns a newly allocated node. Caller must free with `xmlFreeNode`.
782#[no_mangle]
783pub unsafe extern "C" fn xmlNewNode(ns: *mut _xmlNs, name: *const xmlChar) -> *mut _xmlNode {
784 crate::xml::tree::new_node(ns, name)
785}
786
787/// Free a node.
788///
789/// # UPSTREAM-PARITY
790///
791/// ```c
792/// void xmlFreeNode(xmlNodePtr node);
793/// ```
794///
795/// # SAFETY
796///
797/// - `node` must be a valid node pointer or NULL.
798/// - The node must NOT be part of a document tree (must be unlinked first).
799#[no_mangle]
800pub unsafe extern "C" fn xmlFreeNode(node: *mut _xmlNode) {
801 crate::xml::tree::free_node(node);
802}
803
804/// Unlink a node from its tree.
805///
806/// # UPSTREAM-PARITY
807///
808/// ```c
809/// void xmlUnlinkNode(xmlNodePtr node);
810/// ```
811///
812/// # SAFETY
813///
814/// - `node` must be a valid node pointer or NULL.
815#[no_mangle]
816pub unsafe extern "C" fn xmlUnlinkNode(node: *mut _xmlNode) {
817 crate::xml::tree::unlink_node(node);
818}
819
820/// Add a child node.
821///
822/// # UPSTREAM-PARITY
823///
824/// ```c
825/// xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur);
826/// ```
827///
828/// # SAFETY
829///
830/// - `parent` must be a valid node.
831/// - `cur` must be a valid node (ownership transfers to parent).
832/// - Returns pointer to the added child (borrowed).
833#[no_mangle]
834pub unsafe extern "C" fn xmlAddChild(parent: *mut _xmlNode, cur: *mut _xmlNode) -> *mut _xmlNode {
835 crate::xml::tree::add_child(parent, cur)
836}
837
838/// Add a sibling node.
839///
840/// # UPSTREAM-PARITY
841///
842/// ```c
843/// xmlNodePtr xmlAddSibling(xmlNodePtr cur, xmlNodePtr sibling);
844/// ```
845///
846/// # SAFETY
847///
848/// Same as xmlAddChild, but adds after `cur` instead of as a child.
849#[no_mangle]
850pub unsafe extern "C" fn xmlAddSibling(
851 cur: *mut _xmlNode,
852 sibling: *mut _xmlNode,
853) -> *mut _xmlNode {
854 crate::xml::tree::add_sibling(cur, sibling)
855}
856
857/// Create a new child element.
858///
859/// # UPSTREAM-PARITY
860///
861/// ```c
862/// xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
863/// const xmlChar *name, const xmlChar *content);
864/// ```
865///
866/// Creates a new element node, adds it as a child of `parent`, and
867/// sets its content if `content` is non-NULL.
868///
869/// # SAFETY
870///
871/// - `parent` must be a valid node (may be NULL).
872/// - `ns` may be NULL.
873/// - `name` must be a valid string.
874/// - Returns a newly allocated node (owned by parent).
875#[no_mangle]
876pub unsafe extern "C" fn xmlNewChild(
877 parent: *mut _xmlNode,
878 ns: *mut _xmlNs,
879 name: *const xmlChar,
880 content: *const xmlChar,
881) -> *mut _xmlNode {
882 crate::xml::tree::new_child(parent, ns, name)
883}
884
885/// Set the root element of a document.
886///
887/// # UPSTREAM-PARITY
888///
889/// ```c
890/// xmlNodePtr xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root);
891/// ```
892///
893/// Returns the old root element (if any), which the caller must free.
894///
895/// # SAFETY
896///
897/// - `doc` must be a valid document.
898/// - `root` must be a valid node (ownership transfers to doc).
899#[no_mangle]
900pub unsafe extern "C" fn xmlDocSetRootElement(
901 doc: *mut _xmlDoc,
902 root: *mut _xmlNode,
903) -> *mut _xmlNode {
904 crate::xml::tree::doc_set_root_element(doc, root)
905}
906
907/// Get the root element of a document.
908///
909/// # UPSTREAM-PARITY
910///
911/// ```c
912/// xmlNodePtr xmlDocGetRootElement(const xmlDoc *doc);
913/// ```
914///
915/// Returns a borrowed pointer (do not free).
916#[no_mangle]
917pub extern "C" fn xmlDocGetRootElement(doc: *const _xmlDoc) -> *mut _xmlNode {
918 crate::xml::tree::doc_get_root_element(doc as *mut _xmlDoc)
919}
920
921/// Copy a node.
922///
923/// # UPSTREAM-PARITY
924///
925/// ```c
926/// xmlNodePtr xmlCopyNode(const xmlNodePtr node, int extended);
927/// ```
928///
929/// If `extended` is 1, copies recursively (deep copy).
930/// If `extended` is 0, copies only the node itself (shallow copy).
931///
932/// Returns a newly allocated copy. Caller must free with `xmlFreeNode`.
933#[no_mangle]
934pub unsafe extern "C" fn xmlCopyNode(node: *const _xmlNode, extended: c_int) -> *mut _xmlNode {
935 crate::xml::tree::copy_node(node, extended)
936}
937
938/// Copy a document.
939///
940/// # UPSTREAM-PARITY
941///
942/// ```c
943/// xmlDocPtr xmlCopyDoc(const xmlDocPtr doc, int recursive);
944/// ```
945///
946/// Returns a newly allocated copy. Caller must free with `xmlFreeDoc`.
947#[no_mangle]
948pub unsafe extern "C" fn xmlCopyDoc(doc: *const _xmlDoc, recursive: c_int) -> *mut _xmlDoc {
949 crate::xml::tree::copy_doc(doc, recursive)
950}
951
952/// Create a text node.
953///
954/// # UPSTREAM-PARITY
955///
956/// ```c
957/// xmlNodePtr xmlNewText(const xmlChar *content);
958/// ```
959///
960/// Creates a new text node with the given content.
961/// If `content` is NULL, creates an empty text node.
962#[no_mangle]
963pub unsafe extern "C" fn xmlNewText(content: *const xmlChar) -> *mut _xmlNode {
964 crate::xml::tree::new_text(content)
965}
966
967/// Create a new comment node.
968///
969/// # UPSTREAM-PARITY
970///
971/// ```c
972/// xmlNodePtr xmlNewComment(const xmlChar *content);
973/// ```
974#[no_mangle]
975pub unsafe extern "C" fn xmlNewComment(content: *const xmlChar) -> *mut _xmlNode {
976 crate::xml::tree::new_comment(content)
977}
978
979/// Create a new PI node.
980///
981/// # UPSTREAM-PARITY
982///
983/// ```c
984/// xmlNodePtr xmlNewPI(const xmlChar *name, const xmlChar *content);
985/// ```
986#[no_mangle]
987pub unsafe extern "C" fn xmlNewPI(name: *const xmlChar, content: *const xmlChar) -> *mut _xmlNode {
988 crate::xml::tree::new_pi(name, content)
989}
990
991/// Create a new CDATA node.
992///
993/// # UPSTREAM-PARITY
994///
995/// ```c
996/// xmlNodePtr xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len);
997/// ```
998#[no_mangle]
999pub unsafe extern "C" fn xmlNewCDataBlock(
1000 doc: *mut _xmlDoc,
1001 content: *const xmlChar,
1002 len: c_int,
1003) -> *mut _xmlNode {
1004 crate::xml::tree::new_cdata_block(doc, content, len)
1005}
1006
1007/// Create a new namespace definition.
1008///
1009/// # UPSTREAM-PARITY
1010///
1011/// ```c
1012/// xmlNsPtr xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix);
1013/// ```
1014///
1015/// # SAFETY
1016///
1017/// - `node` may be NULL.
1018/// - `href` and `prefix` are copied.
1019/// - Returns a borrowed pointer (namespace is owned by the node).
1020#[no_mangle]
1021pub unsafe extern "C" fn xmlNewNs(
1022 node: *mut _xmlNode,
1023 href: *const xmlChar,
1024 prefix: *const xmlChar,
1025) -> *mut _xmlNs {
1026 crate::xml::tree::new_ns(node, href, prefix)
1027}
1028
1029/// Set the namespace of a node.
1030///
1031/// # UPSTREAM-PARITY
1032///
1033/// ```c
1034/// void xmlSetNs(xmlNodePtr node, xmlNsPtr ns);
1035/// ```
1036#[no_mangle]
1037pub unsafe extern "C" fn xmlSetNs(node: *mut _xmlNode, ns: *mut _xmlNs) {
1038 crate::xml::tree::set_ns(node, ns);
1039}
1040
1041/// Get the namespace of a node.
1042///
1043/// # UPSTREAM-PARITY
1044///
1045/// ```c
1046/// xmlNsPtr xmlGetNsList(xmlDocPtr doc, const xmlNode *node);
1047/// ```
1048#[no_mangle]
1049pub unsafe extern "C" fn xmlGetNsList(
1050 doc: *mut _xmlDoc,
1051 node: *const _xmlNode,
1052) -> *mut *mut _xmlNs {
1053 crate::xml::tree::get_ns_list(doc, node as *mut _xmlNode)
1054}
1055
1056/// Search for a namespace by href.
1057///
1058/// # UPSTREAM-PARITY
1059///
1060/// ```c
1061/// xmlNsPtr xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace);
1062/// ```
1063#[no_mangle]
1064pub unsafe extern "C" fn xmlSearchNs(
1065 doc: *mut _xmlDoc,
1066 node: *mut _xmlNode,
1067 nameSpace: *const xmlChar,
1068) -> *mut _xmlNs {
1069 crate::xml::tree::search_ns(doc, node, nameSpace)
1070}
1071
1072/// Search for a namespace by href, using the full in-scope chain.
1073///
1074/// # UPSTREAM-PARITY
1075///
1076/// ```c
1077/// xmlNsPtr xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar *href);
1078/// ```
1079#[no_mangle]
1080pub unsafe extern "C" fn xmlSearchNsByHref(
1081 doc: *mut _xmlDoc,
1082 node: *mut _xmlNode,
1083 href: *const xmlChar,
1084) -> *mut _xmlNs {
1085 crate::xml::tree::search_ns_by_href(doc, node, href)
1086}
1087
1088/// Set a property (attribute) on a node.
1089///
1090/// # UPSTREAM-PARITY
1091///
1092/// ```c
1093/// xmlAttrPtr xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value);
1094/// ```
1095///
1096/// If the attribute already exists, its value is updated.
1097/// Returns a borrowed pointer to the attribute.
1098///
1099/// # SAFETY
1100///
1101/// - `node` must be a valid element node.
1102/// - `name` must be a valid string.
1103/// - `value` may be NULL.
1104#[no_mangle]
1105pub unsafe extern "C" fn xmlSetProp(
1106 node: *mut _xmlNode,
1107 name: *const xmlChar,
1108 value: *const xmlChar,
1109) -> *mut _xmlAttr {
1110 crate::xml::tree::set_prop(node, name, value)
1111}
1112
1113/// Get a property value by name.
1114///
1115/// # UPSTREAM-PARITY
1116///
1117/// ```c
1118/// xmlChar *xmlGetProp(const xmlNode *node, const xmlChar *name);
1119/// ```
1120///
1121/// Returns a newly allocated string. Caller must free with `xmlFree`.
1122#[no_mangle]
1123pub unsafe extern "C" fn xmlGetProp(node: *const _xmlNode, name: *const xmlChar) -> *mut xmlChar {
1124 crate::xml::tree::get_prop(node as *mut _xmlNode, name)
1125}
1126
1127/// Get a namespaced property value.
1128///
1129/// # UPSTREAM-PARITY
1130///
1131/// ```c
1132/// xmlChar *xmlGetNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace);
1133/// ```
1134#[no_mangle]
1135pub unsafe extern "C" fn xmlGetNsProp(
1136 node: *const _xmlNode,
1137 name: *const xmlChar,
1138 nameSpace: *const xmlChar,
1139) -> *mut xmlChar {
1140 crate::xml::tree::get_ns_prop(node as *mut _xmlNode, name, nameSpace)
1141}
1142
1143/// Set a namespaced property.
1144///
1145/// # UPSTREAM-PARITY
1146///
1147/// ```c
1148/// xmlAttrPtr xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns,
1149/// const xmlChar *name, const xmlChar *value);
1150/// ```
1151#[no_mangle]
1152pub unsafe extern "C" fn xmlSetNsProp(
1153 node: *mut _xmlNode,
1154 ns: *mut _xmlNs,
1155 name: *const xmlChar,
1156 value: *const xmlChar,
1157) -> *mut _xmlAttr {
1158 crate::xml::tree::set_ns_prop(node, ns, name, value)
1159}
1160
1161/// Remove a property by name.
1162///
1163/// # UPSTREAM-PARITY
1164///
1165/// ```c
1166/// int xmlRemoveProp(xmlAttrPtr attr);
1167/// ```
1168///
1169/// Returns 0 on success, -1 on error.
1170#[no_mangle]
1171pub unsafe extern "C" fn xmlRemoveProp(attr: *mut _xmlAttr) -> c_int {
1172 crate::xml::tree::remove_prop(attr)
1173}
1174
1175/// Get a DTD from a document, creating one if needed.
1176///
1177/// # UPSTREAM-PARITY
1178///
1179/// ```c
1180/// xmlDtdPtr xmlGetIntSubset(const xmlDoc *doc);
1181/// ```
1182#[no_mangle]
1183pub extern "C" fn xmlGetIntSubset(doc: *const _xmlDoc) -> *mut _xmlDtd {
1184 crate::xml::tree::get_int_subset(doc)
1185}
1186
1187/// Create a new DTD.
1188///
1189/// # UPSTREAM-PARITY
1190///
1191/// ```c
1192/// xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const xmlChar *name,
1193/// const xmlChar *ExternalID, const xmlChar *SystemID);
1194/// ```
1195#[no_mangle]
1196pub unsafe extern "C" fn xmlNewDtd(
1197 doc: *mut _xmlDoc,
1198 name: *const xmlChar,
1199 ExternalID: *const xmlChar,
1200 SystemID: *const xmlChar,
1201) -> *mut _xmlDtd {
1202 crate::xml::tree::new_dtd(doc, name, ExternalID, SystemID)
1203}
1204
1205/// Create a new entity.
1206///
1207/// # UPSTREAM-PARITY
1208///
1209/// ```c
1210/// xmlEntityPtr xmlNewEntity(xmlDocPtr doc, const xmlChar *name, int type,
1211/// const xmlChar *ExternalID, const xmlChar *SystemID,
1212/// const xmlChar *content);
1213/// ```
1214#[no_mangle]
1215pub unsafe extern "C" fn xmlNewEntity(
1216 doc: *mut _xmlDoc,
1217 name: *const xmlChar,
1218 type_: c_int,
1219 ExternalID: *const xmlChar,
1220 SystemID: *const xmlChar,
1221 content: *const xmlChar,
1222) -> *mut _xmlEntity {
1223 crate::xml::tree::new_entity(doc, name, type_, ExternalID, SystemID, content)
1224}
1225
1226/// Get an entity by name.
1227///
1228/// # UPSTREAM-PARITY
1229///
1230/// ```c
1231/// xmlEntityPtr xmlGetDocEntity(const xmlDoc *doc, const xmlChar *name);
1232/// ```
1233#[no_mangle]
1234pub unsafe extern "C" fn xmlGetDocEntity(
1235 doc: *const _xmlDoc,
1236 name: *const xmlChar,
1237) -> *mut _xmlEntity {
1238 crate::xml::tree::get_doc_entity(doc, name)
1239}
1240
1241/// Get a parameter entity by name.
1242///
1243/// # UPSTREAM-PARITY
1244///
1245/// ```c
1246/// xmlEntityPtr xmlGetParameterEntity(const xmlDoc *doc, const xmlChar *name);
1247/// ```
1248#[no_mangle]
1249pub unsafe extern "C" fn xmlGetParameterEntity(
1250 doc: *const _xmlDoc,
1251 name: *const xmlChar,
1252) -> *mut _xmlEntity {
1253 crate::xml::tree::get_parameter_entity(doc, name)
1254}
1255
1256/// Get the line number of a node.
1257///
1258/// # UPSTREAM-PARITY
1259///
1260/// ```c
1261/// long xmlGetLineNo(const xmlNode *node);
1262/// ```
1263#[no_mangle]
1264pub extern "C" fn xmlGetLineNo(node: *const _xmlNode) -> c_int {
1265 crate::xml::tree::get_line_no(node)
1266}
1267
1268// ═══════════════════════════════════════════════════════════════════════════════
1269// 7. Parser — SAX, DOM, Push, Reader
1270// ═══════════════════════════════════════════════════════════════════════════════
1271
1272/// Read an XML document from a string.
1273///
1274/// # UPSTREAM-PARITY
1275///
1276/// ```c
1277/// xmlDocPtr xmlReadDoc(const xmlChar *cur, const char *URL,
1278/// const char *encoding, int options);
1279/// ```
1280///
1281/// Returns a parsed document. Caller must free with `xmlFreeDoc`.
1282#[no_mangle]
1283pub unsafe extern "C" fn xmlReadDoc(
1284 cur: *const xmlChar,
1285 URL: *const c_char,
1286 encoding: *const c_char,
1287 options: c_int,
1288) -> *mut _xmlDoc {
1289 // SAFETY: cur must be a valid null-terminated xmlChar string if non-null.
1290 if cur.is_null() {
1291 return ptr::null_mut();
1292 }
1293 let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
1294 if ctxt.is_null() {
1295 return ptr::null_mut();
1296 }
1297 let len = crate::xml::string::xml_strlen(cur);
1298 let input = crate::xml::parser::helpers::input_from_memory(cur as *const c_char, len as c_int);
1299 crate::xml::parser::helpers::setup_parser_input(ctxt, input);
1300 (*ctxt).options = options;
1301 if crate::xml::parser::helpers::parse_document(ctxt) != 0 {
1302 let doc = (*ctxt).myDoc;
1303 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1304 return doc;
1305 }
1306 let doc = (*ctxt).myDoc;
1307 if !doc.is_null() {
1308 (*doc).URL = crate::xml::string::xml_strdup(URL as *const xmlChar);
1309 }
1310 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1311 doc
1312}
1313
1314/// Read an XML document from a file.
1315///
1316/// # UPSTREAM-PARITY
1317///
1318/// ```c
1319/// xmlDocPtr xmlReadFile(const char *URL, const char *encoding, int options);
1320/// ```
1321#[no_mangle]
1322pub unsafe extern "C" fn xmlReadFile(
1323 URL: *const c_char,
1324 encoding: *const c_char,
1325 options: c_int,
1326) -> *mut _xmlDoc {
1327 // SAFETY: URL must be a valid C string or NULL.
1328 if URL.is_null() {
1329 return ptr::null_mut();
1330 }
1331 let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
1332 if ctxt.is_null() {
1333 return ptr::null_mut();
1334 }
1335 let input = match crate::xml::parser::helpers::input_from_file(URL) {
1336 Ok(input) => input,
1337 Err(_) => {
1338 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1339 return ptr::null_mut();
1340 }
1341 };
1342 crate::xml::parser::helpers::setup_parser_input(ctxt, input);
1343 (*ctxt).options = options;
1344 if crate::xml::parser::helpers::parse_document(ctxt) != 0 {
1345 let doc = (*ctxt).myDoc;
1346 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1347 return doc;
1348 }
1349 let doc = (*ctxt).myDoc;
1350 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1351 doc
1352}
1353
1354/// Read an XML document from memory.
1355///
1356/// # UPSTREAM-PARITY
1357///
1358/// ```c
1359/// xmlDocPtr xmlReadMemory(const char *buffer, int size,
1360/// const char *URL, const char *encoding, int options);
1361/// ```
1362#[no_mangle]
1363pub unsafe extern "C" fn xmlReadMemory(
1364 buffer: *const c_char,
1365 size: c_int,
1366 URL: *const c_char,
1367 encoding: *const c_char,
1368 options: c_int,
1369) -> *mut _xmlDoc {
1370 // SAFETY: buffer must be a valid pointer with at least `size` readable bytes.
1371 if buffer.is_null() || size <= 0 {
1372 return ptr::null_mut();
1373 }
1374 let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
1375 if ctxt.is_null() {
1376 return ptr::null_mut();
1377 }
1378 let input = crate::xml::parser::helpers::input_from_memory(buffer, size);
1379 crate::xml::parser::helpers::setup_parser_input(ctxt, input);
1380 (*ctxt).options = options;
1381 if crate::xml::parser::helpers::parse_document(ctxt) != 0 {
1382 let doc = (*ctxt).myDoc;
1383 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1384 return doc;
1385 }
1386 let doc = (*ctxt).myDoc;
1387 if !doc.is_null() && !URL.is_null() {
1388 (*doc).URL = crate::xml::string::xml_strdup(URL as *const xmlChar);
1389 }
1390 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1391 doc
1392}
1393
1394/// Read an XML document from a file descriptor.
1395///
1396/// # UPSTREAM-PARITY
1397///
1398/// ```c
1399/// xmlDocPtr xmlReadFd(int fd, const char *URL, const char *encoding, int options);
1400/// ```
1401#[no_mangle]
1402pub unsafe extern "C" fn xmlReadFd(
1403 fd: c_int,
1404 URL: *const c_char,
1405 encoding: *const c_char,
1406 options: c_int,
1407) -> *mut _xmlDoc {
1408 // SAFETY: fd must be a valid open file descriptor.
1409 let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
1410 if ctxt.is_null() {
1411 return ptr::null_mut();
1412 }
1413 // Read all data from the fd
1414 let mut buf = Vec::new();
1415 let mut tmp = [0u8; 4096];
1416 loop {
1417 let n = libc::read(fd, tmp.as_mut_ptr() as *mut c_void, tmp.len());
1418 if n <= 0 {
1419 break;
1420 }
1421 buf.extend_from_slice(&tmp[..n as usize]);
1422 }
1423 let input = crate::xml::parser::helpers::input_from_memory(
1424 buf.as_ptr() as *const c_char,
1425 buf.len() as c_int,
1426 );
1427 crate::xml::parser::helpers::setup_parser_input(ctxt, input);
1428 (*ctxt).options = options;
1429 if crate::xml::parser::helpers::parse_document(ctxt) != 0 {
1430 let doc = (*ctxt).myDoc;
1431 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1432 return doc;
1433 }
1434 let doc = (*ctxt).myDoc;
1435 if !doc.is_null() && !URL.is_null() {
1436 (*doc).URL = crate::xml::string::xml_strdup(URL as *const xmlChar);
1437 }
1438 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1439 doc
1440}
1441
1442/// Read an XML document from I/O callbacks.
1443///
1444/// # UPSTREAM-PARITY
1445///
1446/// ```c
1447/// xmlDocPtr xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
1448/// void *ioctx, const char *URL, const char *encoding, int options);
1449/// ```
1450#[no_mangle]
1451pub unsafe extern "C" fn xmlReadIO(
1452 ioread: Option<xmlInputReadCallback>,
1453 ioclose: Option<xmlInputCloseCallback>,
1454 ioctx: *mut c_void,
1455 URL: *const c_char,
1456 encoding: *const c_char,
1457 options: c_int,
1458) -> *mut _xmlDoc {
1459 // SAFETY: callbacks must be valid function pointers if non-NULL.
1460 let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
1461 if ctxt.is_null() {
1462 return ptr::null_mut();
1463 }
1464 let input = crate::xml::parser::helpers::input_from_io(ioread, ioclose, ioctx);
1465 crate::xml::parser::helpers::setup_parser_input(ctxt, input);
1466 (*ctxt).options = options;
1467 if crate::xml::parser::helpers::parse_document(ctxt) != 0 {
1468 let doc = (*ctxt).myDoc;
1469 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1470 return doc;
1471 }
1472 let doc = (*ctxt).myDoc;
1473 if !doc.is_null() && !URL.is_null() {
1474 (*doc).URL = crate::xml::string::xml_strdup(URL as *const xmlChar);
1475 }
1476 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1477 doc
1478}
1479
1480/// Parse an XML document (SAX1).
1481///
1482/// # UPSTREAM-PARITY
1483///
1484/// ```c
1485/// xmlDocPtr xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery);
1486/// ```
1487#[no_mangle]
1488pub unsafe extern "C" fn xmlSAXParseDoc(
1489 sax: *mut _xmlSAXHandler,
1490 cur: *const xmlChar,
1491 recovery: c_int,
1492) -> *mut _xmlDoc {
1493 // SAFETY: cur must be a valid null-terminated xmlChar string.
1494 if cur.is_null() {
1495 return ptr::null_mut();
1496 }
1497 let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
1498 if ctxt.is_null() {
1499 return ptr::null_mut();
1500 }
1501 if !sax.is_null() {
1502 (*ctxt).sax = sax;
1503 (*ctxt).userData = (*ctxt).sax as *mut c_void;
1504 }
1505 if recovery != 0 {
1506 (*ctxt).recovery = 1;
1507 (*ctxt).options |= 1; // XML_PARSE_RECOVER
1508 }
1509 let len = crate::xml::string::xml_strlen(cur);
1510 let input = crate::xml::parser::helpers::input_from_memory(cur as *const c_char, len as c_int);
1511 crate::xml::parser::helpers::setup_parser_input(ctxt, input);
1512 crate::xml::parser::helpers::parse_document(ctxt);
1513 let doc = (*ctxt).myDoc;
1514 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1515 doc
1516}
1517
1518/// Parse an XML file (SAX1).
1519///
1520/// # UPSTREAM-PARITY
1521///
1522/// ```c
1523/// xmlDocPtr xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename, int recovery);
1524/// ```
1525#[no_mangle]
1526pub unsafe extern "C" fn xmlSAXParseFile(
1527 sax: *mut _xmlSAXHandler,
1528 filename: *const c_char,
1529 recovery: c_int,
1530) -> *mut _xmlDoc {
1531 // SAFETY: filename must be a valid C string.
1532 if filename.is_null() {
1533 return ptr::null_mut();
1534 }
1535 let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
1536 if ctxt.is_null() {
1537 return ptr::null_mut();
1538 }
1539 if !sax.is_null() {
1540 (*ctxt).sax = sax;
1541 (*ctxt).userData = (*ctxt).sax as *mut c_void;
1542 }
1543 if recovery != 0 {
1544 (*ctxt).recovery = 1;
1545 (*ctxt).options |= 1;
1546 }
1547 let input = match crate::xml::parser::helpers::input_from_file(filename) {
1548 Ok(input) => input,
1549 Err(_) => {
1550 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1551 return ptr::null_mut();
1552 }
1553 };
1554 crate::xml::parser::helpers::setup_parser_input(ctxt, input);
1555 crate::xml::parser::helpers::parse_document(ctxt);
1556 let doc = (*ctxt).myDoc;
1557 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1558 doc
1559}
1560
1561/// Parse an XML document from memory (SAX1).
1562///
1563/// # UPSTREAM-PARITY
1564///
1565/// ```c
1566/// xmlDocPtr xmlSAXParseMemory(xmlSAXHandlerPtr sax,
1567/// const char *buffer, int size, int recovery);
1568/// ```
1569#[no_mangle]
1570pub unsafe extern "C" fn xmlSAXParseMemory(
1571 sax: *mut _xmlSAXHandler,
1572 buffer: *const c_char,
1573 size: c_int,
1574 recovery: c_int,
1575) -> *mut _xmlDoc {
1576 // SAFETY: buffer must be valid with at least `size` bytes.
1577 if buffer.is_null() || size <= 0 {
1578 return ptr::null_mut();
1579 }
1580 let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
1581 if ctxt.is_null() {
1582 return ptr::null_mut();
1583 }
1584 if !sax.is_null() {
1585 (*ctxt).sax = sax;
1586 (*ctxt).userData = (*ctxt).sax as *mut c_void;
1587 }
1588 if recovery != 0 {
1589 (*ctxt).recovery = 1;
1590 (*ctxt).options |= 1;
1591 }
1592 let input = crate::xml::parser::helpers::input_from_memory(buffer, size);
1593 crate::xml::parser::helpers::setup_parser_input(ctxt, input);
1594 crate::xml::parser::helpers::parse_document(ctxt);
1595 let doc = (*ctxt).myDoc;
1596 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1597 doc
1598}
1599
1600/// SAX user parse file.
1601///
1602/// # UPSTREAM-PARITY
1603///
1604/// ```c
1605/// int xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
1606/// const char *filename);
1607/// ```
1608#[no_mangle]
1609pub unsafe extern "C" fn xmlSAXUserParseFile(
1610 sax: *mut _xmlSAXHandler,
1611 user_data: *mut c_void,
1612 filename: *const c_char,
1613) -> c_int {
1614 // SAFETY: filename must be a valid C string. sax and user_data may be NULL.
1615 if filename.is_null() {
1616 return -1;
1617 }
1618 let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
1619 if ctxt.is_null() {
1620 return -1;
1621 }
1622 if !sax.is_null() {
1623 (*ctxt).sax = sax;
1624 }
1625 (*ctxt).userData = if !user_data.is_null() {
1626 user_data
1627 } else {
1628 ctxt as *mut c_void
1629 };
1630 let input = match crate::xml::parser::helpers::input_from_file(filename) {
1631 Ok(input) => input,
1632 Err(_) => {
1633 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1634 return -1;
1635 }
1636 };
1637 crate::xml::parser::helpers::setup_parser_input(ctxt, input);
1638 let ret = crate::xml::parser::helpers::parse_document(ctxt);
1639 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1640 ret
1641}
1642
1643/// SAX user parse memory.
1644///
1645/// # UPSTREAM-PARITY
1646///
1647/// ```c
1648/// int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
1649/// const char *buffer, int size);
1650/// ```
1651#[no_mangle]
1652pub unsafe extern "C" fn xmlSAXUserParseMemory(
1653 sax: *mut _xmlSAXHandler,
1654 user_data: *mut c_void,
1655 buffer: *const c_char,
1656 size: c_int,
1657) -> c_int {
1658 // SAFETY: buffer must be valid with at least `size` bytes.
1659 if buffer.is_null() || size <= 0 {
1660 return -1;
1661 }
1662 let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
1663 if ctxt.is_null() {
1664 return -1;
1665 }
1666 if !sax.is_null() {
1667 (*ctxt).sax = sax;
1668 }
1669 (*ctxt).userData = if !user_data.is_null() {
1670 user_data
1671 } else {
1672 ctxt as *mut c_void
1673 };
1674 let input = crate::xml::parser::helpers::input_from_memory(buffer, size);
1675 crate::xml::parser::helpers::setup_parser_input(ctxt, input);
1676 let ret = crate::xml::parser::helpers::parse_document(ctxt);
1677 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1678 ret
1679}
1680
1681/// Parse an XML document from a string (DOM).
1682///
1683/// # UPSTREAM-PARITY
1684///
1685/// ```c
1686/// xmlDocPtr xmlParseDoc(const xmlChar *cur);
1687/// ```
1688#[no_mangle]
1689pub unsafe extern "C" fn xmlParseDoc(cur: *const xmlChar) -> *mut _xmlDoc {
1690 // SAFETY: cur must be a valid null-terminated xmlChar string.
1691 if cur.is_null() {
1692 return ptr::null_mut();
1693 }
1694 xmlReadDoc(cur, ptr::null(), ptr::null(), 0)
1695}
1696
1697/// Parse an XML file (DOM).
1698///
1699/// # UPSTREAM-PARITY
1700///
1701/// ```c
1702/// xmlDocPtr xmlParseFile(const char *filename);
1703/// ```
1704#[no_mangle]
1705pub unsafe extern "C" fn xmlParseFile(filename: *const c_char) -> *mut _xmlDoc {
1706 // SAFETY: filename must be a valid C string.
1707 if filename.is_null() {
1708 return ptr::null_mut();
1709 }
1710 xmlReadFile(filename, ptr::null(), 0)
1711}
1712
1713/// Parse an XML document from memory (DOM).
1714///
1715/// # UPSTREAM-PARITY
1716///
1717/// ```c
1718/// xmlDocPtr xmlParseMemory(const char *buffer, int size);
1719/// ```
1720#[no_mangle]
1721pub unsafe extern "C" fn xmlParseMemory(buffer: *const c_char, size: c_int) -> *mut _xmlDoc {
1722 // SAFETY: buffer must be valid with at least `size` bytes.
1723 if buffer.is_null() || size <= 0 {
1724 return ptr::null_mut();
1725 }
1726 xmlReadMemory(buffer, size, ptr::null(), ptr::null(), 0)
1727}
1728
1729/// Create a file parser context.
1730///
1731/// # UPSTREAM-PARITY
1732///
1733/// ```c
1734/// xmlParserCtxtPtr xmlCreateFileParserCtxt(const char *filename);
1735/// ```
1736#[no_mangle]
1737pub unsafe extern "C" fn xmlCreateFileParserCtxt(filename: *const c_char) -> *mut _xmlParserCtxt {
1738 // SAFETY: filename must be a valid C string.
1739 if filename.is_null() {
1740 return ptr::null_mut();
1741 }
1742 let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
1743 if ctxt.is_null() {
1744 return ptr::null_mut();
1745 }
1746 let input = match crate::xml::parser::helpers::input_from_file(filename) {
1747 Ok(input) => input,
1748 Err(_) => {
1749 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1750 return ptr::null_mut();
1751 }
1752 };
1753 crate::xml::parser::helpers::setup_parser_input(ctxt, input);
1754 ctxt
1755}
1756
1757/// Create a document parser context.
1758///
1759/// # UPSTREAM-PARITY
1760///
1761/// ```c
1762/// xmlParserCtxtPtr xmlCreateDocParserCtxt(const xmlChar *cur);
1763/// ```
1764#[no_mangle]
1765pub unsafe extern "C" fn xmlCreateDocParserCtxt(cur: *const xmlChar) -> *mut _xmlParserCtxt {
1766 // SAFETY: cur must be a valid null-terminated xmlChar string.
1767 if cur.is_null() {
1768 return ptr::null_mut();
1769 }
1770 let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
1771 if ctxt.is_null() {
1772 return ptr::null_mut();
1773 }
1774 let len = crate::xml::string::xml_strlen(cur);
1775 let input = crate::xml::parser::helpers::input_from_memory(cur as *const c_char, len as c_int);
1776 crate::xml::parser::helpers::setup_parser_input(ctxt, input);
1777 ctxt
1778}
1779
1780/// Parse a document using an existing parser context.
1781///
1782/// # UPSTREAM-PARITY
1783///
1784/// ```c
1785/// int xmlParseDocument(xmlParserCtxtPtr ctxt);
1786/// ```
1787#[no_mangle]
1788pub unsafe extern "C" fn xmlParseDocument(ctxt: *mut _xmlParserCtxt) -> c_int {
1789 // SAFETY: ctxt must be a valid parser context.
1790 if ctxt.is_null() {
1791 return -1;
1792 }
1793 crate::xml::parser::helpers::parse_document(ctxt)
1794}
1795
1796/// Free a parser context.
1797///
1798/// # UPSTREAM-PARITY
1799///
1800/// ```c
1801/// void xmlFreeParserCtxt(xmlParserCtxtPtr ctxt);
1802/// ```
1803#[no_mangle]
1804pub unsafe extern "C" fn xmlFreeParserCtxt(ctxt: *mut _xmlParserCtxt) {
1805 if ctxt.is_null() {
1806 return;
1807 }
1808 crate::xml::parser::helpers::free_parser_ctxt(ctxt);
1809}
1810
1811/// Set parser options.
1812///
1813/// # UPSTREAM-PARITY
1814///
1815/// ```c
1816/// int xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options);
1817/// ```
1818#[no_mangle]
1819pub unsafe extern "C" fn xmlCtxtUseOptions(ctxt: *mut _xmlParserCtxt, options: c_int) -> c_int {
1820 if ctxt.is_null() {
1821 return -1;
1822 }
1823 // Phase 1: STUB
1824 unsafe {
1825 (*ctxt).options = options;
1826 }
1827 0
1828}
1829
1830/// Parse a well-balanced chunk (for push parsing).
1831///
1832/// # UPSTREAM-PARITY
1833///
1834/// ```c
1835/// xmlParserErrors xmlParseChunk(xmlParserCtxtPtr ctxt,
1836/// const char *chunk, int size, int terminate);
1837/// ```
1838#[no_mangle]
1839pub unsafe extern "C" fn xmlParseChunk(
1840 ctxt: *mut _xmlParserCtxt,
1841 chunk: *const c_char,
1842 size: c_int,
1843 terminate: c_int,
1844) -> c_int {
1845 // SAFETY: ctxt must be a valid parser context.
1846 // chunk may be NULL if terminate is set (finalize without data).
1847 if ctxt.is_null() {
1848 return -1;
1849 }
1850 crate::xml::parser::helpers::parse_chunk(ctxt, chunk, size, terminate)
1851}
1852
1853/// Create a memory parser input buffer.
1854///
1855/// # UPSTREAM-PARITY
1856///
1857/// ```c
1858/// xmlParserInputBufferPtr xmlParserInputBufferCreateMem(const char *buffer, int size, int enc);
1859/// ```
1860#[no_mangle]
1861pub unsafe extern "C" fn xmlParserInputBufferCreateMem(
1862 buffer: *const c_char,
1863 size: c_int,
1864 enc: c_int,
1865) -> *mut _xmlParserInputBuffer {
1866 // SAFETY: buffer must be valid with at least `size` bytes.
1867 if buffer.is_null() || size <= 0 {
1868 return ptr::null_mut();
1869 }
1870 crate::xml::parser::helpers::alloc_parser_input_buffer()
1871}
1872
1873/// Create a file parser input buffer.
1874///
1875/// # UPSTREAM-PARITY
1876///
1877/// ```c
1878/// xmlParserInputBufferPtr xmlParserInputBufferCreateFilename(const char *URI, int enc);
1879/// ```
1880#[no_mangle]
1881pub unsafe extern "C" fn xmlParserInputBufferCreateFilename(
1882 URI: *const c_char,
1883 enc: c_int,
1884) -> *mut _xmlParserInputBuffer {
1885 // SAFETY: URI must be a valid C string or NULL.
1886 if URI.is_null() {
1887 return ptr::null_mut();
1888 }
1889 crate::xml::parser::helpers::alloc_parser_input_buffer()
1890}
1891
1892/// Create an I/O parser input buffer.
1893///
1894/// # UPSTREAM-PARITY
1895///
1896/// ```c
1897/// xmlParserInputBufferPtr xmlParserInputBufferCreateIO(
1898/// xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
1899/// void *ioctx, int enc);
1900/// ```
1901#[no_mangle]
1902pub unsafe extern "C" fn xmlParserInputBufferCreateIO(
1903 ioread: Option<xmlInputReadCallback>,
1904 ioclose: Option<xmlInputCloseCallback>,
1905 ioctx: *mut c_void,
1906 enc: c_int,
1907) -> *mut _xmlParserInputBuffer {
1908 // SAFETY: ioread must be a valid callback if Some. ioctx may be NULL.
1909 let buf = crate::xml::parser::helpers::alloc_parser_input_buffer();
1910 if !buf.is_null() {
1911 (*buf).readcallback = ioread;
1912 (*buf).closecallback = ioclose;
1913 (*buf).context = ioctx;
1914 }
1915 buf
1916}
1917
1918/// Free a parser input buffer.
1919///
1920/// # UPSTREAM-PARITY
1921///
1922/// ```c
1923/// void xmlFreeParserInputBuffer(xmlParserInputBufferPtr buf);
1924/// ```
1925#[no_mangle]
1926pub unsafe extern "C" fn xmlFreeParserInputBuffer(buf: *mut _xmlParserInputBuffer) {
1927 if buf.is_null() {
1928 return;
1929 }
1930 crate::xml::parser::helpers::free_parser_input_buffer(buf);
1931}
1932
1933/// Create a new parser input.
1934///
1935/// # UPSTREAM-PARITY
1936///
1937/// ```c
1938/// xmlParserInputPtr xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename);
1939/// ```
1940#[no_mangle]
1941pub unsafe extern "C" fn xmlNewInputFromFile(
1942 ctxt: *mut _xmlParserCtxt,
1943 filename: *const c_char,
1944) -> *mut _xmlParserInput {
1945 // SAFETY: filename must be a valid C string. ctxt may be NULL.
1946 // This function allocates a _xmlParserInput. The caller owns it.
1947 // Note: The InputBuffer backing data is NOT leaked here (no ctxt._private
1948 // to store it). Use xmlCreateFileParserCtxt + xmlParseDocument instead.
1949 if filename.is_null() {
1950 return ptr::null_mut();
1951 }
1952 crate::xml::parser::helpers::alloc_parser_input_buffer() as *mut _xmlParserInput
1953}
1954
1955/// Free a parser input.
1956///
1957/// # UPSTREAM-PARITY
1958///
1959/// ```c
1960/// void xmlFreeInputStream(xmlParserInputPtr input);
1961/// ```
1962#[no_mangle]
1963pub unsafe extern "C" fn xmlFreeInputStream(input: *mut _xmlParserInput) {
1964 if input.is_null() {
1965 return;
1966 }
1967 crate::xml::parser::helpers::free_parser_input(input);
1968}
1969
1970// ═══════════════════════════════════════════════════════════════════════════════
1971// 8. I/O
1972// ═══════════════════════════════════════════════════════════════════════════════
1973
1974/// Create an output buffer for a file.
1975///
1976/// # UPSTREAM-PARITY
1977///
1978/// ```c
1979/// xmlOutputBufferPtr xmlOutputBufferCreateFilename(const char *URI,
1980/// xmlCharEncodingHandlerPtr encoder,
1981/// int compression);
1982/// ```
1983#[no_mangle]
1984pub unsafe extern "C" fn xmlOutputBufferCreateFilename(
1985 URI: *const c_char,
1986 encoder: *mut c_void,
1987 compression: c_int,
1988) -> *mut _xmlOutputBuffer {
1989 // Phase 1: STUB
1990 ptr::null_mut()
1991}
1992
1993/// Create an output buffer for a file descriptor.
1994///
1995/// # UPSTREAM-PARITY
1996///
1997/// ```c
1998/// xmlOutputBufferPtr xmlOutputBufferCreateFd(int fd,
1999/// xmlCharEncodingHandlerPtr encoder);
2000/// ```
2001#[no_mangle]
2002pub unsafe extern "C" fn xmlOutputBufferCreateFd(
2003 fd: c_int,
2004 encoder: *mut c_void,
2005) -> *mut _xmlOutputBuffer {
2006 // Phase 1: STUB
2007 ptr::null_mut()
2008}
2009
2010/// Create an output buffer from I/O callbacks.
2011///
2012/// # UPSTREAM-PARITY
2013///
2014/// ```c
2015/// xmlOutputBufferPtr xmlOutputBufferCreateIO(
2016/// xmlOutputWriteCallback iowrite, xmlOutputCloseCallback ioclose,
2017/// void *ioctx, xmlCharEncodingHandlerPtr encoder);
2018/// ```
2019#[no_mangle]
2020pub unsafe extern "C" fn xmlOutputBufferCreateIO(
2021 iowrite: Option<xmlOutputWriteCallback>,
2022 ioclose: Option<xmlOutputCloseCallback>,
2023 ioctx: *mut c_void,
2024 encoder: *mut c_void,
2025) -> *mut _xmlOutputBuffer {
2026 // Phase 1: STUB
2027 ptr::null_mut()
2028}
2029
2030/// Free an output buffer.
2031///
2032/// # UPSTREAM-PARITY
2033///
2034/// ```c
2035/// void xmlOutputBufferClose(xmlOutputBufferPtr out);
2036/// ```
2037#[no_mangle]
2038pub unsafe extern "C" fn xmlOutputBufferClose(out: *mut _xmlOutputBuffer) -> c_int {
2039 if out.is_null() {
2040 return 0;
2041 }
2042 // Phase 1: STUB
2043 unsafe {
2044 xmlFree(out as *mut c_void);
2045 }
2046 0
2047}
2048
2049/// Flush an output buffer.
2050///
2051/// # UPSTREAM-PARITY
2052///
2053/// ```c
2054/// int xmlOutputBufferFlush(xmlOutputBufferPtr out);
2055/// ```
2056#[no_mangle]
2057pub unsafe extern "C" fn xmlOutputBufferFlush(out: *mut _xmlOutputBuffer) -> c_int {
2058 // Phase 1: STUB
2059 0
2060}
2061
2062/// Write to an output buffer.
2063///
2064/// # UPSTREAM-PARITY
2065///
2066/// ```c
2067/// int xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *data);
2068/// ```
2069#[no_mangle]
2070pub unsafe extern "C" fn xmlOutputBufferWrite(
2071 out: *mut _xmlOutputBuffer,
2072 len: c_int,
2073 data: *const c_char,
2074) -> c_int {
2075 // Phase 1: STUB
2076 0
2077}
2078
2079/// Write a string to an output buffer.
2080///
2081/// # UPSTREAM-PARITY
2082///
2083/// ```c
2084/// int xmlOutputBufferWriteString(xmlOutputBufferPtr out, const char *str);
2085/// ```
2086#[no_mangle]
2087pub unsafe extern "C" fn xmlOutputBufferWriteString(
2088 out: *mut _xmlOutputBuffer,
2089 str: *const c_char,
2090) -> c_int {
2091 if str.is_null() {
2092 return 0;
2093 }
2094 unsafe { xmlOutputBufferWrite(out, xmlStrlen(str as *const xmlChar), str) }
2095}
2096
2097// ═══════════════════════════════════════════════════════════════════════════════
2098// 9. Dictionary
2099// ═══════════════════════════════════════════════════════════════════════════════
2100
2101/// Create a new dictionary.
2102///
2103/// # UPSTREAM-PARITY
2104///
2105/// ```c
2106/// xmlDictPtr xmlDictCreate(void);
2107/// ```
2108#[no_mangle]
2109pub extern "C" fn xmlDictCreate() -> *mut c_void {
2110 // Phase 1: STUB — will be implemented in xml/dictionary module.
2111 ptr::null_mut()
2112}
2113
2114/// Create a sub-dictionary.
2115///
2116/// # UPSTREAM-PARITY
2117///
2118/// ```c
2119/// xmlDictPtr xmlDictCreateSub(xmlDictPtr sub);
2120/// ```
2121#[no_mangle]
2122pub extern "C" fn xmlDictCreateSub(_sub: *mut c_void) -> *mut c_void {
2123 // Phase 1: STUB
2124 ptr::null_mut()
2125}
2126
2127/// Look up a string in the dictionary.
2128///
2129/// # UPSTREAM-PARITY
2130///
2131/// ```c
2132/// const xmlChar *xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len);
2133/// ```
2134///
2135/// Returns an interned string pointer (valid as long as the dictionary exists).
2136/// - If `len` < 0, `name` must be null-terminated.
2137/// - If `len` >= 0, exactly `len` bytes are used.
2138#[no_mangle]
2139pub unsafe extern "C" fn xmlDictLookup(
2140 dict: *mut c_void,
2141 name: *const xmlChar,
2142 len: c_int,
2143) -> *const xmlChar {
2144 // Phase 1: STUB
2145 name
2146}
2147
2148/// Check if a string exists in the dictionary.
2149///
2150/// # UPSTREAM-PARITY
2151///
2152/// ```c
2153/// const xmlChar *xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len);
2154/// ```
2155#[no_mangle]
2156pub unsafe extern "C" fn xmlDictExists(
2157 dict: *mut c_void,
2158 name: *const xmlChar,
2159 len: c_int,
2160) -> *const xmlChar {
2161 // Phase 1: STUB
2162 ptr::null()
2163}
2164
2165/// Query dictionary size.
2166///
2167/// # UPSTREAM-PARITY
2168///
2169/// ```c
2170/// unsigned int xmlDictSize(const xmlDictPtr dict);
2171/// ```
2172#[no_mangle]
2173pub extern "C" fn xmlDictSize(dict: *const c_void) -> c_uint {
2174 // Phase 1: STUB
2175 0
2176}
2177
2178/// Free a dictionary.
2179///
2180/// # UPSTREAM-PARITY
2181///
2182/// ```c
2183/// void xmlDictFree(xmlDictPtr dict);
2184/// ```
2185#[no_mangle]
2186pub extern "C" fn xmlDictFree(_dict: *mut c_void) {
2187 // Phase 1: STUB
2188}
2189
2190/// Set the dictionary size limit.
2191///
2192/// # UPSTREAM-PARITY
2193///
2194/// ```c
2195/// unsigned int xmlDictSetLimit(xmlDictPtr dict, unsigned int limit);
2196/// ```
2197#[no_mangle]
2198pub extern "C" fn xmlDictSetLimit(_dict: *mut c_void, _limit: c_uint) -> c_uint {
2199 // Phase 1: STUB
2200 0
2201}
2202
2203/// Get current dictionary usage.
2204///
2205/// # UPSTREAM-PARITY
2206///
2207/// ```c
2208/// unsigned int xmlDictGetUsage(const xmlDictPtr dict);
2209/// ```
2210#[no_mangle]
2211pub extern "C" fn xmlDictGetUsage(_dict: *const c_void) -> c_uint {
2212 // Phase 1: STUB
2213 0
2214}
2215
2216// ═══════════════════════════════════════════════════════════════════════════════
2217// 10. Hash Table
2218// ═══════════════════════════════════════════════════════════════════════════════
2219
2220/// Create a new hash table.
2221///
2222/// # UPSTREAM-PARITY
2223///
2224/// ```c
2225/// xmlHashTablePtr xmlHashCreate(int size);
2226/// ```
2227#[no_mangle]
2228pub extern "C" fn xmlHashCreate(_size: c_int) -> *mut c_void {
2229 // Phase 1: STUB
2230 ptr::null_mut()
2231}
2232
2233/// Create a new hash table with a dictionary.
2234///
2235/// # UPSTREAM-PARITY
2236///
2237/// ```c
2238/// xmlHashTablePtr xmlHashCreateDict(int size, xmlDictPtr dict);
2239/// ```
2240#[no_mangle]
2241pub extern "C" fn xmlHashCreateDict(_size: c_int, _dict: *mut c_void) -> *mut c_void {
2242 // Phase 1: STUB
2243 ptr::null_mut()
2244}
2245
2246/// Free a hash table.
2247///
2248/// # UPSTREAM-PARITY
2249///
2250/// ```c
2251/// void xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f);
2252/// ```
2253#[no_mangle]
2254pub extern "C" fn xmlHashFree(
2255 _table: *mut c_void,
2256 _f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
2257) {
2258 // Phase 1: STUB
2259}
2260
2261/// Add an entry to a hash table.
2262///
2263/// # UPSTREAM-PARITY
2264///
2265/// ```c
2266/// int xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata);
2267/// ```
2268#[no_mangle]
2269pub unsafe extern "C" fn xmlHashAddEntry(
2270 _table: *mut c_void,
2271 _name: *const xmlChar,
2272 _userdata: *mut c_void,
2273) -> c_int {
2274 // Phase 1: STUB
2275 0
2276}
2277
2278/// Add a 2-key entry.
2279///
2280/// # UPSTREAM-PARITY
2281///
2282/// ```c
2283/// int xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name,
2284/// const xmlChar *name2, void *userdata);
2285/// ```
2286#[no_mangle]
2287pub unsafe extern "C" fn xmlHashAddEntry2(
2288 _table: *mut c_void,
2289 _name: *const xmlChar,
2290 _name2: *const xmlChar,
2291 _userdata: *mut c_void,
2292) -> c_int {
2293 // Phase 1: STUB
2294 0
2295}
2296
2297/// Add a 3-key entry.
2298///
2299/// # UPSTREAM-PARITY
2300///
2301/// ```c
2302/// int xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
2303/// const xmlChar *name2, const xmlChar *name3, void *userdata);
2304/// ```
2305#[no_mangle]
2306pub unsafe extern "C" fn xmlHashAddEntry3(
2307 _table: *mut c_void,
2308 _name: *const xmlChar,
2309 _name2: *const xmlChar,
2310 _name3: *const xmlChar,
2311 _userdata: *mut c_void,
2312) -> c_int {
2313 // Phase 1: STUB
2314 0
2315}
2316
2317/// Update or add an entry.
2318///
2319/// # UPSTREAM-PARITY
2320///
2321/// ```c
2322/// int xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
2323/// void *userdata, xmlHashDeallocator f);
2324/// ```
2325#[no_mangle]
2326pub unsafe extern "C" fn xmlHashUpdateEntry(
2327 _table: *mut c_void,
2328 _name: *const xmlChar,
2329 _userdata: *mut c_void,
2330 _f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
2331) -> c_int {
2332 // Phase 1: STUB
2333 0
2334}
2335
2336/// Update or add a 2-key entry.
2337#[no_mangle]
2338pub unsafe extern "C" fn xmlHashUpdateEntry2(
2339 _table: *mut c_void,
2340 _name: *const xmlChar,
2341 _name2: *const xmlChar,
2342 _userdata: *mut c_void,
2343 _f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
2344) -> c_int {
2345 // Phase 1: STUB
2346 0
2347}
2348
2349/// Update or add a 3-key entry.
2350#[no_mangle]
2351pub unsafe extern "C" fn xmlHashUpdateEntry3(
2352 _table: *mut c_void,
2353 _name: *const xmlChar,
2354 _name2: *const xmlChar,
2355 _name3: *const xmlChar,
2356 _userdata: *mut c_void,
2357 _f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
2358) -> c_int {
2359 // Phase 1: STUB
2360 0
2361}
2362
2363/// Look up an entry.
2364///
2365/// # UPSTREAM-PARITY
2366///
2367/// ```c
2368/// void *xmlHashLookup(xmlHashTablePtr table, const xmlChar *name);
2369/// ```
2370#[no_mangle]
2371pub unsafe extern "C" fn xmlHashLookup(_table: *mut c_void, _name: *const xmlChar) -> *mut c_void {
2372 // Phase 1: STUB
2373 ptr::null_mut()
2374}
2375
2376/// Look up a 2-key entry.
2377#[no_mangle]
2378pub unsafe extern "C" fn xmlHashLookup2(
2379 _table: *mut c_void,
2380 _name: *const xmlChar,
2381 _name2: *const xmlChar,
2382) -> *mut c_void {
2383 // Phase 1: STUB
2384 ptr::null_mut()
2385}
2386
2387/// Look up a 3-key entry.
2388#[no_mangle]
2389pub unsafe extern "C" fn xmlHashLookup3(
2390 _table: *mut c_void,
2391 _name: *const xmlChar,
2392 _name2: *const xmlChar,
2393 _name3: *const xmlChar,
2394) -> *mut c_void {
2395 // Phase 1: STUB
2396 ptr::null_mut()
2397}
2398
2399/// Get the size of a hash table.
2400///
2401/// # UPSTREAM-PARITY
2402///
2403/// ```c
2404/// int xmlHashSize(xmlHashTablePtr table);
2405/// ```
2406#[no_mangle]
2407pub extern "C" fn xmlHashSize(_table: *mut c_void) -> c_int {
2408 // Phase 1: STUB
2409 0
2410}
2411
2412/// Remove an entry.
2413///
2414/// # UPSTREAM-PARITY
2415///
2416/// ```c
2417/// int xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name,
2418/// xmlHashDeallocator f);
2419/// ```
2420#[no_mangle]
2421pub unsafe extern "C" fn xmlHashRemoveEntry(
2422 _table: *mut c_void,
2423 _name: *const xmlChar,
2424 _f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
2425) -> c_int {
2426 // Phase 1: STUB
2427 0
2428}
2429
2430/// Remove a 2-key entry.
2431#[no_mangle]
2432pub unsafe extern "C" fn xmlHashRemoveEntry2(
2433 _table: *mut c_void,
2434 _name: *const xmlChar,
2435 _name2: *const xmlChar,
2436 _f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
2437) -> c_int {
2438 // Phase 1: STUB
2439 0
2440}
2441
2442/// Remove a 3-key entry.
2443#[no_mangle]
2444pub unsafe extern "C" fn xmlHashRemoveEntry3(
2445 _table: *mut c_void,
2446 _name: *const xmlChar,
2447 _name2: *const xmlChar,
2448 _name3: *const xmlChar,
2449 _f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
2450) -> c_int {
2451 // Phase 1: STUB
2452 0
2453}
2454
2455/// Scan a hash table with a scanner function.
2456///
2457/// # UPSTREAM-PARITY
2458///
2459/// ```c
2460/// void xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data);
2461/// ```
2462#[no_mangle]
2463pub extern "C" fn xmlHashScan(
2464 _table: *mut c_void,
2465 _f: Option<unsafe extern "C" fn(*mut c_void, *const xmlChar, *mut c_void)>,
2466 _data: *mut c_void,
2467) {
2468 // Phase 1: STUB
2469}
2470
2471/// Scan a hash table with a full scanner function.
2472#[no_mangle]
2473pub extern "C" fn xmlHashScanFull(
2474 _table: *mut c_void,
2475 _f: Option<unsafe extern "C" fn(*mut c_void, *const xmlChar, *mut c_void, *mut c_void)>,
2476 _data: *mut c_void,
2477) {
2478 // Phase 1: STUB
2479}
2480
2481/// Copy a hash table.
2482///
2483/// # UPSTREAM-PARITY
2484///
2485/// ```c
2486/// xmlHashTablePtr xmlHashCopy(xmlHashTablePtr table, xmlHashCopier f);
2487/// ```
2488#[no_mangle]
2489pub extern "C" fn xmlHashCopy(
2490 _table: *mut c_void,
2491 _f: Option<unsafe extern "C" fn(*mut c_void, *const xmlChar) -> *mut c_void>,
2492) -> *mut c_void {
2493 // Phase 1: STUB
2494 ptr::null_mut()
2495}
2496
2497// ═══════════════════════════════════════════════════════════════════════════════
2498// 11. List
2499// ═══════════════════════════════════════════════════════════════════════════════
2500
2501/// Create a new list.
2502///
2503/// # UPSTREAM-PARITY
2504///
2505/// ```c
2506/// xmlListPtr xmlListCreate(xmlListDeallocator deallocator,
2507/// xmlListDataCompare compare);
2508/// ```
2509#[no_mangle]
2510pub extern "C" fn xmlListCreate(
2511 _deallocator: Option<unsafe extern "C" fn(*mut c_void)>,
2512 _compare: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
2513) -> *mut c_void {
2514 // Phase 1: STUB
2515 ptr::null_mut()
2516}
2517
2518/// Delete a list.
2519///
2520/// # UPSTREAM-PARITY
2521///
2522/// ```c
2523/// void xmlListDelete(xmlListPtr list);
2524/// ```
2525#[no_mangle]
2526pub extern "C" fn xmlListDelete(_list: *mut c_void) {
2527 // Phase 1: STUB
2528}
2529
2530/// Search a list.
2531///
2532/// # UPSTREAM-PARITY
2533///
2534/// ```c
2535/// void *xmlListSearch(xmlListPtr list, void *data);
2536/// ```
2537#[no_mangle]
2538pub extern "C" fn xmlListSearch(_list: *mut c_void, _data: *mut c_void) -> *mut c_void {
2539 // Phase 1: STUB
2540 ptr::null_mut()
2541}
2542
2543/// Walk a list.
2544///
2545/// # UPSTREAM-PARITY
2546///
2547/// ```c
2548/// void xmlListWalk(xmlListPtr list, xmlListWalker walker, void *data);
2549/// ```
2550#[no_mangle]
2551pub extern "C" fn xmlListWalk(
2552 _list: *mut c_void,
2553 _walker: Option<unsafe extern "C" fn(*mut c_void, *mut c_void) -> c_int>,
2554 _data: *mut c_void,
2555) {
2556 // Phase 1: STUB
2557}
2558
2559/// Push to back.
2560///
2561/// # UPSTREAM-PARITY
2562///
2563/// ```c
2564/// int xmlListPushBack(xmlListPtr list, void *data);
2565/// ```
2566#[no_mangle]
2567pub extern "C" fn xmlListPushBack(_list: *mut c_void, _data: *mut c_void) -> c_int {
2568 // Phase 1: STUB
2569 0
2570}
2571
2572/// Push to front.
2573///
2574/// # UPSTREAM-PARITY
2575///
2576/// ```c
2577/// int xmlListPushFront(xmlListPtr list, void *data);
2578/// ```
2579#[no_mangle]
2580pub extern "C" fn xmlListPushFront(_list: *mut c_void, _data: *mut c_void) -> c_int {
2581 // Phase 1: STUB
2582 0
2583}
2584
2585/// Pop from back.
2586#[no_mangle]
2587pub extern "C" fn xmlListPopBack(_list: *mut c_void) {
2588 // Phase 1: STUB
2589}
2590
2591/// Pop from front.
2592#[no_mangle]
2593pub extern "C" fn xmlListPopFront(_list: *mut c_void) {
2594 // Phase 1: STUB
2595}
2596
2597/// Insert into sorted list.
2598///
2599/// # UPSTREAM-PARITY
2600///
2601/// ```c
2602/// int xmlListInsert(xmlListPtr list, void *data);
2603/// ```
2604#[no_mangle]
2605pub extern "C" fn xmlListInsert(_list: *mut c_void, _data: *mut c_void) -> c_int {
2606 // Phase 1: STUB
2607 0
2608}
2609
2610/// Append to list.
2611#[no_mangle]
2612pub extern "C" fn xmlListAppend(_list: *mut c_void, _data: *mut c_void) -> c_int {
2613 // Phase 1: STUB
2614 0
2615}
2616
2617/// Remove first matching element.
2618#[no_mangle]
2619pub extern "C" fn xmlListRemoveFirst(_list: *mut c_void, _data: *mut c_void) -> c_int {
2620 // Phase 1: STUB
2621 0
2622}
2623
2624/// Remove last matching element.
2625#[no_mangle]
2626pub extern "C" fn xmlListRemoveLast(_list: *mut c_void, _data: *mut c_void) -> c_int {
2627 // Phase 1: STUB
2628 0
2629}
2630
2631/// Remove all matching elements.
2632#[no_mangle]
2633pub extern "C" fn xmlListRemoveAll(_list: *mut c_void, _data: *mut c_void) -> c_int {
2634 // Phase 1: STUB
2635 0
2636}
2637
2638/// Clear a list.
2639#[no_mangle]
2640pub extern "C" fn xmlListClear(_list: *mut c_void) {
2641 // Phase 1: STUB
2642}
2643
2644/// Check if list is empty.
2645///
2646/// # UPSTREAM-PARITY
2647///
2648/// ```c
2649/// int xmlListEmpty(xmlListPtr list);
2650/// ```
2651#[no_mangle]
2652pub extern "C" fn xmlListEmpty(_list: *mut c_void) -> c_int {
2653 // Phase 1: STUB
2654 1
2655}
2656
2657/// Get front element.
2658///
2659/// # UPSTREAM-PARITY
2660///
2661/// ```c
2662/// void *xmlListFront(xmlListPtr list);
2663/// ```
2664#[no_mangle]
2665pub extern "C" fn xmlListFront(_list: *mut c_void) -> *mut c_void {
2666 // Phase 1: STUB
2667 ptr::null_mut()
2668}
2669
2670/// Get back element.
2671///
2672/// # UPSTREAM-PARITY
2673///
2674/// ```c
2675/// void *xmlListBack(xmlListPtr list);
2676/// ```
2677#[no_mangle]
2678pub extern "C" fn xmlListBack(_list: *mut c_void) -> *mut c_void {
2679 // Phase 1: STUB
2680 ptr::null_mut()
2681}
2682
2683/// Get list size.
2684///
2685/// # UPSTREAM-PARITY
2686///
2687/// ```c
2688/// int xmlListSize(xmlListPtr list);
2689/// ```
2690#[no_mangle]
2691pub extern "C" fn xmlListSize(_list: *mut c_void) -> c_int {
2692 // Phase 1: STUB
2693 0
2694}
2695
2696/// Sort a list.
2697#[no_mangle]
2698pub extern "C" fn xmlListSort(_list: *mut c_void) {
2699 // Phase 1: STUB
2700}
2701
2702/// Reverse a list.
2703#[no_mangle]
2704pub extern "C" fn xmlListReverse(_list: *mut c_void) {
2705 // Phase 1: STUB
2706}
2707
2708/// Reverse a list in-place.
2709#[no_mangle]
2710pub extern "C" fn xmlListReverseSplice(_list: *mut c_void, _list2: *mut c_void) {
2711 // Phase 1: STUB
2712}
2713
2714/// Merge two sorted lists.
2715#[no_mangle]
2716pub extern "C" fn xmlListMerge(_list: *mut c_void, _list2: *mut c_void) {
2717 // Phase 1: STUB
2718}
2719
2720// ═══════════════════════════════════════════════════════════════════════════════
2721// 12. Buffer
2722// ═══════════════════════════════════════════════════════════════════════════════
2723
2724/// Create a new buffer.
2725///
2726/// # UPSTREAM-PARITY
2727///
2728/// ```c
2729/// xmlBufferPtr xmlBufferCreate(void);
2730/// ```
2731#[no_mangle]
2732pub extern "C" fn xmlBufferCreate() -> *mut _xmlBuffer {
2733 // Phase 1: STUB
2734 ptr::null_mut()
2735}
2736
2737/// Create a new buffer of a given size.
2738///
2739/// # UPSTREAM-PARITY
2740///
2741/// ```c
2742/// xmlBufferPtr xmlBufferCreateSize(size_t size);
2743/// ```
2744#[no_mangle]
2745pub extern "C" fn xmlBufferCreateSize(_size: usize) -> *mut _xmlBuffer {
2746 // Phase 1: STUB
2747 ptr::null_mut()
2748}
2749
2750/// Create a buffer from a static string.
2751///
2752/// # UPSTREAM-PARITY
2753///
2754/// ```c
2755/// xmlBufferPtr xmlBufferCreateStatic(void *mem, size_t size);
2756/// ```
2757#[no_mangle]
2758pub extern "C" fn xmlBufferCreateStatic(_mem: *mut c_void, _size: usize) -> *mut _xmlBuffer {
2759 // Phase 1: STUB
2760 ptr::null_mut()
2761}
2762
2763/// Free a buffer.
2764///
2765/// # UPSTREAM-PARITY
2766///
2767/// ```c
2768/// void xmlBufferFree(xmlBufferPtr buf);
2769/// ```
2770#[no_mangle]
2771pub extern "C" fn xmlBufferFree(_buf: *mut _xmlBuffer) {
2772 // Phase 1: STUB
2773}
2774
2775/// Empty a buffer.
2776///
2777/// # UPSTREAM-PARITY
2778///
2779/// ```c
2780/// void xmlBufferEmpty(xmlBufferPtr buf);
2781/// ```
2782#[no_mangle]
2783pub extern "C" fn xmlBufferEmpty(_buf: *mut _xmlBuffer) {
2784 // Phase 1: STUB
2785}
2786
2787/// Get buffer content.
2788///
2789/// # UPSTREAM-PARITY
2790///
2791/// ```c
2792/// xmlChar *xmlBufferContent(const xmlBuffer *buf);
2793/// ```
2794#[no_mangle]
2795pub extern "C" fn xmlBufferContent(_buf: *const _xmlBuffer) -> *mut xmlChar {
2796 // Phase 1: STUB
2797 ptr::null_mut()
2798}
2799
2800/// Get buffer length.
2801///
2802/// # UPSTREAM-PARITY
2803///
2804/// ```c
2805/// int xmlBufferLength(const xmlBuffer *buf);
2806/// ```
2807#[no_mangle]
2808pub extern "C" fn xmlBufferLength(_buf: *const _xmlBuffer) -> c_int {
2809 // Phase 1: STUB
2810 0
2811}
2812
2813/// Write to a buffer.
2814///
2815/// # UPSTREAM-PARITY
2816///
2817/// ```c
2818/// int xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len);
2819/// ```
2820#[no_mangle]
2821pub unsafe extern "C" fn xmlBufferAdd(
2822 _buf: *mut _xmlBuffer,
2823 _str: *const xmlChar,
2824 _len: c_int,
2825) -> c_int {
2826 // Phase 1: STUB
2827 0
2828}
2829
2830/// Write to a buffer at a position.
2831///
2832/// # UPSTREAM-PARITY
2833///
2834/// ```c
2835/// int xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len);
2836/// ```
2837#[no_mangle]
2838pub unsafe extern "C" fn xmlBufferAddHead(
2839 _buf: *mut _xmlBuffer,
2840 _str: *const xmlChar,
2841 _len: c_int,
2842) -> c_int {
2843 // Phase 1: STUB
2844 0
2845}
2846
2847/// Set buffer allocation scheme.
2848///
2849/// # UPSTREAM-PARITY
2850///
2851/// ```c
2852/// void xmlBufferSetAllocationScheme(xmlBufferPtr buf,
2853/// xmlBufferAllocationScheme scheme);
2854/// ```
2855#[no_mangle]
2856pub extern "C" fn xmlBufferSetAllocationScheme(_buf: *mut _xmlBuffer, _scheme: c_int) {
2857 // Phase 1: STUB
2858}
2859
2860/// Shrink buffer.
2861///
2862/// # UPSTREAM-PARITY
2863///
2864/// ```c
2865/// int xmlBufferShrink(xmlBufferPtr buf, int len);
2866/// ```
2867#[no_mangle]
2868pub extern "C" fn xmlBufferShrink(_buf: *mut _xmlBuffer, _len: c_int) -> c_int {
2869 // Phase 1: STUB
2870 0
2871}
2872
2873/// Grow buffer.
2874///
2875/// # UPSTREAM-PARITY
2876///
2877/// ```c
2878/// int xmlBufferGrow(xmlBufferPtr buf, int len);
2879/// ```
2880#[no_mangle]
2881pub extern "C" fn xmlBufferGrow(_buf: *mut _xmlBuffer, _len: c_int) -> c_int {
2882 // Phase 1: STUB
2883 0
2884}
2885
2886/// Reserve buffer space.
2887///
2888/// # UPSTREAM-PARITY
2889///
2890/// ```c
2891/// int xmlBufferReserve(xmlBufferPtr buf, int len);
2892/// ```
2893#[no_mangle]
2894pub extern "C" fn xmlBufferReserve(_buf: *mut _xmlBuffer, _len: c_int) -> c_int {
2895 // Phase 1: STUB
2896 0
2897}
2898
2899/// Detach buffer content.
2900///
2901/// # UPSTREAM-PARITY
2902///
2903/// ```c
2904/// xmlChar *xmlBufferDetach(xmlBufferPtr buf);
2905/// ```
2906#[no_mangle]
2907pub extern "C" fn xmlBufferDetach(_buf: *mut _xmlBuffer) -> *mut xmlChar {
2908 // Phase 1: STUB
2909 ptr::null_mut()
2910}
2911
2912// ═══════════════════════════════════════════════════════════════════════════════
2913// 13. Encoding
2914// ═══════════════════════════════════════════════════════════════════════════════
2915
2916/// Get encoding from a name string.
2917///
2918/// # UPSTREAM-PARITY
2919///
2920/// ```c
2921/// xmlCharEncoding xmlGetCharEncoding(const char *name);
2922/// ```
2923#[no_mangle]
2924pub extern "C" fn xmlGetCharEncoding(_name: *const c_char) -> c_int {
2925 // Phase 1: STUB
2926 // Return XML_CHAR_ENCODING_NONE = 0
2927 0
2928}
2929
2930/// Find an encoding handler.
2931///
2932/// # UPSTREAM-PARITY
2933///
2934/// ```c
2935/// xmlCharEncodingHandlerPtr xmlFindCharEncodingHandler(const char *name);
2936/// ```
2937#[no_mangle]
2938pub extern "C" fn xmlFindCharEncodingHandler(_name: *const c_char) -> *mut c_void {
2939 // Phase 1: STUB
2940 ptr::null_mut()
2941}
2942
2943/// Close an encoding handler.
2944///
2945/// # UPSTREAM-PARITY
2946///
2947/// ```c
2948/// int xmlCharEncCloseFunc(xmlCharEncodingHandlerPtr handler);
2949/// ```
2950#[no_mangle]
2951pub extern "C" fn xmlCharEncCloseFunc(_handler: *mut c_void) -> c_int {
2952 // Phase 1: STUB
2953 0
2954}
2955
2956/// Convert an input buffer's encoding.
2957///
2958/// # UPSTREAM-PARITY
2959///
2960/// ```c
2961/// int xmlCharEncInput(xmlParserInputBufferPtr input, int to);
2962/// ```
2963#[no_mangle]
2964pub extern "C" fn xmlCharEncInput(_input: *mut _xmlParserInputBuffer, _to: c_int) -> c_int {
2965 // Phase 1: STUB
2966 0
2967}
2968
2969/// Convert an output buffer's encoding.
2970///
2971/// # UPSTREAM-PARITY
2972///
2973/// ```c
2974/// int xmlCharEncOutput(xmlOutputBufferPtr output, int to);
2975/// ```
2976#[no_mangle]
2977pub extern "C" fn xmlCharEncOutput(_output: *mut _xmlOutputBuffer, _to: c_int) -> c_int {
2978 // Phase 1: STUB
2979 0
2980}
2981
2982// ═══════════════════════════════════════════════════════════════════════════════
2983// 14. XPath
2984// ═══════════════════════════════════════════════════════════════════════════════
2985
2986/// Create a new XPath context.
2987///
2988/// # UPSTREAM-PARITY
2989///
2990/// ```c
2991/// xmlXPathContextPtr xmlXPathNewContext(xmlDocPtr doc);
2992/// ```
2993#[no_mangle]
2994pub unsafe extern "C" fn xmlXPathNewContext(_doc: *mut _xmlDoc) -> *mut _xmlXPathContext {
2995 // Phase 1: STUB
2996 ptr::null_mut()
2997}
2998
2999/// Free an XPath context.
3000///
3001/// # UPSTREAM-PARITY
3002///
3003/// ```c
3004/// void xmlXPathFreeContext(xmlXPathContextPtr ctxt);
3005/// ```
3006#[no_mangle]
3007pub extern "C" fn xmlXPathFreeContext(_ctxt: *mut _xmlXPathContext) {
3008 // Phase 1: STUB
3009}
3010
3011/// Evaluate an XPath expression.
3012///
3013/// # UPSTREAM-PARITY
3014///
3015/// ```c
3016/// xmlXPathObjectPtr xmlXPathEvalExpression(const xmlChar *str,
3017/// xmlXPathContextPtr ctxt);
3018/// ```
3019#[no_mangle]
3020pub unsafe extern "C" fn xmlXPathEvalExpression(
3021 _str: *const xmlChar,
3022 _ctxt: *mut _xmlXPathContext,
3023) -> *mut _xmlXPathObject {
3024 // Phase 1: STUB
3025 ptr::null_mut()
3026}
3027
3028/// Evaluate an XPath expression (simplified).
3029///
3030/// # UPSTREAM-PARITY
3031///
3032/// ```c
3033/// xmlXPathObjectPtr xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctxt);
3034/// ```
3035#[no_mangle]
3036pub unsafe extern "C" fn xmlXPathEval(
3037 _str: *const xmlChar,
3038 _ctxt: *mut _xmlXPathContext,
3039) -> *mut _xmlXPathObject {
3040 // Phase 1: STUB
3041 ptr::null_mut()
3042}
3043
3044/// Free an XPath object.
3045///
3046/// # UPSTREAM-PARITY
3047///
3048/// ```c
3049/// void xmlXPathFreeObject(xmlXPathObjectPtr obj);
3050/// ```
3051#[no_mangle]
3052pub extern "C" fn xmlXPathFreeObject(_obj: *mut _xmlXPathObject) {
3053 // Phase 1: STUB
3054}
3055
3056/// Compile an XPath expression.
3057///
3058/// # UPSTREAM-PARITY
3059///
3060/// ```c
3061/// xmlXPathCompExprPtr xmlXPathCompile(const xmlChar *str);
3062/// ```
3063#[no_mangle]
3064pub unsafe extern "C" fn xmlXPathCompile(_str: *const xmlChar) -> *mut c_void {
3065 // Phase 1: STUB
3066 ptr::null_mut()
3067}
3068
3069/// Free a compiled XPath expression.
3070///
3071/// # UPSTREAM-PARITY
3072///
3073/// ```c
3074/// void xmlXPathFreeCompExpr(xmlXPathCompExprPtr comp);
3075/// ```
3076#[no_mangle]
3077pub extern "C" fn xmlXPathFreeCompExpr(_comp: *mut c_void) {
3078 // Phase 1: STUB
3079}
3080
3081/// Register an XPath namespace.
3082///
3083/// # UPSTREAM-PARITY
3084///
3085/// ```c
3086/// int xmlXPathRegisterNs(xmlXPathContextPtr ctxt,
3087/// const xmlChar *prefix, const xmlChar *ns_uri);
3088/// ```
3089#[no_mangle]
3090pub unsafe extern "C" fn xmlXPathRegisterNs(
3091 _ctxt: *mut _xmlXPathContext,
3092 _prefix: *const xmlChar,
3093 _ns_uri: *const xmlChar,
3094) -> c_int {
3095 // Phase 1: STUB
3096 0
3097}
3098
3099/// Register an XPath function.
3100///
3101/// # UPSTREAM-PARITY
3102///
3103/// ```c
3104/// int xmlXPathRegisterFunc(xmlXPathContextPtr ctxt,
3105/// const xmlChar *name, xmlXPathFunction f);
3106/// ```
3107#[no_mangle]
3108pub unsafe extern "C" fn xmlXPathRegisterFunc(
3109 _ctxt: *mut _xmlXPathContext,
3110 _name: *const xmlChar,
3111 _f: Option<unsafe extern "C" fn(*mut c_void, c_int)>,
3112) -> c_int {
3113 // Phase 1: STUB
3114 0
3115}
3116
3117/// Register an XPath function with namespace.
3118///
3119/// # UPSTREAM-PARITY
3120///
3121/// ```c
3122/// int xmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt,
3123/// const xmlChar *name, const xmlChar *ns_uri,
3124/// xmlXPathFunction f);
3125/// ```
3126#[no_mangle]
3127pub unsafe extern "C" fn xmlXPathRegisterFuncNS(
3128 _ctxt: *mut _xmlXPathContext,
3129 _name: *const xmlChar,
3130 _ns_uri: *const xmlChar,
3131 _f: Option<unsafe extern "C" fn(*mut c_void, c_int)>,
3132) -> c_int {
3133 // Phase 1: STUB
3134 0
3135}
3136
3137/// Register an XPath variable.
3138///
3139/// # UPSTREAM-PARITY
3140///
3141/// ```c
3142/// int xmlXPathRegisterVariable(xmlXPathContextPtr ctxt,
3143/// const xmlChar *name, xmlXPathObjectPtr value);
3144/// ```
3145#[no_mangle]
3146pub unsafe extern "C" fn xmlXPathRegisterVariable(
3147 _ctxt: *mut _xmlXPathContext,
3148 _name: *const xmlChar,
3149 _value: *mut _xmlXPathObject,
3150) -> c_int {
3151 // Phase 1: STUB
3152 0
3153}
3154
3155/// Create an XPath object from a node set.
3156///
3157/// # UPSTREAM-PARITY
3158///
3159/// ```c
3160/// xmlXPathObjectPtr xmlXPathNewNodeSet(xmlNodePtr val);
3161/// ```
3162#[no_mangle]
3163pub unsafe extern "C" fn xmlXPathNewNodeSet(_val: *mut _xmlNode) -> *mut _xmlXPathObject {
3164 // Phase 1: STUB
3165 ptr::null_mut()
3166}
3167
3168/// Create an XPath object from a value.
3169///
3170/// # UPSTREAM-PARITY
3171///
3172/// ```c
3173/// xmlXPathObjectPtr xmlXPathNewCString(const xmlChar *val);
3174/// ```
3175#[no_mangle]
3176pub unsafe extern "C" fn xmlXPathNewCString(_val: *const xmlChar) -> *mut _xmlXPathObject {
3177 // Phase 1: STUB
3178 ptr::null_mut()
3179}
3180
3181/// Create an XPath number object.
3182///
3183/// # UPSTREAM-PARITY
3184///
3185/// ```c
3186/// xmlXPathObjectPtr xmlXPathNewFloat(double val);
3187/// ```
3188#[no_mangle]
3189pub extern "C" fn xmlXPathNewFloat(_val: f64) -> *mut _xmlXPathObject {
3190 // Phase 1: STUB
3191 ptr::null_mut()
3192}
3193
3194/// Create an XPath boolean object.
3195///
3196/// # UPSTREAM-PARITY
3197///
3198/// ```c
3199/// xmlXPathObjectPtr xmlXPathNewBoolean(int val);
3200/// ```
3201#[no_mangle]
3202pub extern "C" fn xmlXPathNewBoolean(_val: c_int) -> *mut _xmlXPathObject {
3203 // Phase 1: STUB
3204 ptr::null_mut()
3205}
3206
3207// ═══════════════════════════════════════════════════════════════════════════════
3208// 15. XInclude
3209// ═══════════════════════════════════════════════════════════════════════════════
3210
3211/// Process XInclude nodes in a document.
3212///
3213/// # UPSTREAM-PARITY
3214///
3215/// ```c
3216/// int xmlXIncludeProcess(xmlDocPtr doc);
3217/// ```
3218#[no_mangle]
3219pub extern "C" fn xmlXIncludeProcess(_doc: *mut _xmlDoc) -> c_int {
3220 // Phase 1: STUB
3221 -1
3222}
3223
3224/// Process XInclude nodes with flags.
3225///
3226/// # UPSTREAM-PARITY
3227///
3228/// ```c
3229/// int xmlXIncludeProcessFlags(xmlDocPtr doc, int flags);
3230/// ```
3231#[no_mangle]
3232pub extern "C" fn xmlXIncludeProcessFlags(_doc: *mut _xmlDoc, _flags: c_int) -> c_int {
3233 // Phase 1: STUB
3234 -1
3235}
3236
3237// ═══════════════════════════════════════════════════════════════════════════════
3238// 16. Catalog
3239// ═══════════════════════════════════════════════════════════════════════════════
3240
3241/// Load a catalog.
3242///
3243/// # UPSTREAM-PARITY
3244///
3245/// ```c
3246/// xmlCatalogPtr xmlCatalogLoad(const char *catalogs);
3247/// ```
3248#[no_mangle]
3249pub extern "C" fn xmlCatalogLoad(_catalogs: *const c_char) -> *mut c_void {
3250 // Phase 1: STUB
3251 ptr::null_mut()
3252}
3253
3254/// Resolve a public ID.
3255///
3256/// # UPSTREAM-PARITY
3257///
3258/// ```c
3259/// xmlCharPtr xmlCatalogResolvePublic(const xmlChar *pubID);
3260/// ```
3261#[no_mangle]
3262pub unsafe extern "C" fn xmlCatalogResolvePublic(_pubID: *const xmlChar) -> *mut xmlChar {
3263 // Phase 1: STUB
3264 ptr::null_mut()
3265}
3266
3267/// Resolve a system ID.
3268///
3269/// # UPSTREAM-PARITY
3270///
3271/// ```c
3272/// xmlCharPtr xmlCatalogResolveSystem(const xmlChar *sysID);
3273/// ```
3274#[no_mangle]
3275pub unsafe extern "C" fn xmlCatalogResolveSystem(_sysID: *const xmlChar) -> *mut xmlChar {
3276 // Phase 1: STUB
3277 ptr::null_mut()
3278}
3279
3280/// Resolve a URI.
3281///
3282/// # UPSTREAM-PARITY
3283///
3284/// ```c
3285/// xmlCharPtr xmlCatalogResolveURI(const xmlChar *URI);
3286/// ```
3287#[no_mangle]
3288pub unsafe extern "C" fn xmlCatalogResolveURI(_URI: *const xmlChar) -> *mut xmlChar {
3289 // Phase 1: STUB
3290 ptr::null_mut()
3291}
3292
3293/// Set catalog defaults.
3294///
3295/// # UPSTREAM-PARITY
3296///
3297/// ```c
3298/// void xmlCatalogSetDefaults(xmlCatalogAllowValue allow);
3299/// ```
3300#[no_mangle]
3301pub extern "C" fn xmlCatalogSetDefaults(_allow: c_int) {
3302 // Phase 1: STUB
3303}
3304
3305/// Get catalog defaults.
3306///
3307/// # UPSTREAM-PARITY
3308///
3309/// ```c
3310/// xmlCatalogAllowValue xmlCatalogGetDefaults(void);
3311/// ```
3312#[no_mangle]
3313pub extern "C" fn xmlCatalogGetDefaults() -> c_int {
3314 // Phase 1: STUB
3315 0
3316}
3317
3318/// Add a catalog.
3319///
3320/// # UPSTREAM-PARITY
3321///
3322/// ```c
3323/// int xmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace);
3324/// ```
3325#[no_mangle]
3326pub unsafe extern "C" fn xmlCatalogAdd(
3327 _type: *const xmlChar,
3328 _orig: *const xmlChar,
3329 _replace: *const xmlChar,
3330) -> c_int {
3331 // Phase 1: STUB
3332 0
3333}
3334
3335/// Remove a catalog entry.
3336///
3337/// # UPSTREAM-PARITY
3338///
3339/// ```c
3340/// int xmlCatalogRemove(const xmlChar *value);
3341/// ```
3342#[no_mangle]
3343pub unsafe extern "C" fn xmlCatalogRemove(_value: *const xmlChar) -> c_int {
3344 // Phase 1: STUB
3345 0
3346}
3347
3348/// Clean up the catalog subsystem.
3349///
3350/// # UPSTREAM-PARITY
3351///
3352/// ```c
3353/// void xmlCatalogCleanup(void);
3354/// ```
3355#[no_mangle]
3356pub extern "C" fn xmlCatalogCleanup() {
3357 // Phase 1: STUB
3358}
3359
3360/// Convert an SGML catalog to XML.
3361///
3362/// # UPSTREAM-PARITY
3363///
3364/// ```c
3365/// xmlDocPtr xmlCatalogConvert(void);
3366/// ```
3367#[no_mangle]
3368pub extern "C" fn xmlCatalogConvert() -> *mut _xmlDoc {
3369 // Phase 1: STUB
3370 ptr::null_mut()
3371}
3372
3373// ═══════════════════════════════════════════════════════════════════════════════
3374// 17. HTML
3375// ═══════════════════════════════════════════════════════════════════════════════
3376
3377/// Parse an HTML document from a file.
3378///
3379/// # UPSTREAM-PARITY
3380///
3381/// ```c
3382/// htmlDocPtr htmlParseFile(const char *filename, const char *encoding);
3383/// ```
3384#[no_mangle]
3385pub unsafe extern "C" fn htmlParseFile(
3386 _filename: *const c_char,
3387 _encoding: *const c_char,
3388) -> *mut _xmlDoc {
3389 // Phase 1: STUB
3390 ptr::null_mut()
3391}
3392
3393/// Parse an HTML document from memory.
3394///
3395/// # UPSTREAM-PARITY
3396///
3397/// ```c
3398/// htmlDocPtr htmlParseMemory(const char *buffer, int size);
3399/// ```
3400#[no_mangle]
3401pub unsafe extern "C" fn htmlParseMemory(_buffer: *const c_char, _size: c_int) -> *mut _xmlDoc {
3402 // Phase 1: STUB
3403 ptr::null_mut()
3404}
3405
3406/// Parse an HTML document from a document string.
3407///
3408/// # UPSTREAM-PARITY
3409///
3410/// ```c
3411/// htmlDocPtr htmlParseDoc(const xmlChar *cur, const char *encoding);
3412/// ```
3413#[no_mangle]
3414pub unsafe extern "C" fn htmlParseDoc(
3415 _cur: *const xmlChar,
3416 _encoding: *const c_char,
3417) -> *mut _xmlDoc {
3418 // Phase 1: STUB
3419 ptr::null_mut()
3420}
3421
3422/// Create an HTML parser context.
3423///
3424/// # UPSTREAM-PARITY
3425///
3426/// ```c
3427/// htmlParserCtxtPtr htmlCreateFileParserCtxt(const char *filename,
3428/// const char *encoding);
3429/// ```
3430#[no_mangle]
3431pub unsafe extern "C" fn htmlCreateFileParserCtxt(
3432 _filename: *const c_char,
3433 _encoding: *const c_char,
3434) -> *mut c_void {
3435 // Phase 1: STUB
3436 ptr::null_mut()
3437}
3438
3439/// Free an HTML parser context.
3440///
3441/// # UPSTREAM-PARITY
3442///
3443/// ```c
3444/// void htmlFreeParserCtxt(htmlParserCtxtPtr ctxt);
3445/// ```
3446#[no_mangle]
3447pub extern "C" fn htmlFreeParserCtxt(_ctxt: *mut c_void) {
3448 // Phase 1: STUB
3449}
3450
3451/// Initialize the HTML parser.
3452///
3453/// # UPSTREAM-PARITY
3454///
3455/// ```c
3456/// void htmlInitParser(void);
3457/// ```
3458#[no_mangle]
3459pub extern "C" fn htmlInitParser() {
3460 // Phase 1: STUB
3461}
3462
3463/// Clean up the HTML parser.
3464///
3465/// # UPSTREAM-PARITY
3466///
3467/// ```c
3468/// void htmlCleanupParser(void);
3469/// ```
3470#[no_mangle]
3471pub extern "C" fn htmlCleanupParser() {
3472 // Phase 1: STUB
3473}
3474
3475// ═══════════════════════════════════════════════════════════════════════════════
3476// 18. Debug / Miscellaneous
3477// ═══════════════════════════════════════════════════════════════════════════════
3478
3479/// Dump a document to a file for debugging.
3480///
3481/// # UPSTREAM-PARITY
3482///
3483/// ```c
3484/// void xmlDebugDumpDocument(FILE *output, xmlDocPtr doc);
3485/// ```
3486#[no_mangle]
3487pub unsafe extern "C" fn xmlDebugDumpDocument(_output: *mut c_void, _doc: *mut _xmlDoc) {
3488 // Phase 1: STUB
3489}
3490
3491/// Dump a node for debugging.
3492///
3493/// # UPSTREAM-PARITY
3494///
3495/// ```c
3496/// void xmlDebugDumpNode(FILE *output, xmlNodePtr node);
3497/// ```
3498#[no_mangle]
3499pub unsafe extern "C" fn xmlDebugDumpNode(_output: *mut c_void, _node: *mut _xmlNode) {
3500 // Phase 1: STUB
3501}
3502
3503/// Dump a node for debugging (recursive).
3504///
3505/// # UPSTREAM-PARITY
3506///
3507/// ```c
3508/// void xmlDebugDumpNodeList(FILE *output, xmlNodePtr node);
3509/// ```
3510#[no_mangle]
3511pub unsafe extern "C" fn xmlDebugDumpNodeList(_output: *mut c_void, _node: *mut _xmlNode) {
3512 // Phase 1: STUB
3513}
3514
3515/// Get the path to the current executable.
3516///
3517/// # UPSTREAM-PARITY
3518///
3519/// ```c
3520/// char *xmlGetBinaryPath(void);
3521/// ```
3522#[no_mangle]
3523pub extern "C" fn xmlGetBinaryPath() -> *mut c_char {
3524 // Phase 1: STUB
3525 ptr::null_mut()
3526}
3527
3528/// Get the path to the current executable's home directory.
3529///
3530/// # UPSTREAM-PARITY
3531///
3532/// ```c
3533/// char *xmlGetHomeOfBinary(void);
3534/// ```
3535#[no_mangle]
3536pub extern "C" fn xmlGetHomeOfBinary() -> *mut c_char {
3537 // Phase 1: STUB
3538 ptr::null_mut()
3539}