source: libyaml/trunk/src/parser.c @ 250

Revision 250, 44.1 KB checked in by xi, 7 years ago (diff)

Fixed a problem when the DOCUMENT-END event is not emitted until the beginning of the next document is available. Fixed #51. Thanks edward(at)sweetbytes.net for the bug report.

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