Skip to main content

unsafe_libyaml/
api.rs

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