Coverage Report

Created: 2025-12-14 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/tools/yaml/parser.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
/*
25
 * The parser implements the following grammar:
26
 *
27
 * stream               ::= STREAM-START implicit_document? explicit_document* STREAM-END
28
 * implicit_document    ::= block_node DOCUMENT-END*
29
 * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
30
 * block_node_or_indentless_sequence    ::=
31
 *                          ALIAS
32
 *                          | properties (block_content | indentless_block_sequence)?
33
 *                          | block_content
34
 *                          | indentless_block_sequence
35
 * block_node           ::= ALIAS
36
 *                          | properties block_content?
37
 *                          | block_content
38
 * flow_node            ::= ALIAS
39
 *                          | properties flow_content?
40
 *                          | flow_content
41
 * properties           ::= TAG ANCHOR? | ANCHOR TAG?
42
 * block_content        ::= block_collection | flow_collection | SCALAR
43
 * flow_content         ::= flow_collection | SCALAR
44
 * block_collection     ::= block_sequence | block_mapping
45
 * flow_collection      ::= flow_sequence | flow_mapping
46
 * block_sequence       ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
47
 * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
48
 * block_mapping        ::= BLOCK-MAPPING_START
49
 *                          ((KEY block_node_or_indentless_sequence?)?
50
 *                          (VALUE block_node_or_indentless_sequence?)?)*
51
 *                          BLOCK-END
52
 * flow_sequence        ::= FLOW-SEQUENCE-START
53
 *                          (flow_sequence_entry FLOW-ENTRY)*
54
 *                          flow_sequence_entry?
55
 *                          FLOW-SEQUENCE-END
56
 * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
57
 * flow_mapping         ::= FLOW-MAPPING-START
58
 *                          (flow_mapping_entry FLOW-ENTRY)*
59
 *                          flow_mapping_entry?
60
 *                          FLOW-MAPPING-END
61
 * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
62
 */
63
64
#include "yaml_private.h"
65
66
/*
67
 * Peek the next token in the token queue.
68
 */
69
70
#define PEEK_TOKEN(parser)                                                      \
71
0
    ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ?       \
72
0
        parser->tokens.head : NULL)
73
74
/*
75
 * Remove the next token from the queue (must be called after PEEK_TOKEN).
76
 */
77
78
#define SKIP_TOKEN(parser)                                                      \
79
0
    (parser->token_available = 0,                                               \
80
0
     parser->tokens_parsed ++,                                                  \
81
0
     parser->stream_end_produced =                                              \
82
0
        (parser->tokens.head->type == YAML_STREAM_END_TOKEN),                   \
83
0
     parser->tokens.head ++)
84
85
/*
86
 * Public API declarations.
87
 */
88
89
YAML_DECLARE(int)
90
yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
91
92
/*
93
 * Error handling.
94
 */
95
96
static int
97
yaml_parser_set_parser_error(yaml_parser_t *parser,
98
        const char *problem, yaml_mark_t problem_mark);
99
100
static int
101
yaml_parser_set_parser_error_context(yaml_parser_t *parser,
102
        const char *context, yaml_mark_t context_mark,
103
        const char *problem, yaml_mark_t problem_mark);
104
105
/*
106
 * State functions.
107
 */
108
109
static int
110
yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
111
112
static int
113
yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
114
115
static int
116
yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
117
        int implicit);
118
119
static int
120
yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
121
122
static int
123
yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
124
125
static int
126
yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
127
        int block, int indentless_sequence);
128
129
static int
130
yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
131
        yaml_event_t *event, int first);
132
133
static int
134
yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
135
        yaml_event_t *event);
136
137
static int
138
yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
139
        yaml_event_t *event, int first);
140
141
static int
142
yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
143
        yaml_event_t *event);
144
145
static int
146
yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
147
        yaml_event_t *event, int first);
148
149
static int
150
yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
151
        yaml_event_t *event);
152
153
static int
154
yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
155
        yaml_event_t *event);
156
157
static int
158
yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
159
        yaml_event_t *event);
160
161
static int
162
yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
163
        yaml_event_t *event, int first);
164
165
static int
166
yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
167
        yaml_event_t *event, int empty);
168
169
/*
170
 * Utility functions.
171
 */
172
173
static int
174
yaml_parser_process_empty_scalar(yaml_parser_t *parser,
175
        yaml_event_t *event, yaml_mark_t mark);
176
177
static int
178
yaml_parser_process_directives(yaml_parser_t *parser,
179
        yaml_version_directive_t **version_directive_ref,
180
        yaml_tag_directive_t **tag_directives_start_ref,
181
        yaml_tag_directive_t **tag_directives_end_ref);
