1use crate::api::{yaml_free, yaml_malloc};
2use crate::externs::{memset, strcmp};
3use crate::fmt::WriteToPtr;
4use crate::ops::ForceMul as _;
5use crate::success::{Success, FAIL, OK};
6use crate::yaml::{
7 yaml_anchors_t, yaml_char_t, yaml_document_t, yaml_emitter_t, yaml_event_t, yaml_mark_t,
8 yaml_node_item_t, yaml_node_pair_t, yaml_node_t, YAML_ALIAS_EVENT, YAML_ANY_ENCODING,
9 YAML_DOCUMENT_END_EVENT, YAML_DOCUMENT_START_EVENT, YAML_MAPPING_END_EVENT, YAML_MAPPING_NODE,
10 YAML_MAPPING_START_EVENT, YAML_SCALAR_EVENT, YAML_SCALAR_NODE, YAML_SEQUENCE_END_EVENT,
11 YAML_SEQUENCE_NODE, YAML_SEQUENCE_START_EVENT, YAML_STREAM_END_EVENT, YAML_STREAM_START_EVENT,
12};
13use crate::{libc, yaml_document_delete, yaml_emitter_emit, PointerExt};
14use core::mem::{size_of, MaybeUninit};
15use core::ptr::{self, addr_of_mut};
16
17pub unsafe fn yaml_emitter_open(emitter: *mut yaml_emitter_t) -> Success {
21 let mut event = MaybeUninit::<yaml_event_t>::uninit();
22 let event = event.as_mut_ptr();
23 let mark = yaml_mark_t {
24 index: 0_u64,
25 line: 0_u64,
26 column: 0_u64,
27 };
28 __assert!(!emitter.is_null());
29 __assert!(!(*emitter).opened);
30 memset(
31 event as *mut libc::c_void,
32 0,
33 size_of::<yaml_event_t>() as libc::c_ulong,
34 );
35 (*event).type_ = YAML_STREAM_START_EVENT;
36 (*event).start_mark = mark;
37 (*event).end_mark = mark;
38 (*event).data.stream_start.encoding = YAML_ANY_ENCODING;
39 if yaml_emitter_emit(emitter, event).fail {
40 return FAIL;
41 }
42 (*emitter).opened = true;
43 OK
44}
45
46pub unsafe fn yaml_emitter_close(emitter: *mut yaml_emitter_t) -> Success {
50 let mut event = MaybeUninit::<yaml_event_t>::uninit();
51 let event = event.as_mut_ptr();
52 let mark = yaml_mark_t {
53 index: 0_u64,
54 line: 0_u64,
55 column: 0_u64,
56 };
57 __assert!(!emitter.is_null());
58 __assert!((*emitter).opened);
59 if (*emitter).closed {
60 return OK;
61 }
62 memset(
63 event as *mut libc::c_void,
64 0,
65 size_of::<yaml_event_t>() as libc::c_ulong,
66 );
67 (*event).type_ = YAML_STREAM_END_EVENT;
68 (*event).start_mark = mark;
69 (*event).end_mark = mark;
70 if yaml_emitter_emit(emitter, event).fail {
71 return FAIL;
72 }
73 (*emitter).closed = true;
74 OK
75}
76
77pub unsafe fn yaml_emitter_dump(
84 emitter: *mut yaml_emitter_t,
85 document: *mut yaml_document_t,
86) -> Success {
87 let current_block: u64;
88 let mut event = MaybeUninit::<yaml_event_t>::uninit();
89 let event = event.as_mut_ptr();
90 let mark = yaml_mark_t {
91 index: 0_u64,
92 line: 0_u64,
93 column: 0_u64,
94 };
95 __assert!(!emitter.is_null());
96 __assert!(!document.is_null());
97 let fresh0 = addr_of_mut!((*emitter).document);
98 *fresh0 = document;
99 if !(*emitter).opened {
100 if yaml_emitter_open(emitter).fail {
101 current_block = 5018439318894558507;
102 } else {
103 current_block = 15619007995458559411;
104 }
105 } else {
106 current_block = 15619007995458559411;
107 }
108 match current_block {
109 15619007995458559411 => {
110 if STACK_EMPTY!((*document).nodes) {
111 if yaml_emitter_close(emitter).ok {
112 yaml_emitter_delete_document_and_anchors(emitter);
113 return OK;
114 }
115 } else {
116 __assert!((*emitter).opened);
117 let fresh1 = addr_of_mut!((*emitter).anchors);
118 *fresh1 = yaml_malloc(
119 (size_of::<yaml_anchors_t>() as libc::c_ulong)
120 .force_mul((*document).nodes.top.c_offset_from((*document).nodes.start)
121 as libc::c_ulong),
122 ) as *mut yaml_anchors_t;
123 memset(
124 (*emitter).anchors as *mut libc::c_void,
125 0,
126 (size_of::<yaml_anchors_t>() as libc::c_ulong)
127 .force_mul((*document).nodes.top.c_offset_from((*document).nodes.start)
128 as libc::c_ulong),
129 );
130 memset(
131 event as *mut libc::c_void,
132 0,
133 size_of::<yaml_event_t>() as libc::c_ulong,
134 );
135 (*event).type_ = YAML_DOCUMENT_START_EVENT;
136 (*event).start_mark = mark;
137 (*event).end_mark = mark;
138 (*event).data.document_start.version_directive = (*document).version_directive;
139 (*event).data.document_start.tag_directives.start =
140 (*document).tag_directives.start;
141 (*event).data.document_start.tag_directives.end = (*document).tag_directives.end;
142 (*event).data.document_start.implicit = (*document).start_implicit;
143 if yaml_emitter_emit(emitter, event).ok {
144 yaml_emitter_anchor_node(emitter, 1);
145 if yaml_emitter_dump_node(emitter, 1).ok {
146 memset(
147 event as *mut libc::c_void,
148 0,
149 size_of::<yaml_event_t>() as libc::c_ulong,
150 );
151 (*event).type_ = YAML_DOCUMENT_END_EVENT;
152 (*event).start_mark = mark;
153 (*event).end_mark = mark;
154 (*event).data.document_end.implicit = (*document).end_implicit;
155 if yaml_emitter_emit(emitter, event).ok {
156 yaml_emitter_delete_document_and_anchors(emitter);
157 return OK;
158 }
159 }
160 }
161 }
162 }
163 _ => {}
164 }
165 yaml_emitter_delete_document_and_anchors(emitter);
166 FAIL
167}
168
169unsafe fn yaml_emitter_delete_document_and_anchors(emitter: *mut yaml_emitter_t) {
170 let mut index: libc::c_int;
171 if (*emitter).anchors.is_null() {
172 yaml_document_delete((*emitter).document);
173 let fresh2 = addr_of_mut!((*emitter).document);
174 *fresh2 = ptr::null_mut::<yaml_document_t>();
175 return;
176 }
177 index = 0;
178 while (*(*emitter).document)
179 .nodes
180 .start
181 .wrapping_offset(index as isize)
182 < (*(*emitter).document).nodes.top
183 {
184 let mut node: yaml_node_t = *(*(*emitter).document)
185 .nodes
186 .start
187 .wrapping_offset(index as isize);
188 if !(*(*emitter).anchors.wrapping_offset(index as isize)).serialized {
189 yaml_free(node.tag as *mut libc::c_void);
190 if node.type_ == YAML_SCALAR_NODE {
191 yaml_free(node.data.scalar.value as *mut libc::c_void);
192 }
193 }
194 if node.type_ == YAML_SEQUENCE_NODE {
195 STACK_DEL!(node.data.sequence.items);
196 }
197 if node.type_ == YAML_MAPPING_NODE {
198 STACK_DEL!(node.data.mapping.pairs);
199 }
200 index += 1;
201 }
202 STACK_DEL!((*(*emitter).document).nodes);
203 yaml_free((*emitter).anchors as *mut libc::c_void);
204 let fresh6 = addr_of_mut!((*emitter).anchors);
205 *fresh6 = ptr::null_mut::<yaml_anchors_t>();
206 (*emitter).last_anchor_id = 0;
207 let fresh7 = addr_of_mut!((*emitter).document);
208 *fresh7 = ptr::null_mut::<yaml_document_t>();
209}
210
211unsafe fn yaml_emitter_anchor_node_sub(emitter: *mut yaml_emitter_t, index: libc::c_int) {
212 (*((*emitter).anchors).offset((index - 1) as isize)).references += 1;
213 if (*(*emitter).anchors.offset((index - 1) as isize)).references == 2 {
214 (*emitter).last_anchor_id += 1;
215 (*(*emitter).anchors.offset((index - 1) as isize)).anchor = (*emitter).last_anchor_id;
216 }
217}
218
219unsafe fn yaml_emitter_anchor_node(emitter: *mut yaml_emitter_t, index: libc::c_int) {
220 let node: *mut yaml_node_t = (*(*emitter).document)
221 .nodes
222 .start
223 .wrapping_offset(index as isize)
224 .wrapping_offset(-1_isize);
225 let mut item: *mut yaml_node_item_t;
226 let mut pair: *mut yaml_node_pair_t;
227 let fresh8 =
228 addr_of_mut!((*((*emitter).anchors).wrapping_offset((index - 1) as isize)).references);
229 *fresh8 += 1;
230 if (*(*emitter).anchors.wrapping_offset((index - 1) as isize)).references == 1 {
231 match (*node).type_ {
232 YAML_SEQUENCE_NODE => {
233 item = (*node).data.sequence.items.start;
234 while item < (*node).data.sequence.items.top {
235 yaml_emitter_anchor_node_sub(emitter, *item);
236 item = item.wrapping_offset(1);
237 }
238 }
239 YAML_MAPPING_NODE => {
240 pair = (*node).data.mapping.pairs.start;
241 while pair < (*node).data.mapping.pairs.top {
242 yaml_emitter_anchor_node_sub(emitter, (*pair).key);
243 yaml_emitter_anchor_node_sub(emitter, (*pair).value);
244 pair = pair.wrapping_offset(1);
245 }
246 }
247 _ => {}
248 }
249 } else if (*(*emitter).anchors.wrapping_offset((index - 1) as isize)).references == 2 {
250 let fresh9 = addr_of_mut!((*emitter).last_anchor_id);
251 *fresh9 += 1;
252 (*(*emitter).anchors.wrapping_offset((index - 1) as isize)).anchor = *fresh9;
253 }
254}
255
256unsafe fn yaml_emitter_generate_anchor(
257 _emitter: *mut yaml_emitter_t,
258 anchor_id: libc::c_int,
259) -> *mut yaml_char_t {
260 let anchor: *mut yaml_char_t = yaml_malloc(16_u64) as *mut yaml_char_t;
261 write!(WriteToPtr::new(anchor), "id{:03}\0", anchor_id);
262 anchor
263}
264
265unsafe fn yaml_emitter_dump_node(emitter: *mut yaml_emitter_t, index: libc::c_int) -> Success {
266 let node: *mut yaml_node_t = (*(*emitter).document)
267 .nodes
268 .start
269 .wrapping_offset(index as isize)
270 .wrapping_offset(-1_isize);
271 let anchor_id: libc::c_int = (*(*emitter).anchors.wrapping_offset((index - 1) as isize)).anchor;
272 let mut anchor: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
273 if anchor_id != 0 {
274 anchor = yaml_emitter_generate_anchor(emitter, anchor_id);
275 }
276 if (*(*emitter).anchors.wrapping_offset((index - 1) as isize)).serialized {
277 return yaml_emitter_dump_alias(emitter, anchor);
278 }
279 (*(*emitter).anchors.wrapping_offset((index - 1) as isize)).serialized = true;
280 match (*node).type_ {
281 YAML_SCALAR_NODE => yaml_emitter_dump_scalar(emitter, node, anchor),
282 YAML_SEQUENCE_NODE => yaml_emitter_dump_sequence(emitter, node, anchor),
283 YAML_MAPPING_NODE => yaml_emitter_dump_mapping(emitter, node, anchor),
284 _ => __assert!(false),
285 }
286}
287
288unsafe fn yaml_emitter_dump_alias(
289 emitter: *mut yaml_emitter_t,
290 anchor: *mut yaml_char_t,
291) -> Success {
292 let mut event = MaybeUninit::<yaml_event_t>::uninit();
293 let event = event.as_mut_ptr();
294 let mark = yaml_mark_t {
295 index: 0_u64,
296 line: 0_u64,
297 column: 0_u64,
298 };
299 memset(
300 event as *mut libc::c_void,
301 0,
302 size_of::<yaml_event_t>() as libc::c_ulong,
303 );
304 (*event).type_ = YAML_ALIAS_EVENT;
305 (*event).start_mark = mark;
306 (*event).end_mark = mark;
307 (*event).data.alias.anchor = anchor;
308 yaml_emitter_emit(emitter, event)
309}
310
311unsafe fn yaml_emitter_dump_scalar(
312 emitter: *mut yaml_emitter_t,
313 node: *mut yaml_node_t,
314 anchor: *mut yaml_char_t,
315) -> Success {
316 let mut event = MaybeUninit::<yaml_event_t>::uninit();
317 let event = event.as_mut_ptr();
318 let mark = yaml_mark_t {
319 index: 0_u64,
320 line: 0_u64,
321 column: 0_u64,
322 };
323 let plain_implicit = strcmp(
324 (*node).tag as *mut libc::c_char,
325 b"tag:yaml.org,2002:str\0" as *const u8 as *const libc::c_char,
326 ) == 0;
327 let quoted_implicit = strcmp(
328 (*node).tag as *mut libc::c_char,
329 b"tag:yaml.org,2002:str\0" as *const u8 as *const libc::c_char,
330 ) == 0;
331 memset(
332 event as *mut libc::c_void,
333 0,
334 size_of::<yaml_event_t>() as libc::c_ulong,
335 );
336 (*event).type_ = YAML_SCALAR_EVENT;
337 (*event).start_mark = mark;
338 (*event).end_mark = mark;
339 (*event).data.scalar.anchor = anchor;
340 (*event).data.scalar.tag = (*node).tag;
341 (*event).data.scalar.value = (*node).data.scalar.value;
342 (*event).data.scalar.length = (*node).data.scalar.length;
343 (*event).data.scalar.plain_implicit = plain_implicit;
344 (*event).data.scalar.quoted_implicit = quoted_implicit;
345 (*event).data.scalar.style = (*node).data.scalar.style;
346 yaml_emitter_emit(emitter, event)
347}
348
349unsafe fn yaml_emitter_dump_sequence(
350 emitter: *mut yaml_emitter_t,
351 node: *mut yaml_node_t,
352 anchor: *mut yaml_char_t,
353) -> Success {
354 let mut event = MaybeUninit::<yaml_event_t>::uninit();
355 let event = event.as_mut_ptr();
356 let mark = yaml_mark_t {
357 index: 0_u64,
358 line: 0_u64,
359 column: 0_u64,
360 };
361 let implicit = strcmp(
362 (*node).tag as *mut libc::c_char,
363 b"tag:yaml.org,2002:seq\0" as *const u8 as *const libc::c_char,
364 ) == 0;
365 let mut item: *mut yaml_node_item_t;
366 memset(
367 event as *mut libc::c_void,
368 0,
369 size_of::<yaml_event_t>() as libc::c_ulong,
370 );
371 (*event).type_ = YAML_SEQUENCE_START_EVENT;
372 (*event).start_mark = mark;
373 (*event).end_mark = mark;
374 (*event).data.sequence_start.anchor = anchor;
375 (*event).data.sequence_start.tag = (*node).tag;
376 (*event).data.sequence_start.implicit = implicit;
377 (*event).data.sequence_start.style = (*node).data.sequence.style;
378 if yaml_emitter_emit(emitter, event).fail {
379 return FAIL;
380 }
381 item = (*node).data.sequence.items.start;
382 while item < (*node).data.sequence.items.top {
383 if yaml_emitter_dump_node(emitter, *item).fail {
384 return FAIL;
385 }
386 item = item.wrapping_offset(1);
387 }
388 memset(
389 event as *mut libc::c_void,
390 0,
391 size_of::<yaml_event_t>() as libc::c_ulong,
392 );
393 (*event).type_ = YAML_SEQUENCE_END_EVENT;
394 (*event).start_mark = mark;
395 (*event).end_mark = mark;
396 yaml_emitter_emit(emitter, event)
397}
398
399unsafe fn yaml_emitter_dump_mapping(
400 emitter: *mut yaml_emitter_t,
401 node: *mut yaml_node_t,
402 anchor: *mut yaml_char_t,
403) -> Success {
404 let mut event = MaybeUninit::<yaml_event_t>::uninit();
405 let event = event.as_mut_ptr();
406 let mark = yaml_mark_t {
407 index: 0_u64,
408 line: 0_u64,
409 column: 0_u64,
410 };
411 let implicit = strcmp(
412 (*node).tag as *mut libc::c_char,
413 b"tag:yaml.org,2002:map\0" as *const u8 as *const libc::c_char,
414 ) == 0;
415 let mut pair: *mut yaml_node_pair_t;
416 memset(
417 event as *mut libc::c_void,
418 0,
419 size_of::<yaml_event_t>() as libc::c_ulong,
420 );
421 (*event).type_ = YAML_MAPPING_START_EVENT;
422 (*event).start_mark = mark;
423 (*event).end_mark = mark;
424 (*event).data.mapping_start.anchor = anchor;
425 (*event).data.mapping_start.tag = (*node).tag;
426 (*event).data.mapping_start.implicit = implicit;
427 (*event).data.mapping_start.style = (*node).data.mapping.style;
428 if yaml_emitter_emit(emitter, event).fail {
429 return FAIL;
430 }
431 pair = (*node).data.mapping.pairs.start;
432 while pair < (*node).data.mapping.pairs.top {
433 if yaml_emitter_dump_node(emitter, (*pair).key).fail {
434 return FAIL;
435 }
436 if yaml_emitter_dump_node(emitter, (*pair).value).fail {
437 return FAIL;
438 }
439 pair = pair.wrapping_offset(1);
440 }
441 memset(
442 event as *mut libc::c_void,
443 0,
444 size_of::<yaml_event_t>() as libc::c_ulong,
445 );
446 (*event).type_ = YAML_MAPPING_END_EVENT;
447 (*event).start_mark = mark;
448 (*event).end_mark = mark;
449 yaml_emitter_emit(emitter, event)
450}