Coverage Report

Created: 2026-01-09 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/tools/yaml/api.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2006-2016 Kirill Simonov
3
 * 
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
5
 * this software and associated documentation files (the "Software"), to deal in
6
 * the Software without restriction, including without limitation the rights to
7
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8
 * of the Software, and to permit persons to whom the Software is furnished to do
9
 * so, subject to the following conditions:
10
 * 
11
 * The above copyright notice and this permission notice shall be included in all
12
 * copies or substantial portions of the Software.
13
 * 
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
 * SOFTWARE.
21
 *
22
 */
23
24
#include "yaml_private.h"
25
26
/*
27
 * Get the library version.
28
 */
29
30
YAML_DECLARE(const char *)
31
yaml_get_version_string(void)
32
0
{
33
0
    return YAML_VERSION_STRING;
34
0
}
35
36
/*
37
 * Get the library version numbers.
38
 */
39
40
YAML_DECLARE(void)
41
yaml_get_version(int *major, int *minor, int *patch)
42
0
{
43
0
    *major = YAML_VERSION_MAJOR;
44
0
    *minor = YAML_VERSION_MINOR;
45
0
    *patch = YAML_VERSION_PATCH;
46
0
}
47
48
/*
49
 * Allocate a dynamic memory block.
50
 */
51
52
YAML_DECLARE(void *)
53
yaml_malloc(size_t size)
54
0
{
55
0
    return malloc(size ? size : 1);
56
0
}
57
58
/*
59
 * Reallocate a dynamic memory block.
60
 */
61
62
YAML_DECLARE(void *)
63
yaml_realloc(void *ptr, size_t size)
64
0
{
65
0
    return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1);
66
0
}
67
68
/*
69
 * Free a dynamic memory block.
70
 */
71
72
YAML_DECLARE(void)
73
yaml_free(void *ptr)
74
0
{
75
0
    if (ptr) free(ptr);
76
0
}
77
78
/*
79
 * Duplicate a string.
80
 */
81
82
YAML_DECLARE(yaml_char_t *)
83
yaml_strdup(const yaml_char_t *str)
84
0
{
85
0
    if (!str)
86
0
        return NULL;
87
88
#ifdef WIN32
89
    return (yaml_char_t *)_strdup((char *)str);
90
#else
91
0
    return (yaml_char_t *)strdup((char *)str);
92
0
#endif
93
0
}
94
95
/*
96
 * Extend a string.
97
 */
98
99
YAML_DECLARE(int)
100
yaml_string_extend(yaml_char_t **start,
101
        yaml_char_t **pointer, yaml_char_t **end)
102
0
{
103
0
    yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2);
104
105
0
    if (!new_start) return 0;
106
107
0
    memset(new_start + (*end - *start), 0, *end - *start);
108
109
0
    *pointer = new_start + (*pointer - *start);
110
0
    *end = new_start + (*end - *start)*2;
111
0
    *start = new_start;
112
113
0
    return 1;
114
0
}
115
116
/*
117
 * Append a string B to a string A.
118
 */
119
120
YAML_DECLARE(int)
121
yaml_string_join(
122
        yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
123
        yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end)
124
0
{
125
0
    if (*b_start == *b_pointer)
126
0
        return 1;
127
128
0
    while (*a_end - *a_pointer <= *b_pointer - *b_start) {
129
0
        if (!yaml_string_extend(a_start, a_pointer, a_end))
130
0
            return 0;
131
0
    }
132
133
0
    memcpy(*a_pointer, *b_start, *b_pointer - *b_start);
134
0
    *a_pointer += *b_pointer - *b_start;
135
136
0
    return 1;
137
0
}
138
139
/*
140
 * Extend a stack.
141
 */
142
143
YAML_DECLARE(int)
144
yaml_stack_extend(void **start, void **top, void **end)
145
0
{
146
0
    void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
147
148
0
    if (!new_start) return 0;
149
150
0
    *top = (char *)new_start + ((char *)*top - (char *)*start);
151
0
    *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
152
0
    *start = new_start;
153
154
0
    return 1;
155
0
}
156
157
/*
158
 * Extend or move a queue.
159
 */
160
161
YAML_DECLARE(int)
162
yaml_queue_extend(void **start, void **head, void **tail, void **end)
163
0
{
164
    /* Check if we need to resize the queue. */
165
166
0
    if (*start == *head && *tail == *end) {
167
0
        void *new_start = yaml_realloc(*start,
168
0
                ((char *)*end - (char *)*start)*2);
169
170
0
        if (!new_start) return 0;
171
172
0
        *head = (char *)new_start + ((char *)*head - (char *)*start);
173
0
        *tail = (char *)new_start + ((char *)*tail - (char *)*start);
174
0
        *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
175
0
        *start = new_start;
176
0
    }
177
178
    /* Check if we need to move the queue at the beginning of the buffer. */
179
180
0
    if (*tail == *end) {
181
0
        if (*head != *tail) {
182
0
            memmove(*start, *head, (char *)*tail - (char *)*head);
183
0
        }
184
0
        *tail = (char *)*tail - (char *)*head + (char *)*start;
185
0
        *head = *start;
186
0
    }
187
188
0
    return 1;
189
0
}
190
191
192
/*
193
 * Create a new parser object.
194
 */
195
196
YAML_DECLARE(int)
197
yaml_parser_initialize(yaml_parser_t *parser)
198
0
{
199
0
    assert(parser);     /* Non-NULL parser object expected. */
200
201
0
    memset(parser, 0, sizeof(yaml_parser_t));
202
0
    if (!BUFFER_INIT(parser, parser->raw_buffer, INPUT_RAW_BUFFER_SIZE))
203
0
        goto error;
204
0
    if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE))
205
0
        goto error;
206
0
    if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE))
207
0
        goto error;
208
0
    if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_SIZE))
209
0
        goto error;
210
0
    if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_SIZE))
211
0
        goto error;
212
0
    if (!STACK_INIT(parser, parser->states, INITIAL_STACK_SIZE))
213
0
        goto error;