182
183
static int
184
yaml_parser_append_tag_directive(yaml_parser_t *parser,
185
        yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
186
187
/*
188
 * Get the next event.
189
 */
190
191
YAML_DECLARE(int)
192
yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
193
0
{
194
0
    assert(parser);     /* Non-NULL parser object is expected. */
195
0
    assert(event);      /* Non-NULL event object is expected. */
196
197
    /* Erase the event object. */
198
199
0
    memset(event, 0, sizeof(yaml_event_t));
200
201
    /* No events after the end of the stream or error. */
202
203
0
    if (parser->stream_end_produced || parser->error ||
204
0
            parser->state == YAML_PARSE_END_STATE) {
205
0
        return 1;
206
0
    }
207
208
    /* Generate the next event. */
209
210
0
    return yaml_parser_state_machine(parser, event);
211
0
}
212
213
/*
214
 * Set parser error.
215
 */
216
217
static int
218
yaml_parser_set_parser_error(yaml_parser_t *parser,
219
        const char *problem, yaml_mark_t problem_mark)
220
0
{
221
0
    parser->error = YAML_PARSER_ERROR;
222
0
    parser->problem = problem;
223
0
    parser->problem_mark = problem_mark;
224
225
0
    return 0;
226
0
}
227
228
static int
229
yaml_parser_set_parser_error_context(yaml_parser_t *parser,
230
        const char *context, yaml_mark_t context_mark,
231
        const char *problem, yaml_mark_t problem_mark)
232
0
{
233
0
    parser->error = YAML_PARSER_ERROR;
234
0
    parser->context = context;
235
0
    parser->context_mark = context_mark;
236
0
    parser->problem = problem;
237
0
    parser->problem_mark = problem_mark;
238
239
0
    return 0;
240
0
}
241
242
243
/*
244
 * State dispatcher.
245
 */
246
247
static int
248
yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
249
0
{
250
0
    switch (parser->state)
251
0
    {
252
0
        case YAML_PARSE_STREAM_START_STATE:
253
0
            return yaml_parser_parse_stream_start(parser, event);
254
255
0
        case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
256
0
            return yaml_parser_parse_document_start(parser, event, 1);
257
258
0
        case YAML_PARSE_DOCUMENT_START_STATE:
259
0
            return yaml_parser_parse_document_start(parser, event, 0);
260
261
0
        case YAML_PARSE_DOCUMENT_CONTENT_STATE:
262
0
            return yaml_parser_parse_document_content(parser, event);
263
264
0
        case YAML_PARSE_DOCUMENT_END_STATE:
265
0
            return yaml_parser_parse_document_end(parser, event);
266
267
0
        case YAML_PARSE_BLOCK_NODE_STATE:
268
0
            return yaml_parser_parse_node(parser, event, 1, 0);
269
270
0
        case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
271
0
            return yaml_parser_parse_node(parser, event, 1, 1);
272
273
0
        case YAML_PARSE_FLOW_NODE_STATE:
274
0
            return yaml_parser_parse_node(parser, event, 0, 0);
275
276
0
        case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
277
0
            return yaml_parser_parse_block_sequence_entry(parser, event, 1);
278
279
0
        case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
280
0
            return yaml_parser_parse_block_sequence_entry(parser, event, 0);
281
282
0
        case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
283
0
            return yaml_parser_parse_indentless_sequence_entry(parser, event);
284
285
0
        case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
286
0
            return yaml_parser_parse_block_mapping_key(parser, event, 1);
287
288
0
        case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
289
0
            return yaml_parser_parse_block_mapping_key(parser, event, 0);
290
291
0
        case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
292
0
            return yaml_parser_parse_block_mapping_value(parser, event);
293
294
0
        case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
295
0
            return yaml_parser_parse_flow_sequence_entry(parser, event, 1);
296
297
0
        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
298
0
            return yaml_parser_parse_flow_sequence_entry(parser, event, 0);
299
300
0
        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
301
0
            return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event);
302
303
0
        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
304
0
            return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event);
305
306
0
        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
307
0
            return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event);
308
309
0
        case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
310
0
            return yaml_parser_parse_flow_mapping_key(parser, event, 1);
311
312
0
        case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
313
0
            return yaml_parser_parse_flow_mapping_key(parser, event, 0);
314
315
0
        case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
316
0
            return yaml_parser_parse_flow_mapping_value(parser, event, 0);
317
318
0
        case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
319
0
            return yaml_parser_parse_flow_mapping_value(parser, event, 1);
320
321
0
        default:
322
0
            assert(1);      /* Invalid state. */
323
0
    }
324
325
0
    return 0;
326
0
}
327
328
/*
329
 * Parse the production:
330
 * stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
331
 *              ************
332
 */
333
334
static int
335
yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
336
0
{
337
0
    yaml_token_t *token;
338
339
0
    token = PEEK_TOKEN(parser);
340
0
    if (!token) return 0;
341
342
0
    if (token->type != YAML_STREAM_START_TOKEN) {
343
0
        return yaml_parser_set_parser_error(parser,
344
0
                "did not find expected <stream-start>", token->start_mark);
345
0
    }
346
347
0
    parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
348
0
    STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding,
349
0
            token->start_mark, token->start_mark);
350
0
    SKIP_TOKEN(parser);
351
352
0
    return 1;
353
0
}
354
355
/*
356
 * Parse the productions:
357
 * implicit_document    ::= block_node DOCUMENT-END*
358
 *                          *
359
 * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
360
 *                          *************************
361
 */
362
363
static int
364
yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
365
        int implicit)
366
0
{
367
0
    yaml_token_t *token;
368
0
    yaml_version_directive_t *version_directive = NULL;
369
0
    struct {
370
0
        yaml_tag_directive_t *start;
371
0
        yaml_tag_directive_t *end;
372
0
    } tag_directives = { NULL, NULL };
373
374
0
    token = PEEK_TOKEN(parser);
375
0
    if (!token) return 0;
376
377
    /* Parse extra document end indicators. */
378
379
0
    if (!implicit)
380
0
    {
381
0
        while (token->type == YAML_DOCUMENT_END_TOKEN) {
382
0
            SKIP_TOKEN(parser);
383
0
            token = PEEK_TOKEN(parser);
384
0
            if (!token) return 0;
385
0
        }
386
0
    }
387
388
    /* Parse an implicit document. */
389
390
0
    if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
391
0
            token->type != YAML_TAG_DIRECTIVE_TOKEN &&
392
0
            token->type != YAML_DOCUMENT_START_TOKEN &&
393
0
            token->type != YAML_STREAM_END_TOKEN)
394
0
    {
395
0
        if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
396
0
            return 0;
397
0
        if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
398
0
            return 0;
399
0
        parser->state = YAML_PARSE_BLOCK_NODE_STATE;
400
0
        DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
401
0
                token->start_mark, token->start_mark);
402
0
        return 1;
403
0
    }
404
405
    /* Parse an explicit document. */
