1//
2// Copyright (c) 2011-2019 Canonical Ltd
3// Copyright (c) 2006-2010 Kirill Simonov
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy of
6// this software and associated documentation files (the "Software"), to deal in
7// the Software without restriction, including without limitation the rights to
8// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9// of the Software, and to permit persons to whom the Software is furnished to do
10// so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in all
13// copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21// SOFTWARE.
22
23package yaml
24
25import (
26	"io"
27)
28
29func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
30	//fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens))
31
32	// Check if we can move the queue at the beginning of the buffer.
33	if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) {
34		if parser.tokens_head != len(parser.tokens) {
35			copy(parser.tokens, parser.tokens[parser.tokens_head:])
36		}
37		parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head]
38		parser.tokens_head = 0
39	}
40	parser.tokens = append(parser.tokens, *token)
41	if pos < 0 {
42		return
43	}
44	copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:])
45	parser.tokens[parser.tokens_head+pos] = *token
46}
47
48// Create a new parser object.
49func yaml_parser_initialize(parser *yaml_parser_t) bool {
50	*parser = yaml_parser_t{
51		raw_buffer: make([]byte, 0, input_raw_buffer_size),
52		buffer:     make([]byte, 0, input_buffer_size),
53	}
54	return true
55}
56
57// Destroy a parser object.
58func yaml_parser_delete(parser *yaml_parser_t) {
59	*parser = yaml_parser_t{}
60}
61
62// String read handler.
63func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
64	if parser.input_pos == len(parser.input) {
65		return 0, io.EOF
66	}
67	n = copy(buffer, parser.input[parser.input_pos:])
68	parser.input_pos += n
69	return n, nil
70}
71
72// Reader read handler.
73func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
74	return parser.input_reader.Read(buffer)
75}
76
77// Set a string input.
78func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
79	if parser.read_handler != nil {
80		panic("must set the input source only once")
81	}
82	parser.read_handler = yaml_string_read_handler
83	parser.input = input
84	parser.input_pos = 0
85}
86
87// Set a file input.
88func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {
89	if parser.read_handler != nil {
90		panic("must set the input source only once")
91	}
92	parser.read_handler = yaml_reader_read_handler
93	parser.input_reader = r
94}
95
96// Set the source encoding.
97func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
98	if parser.encoding != yaml_ANY_ENCODING {
99		panic("must set the encoding only once")
100	}
101	parser.encoding = encoding
102}
103
104// Create a new emitter object.
105func yaml_emitter_initialize(emitter *yaml_emitter_t) {
106	*emitter = yaml_emitter_t{
107		buffer:     make([]byte, output_buffer_size),
108		raw_buffer: make([]byte, 0, output_raw_buffer_size),
109		states:     make([]yaml_emitter_state_t, 0, initial_stack_size),
110		events:     make([]yaml_event_t, 0, initial_queue_size),
111		best_width: -1,
112	}
113}
114
115// Destroy an emitter object.
116func yaml_emitter_delete(emitter *yaml_emitter_t) {
117	*emitter = yaml_emitter_t{}
118}
119
120// String write handler.
121func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
122	*emitter.output_buffer = append(*emitter.output_buffer, buffer...)
123	return nil
124}
125
126// yaml_writer_write_handler uses emitter.output_writer to write the
127// emitted text.
128func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
129	_, err := emitter.output_writer.Write(buffer)
130	return err
131}
132
133// Set a string output.
134func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) {
135	if emitter.write_handler != nil {
136		panic("must set the output target only once")
137	}
138	emitter.write_handler = yaml_string_write_handler
139	emitter.output_buffer = output_buffer
140}
141
142// Set a file output.
143func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {
144	if emitter.write_handler != nil {
145		panic("must set the output target only once")
146	}
147	emitter.write_handler = yaml_writer_write_handler
148	emitter.output_writer = w
149}
150
151// Set the output encoding.
152func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) {
153	if emitter.encoding != yaml_ANY_ENCODING {
154		panic("must set the output encoding only once")
155	}
156	emitter.encoding = encoding
157}
158
159// Set the canonical output style.
160func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) {
161	emitter.canonical = canonical
162}
163
164// Set the indentation increment.
165func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) {
166	if indent < 2 || indent > 9 {
167		indent = 2
168	}
169	emitter.best_indent = indent
170}
171
172// Set the preferred line width.
173func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) {
174	if width < 0 {
175		width = -1
176	}
177	emitter.best_width = width
178}
179
180// Set if unescaped non-ASCII characters are allowed.
181func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) {
182	emitter.unicode = unicode
183}
184
185// Set the preferred line break character.
186func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
187	emitter.line_break = line_break
188}
189
190///*
191// * Destroy a token object.
192// */
193//
194//YAML_DECLARE(void)
195//yaml_token_delete(yaml_token_t *token)
196//{
197//    assert(token);  // Non-NULL token object expected.
198//
199//    switch (token.type)
200//    {
201//        case YAML_TAG_DIRECTIVE_TOKEN:
202//            yaml_free(token.data.tag_directive.handle);
203//            yaml_free(token.data.tag_directive.prefix);
204//            break;
205//
206//        case YAML_ALIAS_TOKEN:
207//            yaml_free(token.data.alias.value);
208//            break;
209//
210//        case YAML_ANCHOR_TOKEN:
211//            yaml_free(token.data.anchor.value);
212//            break;
213//
214//        case YAML_TAG_TOKEN:
215//            yaml_free(token.data.tag.handle);
216//            yaml_free(token.data.tag.suffix);
217//            break;
218//
219//        case YAML_SCALAR_TOKEN:
220//            yaml_free(token.data.scalar.value);
221//            break;
222//
223//        default:
224//            break;
225//    }
226//
227//    memset(token, 0, sizeof(yaml_token_t));
228//}
229//
230///*
231// * Check if a string is a valid UTF-8 sequence.
232// *
233// * Check 'reader.c' for more details on UTF-8 encoding.
234// */
235//
236//static int
237//yaml_check_utf8(yaml_char_t *start, size_t length)
238//{
239//    yaml_char_t *end = start+length;
240//    yaml_char_t *pointer = start;
241//
242//    while (pointer < end) {
243//        unsigned char octet;
244//        unsigned int width;
245//        unsigned int value;
246//        size_t k;
247//
248//        octet = pointer[0];
249//        width = (octet & 0x80) == 0x00 ? 1 :
250//                (octet & 0xE0) == 0xC0 ? 2 :
251//                (octet & 0xF0) == 0xE0 ? 3 :
252//                (octet & 0xF8) == 0xF0 ? 4 : 0;
253//        value = (octet & 0x80) == 0x00 ? octet & 0x7F :
254//                (octet & 0xE0) == 0xC0 ? octet & 0x1F :
255//                (octet & 0xF0) == 0xE0 ? octet & 0x0F :
256//                (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
257//        if (!width) return 0;
258//        if (pointer+width > end) return 0;
259//        for (k = 1; k < width; k ++) {
260//            octet = pointer[k];
261//            if ((octet & 0xC0) != 0x80) return 0;
262//            value = (value << 6) + (octet & 0x3F);
263//        }
264//        if (!((width == 1) ||
265//            (width == 2 && value >= 0x80) ||
266//            (width == 3 && value >= 0x800) ||
267//            (width == 4 && value >= 0x10000))) return 0;
268//
269//        pointer += width;
270//    }
271//
272//    return 1;
273//}
274//
275
276// Create STREAM-START.
277func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) {
278	*event = yaml_event_t{
279		typ:      yaml_STREAM_START_EVENT,
280		encoding: encoding,
281	}
282}
283
284// Create STREAM-END.
285func yaml_stream_end_event_initialize(event *yaml_event_t) {
286	*event = yaml_event_t{
287		typ: yaml_STREAM_END_EVENT,
288	}
289}
290
291// Create DOCUMENT-START.
292func yaml_document_start_event_initialize(
293	event *yaml_event_t,
294	version_directive *yaml_version_directive_t,
295	tag_directives []yaml_tag_directive_t,
296	implicit bool,
297) {
298	*event = yaml_event_t{
299		typ:               yaml_DOCUMENT_START_EVENT,
300		version_directive: version_directive,
301		tag_directives:    tag_directives,
302		implicit:          implicit,
303	}
304}
305
306// Create DOCUMENT-END.
307func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) {
308	*event = yaml_event_t{
309		typ:      yaml_DOCUMENT_END_EVENT,
310		implicit: implicit,
311	}
312}
313
314// Create ALIAS.
315func yaml_alias_event_initialize(event *yaml_event_t, anchor []byte) bool {
316	*event = yaml_event_t{
317		typ:    yaml_ALIAS_EVENT,
318		anchor: anchor,
319	}
320	return true
321}
322
323// Create SCALAR.
324func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool {
325	*event = yaml_event_t{
326		typ:             yaml_SCALAR_EVENT,
327		anchor:          anchor,
328		tag:             tag,
329		value:           value,
330		implicit:        plain_implicit,
331		quoted_implicit: quoted_implicit,
332		style:           yaml_style_t(style),
333	}
334	return true
335}
336
337// Create SEQUENCE-START.
338func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool {
339	*event = yaml_event_t{
340		typ:      yaml_SEQUENCE_START_EVENT,
341		anchor:   anchor,
342		tag:      tag,
343		implicit: implicit,
344		style:    yaml_style_t(style),
345	}
346	return true
347}
348
349// Create SEQUENCE-END.
350func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
351	*event = yaml_event_t{
352		typ: yaml_SEQUENCE_END_EVENT,
353	}
354	return true
355}
356
357// Create MAPPING-START.
358func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {
359	*event = yaml_event_t{
360		typ:      yaml_MAPPING_START_EVENT,
361		anchor:   anchor,
362		tag:      tag,
363		implicit: implicit,
364		style:    yaml_style_t(style),
365	}
366}
367
368// Create MAPPING-END.
369func yaml_mapping_end_event_initialize(event *yaml_event_t) {
370	*event = yaml_event_t{
371		typ: yaml_MAPPING_END_EVENT,
372	}
373}
374
375// Destroy an event object.
376func yaml_event_delete(event *yaml_event_t) {
377	*event = yaml_event_t{}
378}
379
380///*
381// * Create a document object.
382// */
383//
384//YAML_DECLARE(int)
385//yaml_document_initialize(document *yaml_document_t,
386//        version_directive *yaml_version_directive_t,
387//        tag_directives_start *yaml_tag_directive_t,
388//        tag_directives_end *yaml_tag_directive_t,
389//        start_implicit int, end_implicit int)
390//{
391//    struct {
392//        error yaml_error_type_t
393//    } context
394//    struct {
395//        start *yaml_node_t
396//        end *yaml_node_t
397//        top *yaml_node_t
398//    } nodes = { NULL, NULL, NULL }
399//    version_directive_copy *yaml_version_directive_t = NULL
400//    struct {
401//        start *yaml_tag_directive_t
402//        end *yaml_tag_directive_t
403//        top *yaml_tag_directive_t
404//    } tag_directives_copy = { NULL, NULL, NULL }
405//    value yaml_tag_directive_t = { NULL, NULL }
406//    mark yaml_mark_t = { 0, 0, 0 }
407//
408//    assert(document) // Non-NULL document object is expected.
409//    assert((tag_directives_start && tag_directives_end) ||
410//            (tag_directives_start == tag_directives_end))
411//                            // Valid tag directives are expected.
412//
413//    if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error
414//
415//    if (version_directive) {
416//        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t))
417//        if (!version_directive_copy) goto error
418//        version_directive_copy.major = version_directive.major
419//        version_directive_copy.minor = version_directive.minor
420//    }
421//
422//    if (tag_directives_start != tag_directives_end) {
423//        tag_directive *yaml_tag_directive_t
424//        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
425//            goto error
426//        for (tag_directive = tag_directives_start
427//                tag_directive != tag_directives_end; tag_directive ++) {
428//            assert(tag_directive.handle)
429//            assert(tag_directive.prefix)
430//            if (!yaml_check_utf8(tag_directive.handle,
431//                        strlen((char *)tag_directive.handle)))
432//                goto error
433//            if (!yaml_check_utf8(tag_directive.prefix,
434//                        strlen((char *)tag_directive.prefix)))
435//                goto error
436//            value.handle = yaml_strdup(tag_directive.handle)
437//            value.prefix = yaml_strdup(tag_directive.prefix)
438//            if (!value.handle || !value.prefix) goto error
439//            if (!PUSH(&context, tag_directives_copy, value))
440//                goto error
441//            value.handle = NULL
442//            value.prefix = NULL
443//        }
444//    }
445//
446//    DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
447//            tag_directives_copy.start, tag_directives_copy.top,
448//            start_implicit, end_implicit, mark, mark)
449//
450//    return 1
451//
452//error:
453//    STACK_DEL(&context, nodes)
454//    yaml_free(version_directive_copy)
455//    while (!STACK_EMPTY(&context, tag_directives_copy)) {
456//        value yaml_tag_directive_t = POP(&context, tag_directives_copy)
457//        yaml_free(value.handle)
458//        yaml_free(value.prefix)
459//    }
460//    STACK_DEL(&context, tag_directives_copy)
461//    yaml_free(value.handle)
462//    yaml_free(value.prefix)
463//
464//    return 0
465//}
466//
467///*
468// * Destroy a document object.
469// */
470//
471//YAML_DECLARE(void)
472//yaml_document_delete(document *yaml_document_t)
473//{
474//    struct {
475//        error yaml_error_type_t
476//    } context
477//    tag_directive *yaml_tag_directive_t
478//
479//    context.error = YAML_NO_ERROR // Eliminate a compiler warning.
480//
481//    assert(document) // Non-NULL document object is expected.
482//
483//    while (!STACK_EMPTY(&context, document.nodes)) {
484//        node yaml_node_t = POP(&context, document.nodes)
485//        yaml_free(node.tag)
486//        switch (node.type) {
487//            case YAML_SCALAR_NODE:
488//                yaml_free(node.data.scalar.value)
489//                break
490//            case YAML_SEQUENCE_NODE:
491//                STACK_DEL(&context, node.data.sequence.items)
492//                break
493//            case YAML_MAPPING_NODE:
494//                STACK_DEL(&context, node.data.mapping.pairs)
495//                break
496//            default:
497//                assert(0) // Should not happen.
498//        }
499//    }
500//    STACK_DEL(&context, document.nodes)
501//
502//    yaml_free(document.version_directive)
503//    for (tag_directive = document.tag_directives.start
504//            tag_directive != document.tag_directives.end
505//            tag_directive++) {
506//        yaml_free(tag_directive.handle)
507//        yaml_free(tag_directive.prefix)
508//    }
509//    yaml_free(document.tag_directives.start)
510//
511//    memset(document, 0, sizeof(yaml_document_t))
512//}
513//
514///**
515// * Get a document node.
516// */
517//
518//YAML_DECLARE(yaml_node_t *)
519//yaml_document_get_node(document *yaml_document_t, index int)
520//{
521//    assert(document) // Non-NULL document object is expected.
522//
523//    if (index > 0 && document.nodes.start + index <= document.nodes.top) {
524//        return document.nodes.start + index - 1
525//    }
526//    return NULL
527//}
528//
529///**
530// * Get the root object.
531// */
532//
533//YAML_DECLARE(yaml_node_t *)
534//yaml_document_get_root_node(document *yaml_document_t)
535//{
536//    assert(document) // Non-NULL document object is expected.
537//
538//    if (document.nodes.top != document.nodes.start) {
539//        return document.nodes.start
540//    }
541//    return NULL
542//}
543//
544///*
545// * Add a scalar node to a document.
546// */
547//
548//YAML_DECLARE(int)
549//yaml_document_add_scalar(document *yaml_document_t,
550//        tag *yaml_char_t, value *yaml_char_t, length int,
551//        style yaml_scalar_style_t)
552//{
553//    struct {
554//        error yaml_error_type_t
555//    } context
556//    mark yaml_mark_t = { 0, 0, 0 }
557//    tag_copy *yaml_char_t = NULL
558//    value_copy *yaml_char_t = NULL
559//    node yaml_node_t
560//
561//    assert(document) // Non-NULL document object is expected.
562//    assert(value) // Non-NULL value is expected.
563//
564//    if (!tag) {
565//        tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG
566//    }
567//
568//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
569//    tag_copy = yaml_strdup(tag)
570//    if (!tag_copy) goto error
571//
572//    if (length < 0) {
573//        length = strlen((char *)value)
574//    }
575//
576//    if (!yaml_check_utf8(value, length)) goto error
577//    value_copy = yaml_malloc(length+1)
578//    if (!value_copy) goto error
579//    memcpy(value_copy, value, length)
580//    value_copy[length] = '\0'
581//
582//    SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark)
583//    if (!PUSH(&context, document.nodes, node)) goto error
584//
585//    return document.nodes.top - document.nodes.start
586//
587//error:
588//    yaml_free(tag_copy)
589//    yaml_free(value_copy)
590//
591//    return 0
592//}
593//
594///*
595// * Add a sequence node to a document.
596// */
597//
598//YAML_DECLARE(int)
599//yaml_document_add_sequence(document *yaml_document_t,
600//        tag *yaml_char_t, style yaml_sequence_style_t)
601//{
602//    struct {
603//        error yaml_error_type_t
604//    } context
605//    mark yaml_mark_t = { 0, 0, 0 }
606//    tag_copy *yaml_char_t = NULL
607//    struct {
608//        start *yaml_node_item_t
609//        end *yaml_node_item_t
610//        top *yaml_node_item_t
611//    } items = { NULL, NULL, NULL }
612//    node yaml_node_t
613//
614//    assert(document) // Non-NULL document object is expected.
615//
616//    if (!tag) {
617//        tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG
618//    }
619//
620//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
621//    tag_copy = yaml_strdup(tag)
622//    if (!tag_copy) goto error
623//
624//    if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error
625//
626//    SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
627//            style, mark, mark)
628//    if (!PUSH(&context, document.nodes, node)) goto error
629//
630//    return document.nodes.top - document.nodes.start
631//
632//error:
633//    STACK_DEL(&context, items)
634//    yaml_free(tag_copy)
635//
636//    return 0
637//}
638//
639///*
640// * Add a mapping node to a document.
641// */
642//
643//YAML_DECLARE(int)
644//yaml_document_add_mapping(document *yaml_document_t,
645//        tag *yaml_char_t, style yaml_mapping_style_t)
646//{
647//    struct {
648//        error yaml_error_type_t
649//    } context
650//    mark yaml_mark_t = { 0, 0, 0 }
651//    tag_copy *yaml_char_t = NULL
652//    struct {
653//        start *yaml_node_pair_t
654//        end *yaml_node_pair_t
655//        top *yaml_node_pair_t
656//    } pairs = { NULL, NULL, NULL }
657//    node yaml_node_t
658//
659//    assert(document) // Non-NULL document object is expected.
660//
661//    if (!tag) {
662//        tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG
663//    }
664//
665//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
666//    tag_copy = yaml_strdup(tag)
667//    if (!tag_copy) goto error
668//
669//    if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error
670//
671//    MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
672//            style, mark, mark)
673//    if (!PUSH(&context, document.nodes, node)) goto error
674//
675//    return document.nodes.top - document.nodes.start
676//
677//error:
678//    STACK_DEL(&context, pairs)
679//    yaml_free(tag_copy)
680//
681//    return 0
682//}
683//
684///*
685// * Append an item to a sequence node.
686// */
687//
688//YAML_DECLARE(int)
689//yaml_document_append_sequence_item(document *yaml_document_t,
690//        sequence int, item int)
691//{
692//    struct {
693//        error yaml_error_type_t
694//    } context
695//
696//    assert(document) // Non-NULL document is required.
697//    assert(sequence > 0
698//            && document.nodes.start + sequence <= document.nodes.top)
699//                            // Valid sequence id is required.
700//    assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE)
701//                            // A sequence node is required.
702//    assert(item > 0 && document.nodes.start + item <= document.nodes.top)
703//                            // Valid item id is required.
704//
705//    if (!PUSH(&context,
706//                document.nodes.start[sequence-1].data.sequence.items, item))
707//        return 0
708//
709//    return 1
710//}
711//
712///*
713// * Append a pair of a key and a value to a mapping node.
714// */
715//
716//YAML_DECLARE(int)
717//yaml_document_append_mapping_pair(document *yaml_document_t,
718//        mapping int, key int, value int)
719//{
720//    struct {
721//        error yaml_error_type_t
722//    } context
723//
724//    pair yaml_node_pair_t
725//
726//    assert(document) // Non-NULL document is required.
727//    assert(mapping > 0
728//            && document.nodes.start + mapping <= document.nodes.top)
729//                            // Valid mapping id is required.
730//    assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE)
731//                            // A mapping node is required.
732//    assert(key > 0 && document.nodes.start + key <= document.nodes.top)
733//                            // Valid key id is required.
734//    assert(value > 0 && document.nodes.start + value <= document.nodes.top)
735//                            // Valid value id is required.
736//
737//    pair.key = key
738//    pair.value = value
739//
740//    if (!PUSH(&context,
741//                document.nodes.start[mapping-1].data.mapping.pairs, pair))
742//        return 0
743//
744//    return 1
745//}
746//
747//
748