214
0
    if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_SIZE))
215
0
        goto error;
216
0
    if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_SIZE))
217
0
        goto error;
218
219
0
    return 1;
220
221
0
error:
222
223
0
    BUFFER_DEL(parser, parser->raw_buffer);
224
0
    BUFFER_DEL(parser, parser->buffer);
225
0
    QUEUE_DEL(parser, parser->tokens);
226
0
    STACK_DEL(parser, parser->indents);
227
0
    STACK_DEL(parser, parser->simple_keys);
228
0
    STACK_DEL(parser, parser->states);
229
0
    STACK_DEL(parser, parser->marks);
230
0
    STACK_DEL(parser, parser->tag_directives);
231
232
0
    return 0;
233
0
}
234
235
/*
236
 * Destroy a parser object.
237
 */
238
239
YAML_DECLARE(void)
240
yaml_parser_delete(yaml_parser_t *parser)
241
0
{
242
0
    assert(parser); /* Non-NULL parser object expected. */
243
244
0
    BUFFER_DEL(parser, parser->raw_buffer);
245
0
    BUFFER_DEL(parser, parser->buffer);
246
0
    while (!QUEUE_EMPTY(parser, parser->tokens)) {
247
0
        yaml_token_delete(&DEQUEUE(parser, parser->tokens));
248
0
    }
249
0
    QUEUE_DEL(parser, parser->tokens);
250
0
    STACK_DEL(parser, parser->indents);
251
0
    STACK_DEL(parser, parser->simple_keys);
252
0
    STACK_DEL(parser, parser->states);
253
0
    STACK_DEL(parser, parser->marks);
254
0
    while (!STACK_EMPTY(parser, parser->tag_directives)) {
255
0
        yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
256
0
        yaml_free(tag_directive.handle);
257
0
        yaml_free(tag_directive.prefix);
258
0
    }
259
0
    STACK_DEL(parser, parser->tag_directives);
260
261
0
    memset(parser, 0, sizeof(yaml_parser_t));
262
0
}
263
264
/*
265
 * String read handler.
266
 */
267
268
static int
269
yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
270
        size_t *size_read)
271
0
{
272
0
    yaml_parser_t *parser = data;
273
274
0
    if (parser->input.string.current == parser->input.string.end) {
275
0
        *size_read = 0;
276
0
        return 1;
277
0
    }
278
279
0
    if (size > (size_t)(parser->input.string.end
280
0
                - parser->input.string.current)) {
281
0
        size = parser->input.string.end - parser->input.string.current;
282
0
    }
283
284
0
    memcpy(buffer, parser->input.string.current, size);
285
0
    parser->input.string.current += size;
286
0
    *size_read = size;
287
0
    return 1;
288
0
}
289
290
/*
291
 * File read handler.
292
 */
293
294
static int
295
yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
296
        size_t *size_read)
297
0
{
298
0
    yaml_parser_t *parser = data;
299
300
0
    *size_read = fread(buffer, 1, size, parser->input.file);
301
0
    return !ferror(parser->input.file);
302
0
}
303
304
/*
305
 * Set a string input.
306
 */
307
308
YAML_DECLARE(void)
309
yaml_parser_set_input_string(yaml_parser_t *parser,
310
        const unsigned char *input, size_t size)
311
0
{
312
0
    assert(parser); /* Non-NULL parser object expected. */
313
0
    assert(!parser->read_handler);  /* You can set the source only once. */
314
0
    assert(input);  /* Non-NULL input string expected. */
315
316
0
    parser->read_handler = yaml_string_read_handler;
317
0
    parser->read_handler_data = parser;
318
319
0
    parser->input.string.start = input;
320
0
    parser->input.string.current = input;
321
0
    parser->input.string.end = input+size;
322
0
}
323
324
/*
325
 * Set a file input.
326
 */
327
328
YAML_DECLARE(void)
329
yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
330
0
{
331
0
    assert(parser); /* Non-NULL parser object expected. */
332
0
    assert(!parser->read_handler);  /* You can set the source only once. */
333
0
    assert(file);   /* Non-NULL file object expected. */
334
335
0
    parser->read_handler = yaml_file_read_handler;
336
0
    parser->read_handler_data = parser;
337
338
0
    parser->input.file = file;
339
0
}
340
341
/*
342
 * Set a generic input.
343
 */
344
345
YAML_DECLARE(void)
346
yaml_parser_set_input(yaml_parser_t *parser,
347
        yaml_read_handler_t *handler, void *data)
348
0
{
349
0
    assert(parser); /* Non-NULL parser object expected. */
350
0
    assert(!parser->read_handler);  /* You can set the source only once. */
351
0
    assert(handler);    /* Non-NULL read handler expected. */
352
353
0
    parser->read_handler = handler;
354
0
    parser->read_handler_data = data;
355
0
}
356
357
/*
358
 * Set the source encoding.
359
 */
360
361
YAML_DECLARE(void)
362
yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
363
0
{
364
0
    assert(parser); /* Non-NULL parser object expected. */
365
0
    assert(!parser->encoding); /* Encoding is already set or detected. */
366
367
0
    parser->encoding = encoding;
368
0
}
369
370
/*
371
 * Create a new emitter object.
372
 */
373
374
YAML_DECLARE(int)
375
yaml_emitter_initialize(yaml_emitter_t *emitter)
376
0
{
377
0
    assert(emitter);    /* Non-NULL emitter object expected. */
378
379
0
    memset(emitter, 0, sizeof(yaml_emitter_t));
380
0
    if (!BUFFER_INIT(emitter, emitter->buffer, OUTPUT_BUFFER_SIZE))
381
0
        goto error;
382
0
    if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
383
0
        goto error;
384
0
    if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_SIZE))
385
0
        goto error;
386
0
    if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE))
387
0
        goto error;
388
0
    if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_SIZE))
389
0
        goto error;
390
0
    if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_SIZE))
391
0
        goto error;
392
393
0
    return 1;
394
395
0
error:
396
397
0
    BUFFER_DEL(emitter, emitter->buffer);