406
407
0
    else if (token->type != YAML_STREAM_END_TOKEN)
408
0
    {
409
0
        yaml_mark_t start_mark, end_mark;
410
0
        start_mark = token->start_mark;
411
0
        if (!yaml_parser_process_directives(parser, &version_directive,
412
0
                    &tag_directives.start, &tag_directives.end))
413
0
            return 0;
414
0
        token = PEEK_TOKEN(parser);
415
0
        if (!token) goto error;
416
0
        if (token->type != YAML_DOCUMENT_START_TOKEN) {
417
0
            yaml_parser_set_parser_error(parser,
418
0
                    "did not find expected <document start>", token->start_mark);
419
0
            goto error;
420
0
        }
421
0
        if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
422
0
            goto error;
423
0
        parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
424
0
        end_mark = token->end_mark;
425
0
        DOCUMENT_START_EVENT_INIT(*event, version_directive,
426
0
                tag_directives.start, tag_directives.end, 0,
427
0
                start_mark, end_mark);
428
0
        SKIP_TOKEN(parser);
429
0
        version_directive = NULL;
430
0
        tag_directives.start = tag_directives.end = NULL;
431
0
        return 1;
432
0
    }
433
434
    /* Parse the stream end. */
435
436
0
    else
437
0
    {
438
0
        parser->state = YAML_PARSE_END_STATE;
439
0
        STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
440
0
        SKIP_TOKEN(parser);
441
0
        return 1;
442
0
    }
443
444
0
error:
445
0
    yaml_free(version_directive);
446
0
    while (tag_directives.start != tag_directives.end) {
447
0
        yaml_free(tag_directives.end[-1].handle);
448
0
        yaml_free(tag_directives.end[-1].prefix);
449
0
        tag_directives.end --;
450
0
    }
451
0
    yaml_free(tag_directives.start);
452
0
    return 0;
453
0
}
454
455
/*
456
 * Parse the productions:
457
 * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
458
 *                                                    ***********
459
 */
460
461
static int
462
yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
463
0
{
464
0
    yaml_token_t *token;
465
466
0
    token = PEEK_TOKEN(parser);
467
0
    if (!token) return 0;
468
469
0
    if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
470
0
            token->type == YAML_TAG_DIRECTIVE_TOKEN ||
471
0
            token->type == YAML_DOCUMENT_START_TOKEN ||
472
0
            token->type == YAML_DOCUMENT_END_TOKEN ||
473
0
            token->type == YAML_STREAM_END_TOKEN) {
474
0
        parser->state = POP(parser, parser->states);
475
0
        return yaml_parser_process_empty_scalar(parser, event,
476
0
                token->start_mark);
477
0
    }
478
0
    else {
479
0
        return yaml_parser_parse_node(parser, event, 1, 0);
480
0
    }
481
0
}
482
483
/*
484
 * Parse the productions:
485
 * implicit_document    ::= block_node DOCUMENT-END*
486
 *                                     *************
487
 * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
488
 *                                                                *************
489
 */
490
491
static int
492
yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
493
0
{
494
0
    yaml_token_t *token;
495
0
    yaml_mark_t start_mark, end_mark;
496
0
    int implicit = 1;
497
498
0
    token = PEEK_TOKEN(parser);
499
0
    if (!token) return 0;
500
501
0
    start_mark = end_mark = token->start_mark;
502
503
0
    if (token->type == YAML_DOCUMENT_END_TOKEN) {
504
0
        end_mark = token->end_mark;
505
0
        SKIP_TOKEN(parser);
506
0
        implicit = 0;
507
0
    }
508
509
0
    while (!STACK_EMPTY(parser, parser->tag_directives)) {
510
0
        yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
511
0
        yaml_free(tag_directive.handle);
512
0
        yaml_free(tag_directive.prefix);
513
0
    }
514
515
0
    parser->state = YAML_PARSE_DOCUMENT_START_STATE;
516
0
    DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
517
518
0
    return 1;
519
0
}
520
521
/*
522
 * Parse the productions:
523
 * block_node_or_indentless_sequence    ::=
524
 *                          ALIAS
525
 *                          *****
526
 *                          | properties (block_content | indentless_block_sequence)?
527
 *                            **********  *
528
 *                          | block_content | indentless_block_sequence
529
 *                            *
530
 * block_node           ::= ALIAS
531
 *                          *****
532
 *                          | properties block_content?
533
 *                            ********** *
534
 *                          | block_content
535
 *                            *
536
 * flow_node            ::= ALIAS
537
 *                          *****
538
 *                          | properties flow_content?
539
 *                            ********** *
540
 *                          | flow_content
541
 *                            *
542
 * properties           ::= TAG ANCHOR? | ANCHOR TAG?
543
 *                          *************************
544
 * block_content        ::= block_collection | flow_collection | SCALAR
545
 *                                                               ******
546
 * flow_content         ::= flow_collection | SCALAR
547
 *                                            ******
548
 */
549
550
static int
551
yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
552
        int block, int indentless_sequence)
