unsafe_libyaml/
api.rs

1use crate::externs::{free, malloc, memcpy, memmove, memset, realloc, strdup, strlen};
2use crate::ops::{ForceAdd as _, ForceMul as _};
3use crate::success::{Success, FAIL, OK};
4use crate::yaml::{size_t, yaml_char_t};
5use crate::{
6    libc, yaml_break_t, yaml_document_t, yaml_emitter_state_t, yaml_emitter_t, yaml_encoding_t,
7    yaml_event_t, yaml_mapping_style_t, yaml_mark_t, yaml_node_item_t, yaml_node_pair_t,
8    yaml_node_t, yaml_parser_state_t, yaml_parser_t, yaml_read_handler_t, yaml_scalar_style_t,
9    yaml_sequence_style_t, yaml_simple_key_t, yaml_tag_directive_t, yaml_token_t,
10    yaml_version_directive_t, yaml_write_handler_t, PointerExt, YAML_ALIAS_EVENT, YAML_ALIAS_TOKEN,
11    YAML_ANCHOR_TOKEN, YAML_ANY_ENCODING, YAML_DOCUMENT_END_EVENT, YAML_DOCUMENT_START_EVENT,
12    YAML_MAPPING_END_EVENT, YAML_MAPPING_NODE, YAML_MAPPING_START_EVENT, YAML_SCALAR_EVENT,
13    YAML_SCALAR_NODE, YAML_SCALAR_TOKEN, YAML_SEQUENCE_END_EVENT, YAML_SEQUENCE_NODE,
14    YAML_SEQUENCE_START_EVENT, YAML_STREAM_END_EVENT, YAML_STREAM_START_EVENT,
15    YAML_TAG_DIRECTIVE_TOKEN, YAML_TAG_TOKEN,
16};
17use core::mem::{size_of, MaybeUninit};
18use core::ptr::{self, addr_of_mut};
19
20const INPUT_RAW_BUFFER_SIZE: usize = 16384;
21const INPUT_BUFFER_SIZE: usize = INPUT_RAW_BUFFER_SIZE * 3;
22const OUTPUT_BUFFER_SIZE: usize = 16384;
23const OUTPUT_RAW_BUFFER_SIZE: usize = OUTPUT_BUFFER_SIZE * 2 + 2;
24
25pub(crate) unsafe fn yaml_malloc(size: size_t) -> *mut libc::c_void {
26    malloc(size)
27}
28
29pub(crate) unsafe fn yaml_realloc(ptr: *mut libc::c_void, size: size_t) -> *mut libc::c_void {
30    if !ptr.is_null() {
31        realloc(ptr, size)
32    } else {
33        malloc(size)
34    }
35}
36
37pub(crate) unsafe fn yaml_free(ptr: *mut libc::c_void) {
38    if !ptr.is_null() {
39        free(ptr);
40    }
41}
42
43pub(crate) unsafe fn yaml_strdup(str: *const yaml_char_t) -> *mut yaml_char_t {
44    if str.is_null() {
45        return ptr::null_mut::<yaml_char_t>();
46    }
47    strdup(str as *mut libc::c_char) as *mut yaml_char_t
48}
49
50pub(crate) unsafe fn yaml_string_extend(
51    start: *mut *mut yaml_char_t,
52    pointer: *mut *mut yaml_char_t,
53    end: *mut *mut yaml_char_t,
54) {
55    let new_start: *mut yaml_char_t = yaml_realloc(
56        *start as *mut libc::c_void,
57        (((*end).c_offset_from(*start) as libc::c_long).force_mul(2_i64)) as size_t,
58    ) as *mut yaml_char_t;
59    memset(
60        new_start.wrapping_offset((*end).c_offset_from(*start) as libc::c_long as isize)
61            as *mut libc::c_void,
62        0,
63        (*end).c_offset_from(*start) as libc::c_ulong,
64    );
65    *pointer = new_start.wrapping_offset((*pointer).c_offset_from(*start) as libc::c_long as isize);
66    *end = new_start.wrapping_offset(
67        (((*end).c_offset_from(*start) as libc::c_long).force_mul(2_i64)) as isize,
68    );
69    *start = new_start;
70}
71
72pub(crate) unsafe fn yaml_string_join(
73    a_start: *mut *mut yaml_char_t,
74    a_pointer: *mut *mut yaml_char_t,
75    a_end: *mut *mut yaml_char_t,
76    b_start: *mut *mut yaml_char_t,
77    b_pointer: *mut *mut yaml_char_t,
78    _b_end: *mut *mut yaml_char_t,
79) {
80    if *b_start == *b_pointer {
81        return;
82    }
83    while (*a_end).c_offset_from(*a_pointer) as libc::c_long
84        <= (*b_pointer).c_offset_from(*b_start) as libc::c_long
85    {
86        yaml_string_extend(a_start, a_pointer, a_end);
87    }
88    memcpy(
89        *a_pointer as *mut libc::c_void,
90        *b_start as *const libc::c_void,
91        (*b_pointer).c_offset_from(*b_start) as libc::c_ulong,
92    );
93    *a_pointer =
94        (*a_pointer).wrapping_offset((*b_pointer).c_offset_from(*b_start) as libc::c_long as isize);
95}
96
97pub(crate) unsafe fn yaml_stack_extend(
98    start: *mut *mut libc::c_void,
99    top: *mut *mut libc::c_void,
100    end: *mut *mut libc::c_void,
101) {
102    let new_start: *mut libc::c_void = yaml_realloc(
103        *start,
104        (((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long)
105            .force_mul(2_i64)) as size_t,
106    );
107    *top = (new_start as *mut libc::c_char).wrapping_offset(
108        (*top as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
109            as isize,
110    ) as *mut libc::c_void;
111    *end = (new_start as *mut libc::c_char).wrapping_offset(
112        (((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long)
113            .force_mul(2_i64)) as isize,
114    ) as *mut libc::c_void;
115    *start = new_start;
116}
117
118pub(crate) unsafe fn yaml_queue_extend(
119    start: *mut *mut libc::c_void,
120    head: *mut *mut libc::c_void,
121    tail: *mut *mut libc::c_void,
122    end: *mut *mut libc::c_void,
123) {
124    if *start == *head && *tail == *end {
125        let new_start: *mut libc::c_void = yaml_realloc(
126            *start,
127            (((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char)
128                as libc::c_long)
129                .force_mul(2_i64)) as size_t,
130        );
131        *head = (new_start as *mut libc::c_char).wrapping_offset(
132            (*head as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
133                as isize,
134        ) as *mut libc::c_void;
135        *tail = (new_start as *mut libc::c_char).wrapping_offset(
136            (*tail as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
137                as isize,
138        ) as *mut libc::c_void;
139        *end = (new_start as *mut libc::c_char).wrapping_offset(
140            (((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char)
141                as libc::c_long)
142                .force_mul(2_i64)) as isize,
143        ) as *mut libc::c_void;
144        *start = new_start;
145    }
146    if *tail == *end {
147        if *head != *tail {
148            memmove(
149                *start,
150                *head,
151                (*tail as *mut libc::c_char).c_offset_from(*head as *mut libc::c_char)
152                    as libc::c_ulong,
153            );
154        }
155        *tail = (*start as *mut libc::c_char).wrapping_offset(
156            (*tail as *mut libc::c_char).c_offset_from(*head as *mut libc::c_char) as libc::c_long
157                as isize,
158        ) as *mut libc::c_void;
159        *head = *start;
160    }
161}
162
163/// Initialize a parser.
164///
165/// This function creates a new parser object. An application is responsible
166/// for destroying the object using the yaml_parser_delete() function.
167pub unsafe fn yaml_parser_initialize(parser: *mut yaml_parser_t) -> Success {
168    __assert!(!parser.is_null());
169    memset(
170        parser as *mut libc::c_void,
171        0,
172        size_of::<yaml_parser_t>() as libc::c_ulong,
173    );
174    BUFFER_INIT!((*parser).raw_buffer, INPUT_RAW_BUFFER_SIZE);
175    BUFFER_INIT!((*parser).buffer, INPUT_BUFFER_SIZE);
176    QUEUE_INIT!((*parser).tokens, yaml_token_t);
177    STACK_INIT!((*parser).indents, libc::c_int);
178    STACK_INIT!((*parser).simple_keys, yaml_simple_key_t);
179    STACK_INIT!((*parser).states, yaml_parser_state_t);
180    STACK_INIT!((*parser).marks, yaml_mark_t);
181    STACK_INIT!((*parser).tag_directives, yaml_tag_directive_t);
182    OK
183}
184
185/// Destroy a parser.
186pub unsafe fn yaml_parser_delete(parser: *mut yaml_parser_t) {
187    __assert!(!parser.is_null());
188    BUFFER_DEL!((*parser).raw_buffer);
189    BUFFER_DEL!((*parser).buffer);
190    while !QUEUE_EMPTY!((*parser).tokens) {
191        yaml_token_delete(addr_of_mut!(DEQUEUE!((*parser).tokens)));
192    }
193    QUEUE_DEL!((*parser).tokens);
194    STACK_DEL!((*parser).indents);
195    STACK_DEL!((*parser).simple_keys);
196    STACK_DEL!((*parser).states);
197    STACK_DEL!((*parser).marks);
198    while !STACK_EMPTY!((*parser).tag_directives) {
199        let tag_directive = POP!((*parser).tag_directives);
200        yaml_free(tag_directive.handle as *mut libc::c_void);
201        yaml_free(tag_directive.prefix as *mut libc::c_void);
202    }
203    STACK_DEL!((*parser).tag_directives);
204    memset(
205        parser as *mut libc::c_void,
206        0,
207        size_of::<yaml_parser_t>() as libc::c_ulong,
208    );
209}
210
211unsafe fn yaml_string_read_handler(
212    data: *mut libc::c_void,
213    buffer: *mut libc::c_uchar,
214    mut size: size_t,
215    size_read: *mut size_t,
216) -> libc::c_int {
217    let parser: *mut yaml_parser_t = data as *mut yaml_parser_t;
218    if (*parser).input.string.current == (*parser).input.string.end {
219        *size_read = 0_u64;
220        return 1;
221    }
222    if size
223        > (*parser)
224            .input
225            .string
226            .end
227            .c_offset_from((*parser).input.string.current) as size_t
228    {
229        size = (*parser)
230            .input
231            .string
232            .end
233            .c_offset_from((*parser).input.string.current) as size_t;
234    }
235    memcpy(
236        buffer as *mut libc::c_void,
237        (*parser).input.string.current as *const libc::c_void,
238        size,
239    );
240    let fresh80 = addr_of_mut!((*parser).input.string.current);
241    *fresh80 = (*fresh80).wrapping_offset(size as isize);
242    *size_read = size;
243    1
244}
245
246/// Set a string input.
247///
248/// Note that the `input` pointer must be valid while the `parser` object
249/// exists. The application is responsible for destroying `input` after
250/// destroying the `parser`.
251pub unsafe fn yaml_parser_set_input_string(
252    parser: *mut yaml_parser_t,
253    input: *const libc::c_uchar,
254    size: size_t,
255) {
256    __assert!(!parser.is_null());
257    __assert!(((*parser).read_handler).is_none());
258    __assert!(!input.is_null());
259    let fresh81 = addr_of_mut!((*parser).read_handler);
260    *fresh81 = Some(
261        yaml_string_read_handler
262            as unsafe fn(*mut libc::c_void, *mut libc::c_uchar, size_t, *mut size_t) -> libc::c_int,
263    );
264    let fresh82 = addr_of_mut!((*parser).read_handler_data);
265    *fresh82 = parser as *mut libc::c_void;
266    let fresh83 = addr_of_mut!((*parser).input.string.start);
267    *fresh83 = input;
268    let fresh84 = addr_of_mut!((*parser).input.string.current);
269    *fresh84 = input;
270    let fresh85 = addr_of_mut!((*parser).input.string.end);
271    *fresh85 = input.wrapping_offset(size as isize);
272}
273
274/// Set a generic input handler.
275pub unsafe fn yaml_parser_set_input(
276    parser: *mut yaml_parser_t,
277    handler: yaml_read_handler_t,
278    data: *mut libc::c_void,
279) {
280    __assert!(!parser.is_null());
281    __assert!(((*parser).read_handler).is_none());
282    let fresh89 = addr_of_mut!((*parser).read_handler);
283    *fresh89 = Some(handler);
284    let fresh90 = addr_of_mut!((*parser).read_handler_data);
285    *fresh90 = data;
286}
287
288/// Set the source encoding.
289pub unsafe fn yaml_parser_set_encoding(parser: *mut yaml_parser_t, encoding: yaml_encoding_t) {
290    __assert!(!parser.is_null());
291    __assert!((*parser).encoding == YAML_ANY_ENCODING);
292    (*parser).encoding = encoding;
293}
294
295/// Initialize an emitter.
296///
297/// This function creates a new emitter object. An application is responsible
298/// for destroying the object using the yaml_emitter_delete() function.
299pub unsafe fn yaml_emitter_initialize(emitter: *mut yaml_emitter_t) -> Success {
300    __assert!(!emitter.is_null());
301    memset(
302        emitter as *mut libc::c_void,
303        0,
304        size_of::<yaml_emitter_t>() as libc::c_ulong,
305    );
306    BUFFER_INIT!((*emitter).buffer, OUTPUT_BUFFER_SIZE);
307    BUFFER_INIT!((*emitter).raw_buffer, OUTPUT_RAW_BUFFER_SIZE);
308    STACK_INIT!((*emitter).states, yaml_emitter_state_t);
309    QUEUE_INIT!((*emitter).events, yaml_event_t);
310    STACK_INIT!((*emitter).indents, libc::c_int);
311    STACK_INIT!((*emitter).tag_directives, yaml_tag_directive_t);
312    OK
313}
314
315/// Destroy an emitter.
316pub unsafe fn yaml_emitter_delete(emitter: *mut yaml_emitter_t) {
317    __assert!(!emitter.is_null());
318    BUFFER_DEL!((*emitter).buffer);
319    BUFFER_DEL!((*emitter).raw_buffer);
320    STACK_DEL!((*emitter).states);
321    while !QUEUE_EMPTY!((*emitter).events) {
322        yaml_event_delete(addr_of_mut!(DEQUEUE!((*emitter).events)));
323    }
324    QUEUE_DEL!((*emitter).events);
325    STACK_DEL!((*emitter).indents);
326    while !STACK_EMPTY!((*emitter).tag_directives) {
327        let tag_directive = POP!((*emitter).tag_directives);
328        yaml_free(tag_directive.handle as *mut libc::c_void);
329        yaml_free(tag_directive.prefix as *mut libc::c_void);
330    }
331    STACK_DEL!((*emitter).tag_directives);
332    yaml_free((*emitter).anchors as *mut libc::c_void);
333    memset(
334        emitter as *mut libc::c_void,
335        0,
336        size_of::<yaml_emitter_t>() as libc::c_ulong,
337    );
338}
339
340unsafe fn yaml_string_write_handler(
341    data: *mut libc::c_void,
342    buffer: *mut libc::c_uchar,
343    size: size_t,
344) -> libc::c_int {
345    let emitter: *mut yaml_emitter_t = data as *mut yaml_emitter_t;
346    if (*emitter)
347        .output
348        .string
349        .size
350        .wrapping_sub(*(*emitter).output.string.size_written)
351        < size
352    {
353        memcpy(
354            (*emitter)
355                .output
356                .string
357                .buffer
358                .wrapping_offset(*(*emitter).output.string.size_written as isize)
359                as *mut libc::c_void,
360            buffer as *const libc::c_void,
361            (*emitter)
362                .output
363                .string
364                .size
365                .wrapping_sub(*(*emitter).output.string.size_written),
366        );
367        *(*emitter).output.string.size_written = (*emitter).output.string.size;
368        return 0;
369    }
370    memcpy(
371        (*emitter)
372            .output
373            .string
374            .buffer
375            .wrapping_offset(*(*emitter).output.string.size_written as isize)
376            as *mut libc::c_void,
377        buffer as *const libc::c_void,
378        size,
379    );
380    let fresh153 = addr_of_mut!((*(*emitter).output.string.size_written));
381    *fresh153 = (*fresh153 as libc::c_ulong).force_add(size) as size_t;
382    1
383}
384
385/// Set a string output.
386///
387/// The emitter will write the output characters to the `output` buffer of the
388/// size `size`. The emitter will set `size_written` to the number of written
389/// bytes. If the buffer is smaller than required, the emitter produces the
390/// YAML_WRITE_ERROR error.
391pub unsafe fn yaml_emitter_set_output_string(
392    emitter: *mut yaml_emitter_t,
393    output: *mut libc::c_uchar,
394    size: size_t,
395    size_written: *mut size_t,
396) {
397    __assert!(!emitter.is_null());
398    __assert!(((*emitter).write_handler).is_none());
399    __assert!(!output.is_null());
400    let fresh154 = addr_of_mut!((*emitter).write_handler);
401    *fresh154 = Some(
402        yaml_string_write_handler
403            as unsafe fn(*mut libc::c_void, *mut libc::c_uchar, size_t) -> libc::c_int,
404    );
405    let fresh155 = addr_of_mut!((*emitter).write_handler_data);
406    *fresh155 = emitter as *mut libc::c_void;
407    let fresh156 = addr_of_mut!((*emitter).output.string.buffer);
408    *fresh156 = output;
409    (*emitter).output.string.size = size;
410    let fresh157 = addr_of_mut!((*emitter).output.string.size_written);
411    *fresh157 = size_written;
412    *size_written = 0_u64;
413}
414
415/// Set a generic output handler.
416pub unsafe fn yaml_emitter_set_output(
417    emitter: *mut yaml_emitter_t,
418    handler: yaml_write_handler_t,
419    data: *mut libc::c_void,
420) {
421    __assert!(!emitter.is_null());
422    __assert!(((*emitter).write_handler).is_none());
423    let fresh161 = addr_of_mut!((*emitter).write_handler);
424    *fresh161 = Some(handler);
425    let fresh162 = addr_of_mut!((*emitter).write_handler_data);
426    *fresh162 = data;
427}
428
429/// Set the output encoding.
430pub unsafe fn yaml_emitter_set_encoding(emitter: *mut yaml_emitter_t, encoding: yaml_encoding_t) {
431    __assert!(!emitter.is_null());
432    __assert!((*emitter).encoding == YAML_ANY_ENCODING);
433    (*emitter).encoding = encoding;
434}
435
436/// Set if the output should be in the "canonical" format as in the YAML
437/// specification.
438pub unsafe fn yaml_emitter_set_canonical(emitter: *mut yaml_emitter_t, canonical: bool) {
439    __assert!(!emitter.is_null());
440    (*emitter).canonical = canonical;
441}
442
443/// Set the indentation increment.
444pub unsafe fn yaml_emitter_set_indent(emitter: *mut yaml_emitter_t, indent: libc::c_int) {
445    __assert!(!emitter.is_null());
446    (*emitter).best_indent = if 1 < indent && indent < 10 { indent } else { 2 };
447}
448
449/// Set the preferred line width. -1 means unlimited.
450pub unsafe fn yaml_emitter_set_width(emitter: *mut yaml_emitter_t, width: libc::c_int) {
451    __assert!(!emitter.is_null());
452    (*emitter).best_width = if width >= 0 { width } else { -1 };
453}
454
455/// Set if unescaped non-ASCII characters are allowed.
456pub unsafe fn yaml_emitter_set_unicode(emitter: *mut yaml_emitter_t, unicode: bool) {
457    __assert!(!emitter.is_null());
458    (*emitter).unicode = unicode;
459}
460
461/// Set the preferred line break.
462pub unsafe fn yaml_emitter_set_break(emitter: *mut yaml_emitter_t, line_break: yaml_break_t) {
463    __assert!(!emitter.is_null());
464    (*emitter).line_break = line_break;
465}
466
467/// Free any memory allocated for a token object.
468pub unsafe fn yaml_token_delete(token: *mut yaml_token_t) {
469    __assert!(!token.is_null());
470    match (*token).type_ {
471        YAML_TAG_DIRECTIVE_TOKEN => {
472            yaml_free((*token).data.tag_directive.handle as *mut libc::c_void);
473            yaml_free((*token).data.tag_directive.prefix as *mut libc::c_void);
474        }
475        YAML_ALIAS_TOKEN => {
476            yaml_free((*token).data.alias.value as *mut libc::c_void);
477        }
478        YAML_ANCHOR_TOKEN => {
479            yaml_free((*token).data.anchor.value as *mut libc::c_void);
480        }
481        YAML_TAG_TOKEN => {
482            yaml_free((*token).data.tag.handle as *mut libc::c_void);
483            yaml_free((*token).data.tag.suffix as *mut libc::c_void);
484        }
485        YAML_SCALAR_TOKEN => {
486            yaml_free((*token).data.scalar.value as *mut libc::c_void);
487        }
488        _ => {}
489    }
490    memset(
491        token as *mut libc::c_void,
492        0,
493        size_of::<yaml_token_t>() as libc::c_ulong,
494    );
495}
496
497unsafe fn yaml_check_utf8(start: *const yaml_char_t, length: size_t) -> Success {
498    let end: *const yaml_char_t = start.wrapping_offset(length as isize);
499    let mut pointer: *const yaml_char_t = start;
500    while pointer < end {
501        let mut octet: libc::c_uchar;
502        let mut value: libc::c_uint;
503        let mut k: size_t;
504        octet = *pointer;
505        let width: libc::c_uint = if octet & 0x80 == 0 {
506            1
507        } else if octet & 0xE0 == 0xC0 {
508            2
509        } else if octet & 0xF0 == 0xE0 {
510            3
511        } else if octet & 0xF8 == 0xF0 {
512            4
513        } else {
514            0
515        } as libc::c_uint;
516        value = if octet & 0x80 == 0 {
517            octet & 0x7F
518        } else if octet & 0xE0 == 0xC0 {
519            octet & 0x1F
520        } else if octet & 0xF0 == 0xE0 {
521            octet & 0xF
522        } else if octet & 0xF8 == 0xF0 {
523            octet & 0x7
524        } else {
525            0
526        } as libc::c_uint;
527        if width == 0 {
528            return FAIL;
529        }
530        if pointer.wrapping_offset(width as isize) > end {
531            return FAIL;
532        }
533        k = 1_u64;
534        while k < width as libc::c_ulong {
535            octet = *pointer.wrapping_offset(k as isize);
536            if octet & 0xC0 != 0x80 {
537                return FAIL;
538            }
539            value = (value << 6).force_add((octet & 0x3F) as libc::c_uint);
540            k = k.force_add(1);
541        }
542        if !(width == 1
543            || width == 2 && value >= 0x80
544            || width == 3 && value >= 0x800
545            || width == 4 && value >= 0x10000)
546        {
547            return FAIL;
548        }
549        pointer = pointer.wrapping_offset(width as isize);
550    }
551    OK
552}
553
554/// Create the STREAM-START event.
555pub unsafe fn yaml_stream_start_event_initialize(
556    event: *mut yaml_event_t,
557    encoding: yaml_encoding_t,
558) -> Success {
559    let mark = yaml_mark_t {
560        index: 0_u64,
561        line: 0_u64,
562        column: 0_u64,
563    };
564    __assert!(!event.is_null());
565    memset(
566        event as *mut libc::c_void,
567        0,
568        size_of::<yaml_event_t>() as libc::c_ulong,
569    );
570    (*event).type_ = YAML_STREAM_START_EVENT;
571    (*event).start_mark = mark;
572    (*event).end_mark = mark;
573    (*event).data.stream_start.encoding = encoding;
574    OK
575}
576
577/// Create the STREAM-END event.
578pub unsafe fn yaml_stream_end_event_initialize(event: *mut yaml_event_t) -> Success {
579    let mark = yaml_mark_t {
580        index: 0_u64,
581        line: 0_u64,
582        column: 0_u64,
583    };
584    __assert!(!event.is_null());
585    memset(
586        event as *mut libc::c_void,
587        0,
588        size_of::<yaml_event_t>() as libc::c_ulong,
589    );
590    (*event).type_ = YAML_STREAM_END_EVENT;
591    (*event).start_mark = mark;
592    (*event).end_mark = mark;
593    OK
594}
595
596/// Create the DOCUMENT-START event.
597///
598/// The `implicit` argument is considered as a stylistic parameter and may be
599/// ignored by the emitter.
600pub unsafe fn yaml_document_start_event_initialize(
601    event: *mut yaml_event_t,
602    version_directive: *mut yaml_version_directive_t,
603    tag_directives_start: *mut yaml_tag_directive_t,
604    tag_directives_end: *mut yaml_tag_directive_t,
605    implicit: bool,
606) -> Success {
607    let current_block: u64;
608    let mark = yaml_mark_t {
609        index: 0_u64,
610        line: 0_u64,
611        column: 0_u64,
612    };
613    let mut version_directive_copy: *mut yaml_version_directive_t =
614        ptr::null_mut::<yaml_version_directive_t>();
615    struct TagDirectivesCopy {
616        start: *mut yaml_tag_directive_t,
617        end: *mut yaml_tag_directive_t,
618        top: *mut yaml_tag_directive_t,
619    }
620    let mut tag_directives_copy = TagDirectivesCopy {
621        start: ptr::null_mut::<yaml_tag_directive_t>(),
622        end: ptr::null_mut::<yaml_tag_directive_t>(),
623        top: ptr::null_mut::<yaml_tag_directive_t>(),
624    };
625    let mut value = yaml_tag_directive_t {
626        handle: ptr::null_mut::<yaml_char_t>(),
627        prefix: ptr::null_mut::<yaml_char_t>(),
628    };
629    __assert!(!event.is_null());
630    __assert!(
631        !tag_directives_start.is_null() && !tag_directives_end.is_null()
632            || tag_directives_start == tag_directives_end
633    );
634    if !version_directive.is_null() {
635        version_directive_copy = yaml_malloc(size_of::<yaml_version_directive_t>() as libc::c_ulong)
636            as *mut yaml_version_directive_t;
637        (*version_directive_copy).major = (*version_directive).major;
638        (*version_directive_copy).minor = (*version_directive).minor;
639    }
640    if tag_directives_start != tag_directives_end {
641        let mut tag_directive: *mut yaml_tag_directive_t;
642        STACK_INIT!(tag_directives_copy, yaml_tag_directive_t);
643        tag_directive = tag_directives_start;
644        loop {
645            if !(tag_directive != tag_directives_end) {
646                current_block = 16203760046146113240;
647                break;
648            }
649            __assert!(!((*tag_directive).handle).is_null());
650            __assert!(!((*tag_directive).prefix).is_null());
651            if yaml_check_utf8(
652                (*tag_directive).handle,
653                strlen((*tag_directive).handle as *mut libc::c_char),
654            )
655            .fail
656            {
657                current_block = 14964981520188694172;
658                break;
659            }
660            if yaml_check_utf8(
661                (*tag_directive).prefix,
662                strlen((*tag_directive).prefix as *mut libc::c_char),
663            )
664            .fail
665            {
666                current_block = 14964981520188694172;
667                break;
668            }
669            value.handle = yaml_strdup((*tag_directive).handle);
670            value.prefix = yaml_strdup((*tag_directive).prefix);
671            if value.handle.is_null() || value.prefix.is_null() {
672                current_block = 14964981520188694172;
673                break;
674            }
675            PUSH!(tag_directives_copy, value);
676            value.handle = ptr::null_mut::<yaml_char_t>();
677            value.prefix = ptr::null_mut::<yaml_char_t>();
678            tag_directive = tag_directive.wrapping_offset(1);
679        }
680    } else {
681        current_block = 16203760046146113240;
682    }
683    if current_block != 14964981520188694172 {
684        memset(
685            event as *mut libc::c_void,
686            0,
687            size_of::<yaml_event_t>() as libc::c_ulong,
688        );
689        (*event).type_ = YAML_DOCUMENT_START_EVENT;
690        (*event).start_mark = mark;
691        (*event).end_mark = mark;
692        let fresh164 = addr_of_mut!((*event).data.document_start.version_directive);
693        *fresh164 = version_directive_copy;
694        let fresh165 = addr_of_mut!((*event).data.document_start.tag_directives.start);
695        *fresh165 = tag_directives_copy.start;
696        let fresh166 = addr_of_mut!((*event).data.document_start.tag_directives.end);
697        *fresh166 = tag_directives_copy.top;
698        (*event).data.document_start.implicit = implicit;
699        return OK;
700    }
701    yaml_free(version_directive_copy as *mut libc::c_void);
702    while !STACK_EMPTY!(tag_directives_copy) {
703        let value = POP!(tag_directives_copy);
704        yaml_free(value.handle as *mut libc::c_void);
705        yaml_free(value.prefix as *mut libc::c_void);
706    }
707    STACK_DEL!(tag_directives_copy);
708    yaml_free(value.handle as *mut libc::c_void);
709    yaml_free(value.prefix as *mut libc::c_void);
710    FAIL
711}
712
713/// Create the DOCUMENT-END event.
714///
715/// The `implicit` argument is considered as a stylistic parameter and may be
716/// ignored by the emitter.
717pub unsafe fn yaml_document_end_event_initialize(
718    event: *mut yaml_event_t,
719    implicit: bool,
720) -> Success {
721    let mark = yaml_mark_t {
722        index: 0_u64,
723        line: 0_u64,
724        column: 0_u64,
725    };
726    __assert!(!event.is_null());
727    memset(
728        event as *mut libc::c_void,
729        0,
730        size_of::<yaml_event_t>() as libc::c_ulong,
731    );
732    (*event).type_ = YAML_DOCUMENT_END_EVENT;
733    (*event).start_mark = mark;
734    (*event).end_mark = mark;
735    (*event).data.document_end.implicit = implicit;
736    OK
737}
738
739/// Create an ALIAS event.
740pub unsafe fn yaml_alias_event_initialize(
741    event: *mut yaml_event_t,
742    anchor: *const yaml_char_t,
743) -> Success {
744    let mark = yaml_mark_t {
745        index: 0_u64,
746        line: 0_u64,
747        column: 0_u64,
748    };
749    __assert!(!event.is_null());
750    __assert!(!anchor.is_null());
751    if yaml_check_utf8(anchor, strlen(anchor as *mut libc::c_char)).fail {
752        return FAIL;
753    }
754    let anchor_copy: *mut yaml_char_t = yaml_strdup(anchor);
755    if anchor_copy.is_null() {
756        return FAIL;
757    }
758    memset(
759        event as *mut libc::c_void,
760        0,
761        size_of::<yaml_event_t>() as libc::c_ulong,
762    );
763    (*event).type_ = YAML_ALIAS_EVENT;
764    (*event).start_mark = mark;
765    (*event).end_mark = mark;
766    let fresh167 = addr_of_mut!((*event).data.alias.anchor);
767    *fresh167 = anchor_copy;
768    OK
769}
770
771/// Create a SCALAR event.
772///
773/// The `style` argument may be ignored by the emitter.
774///
775/// Either the `tag` attribute or one of the `plain_implicit` and
776/// `quoted_implicit` flags must be set.
777///
778pub unsafe fn yaml_scalar_event_initialize(
779    event: *mut yaml_event_t,
780    anchor: *const yaml_char_t,
781    tag: *const yaml_char_t,
782    value: *const yaml_char_t,
783    mut length: libc::c_int,
784    plain_implicit: bool,
785    quoted_implicit: bool,
786    style: yaml_scalar_style_t,
787) -> Success {
788    let mut current_block: u64;
789    let mark = yaml_mark_t {
790        index: 0_u64,
791        line: 0_u64,
792        column: 0_u64,
793    };
794    let mut anchor_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
795    let mut tag_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
796    let mut value_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
797    __assert!(!event.is_null());
798    __assert!(!value.is_null());
799    if !anchor.is_null() {
800        if yaml_check_utf8(anchor, strlen(anchor as *mut libc::c_char)).fail {
801            current_block = 16285396129609901221;
802        } else {
803            anchor_copy = yaml_strdup(anchor);
804            if anchor_copy.is_null() {
805                current_block = 16285396129609901221;
806            } else {
807                current_block = 8515828400728868193;
808            }
809        }
810    } else {
811        current_block = 8515828400728868193;
812    }
813    if current_block == 8515828400728868193 {
814        if !tag.is_null() {
815            if yaml_check_utf8(tag, strlen(tag as *mut libc::c_char)).fail {
816                current_block = 16285396129609901221;
817            } else {
818                tag_copy = yaml_strdup(tag);
819                if tag_copy.is_null() {
820                    current_block = 16285396129609901221;
821                } else {
822                    current_block = 12800627514080957624;
823                }
824            }
825        } else {
826            current_block = 12800627514080957624;
827        }
828        if current_block != 16285396129609901221 {
829            if length < 0 {
830                length = strlen(value as *mut libc::c_char) as libc::c_int;
831            }
832            if yaml_check_utf8(value, length as size_t).ok {
833                value_copy = yaml_malloc(length.force_add(1) as size_t) as *mut yaml_char_t;
834                memcpy(
835                    value_copy as *mut libc::c_void,
836                    value as *const libc::c_void,
837                    length as libc::c_ulong,
838                );
839                *value_copy.wrapping_offset(length as isize) = b'\0';
840                memset(
841                    event as *mut libc::c_void,
842                    0,
843                    size_of::<yaml_event_t>() as libc::c_ulong,
844                );
845                (*event).type_ = YAML_SCALAR_EVENT;
846                (*event).start_mark = mark;
847                (*event).end_mark = mark;
848                let fresh168 = addr_of_mut!((*event).data.scalar.anchor);
849                *fresh168 = anchor_copy;
850                let fresh169 = addr_of_mut!((*event).data.scalar.tag);
851                *fresh169 = tag_copy;
852                let fresh170 = addr_of_mut!((*event).data.scalar.value);
853                *fresh170 = value_copy;
854                (*event).data.scalar.length = length as size_t;
855                (*event).data.scalar.plain_implicit = plain_implicit;
856                (*event).data.scalar.quoted_implicit = quoted_implicit;
857                (*event).data.scalar.style = style;
858                return OK;
859            }
860        }
861    }
862    yaml_free(anchor_copy as *mut libc::c_void);
863    yaml_free(tag_copy as *mut libc::c_void);
864    yaml_free(value_copy as *mut libc::c_void);
865    FAIL
866}
867
868/// Create a SEQUENCE-START event.
869///
870/// The `style` argument may be ignored by the emitter.
871///
872/// Either the `tag` attribute or the `implicit` flag must be set.
873pub unsafe fn yaml_sequence_start_event_initialize(
874    event: *mut yaml_event_t,
875    anchor: *const yaml_char_t,
876    tag: *const yaml_char_t,
877    implicit: bool,
878    style: yaml_sequence_style_t,
879) -> Success {
880    let mut current_block: u64;
881    let mark = yaml_mark_t {
882        index: 0_u64,
883        line: 0_u64,
884        column: 0_u64,
885    };
886    let mut anchor_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
887    let mut tag_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
888    __assert!(!event.is_null());
889    if !anchor.is_null() {
890        if yaml_check_utf8(anchor, strlen(anchor as *mut libc::c_char)).fail {
891            current_block = 8817775685815971442;
892        } else {
893            anchor_copy = yaml_strdup(anchor);
894            if anchor_copy.is_null() {
895                current_block = 8817775685815971442;
896            } else {
897                current_block = 11006700562992250127;
898            }
899        }
900    } else {
901        current_block = 11006700562992250127;
902    }
903    match current_block {
904        11006700562992250127 => {
905            if !tag.is_null() {
906                if yaml_check_utf8(tag, strlen(tag as *mut libc::c_char)).fail {
907                    current_block = 8817775685815971442;
908                } else {
909                    tag_copy = yaml_strdup(tag);
910                    if tag_copy.is_null() {
911                        current_block = 8817775685815971442;
912                    } else {
913                        current_block = 7651349459974463963;
914                    }
915                }
916            } else {
917                current_block = 7651349459974463963;
918            }
919            if current_block != 8817775685815971442 {
920                memset(
921                    event as *mut libc::c_void,
922                    0,
923                    size_of::<yaml_event_t>() as libc::c_ulong,
924                );
925                (*event).type_ = YAML_SEQUENCE_START_EVENT;
926                (*event).start_mark = mark;
927                (*event).end_mark = mark;
928                let fresh171 = addr_of_mut!((*event).data.sequence_start.anchor);
929                *fresh171 = anchor_copy;
930                let fresh172 = addr_of_mut!((*event).data.sequence_start.tag);
931                *fresh172 = tag_copy;
932                (*event).data.sequence_start.implicit = implicit;
933                (*event).data.sequence_start.style = style;
934                return OK;
935            }
936        }
937        _ => {}
938    }
939    yaml_free(anchor_copy as *mut libc::c_void);
940    yaml_free(tag_copy as *mut libc::c_void);
941    FAIL
942}
943
944/// Create a SEQUENCE-END event.
945pub unsafe fn yaml_sequence_end_event_initialize(event: *mut yaml_event_t) -> Success {
946    let mark = yaml_mark_t {
947        index: 0_u64,
948        line: 0_u64,
949        column: 0_u64,
950    };
951    __assert!(!event.is_null());
952    memset(
953        event as *mut libc::c_void,
954        0,
955        size_of::<yaml_event_t>() as libc::c_ulong,
956    );
957    (*event).type_ = YAML_SEQUENCE_END_EVENT;
958    (*event).start_mark = mark;
959    (*event).end_mark = mark;
960    OK
961}
962
963/// Create a MAPPING-START event.
964///
965/// The `style` argument may be ignored by the emitter.
966///
967/// Either the `tag` attribute or the `implicit` flag must be set.
968pub unsafe fn yaml_mapping_start_event_initialize(
969    event: *mut yaml_event_t,
970    anchor: *const yaml_char_t,
971    tag: *const yaml_char_t,
972    implicit: bool,
973    style: yaml_mapping_style_t,
974) -> Success {
975    let mut current_block: u64;
976    let mark = yaml_mark_t {
977        index: 0_u64,
978        line: 0_u64,
979        column: 0_u64,
980    };
981    let mut anchor_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
982    let mut tag_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
983    __assert!(!event.is_null());
984    if !anchor.is_null() {
985        if yaml_check_utf8(anchor, strlen(anchor as *mut libc::c_char)).fail {
986            current_block = 14748279734549812740;
987        } else {
988            anchor_copy = yaml_strdup(anchor);
989            if anchor_copy.is_null() {
990                current_block = 14748279734549812740;
991            } else {
992                current_block = 11006700562992250127;
993            }
994        }
995    } else {
996        current_block = 11006700562992250127;
997    }
998    if current_block == 11006700562992250127 {
999        if !tag.is_null() {
1000            if yaml_check_utf8(tag, strlen(tag as *mut libc::c_char)).fail {
1001                current_block = 14748279734549812740;
1002            } else {
1003                tag_copy = yaml_strdup(tag);
1004                if tag_copy.is_null() {
1005                    current_block = 14748279734549812740;
1006                } else {
1007                    current_block = 7651349459974463963;
1008                }
1009            }
1010        } else {
1011            current_block = 7651349459974463963;
1012        }
1013        if current_block != 14748279734549812740 {
1014            memset(
1015                event as *mut libc::c_void,
1016                0,
1017                size_of::<yaml_event_t>() as libc::c_ulong,
1018            );
1019            (*event).type_ = YAML_MAPPING_START_EVENT;
1020            (*event).start_mark = mark;
1021            (*event).end_mark = mark;
1022            let fresh173 = addr_of_mut!((*event).data.mapping_start.anchor);
1023            *fresh173 = anchor_copy;
1024            let fresh174 = addr_of_mut!((*event).data.mapping_start.tag);
1025            *fresh174 = tag_copy;
1026            (*event).data.mapping_start.implicit = implicit;
1027            (*event).data.mapping_start.style = style;
1028            return OK;
1029        }
1030    }
1031    yaml_free(anchor_copy as *mut libc::c_void);
1032    yaml_free(tag_copy as *mut libc::c_void);
1033    FAIL
1034}
1035
1036/// Create a MAPPING-END event.
1037pub unsafe fn yaml_mapping_end_event_initialize(event: *mut yaml_event_t) -> Success {
1038    let mark = yaml_mark_t {
1039        index: 0_u64,
1040        line: 0_u64,
1041        column: 0_u64,
1042    };
1043    __assert!(!event.is_null());
1044    memset(
1045        event as *mut libc::c_void,
1046        0,
1047        size_of::<yaml_event_t>() as libc::c_ulong,
1048    );
1049    (*event).type_ = YAML_MAPPING_END_EVENT;
1050    (*event).start_mark = mark;
1051    (*event).end_mark = mark;
1052    OK
1053}
1054
1055/// Free any memory allocated for an event object.
1056pub unsafe fn yaml_event_delete(event: *mut yaml_event_t) {
1057    let mut tag_directive: *mut yaml_tag_directive_t;
1058    __assert!(!event.is_null());
1059    match (*event).type_ {
1060        YAML_DOCUMENT_START_EVENT => {
1061            yaml_free((*event).data.document_start.version_directive as *mut libc::c_void);
1062            tag_directive = (*event).data.document_start.tag_directives.start;
1063            while tag_directive != (*event).data.document_start.tag_directives.end {
1064                yaml_free((*tag_directive).handle as *mut libc::c_void);
1065                yaml_free((*tag_directive).prefix as *mut libc::c_void);
1066                tag_directive = tag_directive.wrapping_offset(1);
1067            }
1068            yaml_free((*event).data.document_start.tag_directives.start as *mut libc::c_void);
1069        }
1070        YAML_ALIAS_EVENT => {
1071            yaml_free((*event).data.alias.anchor as *mut libc::c_void);
1072        }
1073        YAML_SCALAR_EVENT => {
1074            yaml_free((*event).data.scalar.anchor as *mut libc::c_void);
1075            yaml_free((*event).data.scalar.tag as *mut libc::c_void);
1076            yaml_free((*event).data.scalar.value as *mut libc::c_void);
1077        }
1078        YAML_SEQUENCE_START_EVENT => {
1079            yaml_free((*event).data.sequence_start.anchor as *mut libc::c_void);
1080            yaml_free((*event).data.sequence_start.tag as *mut libc::c_void);
1081        }
1082        YAML_MAPPING_START_EVENT => {
1083            yaml_free((*event).data.mapping_start.anchor as *mut libc::c_void);
1084            yaml_free((*event).data.mapping_start.tag as *mut libc::c_void);
1085        }
1086        _ => {}
1087    }
1088    memset(
1089        event as *mut libc::c_void,
1090        0,
1091        size_of::<yaml_event_t>() as libc::c_ulong,
1092    );
1093}
1094
1095/// Create a YAML document.
1096pub unsafe fn yaml_document_initialize(
1097    document: *mut yaml_document_t,
1098    version_directive: *mut yaml_version_directive_t,
1099    tag_directives_start: *mut yaml_tag_directive_t,
1100    tag_directives_end: *mut yaml_tag_directive_t,
1101    start_implicit: bool,
1102    end_implicit: bool,
1103) -> Success {
1104    let current_block: u64;
1105    struct Nodes {
1106        start: *mut yaml_node_t,
1107        end: *mut yaml_node_t,
1108        top: *mut yaml_node_t,
1109    }
1110    let mut nodes = Nodes {
1111        start: ptr::null_mut::<yaml_node_t>(),
1112        end: ptr::null_mut::<yaml_node_t>(),
1113        top: ptr::null_mut::<yaml_node_t>(),
1114    };
1115    let mut version_directive_copy: *mut yaml_version_directive_t =
1116        ptr::null_mut::<yaml_version_directive_t>();
1117    struct TagDirectivesCopy {
1118        start: *mut yaml_tag_directive_t,
1119        end: *mut yaml_tag_directive_t,
1120        top: *mut yaml_tag_directive_t,
1121    }
1122    let mut tag_directives_copy = TagDirectivesCopy {
1123        start: ptr::null_mut::<yaml_tag_directive_t>(),
1124        end: ptr::null_mut::<yaml_tag_directive_t>(),
1125        top: ptr::null_mut::<yaml_tag_directive_t>(),
1126    };
1127    let mut value = yaml_tag_directive_t {
1128        handle: ptr::null_mut::<yaml_char_t>(),
1129        prefix: ptr::null_mut::<yaml_char_t>(),
1130    };
1131    let mark = yaml_mark_t {
1132        index: 0_u64,
1133        line: 0_u64,
1134        column: 0_u64,
1135    };
1136    __assert!(!document.is_null());
1137    __assert!(
1138        !tag_directives_start.is_null() && !tag_directives_end.is_null()
1139            || tag_directives_start == tag_directives_end
1140    );
1141    STACK_INIT!(nodes, yaml_node_t);
1142    if !version_directive.is_null() {
1143        version_directive_copy = yaml_malloc(size_of::<yaml_version_directive_t>() as libc::c_ulong)
1144            as *mut yaml_version_directive_t;
1145        (*version_directive_copy).major = (*version_directive).major;
1146        (*version_directive_copy).minor = (*version_directive).minor;
1147    }
1148    if tag_directives_start != tag_directives_end {
1149        let mut tag_directive: *mut yaml_tag_directive_t;
1150        STACK_INIT!(tag_directives_copy, yaml_tag_directive_t);
1151        tag_directive = tag_directives_start;
1152        loop {
1153            if !(tag_directive != tag_directives_end) {
1154                current_block = 14818589718467733107;
1155                break;
1156            }
1157            __assert!(!((*tag_directive).handle).is_null());
1158            __assert!(!((*tag_directive).prefix).is_null());
1159            if yaml_check_utf8(
1160                (*tag_directive).handle,
1161                strlen((*tag_directive).handle as *mut libc::c_char),
1162            )
1163            .fail
1164            {
1165                current_block = 8142820162064489797;
1166                break;
1167            }
1168            if yaml_check_utf8(
1169                (*tag_directive).prefix,
1170                strlen((*tag_directive).prefix as *mut libc::c_char),
1171            )
1172            .fail
1173            {
1174                current_block = 8142820162064489797;
1175                break;
1176            }
1177            value.handle = yaml_strdup((*tag_directive).handle);
1178            value.prefix = yaml_strdup((*tag_directive).prefix);
1179            if value.handle.is_null() || value.prefix.is_null() {
1180                current_block = 8142820162064489797;
1181                break;
1182            }
1183            PUSH!(tag_directives_copy, value);
1184            value.handle = ptr::null_mut::<yaml_char_t>();
1185            value.prefix = ptr::null_mut::<yaml_char_t>();
1186            tag_directive = tag_directive.wrapping_offset(1);
1187        }
1188    } else {
1189        current_block = 14818589718467733107;
1190    }
1191    if current_block != 8142820162064489797 {
1192        memset(
1193            document as *mut libc::c_void,
1194            0,
1195            size_of::<yaml_document_t>() as libc::c_ulong,
1196        );
1197        let fresh176 = addr_of_mut!((*document).nodes.start);
1198        *fresh176 = nodes.start;
1199        let fresh177 = addr_of_mut!((*document).nodes.end);
1200        *fresh177 = nodes.end;
1201        let fresh178 = addr_of_mut!((*document).nodes.top);
1202        *fresh178 = nodes.start;
1203        let fresh179 = addr_of_mut!((*document).version_directive);
1204        *fresh179 = version_directive_copy;
1205        let fresh180 = addr_of_mut!((*document).tag_directives.start);
1206        *fresh180 = tag_directives_copy.start;
1207        let fresh181 = addr_of_mut!((*document).tag_directives.end);
1208        *fresh181 = tag_directives_copy.top;
1209        (*document).start_implicit = start_implicit;
1210        (*document).end_implicit = end_implicit;
1211        (*document).start_mark = mark;
1212        (*document).end_mark = mark;
1213        return OK;
1214    }
1215    STACK_DEL!(nodes);
1216    yaml_free(version_directive_copy as *mut libc::c_void);
1217    while !STACK_EMPTY!(tag_directives_copy) {
1218        let value = POP!(tag_directives_copy);
1219        yaml_free(value.handle as *mut libc::c_void);
1220        yaml_free(value.prefix as *mut libc::c_void);
1221    }
1222    STACK_DEL!(tag_directives_copy);
1223    yaml_free(value.handle as *mut libc::c_void);
1224    yaml_free(value.prefix as *mut libc::c_void);
1225    FAIL
1226}
1227
1228/// Delete a YAML document and all its nodes.
1229pub unsafe fn yaml_document_delete(document: *mut yaml_document_t) {
1230    let mut tag_directive: *mut yaml_tag_directive_t;
1231    __assert!(!document.is_null());
1232    while !STACK_EMPTY!((*document).nodes) {
1233        let mut node = POP!((*document).nodes);
1234        yaml_free(node.tag as *mut libc::c_void);
1235        match node.type_ {
1236            YAML_SCALAR_NODE => {
1237                yaml_free(node.data.scalar.value as *mut libc::c_void);
1238            }
1239            YAML_SEQUENCE_NODE => {
1240                STACK_DEL!(node.data.sequence.items);
1241            }
1242            YAML_MAPPING_NODE => {
1243                STACK_DEL!(node.data.mapping.pairs);
1244            }
1245            _ => {
1246                __assert!(false);
1247            }
1248        }
1249    }
1250    STACK_DEL!((*document).nodes);
1251    yaml_free((*document).version_directive as *mut libc::c_void);
1252    tag_directive = (*document).tag_directives.start;
1253    while tag_directive != (*document).tag_directives.end {
1254        yaml_free((*tag_directive).handle as *mut libc::c_void);
1255        yaml_free((*tag_directive).prefix as *mut libc::c_void);
1256        tag_directive = tag_directive.wrapping_offset(1);
1257    }
1258    yaml_free((*document).tag_directives.start as *mut libc::c_void);
1259    memset(
1260        document as *mut libc::c_void,
1261        0,
1262        size_of::<yaml_document_t>() as libc::c_ulong,
1263    );
1264}
1265
1266/// Get a node of a YAML document.
1267///
1268/// The pointer returned by this function is valid until any of the functions
1269/// modifying the documents are called.
1270///
1271/// Returns the node objct or NULL if `node_id` is out of range.
1272pub unsafe fn yaml_document_get_node(
1273    document: *mut yaml_document_t,
1274    index: libc::c_int,
1275) -> *mut yaml_node_t {
1276    __assert!(!document.is_null());
1277    if index > 0 && (*document).nodes.start.wrapping_offset(index as isize) <= (*document).nodes.top
1278    {
1279        return (*document)
1280            .nodes
1281            .start
1282            .wrapping_offset(index as isize)
1283            .wrapping_offset(-1_isize);
1284    }
1285    ptr::null_mut::<yaml_node_t>()
1286}
1287
1288/// Get the root of a YAML document node.
1289///
1290/// The root object is the first object added to the document.
1291///
1292/// The pointer returned by this function is valid until any of the functions
1293/// modifying the documents are called.
1294///
1295/// An empty document produced by the parser signifies the end of a YAML stream.
1296///
1297/// Returns the node object or NULL if the document is empty.
1298pub unsafe fn yaml_document_get_root_node(document: *mut yaml_document_t) -> *mut yaml_node_t {
1299    __assert!(!document.is_null());
1300    if (*document).nodes.top != (*document).nodes.start {
1301        return (*document).nodes.start;
1302    }
1303    ptr::null_mut::<yaml_node_t>()
1304}
1305
1306/// Create a SCALAR node and attach it to the document.
1307///
1308/// The `style` argument may be ignored by the emitter.
1309///
1310/// Returns the node id or 0 on error.
1311#[must_use]
1312pub unsafe fn yaml_document_add_scalar(
1313    document: *mut yaml_document_t,
1314    mut tag: *const yaml_char_t,
1315    value: *const yaml_char_t,
1316    mut length: libc::c_int,
1317    style: yaml_scalar_style_t,
1318) -> libc::c_int {
1319    let mark = yaml_mark_t {
1320        index: 0_u64,
1321        line: 0_u64,
1322        column: 0_u64,
1323    };
1324    let mut tag_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
1325    let mut value_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
1326    let mut node = MaybeUninit::<yaml_node_t>::uninit();
1327    let node = node.as_mut_ptr();
1328    __assert!(!document.is_null());
1329    __assert!(!value.is_null());
1330    if tag.is_null() {
1331        tag = b"tag:yaml.org,2002:str\0" as *const u8 as *const libc::c_char as *mut yaml_char_t;
1332    }
1333    if yaml_check_utf8(tag, strlen(tag as *mut libc::c_char)).ok {
1334        tag_copy = yaml_strdup(tag);
1335        if !tag_copy.is_null() {
1336            if length < 0 {
1337                length = strlen(value as *mut libc::c_char) as libc::c_int;
1338            }
1339            if yaml_check_utf8(value, length as size_t).ok {
1340                value_copy = yaml_malloc(length.force_add(1) as size_t) as *mut yaml_char_t;
1341                memcpy(
1342                    value_copy as *mut libc::c_void,
1343                    value as *const libc::c_void,
1344                    length as libc::c_ulong,
1345                );
1346                *value_copy.wrapping_offset(length as isize) = b'\0';
1347                memset(
1348                    node as *mut libc::c_void,
1349                    0,
1350                    size_of::<yaml_node_t>() as libc::c_ulong,
1351                );
1352                (*node).type_ = YAML_SCALAR_NODE;
1353                (*node).tag = tag_copy;
1354                (*node).start_mark = mark;
1355                (*node).end_mark = mark;
1356                (*node).data.scalar.value = value_copy;
1357                (*node).data.scalar.length = length as size_t;
1358                (*node).data.scalar.style = style;
1359                PUSH!((*document).nodes, *node);
1360                return (*document).nodes.top.c_offset_from((*document).nodes.start) as libc::c_int;
1361            }
1362        }
1363    }
1364    yaml_free(tag_copy as *mut libc::c_void);
1365    yaml_free(value_copy as *mut libc::c_void);
1366    0
1367}
1368
1369/// Create a SEQUENCE node and attach it to the document.
1370///
1371/// The `style` argument may be ignored by the emitter.
1372///
1373/// Returns the node id or 0 on error.
1374#[must_use]
1375pub unsafe fn yaml_document_add_sequence(
1376    document: *mut yaml_document_t,
1377    mut tag: *const yaml_char_t,
1378    style: yaml_sequence_style_t,
1379) -> libc::c_int {
1380    let mark = yaml_mark_t {
1381        index: 0_u64,
1382        line: 0_u64,
1383        column: 0_u64,
1384    };
1385    let mut tag_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
1386    struct Items {
1387        start: *mut yaml_node_item_t,
1388        end: *mut yaml_node_item_t,
1389        top: *mut yaml_node_item_t,
1390    }
1391    let mut items = Items {
1392        start: ptr::null_mut::<yaml_node_item_t>(),
1393        end: ptr::null_mut::<yaml_node_item_t>(),
1394        top: ptr::null_mut::<yaml_node_item_t>(),
1395    };
1396    let mut node = MaybeUninit::<yaml_node_t>::uninit();
1397    let node = node.as_mut_ptr();
1398    __assert!(!document.is_null());
1399    if tag.is_null() {
1400        tag = b"tag:yaml.org,2002:seq\0" as *const u8 as *const libc::c_char as *mut yaml_char_t;
1401    }
1402    if yaml_check_utf8(tag, strlen(tag as *mut libc::c_char)).ok {
1403        tag_copy = yaml_strdup(tag);
1404        if !tag_copy.is_null() {
1405            STACK_INIT!(items, yaml_node_item_t);
1406            memset(
1407                node as *mut libc::c_void,
1408                0,
1409                size_of::<yaml_node_t>() as libc::c_ulong,
1410            );
1411            (*node).type_ = YAML_SEQUENCE_NODE;
1412            (*node).tag = tag_copy;
1413            (*node).start_mark = mark;
1414            (*node).end_mark = mark;
1415            (*node).data.sequence.items.start = items.start;
1416            (*node).data.sequence.items.end = items.end;
1417            (*node).data.sequence.items.top = items.start;
1418            (*node).data.sequence.style = style;
1419            PUSH!((*document).nodes, *node);
1420            return (*document).nodes.top.c_offset_from((*document).nodes.start) as libc::c_int;
1421        }
1422    }
1423    STACK_DEL!(items);
1424    yaml_free(tag_copy as *mut libc::c_void);
1425    0
1426}
1427
1428/// Create a MAPPING node and attach it to the document.
1429///
1430/// The `style` argument may be ignored by the emitter.
1431///
1432/// Returns the node id or 0 on error.
1433#[must_use]
1434pub unsafe fn yaml_document_add_mapping(
1435    document: *mut yaml_document_t,
1436    mut tag: *const yaml_char_t,
1437    style: yaml_mapping_style_t,
1438) -> libc::c_int {
1439    let mark = yaml_mark_t {
1440        index: 0_u64,
1441        line: 0_u64,
1442        column: 0_u64,
1443    };
1444    let mut tag_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
1445    struct Pairs {
1446        start: *mut yaml_node_pair_t,
1447        end: *mut yaml_node_pair_t,
1448        top: *mut yaml_node_pair_t,
1449    }
1450    let mut pairs = Pairs {
1451        start: ptr::null_mut::<yaml_node_pair_t>(),
1452        end: ptr::null_mut::<yaml_node_pair_t>(),
1453        top: ptr::null_mut::<yaml_node_pair_t>(),
1454    };
1455    let mut node = MaybeUninit::<yaml_node_t>::uninit();
1456    let node = node.as_mut_ptr();
1457    __assert!(!document.is_null());
1458    if tag.is_null() {
1459        tag = b"tag:yaml.org,2002:map\0" as *const u8 as *const libc::c_char as *mut yaml_char_t;
1460    }
1461    if yaml_check_utf8(tag, strlen(tag as *mut libc::c_char)).ok {
1462        tag_copy = yaml_strdup(tag);
1463        if !tag_copy.is_null() {
1464            STACK_INIT!(pairs, yaml_node_pair_t);
1465            memset(
1466                node as *mut libc::c_void,
1467                0,
1468                size_of::<yaml_node_t>() as libc::c_ulong,
1469            );
1470            (*node).type_ = YAML_MAPPING_NODE;
1471            (*node).tag = tag_copy;
1472            (*node).start_mark = mark;
1473            (*node).end_mark = mark;
1474            (*node).data.mapping.pairs.start = pairs.start;
1475            (*node).data.mapping.pairs.end = pairs.end;
1476            (*node).data.mapping.pairs.top = pairs.start;
1477            (*node).data.mapping.style = style;
1478            PUSH!((*document).nodes, *node);
1479            return (*document).nodes.top.c_offset_from((*document).nodes.start) as libc::c_int;
1480        }
1481    }
1482    STACK_DEL!(pairs);
1483    yaml_free(tag_copy as *mut libc::c_void);
1484    0
1485}
1486
1487/// Add an item to a SEQUENCE node.
1488pub unsafe fn yaml_document_append_sequence_item(
1489    document: *mut yaml_document_t,
1490    sequence: libc::c_int,
1491    item: libc::c_int,
1492) -> Success {
1493    __assert!(!document.is_null());
1494    __assert!(
1495        sequence > 0
1496            && ((*document).nodes.start).wrapping_offset(sequence as isize)
1497                <= (*document).nodes.top
1498    );
1499    __assert!(
1500        (*((*document).nodes.start).wrapping_offset((sequence - 1) as isize)).type_
1501            == YAML_SEQUENCE_NODE
1502    );
1503    __assert!(
1504        item > 0
1505            && ((*document).nodes.start).wrapping_offset(item as isize) <= (*document).nodes.top
1506    );
1507    PUSH!(
1508        (*((*document).nodes.start).wrapping_offset((sequence - 1) as isize))
1509            .data
1510            .sequence
1511            .items,
1512        item
1513    );
1514    OK
1515}
1516
1517/// Add a pair of a key and a value to a MAPPING node.
1518pub unsafe fn yaml_document_append_mapping_pair(
1519    document: *mut yaml_document_t,
1520    mapping: libc::c_int,
1521    key: libc::c_int,
1522    value: libc::c_int,
1523) -> Success {
1524    __assert!(!document.is_null());
1525    __assert!(
1526        mapping > 0
1527            && ((*document).nodes.start).wrapping_offset(mapping as isize) <= (*document).nodes.top
1528    );
1529    __assert!(
1530        (*((*document).nodes.start).wrapping_offset((mapping - 1) as isize)).type_
1531            == YAML_MAPPING_NODE
1532    );
1533    __assert!(
1534        key > 0 && ((*document).nodes.start).wrapping_offset(key as isize) <= (*document).nodes.top
1535    );
1536    __assert!(
1537        value > 0
1538            && ((*document).nodes.start).wrapping_offset(value as isize) <= (*document).nodes.top
1539    );
1540    let pair = yaml_node_pair_t { key, value };
1541    PUSH!(
1542        (*((*document).nodes.start).wrapping_offset((mapping - 1) as isize))
1543            .data
1544            .mapping
1545            .pairs,
1546        pair
1547    );
1548    OK
1549}