398
0
    BUFFER_DEL(emitter, emitter->raw_buffer);
399
0
    STACK_DEL(emitter, emitter->states);
400
0
    QUEUE_DEL(emitter, emitter->events);
401
0
    STACK_DEL(emitter, emitter->indents);
402
0
    STACK_DEL(emitter, emitter->tag_directives);
403
404
0
    return 0;
405
0
}
406
407
/*
408
 * Destroy an emitter object.
409
 */
410
411
YAML_DECLARE(void)
412
yaml_emitter_delete(yaml_emitter_t *emitter)
413
0
{
414
0
    assert(emitter);    /* Non-NULL emitter object expected. */
415
416
0
    BUFFER_DEL(emitter, emitter->buffer);
417
0
    BUFFER_DEL(emitter, emitter->raw_buffer);
418
0
    STACK_DEL(emitter, emitter->states);
419
0
    while (!QUEUE_EMPTY(emitter, emitter->events)) {
420
0
        yaml_event_delete(&DEQUEUE(emitter, emitter->events));
421
0
    }
422
0
    QUEUE_DEL(emitter, emitter->events);
423
0
    STACK_DEL(emitter, emitter->indents);
424
0
    while (!STACK_EMPTY(empty, emitter->tag_directives)) {
425
0
        yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives);
426
0
        yaml_free(tag_directive.handle);
427
0
        yaml_free(tag_directive.prefix);
428
0
    }
429
0
    STACK_DEL(emitter, emitter->tag_directives);
430
0
    yaml_free(emitter->anchors);
431
432
0
    memset(emitter, 0, sizeof(yaml_emitter_t));
433
0
}
434
435
/*
436
 * String write handler.
437
 */
438
439
static int
440
yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
441
0
{
442
0
    yaml_emitter_t *emitter = data;
443
444
0
    if (emitter->output.string.size - *emitter->output.string.size_written
445
0
            < size) {
446
0
        memcpy(emitter->output.string.buffer
447
0
                + *emitter->output.string.size_written,
448
0
                buffer,
449
0
                emitter->output.string.size
450
0
                - *emitter->output.string.size_written);
451
0
        *emitter->output.string.size_written = emitter->output.string.size;
452
0
        return 0;
453
0
    }
454
455
0
    memcpy(emitter->output.string.buffer
456
0
            + *emitter->output.string.size_written, buffer, size);
457
0
    *emitter->output.string.size_written += size;
458
0
    return 1;
459
0
}
460
461
/*
462
 * File write handler.
463
 */
464
465
static int
466
yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
467
0
{
468
0
    yaml_emitter_t *emitter = data;
469
470
0
    return (fwrite(buffer, 1, size, emitter->output.file) == size);
471
0
}
472
/*
473
 * Set a string output.
474
 */
475
476
YAML_DECLARE(void)
477
yaml_emitter_set_output_string(yaml_emitter_t *emitter,
478
        unsigned char *output, size_t size, size_t *size_written)
479
0
{
480
0
    assert(emitter);    /* Non-NULL emitter object expected. */
481
0
    assert(!emitter->write_handler);    /* You can set the output only once. */
482
0
    assert(output);     /* Non-NULL output string expected. */
483
484
0
    emitter->write_handler = yaml_string_write_handler;
485
0
    emitter->write_handler_data = emitter;
486
487
0
    emitter->output.string.buffer = output;
488
0
    emitter->output.string.size = size;
489
0
    emitter->output.string.size_written = size_written;
490
0
    *size_written = 0;
491
0
}
492
493
/*
494
 * Set a file output.
495
 */
496
497
YAML_DECLARE(void)
498
yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file)
499
0
{
500
0
    assert(emitter);    /* Non-NULL emitter object expected. */
501
0
    assert(!emitter->write_handler);    /* You can set the output only once. */
502
0
    assert(file);       /* Non-NULL file object expected. */
503
504
0
    emitter->write_handler = yaml_file_write_handler;
505
0
    emitter->write_handler_data = emitter;
506
507
0
    emitter->output.file = file;
508
0
}
509
510
/*
511
 * Set a generic output handler.
512
 */
513
514
YAML_DECLARE(void)
515
yaml_emitter_set_output(yaml_emitter_t *emitter,
516
        yaml_write_handler_t *handler, void *data)
517
0
{
518
0
    assert(emitter);    /* Non-NULL emitter object expected. */
519
0
    assert(!emitter->write_handler);    /* You can set the output only once. */
520
0
    assert(handler);    /* Non-NULL handler object expected. */
521
522
0
    emitter->write_handler = handler;
523
0
    emitter->write_handler_data = data;
524
0
}
525
526
/*
527
 * Set the output encoding.
528
 */
529
530
YAML_DECLARE(void)
531
yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding)
532
0
{
533
0
    assert(emitter);    /* Non-NULL emitter object expected. */
534
0
    assert(!emitter->encoding);     /* You can set encoding only once. */
535
536
0
    emitter->encoding = encoding;
537
0
}
538
539
/*
540
 * Set the canonical output style.
541
 */
542
543
YAML_DECLARE(void)
544
yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical)
545
0
{
546
0
    assert(emitter);    /* Non-NULL emitter object expected. */
547
548
0
    emitter->canonical = (canonical != 0);
549
0
}
550
551
/*
552
 * Set the indentation increment.
553
 */
554
555
YAML_DECLARE(void)
556
yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent)
557
0
{
558
0
    assert(emitter);    /* Non-NULL emitter object expected. */
559
560
0
    emitter->best_indent = (1 < indent && indent < 10) ? indent : 2;
561
0
}
562
563
/*
564
 * Set the preferred line width.
565
 */
566
567
YAML_DECLARE(void)
568
yaml_emitter_set_width(yaml_emitter_t *emitter, int width)
569
0
{
570
0
    assert(emitter);    /* Non-NULL emitter object expected. */
571
572
0
    emitter->best_width = (width >= 0) ? width : -1;
573
0
}
574
575
/*
576
 * Set if unescaped non-ASCII characters are allowed.
577
 */