553
0
{
554
0
    yaml_token_t *token;
555
0
    yaml_char_t *anchor = NULL;
556
0
    yaml_char_t *tag_handle = NULL;
557
0
    yaml_char_t *tag_suffix = NULL;
558
0
    yaml_char_t *tag = NULL;
559
0
    yaml_mark_t start_mark, end_mark, tag_mark;
560
0
    int implicit;
561
562
0
    token = PEEK_TOKEN(parser);
563
0
    if (!token) return 0;
564
565
0
    if (token->type == YAML_ALIAS_TOKEN)
566
0
    {
567
0
        parser->state = POP(parser, parser->states);
568
0
        ALIAS_EVENT_INIT(*event, token->data.alias.value,
569
0
                token->start_mark, token->end_mark);
570
0
        SKIP_TOKEN(parser);
571
0
        return 1;
572
0
    }
573
574
0
    else
575
0
    {
576
0
        start_mark = end_mark = token->start_mark;
577
578
0
        if (token->type == YAML_ANCHOR_TOKEN)
579
0
        {
580
0
            anchor = token->data.anchor.value;
581
0
            start_mark = token->start_mark;
582
0
            end_mark = token->end_mark;
583
0
            SKIP_TOKEN(parser);
584
0
            token = PEEK_TOKEN(parser);
585
0
            if (!token) goto error;
586
0
            if (token->type == YAML_TAG_TOKEN)
587
0
            {
588
0
                tag_handle = token->data.tag.handle;
589
0
                tag_suffix = token->data.tag.suffix;
590
0
                tag_mark = token->start_mark;
591
0
                end_mark = token->end_mark;
592
0
                SKIP_TOKEN(parser);
593
0
                token = PEEK_TOKEN(parser);
594
0
                if (!token) goto error;
595
0
            }
596
0
        }
597
0
        else if (token->type == YAML_TAG_TOKEN)
598
0
        {
599
0
            tag_handle = token->data.tag.handle;
600
0
            tag_suffix = token->data.tag.suffix;
601
0
            start_mark = tag_mark = token->start_mark;
602
0
            end_mark = token->end_mark;
603
0
            SKIP_TOKEN(parser);
604
0
            token = PEEK_TOKEN(parser);
605
0
            if (!token) goto error;
606
0
            if (token->type == YAML_ANCHOR_TOKEN)
607
0
            {
608
0
                anchor = token->data.anchor.value;
609
0
                end_mark = token->end_mark;
610
0
                SKIP_TOKEN(parser);
611
0
                token = PEEK_TOKEN(parser);
612
0
                if (!token) goto error;
613
0
            }
614
0
        }
615
616
0
        if (tag_handle) {
617
0
            if (!*tag_handle) {
618
0
                tag = tag_suffix;
619
0
                yaml_free(tag_handle);
620
0
                tag_handle = tag_suffix = NULL;
621
0
            }
622
0
            else {
623
0
                yaml_tag_directive_t *tag_directive;
624
0
                for (tag_directive = parser->tag_directives.start;
625
0
                        tag_directive != parser->tag_directives.top;
626
0
                        tag_directive ++) {
627
0
                    if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
628
0
                        size_t prefix_len = strlen((char *)tag_directive->prefix);
629
0
                        size_t suffix_len = strlen((char *)tag_suffix);
630
0
                        tag = yaml_malloc(prefix_len+suffix_len+1);
631
0
                        if (!tag) {
632
0
                            parser->error = YAML_MEMORY_ERROR;
633
0
                            goto error;
634
0
                        }
635
0
                        memcpy(tag, tag_directive->prefix, prefix_len);
636
0
                        memcpy(tag+prefix_len, tag_suffix, suffix_len);
637
0
                        tag[prefix_len+suffix_len] = '\0';
638
0
                        yaml_free(tag_handle);
639
0
                        yaml_free(tag_suffix);
640
0
                        tag_handle = tag_suffix = NULL;
641
0
                        break;
642
0
                    }
643
0
                }
644
0
                if (!tag) {
645
0
                    yaml_parser_set_parser_error_context(parser,
646
0
                            "while parsing a node", start_mark,
647
0
                            "found undefined tag handle", tag_mark);
648
0
                    goto error;
649
0
                }
650
0
            }
651
0
        }
652
653
0
        implicit = (!tag || !*tag);
654
0
        if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
655
0
            end_mark = token->end_mark;
656
0
            parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
657
0
            SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
658
0
                    YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
659
0
            return 1;
660
0
        }
661
0
        else {
662
0
            if (token->type == YAML_SCALAR_TOKEN) {
663
0
                int plain_implicit = 0;
664
0
                int quoted_implicit = 0;
665
0
                end_mark = token->end_mark;
666
0
                if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
667
0
                        || (tag && strcmp((char *)tag, "!") == 0)) {
668
0
                    plain_implicit = 1;
669
0
                }
670
0
                else if (!tag) {
671
0
                    quoted_implicit = 1;
672
0
                }
673
0
                parser->state = POP(parser, parser->states);
674
0
                SCALAR_EVENT_INIT(*event, anchor, tag,
675
0
                        token->data.scalar.value, token->data.scalar.length,
676
0
                        plain_implicit, quoted_implicit,
677
0
                        token->data.scalar.style, start_mark, end_mark);
678
0
                SKIP_TOKEN(parser);
679
0
                return 1;
680
0
            }
681
0
            else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
682
0
                end_mark = token->end_mark;
683
0
                parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
684
0
                SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
685
0
                        YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
686
0
                return 1;
687
0
            }
688
0
            else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
689
0
                end_mark = token->end_mark;
690
0
                parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
691
0
                MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
692
0
                        YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
693
0
                return 1;
694
0
            }
695
0
            else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
696
0
                end_mark = token->end_mark;
697
0
                parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
698
0
                SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
699
0
                        YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
700
0
                return 1;
701
0
            }
702
0
            else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
703
0
                end_mark = token->end_mark;
704
0
                parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
705
0
                MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
706
0
                        YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
707
0
                return 1;
708
0
            }
709
0
            else if (anchor || tag) {
710
0
                yaml_char_t *value = yaml_malloc(1);
711
0
                if (!value) {
712
0
                    parser->error = YAML_MEMORY_ERROR;
713
0
                    goto error;
714
0
                }
715
0
                value[0] = '\0';
716
0
                parser->state = POP(parser, parser->states);
717
0
                SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
718
0
                        implicit, 0, YAML_PLAIN_SCALAR_STYLE,
719
0
                        start_mark, end_mark);
