1#![no_std]
8#![doc(html_root_url = "https://docs.rs/unsafe-libyaml/0.2.11")]
9#![allow(non_camel_case_types, non_snake_case, unsafe_op_in_unsafe_fn)]
10#![warn(clippy::pedantic)]
11#![allow(
12 clippy::bool_to_int_with_if,
13 clippy::cast_lossless,
14 clippy::cast_possible_truncation,
15 clippy::cast_possible_wrap,
16 clippy::cast_ptr_alignment,
17 clippy::cast_sign_loss,
18 clippy::collapsible_if,
19 clippy::doc_markdown,
20 clippy::fn_params_excessive_bools,
21 clippy::if_not_else,
22 clippy::items_after_statements,
23 clippy::let_underscore_untyped,
24 clippy::manual_range_contains,
25 clippy::manual_swap,
26 clippy::missing_panics_doc,
27 clippy::missing_safety_doc,
28 clippy::module_name_repetitions,
29 clippy::must_use_candidate,
30 clippy::nonminimal_bool,
31 clippy::ptr_as_ptr,
32 clippy::redundant_else,
33 clippy::similar_names,
34 clippy::single_match,
35 clippy::single_match_else,
36 clippy::too_many_arguments,
37 clippy::too_many_lines,
38 clippy::unnecessary_cast,
39 clippy::unreadable_literal,
40 clippy::while_immutable_condition, )]
42
43extern crate alloc;
44
45use core::mem::size_of;
46
47mod libc {
48 pub use core::ffi::c_void;
49 pub use core::primitive::{
50 i32 as c_int, i64 as c_long, i8 as c_char, u32 as c_uint, u64 as c_ulong, u8 as c_uchar,
51 };
52}
53
54#[macro_use]
55mod externs {
56 use crate::libc;
57 use crate::ops::{die, ForceAdd as _, ForceInto as _};
58 use alloc::alloc::{self as rust, Layout};
59 use core::mem::{self, MaybeUninit};
60 use core::ptr;
61 use core::slice;
62
63 const HEADER: usize = {
64 let need_len = mem::size_of::<usize>();
65 (need_len + MALLOC_ALIGN - 1) & !(MALLOC_ALIGN - 1)
67 };
68
69 const MALLOC_ALIGN: usize = {
72 let int_align = mem::align_of::<libc::c_ulong>();
73 let ptr_align = mem::align_of::<usize>();
74 if int_align >= ptr_align {
75 int_align
76 } else {
77 ptr_align
78 }
79 };
80
81 pub unsafe fn malloc(size: libc::c_ulong) -> *mut libc::c_void {
82 let size = HEADER.force_add(size.force_into());
83 let layout = Layout::from_size_align(size, MALLOC_ALIGN)
84 .ok()
85 .unwrap_or_else(die);
86 let memory = rust::alloc(layout);
87 if memory.is_null() {
88 rust::handle_alloc_error(layout);
89 }
90 memory.cast::<usize>().write(size);
91 memory.add(HEADER).cast()
92 }
93
94 pub unsafe fn realloc(ptr: *mut libc::c_void, new_size: libc::c_ulong) -> *mut libc::c_void {
95 let mut memory = ptr.cast::<u8>().sub(HEADER);
96 let size = memory.cast::<usize>().read();
97 let layout = Layout::from_size_align_unchecked(size, MALLOC_ALIGN);
98 let new_size = HEADER.force_add(new_size.force_into());
99 let new_layout = Layout::from_size_align(new_size, MALLOC_ALIGN)
100 .ok()
101 .unwrap_or_else(die);
102 memory = rust::realloc(memory, layout, new_size);
103 if memory.is_null() {
104 rust::handle_alloc_error(new_layout);
105 }
106 memory.cast::<usize>().write(new_size);
107 memory.add(HEADER).cast()
108 }
109
110 pub unsafe fn free(ptr: *mut libc::c_void) {
111 let memory = ptr.cast::<u8>().sub(HEADER);
112 let size = memory.cast::<usize>().read();
113 let layout = Layout::from_size_align_unchecked(size, MALLOC_ALIGN);
114 rust::dealloc(memory, layout);
115 }
116
117 pub unsafe fn memcmp(
118 lhs: *const libc::c_void,
119 rhs: *const libc::c_void,
120 count: libc::c_ulong,
121 ) -> libc::c_int {
122 let lhs = slice::from_raw_parts(lhs.cast::<u8>(), count as usize);
123 let rhs = slice::from_raw_parts(rhs.cast::<u8>(), count as usize);
124 lhs.cmp(rhs) as libc::c_int
125 }
126
127 pub unsafe fn memcpy(
128 dest: *mut libc::c_void,
129 src: *const libc::c_void,
130 count: libc::c_ulong,
131 ) -> *mut libc::c_void {
132 ptr::copy_nonoverlapping(
133 src.cast::<MaybeUninit<u8>>(),
134 dest.cast::<MaybeUninit<u8>>(),
135 count as usize,
136 );
137 dest
138 }
139
140 pub unsafe fn memmove(
141 dest: *mut libc::c_void,
142 src: *const libc::c_void,
143 count: libc::c_ulong,
144 ) -> *mut libc::c_void {
145 ptr::copy(
146 src.cast::<MaybeUninit<u8>>(),
147 dest.cast::<MaybeUninit<u8>>(),
148 count as usize,
149 );
150 dest
151 }
152
153 pub unsafe fn memset(
154 dest: *mut libc::c_void,
155 ch: libc::c_int,
156 count: libc::c_ulong,
157 ) -> *mut libc::c_void {
158 ptr::write_bytes(dest.cast::<u8>(), ch as u8, count as usize);
159 dest
160 }
161
162 pub unsafe fn strcmp(lhs: *const libc::c_char, rhs: *const libc::c_char) -> libc::c_int {
163 let lhs = slice::from_raw_parts(lhs.cast::<u8>(), strlen(lhs) as usize);
164 let rhs = slice::from_raw_parts(rhs.cast::<u8>(), strlen(rhs) as usize);
165 lhs.cmp(rhs) as libc::c_int
166 }
167
168 pub unsafe fn strdup(src: *const libc::c_char) -> *mut libc::c_char {
169 let len = strlen(src);
170 let dest = malloc(len + 1);
171 memcpy(dest, src.cast(), len + 1);
172 dest.cast()
173 }
174
175 pub unsafe fn strlen(str: *const libc::c_char) -> libc::c_ulong {
176 let mut end = str;
177 while *end != 0 {
178 end = end.add(1);
179 }
180 end.offset_from(str) as libc::c_ulong
181 }
182
183 pub unsafe fn strncmp(
184 lhs: *const libc::c_char,
185 rhs: *const libc::c_char,
186 mut count: libc::c_ulong,
187 ) -> libc::c_int {
188 let mut lhs = lhs.cast::<u8>();
189 let mut rhs = rhs.cast::<u8>();
190 while count > 0 && *lhs != 0 && *lhs == *rhs {
191 lhs = lhs.add(1);
192 rhs = rhs.add(1);
193 count -= 1;
194 }
195 if count == 0 {
196 0
197 } else {
198 (*lhs).cmp(&*rhs) as libc::c_int
199 }
200 }
201
202 macro_rules! __assert {
203 (false $(,)?) => {
204 $crate::externs::__assert_fail(stringify!(false), file!(), line!())
205 };
206 ($assertion:expr $(,)?) => {
207 if !$assertion {
208 $crate::externs::__assert_fail(stringify!($assertion), file!(), line!());
209 }
210 };
211 }
212
213 pub(crate) unsafe fn __assert_fail(
214 __assertion: &'static str,
215 __file: &'static str,
216 __line: u32,
217 ) -> ! {
218 struct Abort;
219 impl Drop for Abort {
220 fn drop(&mut self) {
221 panic!();
222 }
223 }
224 let _abort_on_panic = Abort;
225 panic!("{}:{}: Assertion `{}` failed.", __file, __line, __assertion);
226 }
227}
228
229mod fmt {
230 use crate::yaml::yaml_char_t;
231 use core::fmt::{self, Write};
232 use core::ptr;
233
234 pub struct WriteToPtr {
235 ptr: *mut yaml_char_t,
236 }
237
238 impl WriteToPtr {
239 pub unsafe fn new(ptr: *mut yaml_char_t) -> Self {
240 WriteToPtr { ptr }
241 }
242
243 pub fn write_fmt(&mut self, args: fmt::Arguments) {
244 let _ = Write::write_fmt(self, args);
245 }
246 }
247
248 impl Write for WriteToPtr {
249 fn write_str(&mut self, s: &str) -> fmt::Result {
250 unsafe {
251 ptr::copy_nonoverlapping(s.as_ptr(), self.ptr, s.len());
252 self.ptr = self.ptr.add(s.len());
253 }
254 Ok(())
255 }
256 }
257}
258
259trait PointerExt: Sized {
260 fn c_offset_from(self, origin: Self) -> isize;
261}
262
263impl<T> PointerExt for *const T {
264 fn c_offset_from(self, origin: *const T) -> isize {
265 (self as isize - origin as isize) / size_of::<T>() as isize
266 }
267}
268
269impl<T> PointerExt for *mut T {
270 fn c_offset_from(self, origin: *mut T) -> isize {
271 (self as isize - origin as isize) / size_of::<T>() as isize
272 }
273}
274
275#[macro_use]
276mod macros;
277
278mod api;
279mod dumper;
280mod emitter;
281mod loader;
282mod ops;
283mod parser;
284mod reader;
285mod scanner;
286mod success;
287mod writer;
288mod yaml;
289
290pub use crate::api::{
291 yaml_alias_event_initialize, yaml_document_add_mapping, yaml_document_add_scalar,
292 yaml_document_add_sequence, yaml_document_append_mapping_pair,
293 yaml_document_append_sequence_item, yaml_document_delete, yaml_document_end_event_initialize,
294 yaml_document_get_node, yaml_document_get_root_node, yaml_document_initialize,
295 yaml_document_start_event_initialize, yaml_emitter_delete, yaml_emitter_initialize,
296 yaml_emitter_set_break, yaml_emitter_set_canonical, yaml_emitter_set_encoding,
297 yaml_emitter_set_indent, yaml_emitter_set_output, yaml_emitter_set_output_string,
298 yaml_emitter_set_unicode, yaml_emitter_set_width, yaml_event_delete,
299 yaml_mapping_end_event_initialize, yaml_mapping_start_event_initialize, yaml_parser_delete,
300 yaml_parser_initialize, yaml_parser_set_encoding, yaml_parser_set_input,
301 yaml_parser_set_input_string, yaml_scalar_event_initialize, yaml_sequence_end_event_initialize,
302 yaml_sequence_start_event_initialize, yaml_stream_end_event_initialize,
303 yaml_stream_start_event_initialize, yaml_token_delete,
304};
305pub use crate::dumper::{yaml_emitter_close, yaml_emitter_dump, yaml_emitter_open};
306pub use crate::emitter::yaml_emitter_emit;
307pub use crate::loader::yaml_parser_load;
308pub use crate::parser::yaml_parser_parse;
309pub use crate::scanner::yaml_parser_scan;
310pub use crate::writer::yaml_emitter_flush;
311pub use crate::yaml::{
312 yaml_alias_data_t, yaml_break_t, yaml_document_t, yaml_emitter_state_t, yaml_emitter_t,
313 yaml_encoding_t, yaml_error_type_t, yaml_event_t, yaml_event_type_t, yaml_mapping_style_t,
314 yaml_mark_t, yaml_node_item_t, yaml_node_pair_t, yaml_node_t, yaml_node_type_t,
315 yaml_parser_state_t, yaml_parser_t, yaml_read_handler_t, yaml_scalar_style_t,
316 yaml_sequence_style_t, yaml_simple_key_t, yaml_stack_t, yaml_tag_directive_t, yaml_token_t,
317 yaml_token_type_t, yaml_version_directive_t, yaml_write_handler_t,
318};
319#[doc(hidden)]
320pub use crate::yaml::{
321 yaml_break_t::*, yaml_emitter_state_t::*, yaml_encoding_t::*, yaml_error_type_t::*,
322 yaml_event_type_t::*, yaml_mapping_style_t::*, yaml_node_type_t::*, yaml_parser_state_t::*,
323 yaml_scalar_style_t::*, yaml_sequence_style_t::*, yaml_token_type_t::*,
324};