578
579
YAML_DECLARE(void)
580
yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode)
581
0
{
582
0
    assert(emitter);    /* Non-NULL emitter object expected. */
583
584
0
    emitter->unicode = (unicode != 0);
585
0
}
586
587
/*
588
 * Set the preferred line break character.
589
 */
590
591
YAML_DECLARE(void)
592
yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break)
593
0
{
594
0
    assert(emitter);    /* Non-NULL emitter object expected. */
595
596
0
    emitter->line_break = line_break;
597
0
}
598
599
/*
600
 * Destroy a token object.
601
 */
602
603
YAML_DECLARE(void)
604
yaml_token_delete(yaml_token_t *token)
605
0
{
606
0
    assert(token);  /* Non-NULL token object expected. */
607
608
0
    switch (token->type)
609
0
    {
610
0
        case YAML_TAG_DIRECTIVE_TOKEN:
611
0
            yaml_free(token->data.tag_directive.handle);
612
0
            yaml_free(token->data.tag_directive.prefix);
613
0
            break;
614
615
0
        case YAML_ALIAS_TOKEN:
616
0
            yaml_free(token->data.alias.value);
617
0
            break;
618
619
0
        case YAML_ANCHOR_TOKEN:
620
0
            yaml_free(token->data.anchor.value);
621
0
            break;
622
623
0
        case YAML_TAG_TOKEN:
624
0
            yaml_free(token->data.tag.handle);
625
0
            yaml_free(token->data.tag.suffix);
626
0
            break;
627
628
0
        case YAML_SCALAR_TOKEN:
629
0
            yaml_free(token->data.scalar.value);
630
0
            break;
631
632
0
        default:
633
0
            break;
634
0
    }
635
636
0
    memset(token, 0, sizeof(yaml_token_t));
637
0
}
638
639
/*
640
 * Check if a string is a valid UTF-8 sequence.
641
 *
642
 * Check 'reader.c' for more details on UTF-8 encoding.
643
 */
644
645
static int
646
yaml_check_utf8(yaml_char_t *start, size_t length)
647
0
{
648
0
    yaml_char_t *end = start+length;
649
0
    yaml_char_t *pointer = start;
650
651
0
    while (pointer < end) {
652
0
        unsigned char octet;
653
0
        unsigned int width;
654
0
        unsigned int value;
655
0
        size_t k;
656
657
0
        octet = pointer[0];
658
0
        width = (octet & 0x80) == 0x00 ? 1 :
659
0
                (octet & 0xE0) == 0xC0 ? 2 :
660
0
                (octet & 0xF0) == 0xE0 ? 3 :
661
0
                (octet & 0xF8) == 0xF0 ? 4 : 0;
662
0
        value = (octet & 0x80) == 0x00 ? octet & 0x7F :
663
0
                (octet & 0xE0) == 0xC0 ? octet & 0x1F :
664
0
                (octet & 0xF0) == 0xE0 ? octet & 0x0F :
665
0
                (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
666
0
        if (!width) return 0;
667
0
        if (pointer+width > end) return 0;
668
0
        for (k = 1; k < width; k ++) {
669
0
            octet = pointer[k];
670
0
            if ((octet & 0xC0) != 0x80) return 0;
671
0
            value = (value << 6) + (octet & 0x3F);
672
0
        }
673
0
        if (!((width == 1) ||
674
0
            (width == 2 && value >= 0x80) ||
675
0
            (width == 3 && value >= 0x800) ||
676
0
            (width == 4 && value >= 0x10000))) return 0;
677
678
0
        pointer += width;
679
0
    }
680
681
0
    return 1;
682
0
}
683
684
/*
685
 * Create STREAM-START.
686
 */
687
688
YAML_DECLARE(int)
689
yaml_stream_start_event_initialize(yaml_event_t *event,
690
        yaml_encoding_t encoding)
691
0
{
692
0
    yaml_mark_t mark = { 0, 0, 0 };
693
694
0
    assert(event);  /* Non-NULL event object is expected. */
695
696
0
    STREAM_START_EVENT_INIT(*event, encoding, mark, mark);
697
698
0
    return 1;
699
0
}
700
701
/*
702
 * Create STREAM-END.
703
 */
704
705
YAML_DECLARE(int)
706
yaml_stream_end_event_initialize(yaml_event_t *event)
707
0
{
708
0
    yaml_mark_t mark = { 0, 0, 0 };
709
710
0
    assert(event);  /* Non-NULL event object is expected. */
711
712
0
    STREAM_END_EVENT_INIT(*event, mark, mark);
713
714
0
    return 1;
715
0
}
716
717
/*
718
 * Create DOCUMENT-START.
719
 */
720
721
YAML_DECLARE(int)
722
yaml_document_start_event_initialize(yaml_event_t *event,
723
        yaml_version_directive_t *version_directive,
724
        yaml_tag_directive_t *tag_directives_start,
725
        yaml_tag_directive_t *tag_directives_end,
726
        int implicit)
727
0
{
728
0
    struct {
729
0
        yaml_error_type_t error;
730
0
    } context;
731
0
    yaml_mark_t mark = { 0, 0, 0 };
732
0
    yaml_version_directive_t *version_directive_copy = NULL;
733
0
    struct {
734
0
        yaml_tag_directive_t *start;
735
0
        yaml_tag_directive_t *end;
736
0
        yaml_tag_directive_t *top;
737
0
    } tag_directives_copy = { NULL, NULL, NULL };
738
0
    yaml_tag_directive_t value = { NULL, NULL };
739
740
0
    assert(event);          /* Non-NULL event object is expected. */
741
0
    assert((tag_directives_start && tag_directives_end) ||
742
0
            (tag_directives_start == tag_directives_end));
743
                            /* Valid tag directives are expected. */
744
745
0
    if (version_directive) {
746
0
        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
747
0
        if (!version_directive_copy) goto error;
748
0
        version_directive_copy->major = version_directive->major;
749
0
        version_directive_copy->minor = version_directive->minor;
750
0
    }
751
752
0
    if (tag_directives_start != tag_directives_end) {
753
0
        yaml_tag_directive_t *tag_directive;
754
0
        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
755
0
            goto error;
756
0
        for (tag_directive = tag_directives_start;
757
0
                tag_directive != tag_directives_end; tag_directive ++) {
758
0
            assert(tag_directive->handle);
759
0
            assert(tag_directive->prefix);
760
0
            if (!yaml_check_utf8(tag_directive->handle,
761
0
                        strlen((char *)tag_directive->handle)))
762
0
                goto error;
763
0
            if (!yaml_check_utf8(tag_directive->prefix,
764
0
                        strlen((char *)tag_directive->prefix)))
765
0
                goto error;
766
0
            value.handle = yaml_strdup(tag_directive->handle);
767
0
            value.prefix = yaml_strdup(tag_directive->prefix);
768
0
            if (!value.handle || !value.prefix) goto error;
769
0
            if (!PUSH(&context, tag_directives_copy, value))
770
0
                goto error;
771
0
            value.handle = NULL;
772
0
            value.prefix = NULL;
773
0
        }
774
0
    }
775
776
0
    DOCUMENT_START_EVENT_INIT(*event, version_directive_copy,
777
0
            tag_directives_copy.start, tag_directives_copy.top,
778
0
            implicit, mark, mark);
779
780
0
    return 1;
781
782
0
error:
783
0
    yaml_free(version_directive_copy);
784
0
    while (!STACK_EMPTY(context, tag_directives_copy)) {
785
0
        yaml_tag_directive_t value = POP(context, tag_directives_copy);
786
0
        yaml_free(value.handle);
787
0
        yaml_free(value.prefix);
788
0
    }
789
0
    STACK_DEL(context, tag_directives_copy);
790
0
    yaml_free(value.handle);
791
0
    yaml_free(value.prefix);
792
793
0
    return 0;
794
0
}
795
796
/*
797
 * Create DOCUMENT-END.
798
 */
799
800
YAML_DECLARE(int)
801
yaml_document_end_event_initialize(yaml_event_t *event, int implicit)
802
0
{
803
0
    yaml_mark_t mark = { 0, 0, 0 };
804
805
0
    assert(event);      /* Non-NULL emitter object is expected. */
806
807
0
    DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark);
808
809
0
    return 1;
810
0
}
811
812
/*
813
 * Create ALIAS.
814
 */