720
0
                return 1;
721
0
            }
722
0
            else {
723
0
                yaml_parser_set_parser_error_context(parser,
724
0
                        (block ? "while parsing a block node"
725
0
                         : "while parsing a flow node"), start_mark,
726
0
                        "did not find expected node content", token->start_mark);
727
0
                goto error;
728
0
            }
729
0
        }
730
0
    }
731
732
0
error:
733
0
    yaml_free(anchor);
734
0
    yaml_free(tag_handle);
735
0
    yaml_free(tag_suffix);
736
0
    yaml_free(tag);
737
738
0
    return 0;
739
0
}
740
741
/*
742
 * Parse the productions:
743
 * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
744
 *                    ********************  *********** *             *********
745
 */
746
747
static int
748
yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
749
        yaml_event_t *event, int first)
750
0
{
751
0
    yaml_token_t *token;
752
753
0
    if (first) {
754
0
        token = PEEK_TOKEN(parser);
755
0
        if (!PUSH(parser, parser->marks, token->start_mark))
756
0
            return 0;
757
0
        SKIP_TOKEN(parser);
758
0
    }
759
760
0
    token = PEEK_TOKEN(parser);
761
0
    if (!token) return 0;
762
763
0
    if (token->type == YAML_BLOCK_ENTRY_TOKEN)
764
0
    {
765
0
        yaml_mark_t mark = token->end_mark;
766
0
        SKIP_TOKEN(parser);
767
0
        token = PEEK_TOKEN(parser);
768
0
        if (!token) return 0;
769
0
        if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
770
0
                token->type != YAML_BLOCK_END_TOKEN) {
771
0
            if (!PUSH(parser, parser->states,
772
0
                        YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
773
0
                return 0;
774
0
            return yaml_parser_parse_node(parser, event, 1, 0);
775
0
        }
776
0
        else {
777
0
            parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
778
0
            return yaml_parser_process_empty_scalar(parser, event, mark);
779
0
        }
780
0
    }
781
782
0
    else if (token->type == YAML_BLOCK_END_TOKEN)
783
0
    {
784
//      yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
785
0
        parser->state = POP(parser, parser->states);
786
0
        /* dummy_mark = */ (void)POP(parser, parser->marks);
787
0
        SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
788
0
        SKIP_TOKEN(parser);
789
0
        return 1;
790
0
    }
791
792
0
    else
793
0
    {
794
0
        return yaml_parser_set_parser_error_context(parser,
795
0
                "while parsing a block collection", POP(parser, parser->marks),
796
0
                "did not find expected '-' indicator", token->start_mark);
797
0
    }
798
0
}
799
800
/*
801
 * Parse the productions:
802
 * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
803
 *                           *********** *
804
 */
805
806
static int
807
yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
808
        yaml_event_t *event)
809
0
{
810
0
    yaml_token_t *token;
811
812
0
    token = PEEK_TOKEN(parser);
813
0
    if (!token) return 0;
814
815
0
    if (token->type == YAML_BLOCK_ENTRY_TOKEN)
816
0
    {
817
0
        yaml_mark_t mark = token->end_mark;
818
0
        SKIP_TOKEN(parser);
819
0
        token = PEEK_TOKEN(parser);
820
0
        if (!token) return 0;
821
0
        if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
822
0
                token->type != YAML_KEY_TOKEN &&
823
0
                token->type != YAML_VALUE_TOKEN &&
824
0
                token->type != YAML_BLOCK_END_TOKEN) {
825
0
            if (!PUSH(parser, parser->states,
826
0
                        YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
827
0
                return 0;
828
0
            return yaml_parser_parse_node(parser, event, 1, 0);
829
0
        }
830
0
        else {
831
0
            parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
832
0
            return yaml_parser_process_empty_scalar(parser, event, mark);
833
0
        }
834
0
    }
835
836
0
    else
837
0
    {
838
0
        parser->state = POP(parser, parser->states);
839
0
        SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
840
0
        return 1;
841
0
    }
842
0
}
843
844
/*
845
 * Parse the productions:
846
 * block_mapping        ::= BLOCK-MAPPING_START
847
 *                          *******************
848
 *                          ((KEY block_node_or_indentless_sequence?)?
849
 *                            *** *
850
 *                          (VALUE block_node_or_indentless_sequence?)?)*
851
 *
852
 *                          BLOCK-END
853
 *                          *********
854
 */
855
856
static int
857
yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
858
        yaml_event_t *event, int first)