815
816
YAML_DECLARE(int)
817
yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor)
818
0
{
819
0
    yaml_mark_t mark = { 0, 0, 0 };
820
0
    yaml_char_t *anchor_copy = NULL;
821
822
0
    assert(event);      /* Non-NULL event object is expected. */
823
0
    assert(anchor);     /* Non-NULL anchor is expected. */
824
825
0
    if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0;
826
827
0
    anchor_copy = yaml_strdup(anchor);
828
0
    if (!anchor_copy)
829
0
        return 0;
830
831
0
    ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark);
832
833
0
    return 1;
834
0
}
835
836
/*
837
 * Create SCALAR.
838
 */
839
840
YAML_DECLARE(int)
841
yaml_scalar_event_initialize(yaml_event_t *event,
842
        yaml_char_t *anchor, yaml_char_t *tag,
843
        yaml_char_t *value, int length,
844
        int plain_implicit, int quoted_implicit,
845
        yaml_scalar_style_t style)
846
0
{
847
0
    yaml_mark_t mark = { 0, 0, 0 };
848
0
    yaml_char_t *anchor_copy = NULL;
849
0
    yaml_char_t *tag_copy = NULL;
850
0
    yaml_char_t *value_copy = NULL;
851
852
0
    assert(event);      /* Non-NULL event object is expected. */
853
0
    assert(value);      /* Non-NULL anchor is expected. */
854
855
0
    if (anchor) {
856
0
        if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
857
0
        anchor_copy = yaml_strdup(anchor);
858
0
        if (!anchor_copy) goto error;
859
0
    }
860
861
0
    if (tag) {
862
0
        if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
863
0
        tag_copy = yaml_strdup(tag);
864
0
        if (!tag_copy) goto error;
865
0
    }
866
867
0
    if (length < 0) {
868
0
        length = (int)strlen((char *)value);
869
0
    }
870
871
0
    if (!yaml_check_utf8(value, length)) goto error;
872
0
    value_copy = yaml_malloc(length+1);
873
0
    if (!value_copy) goto error;
874
0
    memcpy(value_copy, value, length);
875
0
    value_copy[length] = '\0';
876
877
0
    SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length,
878
0
            plain_implicit, quoted_implicit, style, mark, mark);
879
880
0
    return 1;
881
882
0
error:
883
0
    yaml_free(anchor_copy);
884
0
    yaml_free(tag_copy);
885
0
    yaml_free(value_copy);
886
887
0
    return 0;
888
0
}
889
890
/*
891
 * Create SEQUENCE-START.
892
 */
893
894
YAML_DECLARE(int)
895
yaml_sequence_start_event_initialize(yaml_event_t *event,
896
        yaml_char_t *anchor, yaml_char_t *tag, int implicit,
897
        yaml_sequence_style_t style)
898
0
{
899
0
    yaml_mark_t mark = { 0, 0, 0 };
900
0
    yaml_char_t *anchor_copy = NULL;
901
0
    yaml_char_t *tag_copy = NULL;
902
903
0
    assert(event);      /* Non-NULL event object is expected. */
904
905
0
    if (anchor) {
906
0
        if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
907
0
        anchor_copy = yaml_strdup(anchor);
908
0
        if (!anchor_copy) goto error;
909
0
    }
910
911
0
    if (tag) {
912
0
        if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
913
0
        tag_copy = yaml_strdup(tag);
914
0
        if (!tag_copy) goto error;
915
0
    }
916
917
0
    SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy,
918
0
            implicit, style, mark, mark);
919
920
0
    return 1;
921
922
0
error:
923
0
    yaml_free(anchor_copy);
924
0
    yaml_free(tag_copy);
925
926
0
    return 0;
927
0
}
928
929
/*
930
 * Create SEQUENCE-END.
931
 */
932
933
YAML_DECLARE(int)
934
yaml_sequence_end_event_initialize(yaml_event_t *event)
935
0
{
936
0
    yaml_mark_t mark = { 0, 0, 0 };
937
938
0
    assert(event);      /* Non-NULL event object is expected. */
939
940
0
    SEQUENCE_END_EVENT_INIT(*event, mark, mark);
941
942
0
    return 1;
943
0
}
944
945
/*
946
 * Create MAPPING-START.
947
 */
948
949
YAML_DECLARE(int)
950
yaml_mapping_start_event_initialize(yaml_event_t *event,
951
        yaml_char_t *anchor, yaml_char_t *tag, int implicit,
952
        yaml_mapping_style_t style)
953
0
{
954
0
    yaml_mark_t mark = { 0, 0, 0 };
955
0
    yaml_char_t *anchor_copy = NULL;
956
0
    yaml_char_t *tag_copy = NULL;
957
958
0
    assert(event);      /* Non-NULL event object is expected. */
959
960
0
    if (anchor) {
961
0
        if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
962
0
        anchor_copy = yaml_strdup(anchor);
963
0
        if (!anchor_copy) goto error;
964
0
    }
965
966
0
    if (tag) {
967
0
        if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
968
0
        tag_copy = yaml_strdup(tag);
969
0
        if (!tag_copy) goto error;
970
0
    }
971
972
0
    MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy,
973
0
            implicit, style, mark, mark);
974
975
0
    return 1;
976
977
0
error:
978
0
    yaml_free(anchor_copy);
979
0
    yaml_free(tag_copy);
980
981
0
    return 0;
982
0
}
983
984
/*
985
 * Create MAPPING-END.
986
 */
987
988
YAML_DECLARE(int)
989
yaml_mapping_end_event_initialize(yaml_event_t *event)
990
0
{
991
0
    yaml_mark_t mark = { 0, 0, 0 };
992
993
0
    assert(event);      /* Non-NULL event object is expected. */
994
995
0
    MAPPING_END_EVENT_INIT(*event, mark, mark);
996
997
0
    return 1;
998
0
}
999
1000
/*
1001
 * Destroy an event object.
1002
 */
1003
1004
YAML_DECLARE(void)
1005
yaml_event_delete(yaml_event_t *event)
1006
0
{
1007
0
    yaml_tag_directive_t *tag_directive;
1008
1009
0
    assert(event);  /* Non-NULL event object expected. */
1010
1011
0
    switch (event->type)
1012
0
    {
1013
0
        case YAML_DOCUMENT_START_EVENT:
1014
0
            yaml_free(event->data.document_start.version_directive);
1015
0
            for (tag_directive = event->data.document_start.tag_directives.start;
1016
0
                    tag_directive != event->data.document_start.tag_directives.end;
1017
0
                    tag_directive++) {
1018
0
                yaml_free(tag_directive->handle);
1019
0
                yaml_free(tag_directive->prefix);
1020
0
            }
1021
0
            yaml_free(event->data.document_start.tag_directives.start);
1022
0
            break;
1023
1024
0
        case YAML_ALIAS_EVENT:
1025
0
            yaml_free(event->data.alias.anchor);
1026
0
            break;
1027
1028
0
        case YAML_SCALAR_EVENT:
1029
0
            yaml_free(event->data.scalar.anchor);
1030
0
            yaml_free(event->data.scalar.tag);
1031
0
            yaml_free(event->data.scalar.value);
1032
0
            break;
1033
1034
0
        case YAML_SEQUENCE_START_EVENT:
1035
0
            yaml_free(event->data.sequence_start.anchor);
1036
0
            yaml_free(event->data.sequence_start.tag);
1037
0
            break;
1038
1039
0
        case YAML_MAPPING_START_EVENT:
1040
0
            yaml_free(event->data.mapping_start.anchor);
1041
0
            yaml_free(event->data.mapping_start.tag);
1042
0
            break;
1043
1044
0
        default:
1045
0
            break;
1046
0
    }
1047
1048
0
    memset(event, 0, sizeof(yaml_event_t));
1049
0
}
1050
1051
/*
1052
 * Create a document object.
1053
 */
1054
1055
YAML_DECLARE(int)
1056
yaml_document_initialize(yaml_document_t *document,
1057
        yaml_version_directive_t *version_directive,
1058
        yaml_tag_directive_t *tag_directives_start,
1059
        yaml_tag_directive_t *tag_directives_end,
1060
        int start_implicit, int end_implicit)
1061
0
{
1062
0
    struct {
1063
0
        yaml_error_type_t error;
1064
0
    } context;
1065
0
    struct {
1066
0
        yaml_node_t *start;
1067
0
        yaml_node_t *end;
1068
0
        yaml_node_t *top;
1069
0
    } nodes = { NULL, NULL, NULL };
1070
0
    yaml_version_directive_t *version_directive_copy = NULL;
1071
0
    struct {
1072
0
        yaml_tag_directive_t *start;
1073
0
        yaml_tag_directive_t *end;
1074
0
        yaml_tag_directive_t *top;
1075
0
    } tag_directives_copy = { NULL, NULL, NULL };
1076
0
    yaml_tag_directive_t value = { NULL, NULL };
1077
0
    yaml_mark_t mark = { 0, 0, 0 };
1078
1079
0
    assert(document);       /* Non-NULL document object is expected. */
1080
0
    assert((tag_directives_start && tag_directives_end) ||
1081
0
            (tag_directives_start == tag_directives_end));
1082
                            /* Valid tag directives are expected. */
1083
1084
0
    if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error;
1085
1086
0
    if (version_directive) {
1087
0
        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
1088
0
        if (!version_directive_copy) goto error;
1089
0
        version_directive_copy->major = version_directive->major;
1090
0
        version_directive_copy->minor = version_directive->minor;
1091
0
    }
1092
1093
0
    if (tag_directives_start != tag_directives_end) {
1094
0
        yaml_tag_directive_t *tag_directive;
1095
0
        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
1096
0
            goto error;
1097
0
        for (tag_directive = tag_directives_start;
1098
0
                tag_directive != tag_directives_end; tag_directive ++) {
1099
0
            assert(tag_directive->handle);
1100
0
            assert(tag_directive->prefix);
1101
0
            if (!yaml_check_utf8(tag_directive->handle,
1102
0
                        strlen((char *)tag_directive->handle)))
1103
0
                goto error;
1104
0
            if (!yaml_check_utf8(tag_directive->prefix,
1105
0
                        strlen((char *)tag_directive->prefix)))
1106
0
                goto error;
1107
0
            value.handle = yaml_strdup(tag_directive->handle);
1108
0
            value.prefix = yaml_strdup(tag_directive->prefix);
1109
0
            if (!value.handle || !value.prefix) goto error;
1110
0
            if (!PUSH(&context, tag_directives_copy, value))
1111
0
                goto error;
1112
0
            value.handle = NULL;
1113
0
            value.prefix = NULL;
1114
0
        }
1115
0
    }
1116
1117
0
    DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
1118
0
            tag_directives_copy.start, tag_directives_copy.top,
1119
0
            start_implicit, end_implicit, mark, mark);