859
0
{
860
0
    yaml_token_t *token;
861
862
0
    if (first) {
863
0
        token = PEEK_TOKEN(parser);
864
0
        if (!PUSH(parser, parser->marks, token->start_mark))
865
0
            return 0;
866
0
        SKIP_TOKEN(parser);
867
0
    }
868
869
0
    token = PEEK_TOKEN(parser);
870
0
    if (!token) return 0;
871
872
0
    if (token->type == YAML_KEY_TOKEN)
873
0
    {
874
0
        yaml_mark_t mark = token->end_mark;
875
0
        SKIP_TOKEN(parser);
876
0
        token = PEEK_TOKEN(parser);
877
0
        if (!token) return 0;
878
0
        if (token->type != YAML_KEY_TOKEN &&
879
0
                token->type != YAML_VALUE_TOKEN &&
880
0
                token->type != YAML_BLOCK_END_TOKEN) {
881
0
            if (!PUSH(parser, parser->states,
882
0
                        YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
883
0
                return 0;
884
0
            return yaml_parser_parse_node(parser, event, 1, 1);
885
0
        }
886
0
        else {
887
0
            parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
888
0
            return yaml_parser_process_empty_scalar(parser, event, mark);
889
0
        }
890
0
    }
891
892
0
    else if (token->type == YAML_BLOCK_END_TOKEN)
893
0
    {
894
//      yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
895
0
        parser->state = POP(parser, parser->states);
896
0
        /* dummy_mark = */ (void)POP(parser, parser->marks);
897
0
        MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
898
0
        SKIP_TOKEN(parser);
899
0
        return 1;
900
0
    }
901
902
0
    else
903
0
    {
904
0
        return yaml_parser_set_parser_error_context(parser,
905
0
                "while parsing a block mapping", POP(parser, parser->marks),
906
0
                "did not find expected key", token->start_mark);
907
0
    }
908
0
}
909
910
/*
911
 * Parse the productions:
912
 * block_mapping        ::= BLOCK-MAPPING_START
913
 *
914
 *                          ((KEY block_node_or_indentless_sequence?)?
915
 *
916
 *                          (VALUE block_node_or_indentless_sequence?)?)*
917
 *                           ***** *
918
 *                          BLOCK-END
919
 *
920
 */
921
922
static int
923
yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
924
        yaml_event_t *event)
925
0
{
926
0
    yaml_token_t *token;
927
928
0
    token = PEEK_TOKEN(parser);
929
0
    if (!token) return 0;
930
931
0
    if (token->type == YAML_VALUE_TOKEN)
932
0
    {
933
0
        yaml_mark_t mark = token->end_mark;
934
0
        SKIP_TOKEN(parser);
935
0
        token = PEEK_TOKEN(parser);
936
0
        if (!token) return 0;
937
0
        if (token->type != YAML_KEY_TOKEN &&
938
0
                token->type != YAML_VALUE_TOKEN &&
939
0
                token->type != YAML_BLOCK_END_TOKEN) {
940
0
            if (!PUSH(parser, parser->states,
941
0
                        YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
942
0
                return 0;
943
0
            return yaml_parser_parse_node(parser, event, 1, 1);
944
0
        }
945
0
        else {
946
0
            parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
947
0
            return yaml_parser_process_empty_scalar(parser, event, mark);
948
0
        }
949
0
    }
950
951
0
    else
952
0
    {
953
0
        parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
954
0
        return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
955
0
    }
956
0
}
957
958
/*
959
 * Parse the productions:
960
 * flow_sequence        ::= FLOW-SEQUENCE-START
961
 *                          *******************
962
 *                          (flow_sequence_entry FLOW-ENTRY)*
963
 *                           *                   **********
964
 *                          flow_sequence_entry?
965
 *                          *
966
 *                          FLOW-SEQUENCE-END
967
 *                          *****************
968
 * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
969
 *                          *
970
 */
971
972
static int
973
yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
974
        yaml_event_t *event, int first)
975
0
{
976
0
    yaml_token_t *token;
977
//  yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
978
979
0
    if (first) {
980
0
        token = PEEK_TOKEN(parser);
981
0
        if (!PUSH(parser, parser->marks, token->start_mark))
982
0
            return 0;
983
0
        SKIP_TOKEN(parser);
984
0
    }
985
986
0
    token = PEEK_TOKEN(parser);
987
0
    if (!token) return 0;
988
989
0
    if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
990
0
    {
991
0
        if (!first) {
992
0
            if (token->type == YAML_FLOW_ENTRY_TOKEN) {
993
0
                SKIP_TOKEN(parser);
994
0
                token = PEEK_TOKEN(parser);
995
0
                if (!token) return 0;
996
0
            }
997
0
            else {
998
0
                return yaml_parser_set_parser_error_context(parser,
999
0
                        "while parsing a flow sequence", POP(parser, parser->marks),
1000
0
                        "did not find expected ',' or ']'", token->start_mark);
1001
0
            }
1002
0
        }
1003
1004
0
        if (token->type == YAML_KEY_TOKEN) {
1005
0
            parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
1006
0
            MAPPING_START_EVENT_INIT(*event, NULL, NULL,
1007
0
                    1, YAML_FLOW_MAPPING_STYLE,
1008
0
                    token->start_mark, token->end_mark);
1009
0
            SKIP_TOKEN(parser);
1010
0
            return 1;
1011
0
        }
1012
1013
0
        else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1014
0
            if (!PUSH(parser, parser->states,
1015
0
                        YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
1016
0
                return 0;
1017
0
            return yaml_parser_parse_node(parser, event, 0, 0);
1018
0
        }
1019
0
    }
1020
1021
0
    parser->state = POP(parser, parser->states);
1022
0
    /* dummy_mark = */ (void)POP(parser, parser->marks);
1023
0
    SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1024
0
    SKIP_TOKEN(parser);
1025
0
    return 1;
1026
0
}
1027
1028
/*
1029
 * Parse the productions:
1030
 * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1031
 *                                      *** *
1032
 */
1033
1034
static int
1035
yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
1036
        yaml_event_t *event)
1037
0
{
1038
0
    yaml_token_t *token;
1039
1040
0
    token = PEEK_TOKEN(parser);
1041
0
    if (!token) return 0;
1042
1043
0
    if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
1044
0
            && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1045
0
        if (!PUSH(parser, parser->states,
1046
0
                    YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
1047
0
            return 0;
1048
0
        return yaml_parser_parse_node(parser, event, 0, 0);
1049
0
    }
1050
0
    else {
1051
0
        yaml_mark_t mark = token->end_mark;
1052
0
        SKIP_TOKEN(parser);
1053
0
        parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
1054
0
        return yaml_parser_process_empty_scalar(parser, event, mark);
1055
0
    }
1056
0
}
1057
1058
/*
1059
 * Parse the productions:
1060
 * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1061
 *                                                      ***** *
1062
 */
1063
1064
static int
1065
yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
1066
        yaml_event_t *event)
1067
0
{
1068
0
    yaml_token_t *token;
1069
1070
0
    token = PEEK_TOKEN(parser);
1071
0
    if (!token) return 0;
1072
1073
0
    if (token->type == YAML_VALUE_TOKEN) {
1074
0
        SKIP_TOKEN(parser);
1075
0
        token = PEEK_TOKEN(parser);
1076
0
        if (!token) return 0;
1077
0
        if (token->type != YAML_FLOW_ENTRY_TOKEN
1078
0
                && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1079
0
            if (!PUSH(parser, parser->states,
1080
0
                        YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
1081
0
                return 0;
1082
0
            return yaml_parser_parse_node(parser, event, 0, 0);
1083
0
        }
1084
0
    }
1085
0
    parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
1086
0
    return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1087
0
}
1088
1089
/*
1090
 * Parse the productions:
1091
 * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1092
 *                                                                      *
1093
 */
1094
1095
static int
1096
yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
1097
        yaml_event_t *event)
1098
0
{
1099
0
    yaml_token_t *token;
1100
1101
0
    token = PEEK_TOKEN(parser);
1102
0
    if (!token) return 0;
1103
1104
0
    parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
1105
1106
0
    MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
1107
0
    return 1;
1108
0
}
1109
1110
/*
1111
 * Parse the productions:
1112
 * flow_mapping         ::= FLOW-MAPPING-START
1113
 *                          ******************
1114
 *                          (flow_mapping_entry FLOW-ENTRY)*
1115
 *                           *                  **********
1116
 *                          flow_mapping_entry?
1117
 *                          ******************
1118
 *                          FLOW-MAPPING-END
1119
 *                          ****************
1120
 * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1121
 *                          *           *** *
1122
 */
1123
1124
static int
1125
yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
1126
        yaml_event_t *event, int first)
1127
0
{
1128
0
    yaml_token_t *token;
1129
//  yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
1130
1131
0
    if (first) {
1132
0
        token = PEEK_TOKEN(parser);
1133
0
        if (!PUSH(parser, parser->marks, token->start_mark))
1134
0
            return 0;
1135
0
        SKIP_TOKEN(parser);
1136
0
    }
1137
1138
0
    token = PEEK_TOKEN(parser);
1139
0
    if (!token) return 0;
1140
1141
0
    if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1142
0
    {
1143
0
        if (!first) {
1144
0
            if (token->type == YAML_FLOW_ENTRY_TOKEN) {
1145
0
                SKIP_TOKEN(parser);
1146
0
                token = PEEK_TOKEN(parser);
1147
0
                if (!token) return 0;
1148
0
            }
1149
0
            else {
1150
0
                return yaml_parser_set_parser_error_context(parser,
1151
0
                        "while parsing a flow mapping", POP(parser, parser->marks),
1152
0
                        "did not find expected ',' or '}'", token->start_mark);
1153
0
            }
1154
0
        }
1155
1156
0
        if (token->type == YAML_KEY_TOKEN) {
1157
0
            SKIP_TOKEN(parser);
1158
0
            token = PEEK_TOKEN(parser);
1159
0
            if (!token) return 0;
1160
0
            if (token->type != YAML_VALUE_TOKEN
1161
0
                    && token->type != YAML_FLOW_ENTRY_TOKEN
1162
0
                    && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1163
0
                if (!PUSH(parser, parser->states,
1164
0
                            YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
1165
0
                    return 0;
1166
0
                return yaml_parser_parse_node(parser, event, 0, 0);
1167
0
            }
1168
0
            else {
1169
0
                parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
1170
0
                return yaml_parser_process_empty_scalar(parser, event,
1171
0
                        token->start_mark);
1172
0
            }
1173
0
        }
1174
0
        else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1175
0
            if (!PUSH(parser, parser->states,
1176
0
                        YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
1177
0
                return 0;
1178
0
            return yaml_parser_parse_node(parser, event, 0, 0);
1179
0
        }
1180
0
    }
1181
1182
0
    parser->state = POP(parser, parser->states);
1183
0
    /*dummy_mark = */ (void)POP(parser, parser->marks);
1184
0
    MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1185
0
    SKIP_TOKEN(parser);
1186
0
    return 1;
1187
0
}
1188
1189
/*
1190
 * Parse the productions:
1191
 * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1192
 *                                   *                  ***** *
1193
 */
1194
1195
static int
1196
yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
1197
        yaml_event_t *event, int empty)
1198
0
{
1199
0
    yaml_token_t *token;
1200
1201
0
    token = PEEK_TOKEN(parser);
1202
0
    if (!token) return 0;
1203
1204
0
    if (empty) {
1205
0
        parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1206
0
        return yaml_parser_process_empty_scalar(parser, event,
1207
0
                token->start_mark);
1208
0
    }
1209
1210
0
    if (token->type == YAML_VALUE_TOKEN) {
1211
0
        SKIP_TOKEN(parser);
1212
0
        token = PEEK_TOKEN(parser);
1213
0
        if (!token) return 0;
1214
0
        if (token->type != YAML_FLOW_ENTRY_TOKEN
1215
0
                && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1216
0
            if (!PUSH(parser, parser->states,
1217
0
                        YAML_PARSE_FLOW_MAPPING_KEY_STATE))
1218
0
                return 0;
1219
0
            return yaml_parser_parse_node(parser, event, 0, 0);
1220
0
        }
1221
0
    }
1222
1223
0
    parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1224
0
    return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1225
0
}
1226
1227
/*
1228
 * Generate an empty scalar event.
1229
 */
1230
1231
static int
1232
yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
1233
        yaml_mark_t mark)
1234
0
{
1235
0
    yaml_char_t *value;
1236
1237
0
    value = yaml_malloc(1);
1238
0
    if (!value) {
1239
0
        parser->error = YAML_MEMORY_ERROR;
1240
0
        return 0;
1241
0
    }
1242
0
    value[0] = '\0';
1243
1244
0
    SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
1245
0
            1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
1246
1247
0
    return 1;
1248
0
}
1249
1250
/*
1251
 * Parse directives.
1252
 */
1253
1254
static int
1255
yaml_parser_process_directives(yaml_parser_t *parser,
1256
        yaml_version_directive_t **version_directive_ref,
1257
        yaml_tag_directive_t **tag_directives_start_ref,
1258
        yaml_tag_directive_t **tag_directives_end_ref)
1259
0
{
1260
0
    yaml_tag_directive_t default_tag_directives[] = {
1261
0
        {(yaml_char_t *)"!", (yaml_char_t *)"!"},
1262
0
        {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
1263
0
        {NULL, NULL}
1264
0
    };
1265
0
    yaml_tag_directive_t *default_tag_directive;
1266
0
    yaml_version_directive_t *version_directive = NULL;
1267
0
    struct {
1268
0
        yaml_tag_directive_t *start;
1269
0
        yaml_tag_directive_t *end;
1270
0
        yaml_tag_directive_t *top;
1271
0
    } tag_directives = { NULL, NULL, NULL };
1272
0
    yaml_token_t *token;
1273
1274
0
    if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
1275
0
        goto error;
1276
1277
0
    token = PEEK_TOKEN(parser);
1278
0
    if (!token) goto error;
1279
1280
0
    while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
1281
0
            token->type == YAML_TAG_DIRECTIVE_TOKEN)
1282
0
    {
1283
0
        if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
1284
0
            if (version_directive) {
1285
0
                yaml_parser_set_parser_error(parser,
1286
0
                        "found duplicate %YAML directive", token->start_mark);
1287
0
                goto error;
1288
0
            }
1289
0
            if (token->data.version_directive.major != 1
1290
0
                    || token->data.version_directive.minor != 1) {
1291
0
                yaml_parser_set_parser_error(parser,
1292
0
                        "found incompatible YAML document", token->start_mark);
1293
0
                goto error;
1294
0
            }
1295
0
            version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
1296
0
            if (!version_directive) {
1297
0
                parser->error = YAML_MEMORY_ERROR;
1298
0
                goto error;
1299
0
            }
1300
0
            version_directive->major = token->data.version_directive.major;
1301
0
            version_directive->minor = token->data.version_directive.minor;
1302
0
        }
1303
1304
0
        else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1305
0
            yaml_tag_directive_t value;
1306
0
            value.handle = token->data.tag_directive.handle;
1307
0
            value.prefix = token->data.tag_directive.prefix;
1308
1309
0
            if (!yaml_parser_append_tag_directive(parser, value, 0,
1310
0
                        token->start_mark))
1311
0
                goto error;
1312
0
            if (!PUSH(parser, tag_directives, value))
1313
0
                goto error;
1314
0
        }
1315
1316
0
        SKIP_TOKEN(parser);
1317
0
        token = PEEK_TOKEN(parser);
1318
0
        if (!token) goto error;
1319
0
    }
1320
    
1321
0
    for (default_tag_directive = default_tag_directives;
1322
0
            default_tag_directive->handle; default_tag_directive++) {
1323
0
        if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
1324
0
                    token->start_mark))
1325
0
            goto error;
1326
0
    }