1120
1121
0
    return 1;
1122
1123
0
error:
1124
0
    STACK_DEL(&context, nodes);
1125
0
    yaml_free(version_directive_copy);
1126
0
    while (!STACK_EMPTY(&context, tag_directives_copy)) {
1127
0
        yaml_tag_directive_t value = POP(&context, tag_directives_copy);
1128
0
        yaml_free(value.handle);
1129
0
        yaml_free(value.prefix);
1130
0
    }
1131
0
    STACK_DEL(&context, tag_directives_copy);
1132
0
    yaml_free(value.handle);
1133
0
    yaml_free(value.prefix);
1134
1135
0
    return 0;
1136
0
}
1137
1138
/*
1139
 * Destroy a document object.
1140
 */
1141
1142
YAML_DECLARE(void)
1143
yaml_document_delete(yaml_document_t *document)
1144
0
{
1145
0
    struct {
1146
0
        yaml_error_type_t error;
1147
0
    } context;
1148
0
    yaml_tag_directive_t *tag_directive;
1149
1150
0
    context.error = YAML_NO_ERROR;  /* Eliminate a compliler warning. */
1151
1152
0
    assert(document);   /* Non-NULL document object is expected. */
1153
1154
0
    while (!STACK_EMPTY(&context, document->nodes)) {
1155
0
        yaml_node_t node = POP(&context, document->nodes);
1156
0
        yaml_free(node.tag);
1157
0
        switch (node.type) {
1158
0
            case YAML_SCALAR_NODE:
1159
0
                yaml_free(node.data.scalar.value);
1160
0
                break;
1161
0
            case YAML_SEQUENCE_NODE:
1162
0
                STACK_DEL(&context, node.data.sequence.items);
1163
0
                break;
1164
0
            case YAML_MAPPING_NODE:
1165
0
                STACK_DEL(&context, node.data.mapping.pairs);
1166
0
                break;
1167
0
            default:
1168
0
                assert(0);  /* Should not happen. */
1169
0
        }
1170
0
    }
1171
0
    STACK_DEL(&context, document->nodes);
1172
1173
0
    yaml_free(document->version_directive);
1174
0
    for (tag_directive = document->tag_directives.start;
1175
0
            tag_directive != document->tag_directives.end;
1176
0
            tag_directive++) {
1177
0
        yaml_free(tag_directive->handle);
1178
0
        yaml_free(tag_directive->prefix);
1179
0
    }
1180
0
    yaml_free(document->tag_directives.start);
1181
1182
0
    memset(document, 0, sizeof(yaml_document_t));
1183
0
}
1184
1185
/**
1186
 * Get a document node.
1187
 */
1188
1189
YAML_DECLARE(yaml_node_t *)
1190
yaml_document_get_node(yaml_document_t *document, int index)
1191
0
{
1192
0
    assert(document);   /* Non-NULL document object is expected. */
1193
1194
0
    if (index > 0 && document->nodes.start + index <= document->nodes.top) {
1195
0
        return document->nodes.start + index - 1;
1196
0
    }
1197
0
    return NULL;
1198
0
}
1199
1200
/**
1201
 * Get the root object.
1202
 */
1203
1204
YAML_DECLARE(yaml_node_t *)
1205
yaml_document_get_root_node(yaml_document_t *document)
1206
0
{
1207
0
    assert(document);   /* Non-NULL document object is expected. */
1208
1209
0
    if (document->nodes.top != document->nodes.start) {
1210
0
        return document->nodes.start;
1211
0
    }
1212
0
    return NULL;
1213
0
}
1214
1215
/*
1216
 * Add a scalar node to a document.
1217
 */
1218
1219
YAML_DECLARE(int)
1220
yaml_document_add_scalar(yaml_document_t *document,
1221
        yaml_char_t *tag, yaml_char_t *value, int length,
1222
        yaml_scalar_style_t style)
1223
0
{
1224
0
    struct {
1225
0
        yaml_error_type_t error;
1226
0
    } context;
1227
0
    yaml_mark_t mark = { 0, 0, 0 };
1228
0
    yaml_char_t *tag_copy = NULL;
1229
0
    yaml_char_t *value_copy = NULL;
1230
0
    yaml_node_t node;
1231
1232
0
    assert(document);   /* Non-NULL document object is expected. */
1233
0
    assert(value);      /* Non-NULL value is expected. */
1234
1235
0
    if (!tag) {
1236
0
        tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG;
1237
0
    }
1238
1239
0
    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
1240
0
    tag_copy = yaml_strdup(tag);
1241
0
    if (!tag_copy) goto error;
1242
1243
0
    if (length < 0) {
1244
0
        length = (int)strlen((char *)value);
1245
0
    }
1246
1247
0
    if (!yaml_check_utf8(value, length)) goto error;
1248
0
    value_copy = yaml_malloc(length+1);
1249
0
    if (!value_copy) goto error;
1250
0
    memcpy(value_copy, value, length);
1251
0
    value_copy[length] = '\0';
1252
1253
0
    SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark);
1254
0
    if (!PUSH(&context, document->nodes, node)) goto error;
1255
1256
0
    return (int)(document->nodes.top - document->nodes.start);
1257
1258
0
error:
1259
0
    yaml_free(tag_copy);
1260
0
    yaml_free(value_copy);
1261
1262
0
    return 0;
1263
0
}
1264
1265
/*
1266
 * Add a sequence node to a document.
1267
 */
1268
1269
YAML_DECLARE(int)
1270
yaml_document_add_sequence(yaml_document_t *document,
1271
        yaml_char_t *tag, yaml_sequence_style_t style)
1272
0
{
1273
0
    struct {
1274
0
        yaml_error_type_t error;
1275
0
    } context;
1276
0
    yaml_mark_t mark = { 0, 0, 0 };
1277
0
    yaml_char_t *tag_copy = NULL;
1278
0
    struct {
1279
0
        yaml_node_item_t *start;
1280
0
        yaml_node_item_t *end;
1281
0
        yaml_node_item_t *top;
1282
0
    } items = { NULL, NULL, NULL };
1283
0
    yaml_node_t node;
1284
1285
0
    assert(document);   /* Non-NULL document object is expected. */
1286
1287
0
    if (!tag) {
1288
0
        tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG;
1289
0
    }
1290
1291
0
    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
1292
0
    tag_copy = yaml_strdup(tag);
1293
0
    if (!tag_copy) goto error;
1294
1295
0
    if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error;
1296
1297
0
    SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
1298
0
            style, mark, mark);
1299
0
    if (!PUSH(&context, document->nodes, node)) goto error;
1300
1301
0
    return (int)(document->nodes.top - document->nodes.start);
1302
1303
0
error:
1304
0
    STACK_DEL(&context, items);
1305
0
    yaml_free(tag_copy);
1306
1307
0
    return 0;
1308
0
}
1309
1310
/*
1311
 * Add a mapping node to a document.
1312
 */
1313
1314
YAML_DECLARE(int)
1315
yaml_document_add_mapping(yaml_document_t *document,
1316
        yaml_char_t *tag, yaml_mapping_style_t style)
1317
0
{
1318
0
    struct {
1319
0
        yaml_error_type_t error;
1320
0
    } context;
1321
0
    yaml_mark_t mark = { 0, 0, 0 };
1322
0
    yaml_char_t *tag_copy = NULL;
1323
0
    struct {
1324
0
        yaml_node_pair_t *start;
1325
0
        yaml_node_pair_t *end;
1326
0
        yaml_node_pair_t *top;
1327
0
    } pairs = { NULL, NULL, NULL };
1328
0
    yaml_node_t node;
1329
1330
0
    assert(document);   /* Non-NULL document object is expected. */
1331
1332
0
    if (!tag) {
1333
0
        tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG;
1334
0
    }
1335
1336
0
    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
1337
0
    tag_copy = yaml_strdup(tag);
1338
0
    if (!tag_copy) goto error;
1339
1340
0
    if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error;
1341
1342
0
    MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
1343
0
            style, mark, mark);
1344
0
    if (!PUSH(&context, document->nodes, node)) goto error;
1345
1346
0
    return (int)(document->nodes.top - document->nodes.start);
1347
1348
0
error:
1349
0
    STACK_DEL(&context, pairs);
1350
0
    yaml_free(tag_copy);
1351
1352
0
    return 0;
1353
0
}
1354
1355
/*
1356
 * Append an item to a sequence node.
1357
 */
1358
1359
YAML_DECLARE(int)
1360
yaml_document_append_sequence_item(yaml_document_t *document,
1361
        int sequence, int item)
1362
0
{
1363
0
    struct {
1364
0
        yaml_error_type_t error;
1365
0
    } context;
1366
1367
0
    assert(document);       /* Non-NULL document is required. */
1368
0
    assert(sequence > 0
1369
0
            && document->nodes.start + sequence <= document->nodes.top);
1370
                            /* Valid sequence id is required. */
1371
0
    assert(document->nodes.start[sequence-1].type == YAML_SEQUENCE_NODE);
1372
                            /* A sequence node is required. */
1373
0
    assert(item > 0 && document->nodes.start + item <= document->nodes.top);
1374
                            /* Valid item id is required. */
1375
1376
0
    if (!PUSH(&context,
1377
0
                document->nodes.start[sequence-1].data.sequence.items, item))
1378
0
        return 0;
1379
1380
0
    return 1;
1381
0
}
1382
1383
/*
1384
 * Append a pair of a key and a value to a mapping node.
1385
 */
1386
1387
YAML_DECLARE(int)
1388
yaml_document_append_mapping_pair(yaml_document_t *document,
1389
        int mapping, int key, int value)
1390
0
{
1391
0
    struct {
1392
0
        yaml_error_type_t error;
1393
0
    } context;
1394
1395
0
    yaml_node_pair_t pair;
1396
1397
0
    assert(document);       /* Non-NULL document is required. */
1398
0
    assert(mapping > 0
1399
0
            && document->nodes.start + mapping <= document->nodes.top);
1400
                            /* Valid mapping id is required. */
1401
0
    assert(document->nodes.start[mapping-1].type == YAML_MAPPING_NODE);
1402
                            /* A mapping node is required. */
1403
0
    assert(key > 0 && document->nodes.start + key <= document->nodes.top);
1404
                            /* Valid key id is required. */
1405
0
    assert(value > 0 && document->nodes.start + value <= document->nodes.top);
1406
                            /* Valid value id is required. */
1407
1408
0
    pair.key = key;
1409
0
    pair.value = value;
1410
1411
0
    if (!PUSH(&context,
1412
0
                document->nodes.start[mapping-1].data.mapping.pairs, pair))
1413
0
        return 0;
1414
1415
0
    return 1;
1416
0
}
1417
1418