1327
1328
0
    if (version_directive_ref) {
1329
0
        *version_directive_ref = version_directive;
1330
0
    }
1331
0
    if (tag_directives_start_ref) {
1332
0
        if (STACK_EMPTY(parser, tag_directives)) {
1333
0
            *tag_directives_start_ref = *tag_directives_end_ref = NULL;
1334
0
            STACK_DEL(parser, tag_directives);
1335
0
        }
1336
0
        else {
1337
0
            *tag_directives_start_ref = tag_directives.start;
1338
0
            *tag_directives_end_ref = tag_directives.top;
1339
0
        }
1340
0
    }
1341
0
    else {
1342
0
        STACK_DEL(parser, tag_directives);
1343
0
    }
1344
1345
0
    return 1;
1346
1347
0
error:
1348
0
    yaml_free(version_directive);
1349
0
    while (!STACK_EMPTY(parser, tag_directives)) {
1350
0
        yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
1351
0
        yaml_free(tag_directive.handle);
1352
0
        yaml_free(tag_directive.prefix);
1353
0
    }
1354
0
    STACK_DEL(parser, tag_directives);
1355
0
    return 0;
1356
0
}
1357
1358
/*
1359
 * Append a tag directive to the directives stack.
1360
 */
1361
1362
static int
1363
yaml_parser_append_tag_directive(yaml_parser_t *parser,
1364
        yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
1365
0
{
1366
0
    yaml_tag_directive_t *tag_directive;
1367
0
    yaml_tag_directive_t copy = { NULL, NULL };
1368
1369
0
    for (tag_directive = parser->tag_directives.start;
1370
0
            tag_directive != parser->tag_directives.top; tag_directive ++) {
1371
0
        if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
1372
0
            if (allow_duplicates)
1373
0
                return 1;
1374
0
            return yaml_parser_set_parser_error(parser,
1375
0
                    "found duplicate %TAG directive", mark);
1376
0
        }
1377
0
    }
1378
1379
0
    copy.handle = yaml_strdup(value.handle);
1380
0
    copy.prefix = yaml_strdup(value.prefix);
1381
0
    if (!copy.handle || !copy.prefix) {
1382
0
        parser->error = YAML_MEMORY_ERROR;
1383
0
        goto error;
1384
0
    }
1385
1386
0
    if (!PUSH(parser, parser->tag_directives, copy))
1387
0
        goto error;
1388
1389
0
    return 1;
1390
1391
0
error:
1392
0
    yaml_free(copy.handle);
1393
0
    yaml_free(copy.prefix);
1394
0
    return 0;
1395
0
}
1396