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

Revision 243, 44.0 KB checked in by xi, 8 years ago (diff)

Eliminate some warnings and add more doxygen definitions.

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
355    /* Parse an implicit document. */
356
357    if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
358            token->type != YAML_TAG_DIRECTIVE_TOKEN &&
359            token->type != YAML_DOCUMENT_START_TOKEN &&
360            token->type != YAML_STREAM_END_TOKEN)
361    {
[208]362        if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
363            return 0;
364        if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
365            return 0;
[202]366        parser->state = YAML_PARSE_BLOCK_NODE_STATE;
[208]367        DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
[202]368                token->start_mark, token->start_mark);
[208]369        return 1;
[202]370    }
371
372    /* Parse an explicit document. */
373
374    else if (token->type != YAML_STREAM_END_TOKEN)
375    {
376        yaml_mark_t start_mark, end_mark;
377        start_mark = token->start_mark;
[208]378        if (!yaml_parser_process_directives(parser, &version_directive,
379                    &tag_directives.start, &tag_directives.end))
380            return 0;
381        token = PEEK_TOKEN(parser);
382        if (!token) goto error;
[202]383        if (token->type != YAML_DOCUMENT_START_TOKEN) {
384            yaml_parser_set_parser_error(parser,
385                    "did not found expected <document start>", token->start_mark);
[208]386            goto error;
[202]387        }
[208]388        if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
389            goto error;
[202]390        parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
[208]391        end_mark = token->end_mark;
392        DOCUMENT_START_EVENT_INIT(*event, version_directive,
393                tag_directives.start, tag_directives.end, 0,
[202]394                start_mark, end_mark);
[208]395        SKIP_TOKEN(parser);
396        version_directive = NULL;
397        tag_directives.start = tag_directives.end = NULL;
398        return 1;
[202]399    }
400
401    /* Parse the stream end. */
402
403    else
404    {
405        parser->state = YAML_PARSE_END_STATE;
[208]406        STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
407        SKIP_TOKEN(parser);
408        return 1;
[202]409    }
[208]410
411error:
412    yaml_free(version_directive);
413    while (tag_directives.start != tag_directives.end) {
414        yaml_free(tag_directives.end[-1].handle);
415        yaml_free(tag_directives.end[-1].prefix);
416        tag_directives.end --;
417    }
418    yaml_free(tag_directives.start);
419    return 0;
[202]420}
421
422/*
423 * Parse the productions:
424 * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
425 *                                                    ***********
426 */
427
[208]428static int
429yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
[202]430{
431    yaml_token_t *token;
432
[208]433    token = PEEK_TOKEN(parser);
434    if (!token) return 0;
[202]435
436    if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
437            token->type == YAML_TAG_DIRECTIVE_TOKEN ||
438            token->type == YAML_DOCUMENT_START_TOKEN ||
439            token->type == YAML_DOCUMENT_END_TOKEN ||
440            token->type == YAML_STREAM_END_TOKEN) {
[208]441        parser->state = POP(parser, parser->states);
442        return yaml_parser_process_empty_scalar(parser, event,
443                token->start_mark);
[202]444    }
445    else {
[208]446        return yaml_parser_parse_node(parser, event, 1, 0);
[202]447    }
448}
449
450/*
451 * Parse the productions:
452 * implicit_document    ::= block_node DOCUMENT-END*
453 *                                     *************
454 * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
455 *                                                                *************
456 */
457
[208]458static int
459yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
[202]460{
461    yaml_token_t *token;
462    yaml_mark_t start_mark, end_mark;
463    int implicit = 1;
464
[208]465    token = PEEK_TOKEN(parser);
466    if (!token) return 0;
[202]467
468    start_mark = end_mark = token->start_mark;
469
470    while (token->type == YAML_DOCUMENT_END_TOKEN) {
471        end_mark = token->end_mark;
[208]472        SKIP_TOKEN(parser);
473        token = PEEK_TOKEN(parser);
474        if (!token) return 0;
[202]475        implicit = 0;
476    }
477
[208]478    while (!STACK_EMPTY(parser, parser->tag_directives)) {
479        yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
480        yaml_free(tag_directive.handle);
481        yaml_free(tag_directive.prefix);
[203]482    }
483
484    parser->state = YAML_PARSE_DOCUMENT_START_STATE;
[208]485    DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
[203]486
[208]487    return 1;
[202]488}
489
490/*
491 * Parse the productions:
492 * block_node_or_indentless_sequence    ::=
493 *                          ALIAS
494 *                          *****
495 *                          | properties (block_content | indentless_block_sequence)?
496 *                            **********  *
497 *                          | block_content | indentless_block_sequence
498 *                            *
499 * block_node           ::= ALIAS
500 *                          *****
501 *                          | properties block_content?
502 *                            ********** *
503 *                          | block_content
504 *                            *
505 * flow_node            ::= ALIAS
506 *                          *****
507 *                          | properties flow_content?
508 *                            ********** *
509 *                          | flow_content
510 *                            *
511 * properties           ::= TAG ANCHOR? | ANCHOR TAG?
512 *                          *************************
513 * block_content        ::= block_collection | flow_collection | SCALAR
514 *                                                               ******
515 * flow_content         ::= flow_collection | SCALAR
516 *                                            ******
517 */
518
[208]519static int
520yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
[202]521        int block, int indentless_sequence)
522{
523    yaml_token_t *token;
524    yaml_char_t *anchor = NULL;
525    yaml_char_t *tag_handle = NULL;
526    yaml_char_t *tag_suffix = NULL;
527    yaml_char_t *tag = NULL;
528    yaml_mark_t start_mark, end_mark, tag_mark;
529    int implicit;
530
[208]531    token = PEEK_TOKEN(parser);
532    if (!token) return 0;
[202]533
534    if (token->type == YAML_ALIAS_TOKEN)
535    {
[208]536        parser->state = POP(parser, parser->states);
537        ALIAS_EVENT_INIT(*event, token->data.alias.value,
[202]538                token->start_mark, token->end_mark);
[208]539        SKIP_TOKEN(parser);
540        return 1;
[202]541    }
542
543    else
544    {
545        start_mark = end_mark = token->start_mark;
546
547        if (token->type == YAML_ANCHOR_TOKEN)
548        {
549            anchor = token->data.anchor.value;
550            start_mark = token->start_mark;
551            end_mark = token->end_mark;
[208]552            SKIP_TOKEN(parser);
553            token = PEEK_TOKEN(parser);
[202]554            if (!token) goto error;
555            if (token->type == YAML_TAG_TOKEN)
556            {
557                tag_handle = token->data.tag.handle;
558                tag_suffix = token->data.tag.suffix;
559                tag_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            }
565        }
566        else if (token->type == YAML_TAG_TOKEN)
567        {
568            tag_handle = token->data.tag.handle;
569            tag_suffix = token->data.tag.suffix;
570            start_mark = tag_mark = token->start_mark;
571            end_mark = token->end_mark;
[208]572            SKIP_TOKEN(parser);
573            token = PEEK_TOKEN(parser);
[202]574            if (!token) goto error;
575            if (token->type == YAML_ANCHOR_TOKEN)
576            {
577                anchor = token->data.anchor.value;
578                end_mark = token->end_mark;
[208]579                SKIP_TOKEN(parser);
580                token = PEEK_TOKEN(parser);
[202]581                if (!token) goto error;
582            }
583        }
584
585        if (tag_handle) {
586            if (!*tag_handle) {
587                tag = tag_suffix;
588                yaml_free(tag_handle);
589                tag_handle = tag_suffix = NULL;
590            }
591            else {
[208]592                yaml_tag_directive_t *tag_directive;
593                for (tag_directive = parser->tag_directives.start;
594                        tag_directive != parser->tag_directives.top;
595                        tag_directive ++) {
596                    if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
597                        size_t prefix_len = strlen((char *)tag_directive->prefix);
[202]598                        size_t suffix_len = strlen((char *)tag_suffix);
599                        tag = yaml_malloc(prefix_len+suffix_len+1);
600                        if (!tag) {
601                            parser->error = YAML_MEMORY_ERROR;
602                            goto error;
603                        }
[208]604                        memcpy(tag, tag_directive->prefix, prefix_len);
[202]605                        memcpy(tag+prefix_len, tag_suffix, suffix_len);
606                        tag[prefix_len+suffix_len] = '\0';
607                        yaml_free(tag_handle);
608                        yaml_free(tag_suffix);
609                        tag_handle = tag_suffix = NULL;
610                        break;
611                    }
612                }
[208]613                if (!tag) {
[202]614                    yaml_parser_set_parser_error_context(parser,
615                            "while parsing a node", start_mark,
616                            "found undefined tag handle", tag_mark);
617                    goto error;
618                }
619            }
620        }
621
622        implicit = (!tag || !*tag);
623        if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
624            end_mark = token->end_mark;
625            parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
[208]626            SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
[202]627                    YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
[208]628            return 1;
[202]629        }
630        else {
631            if (token->type == YAML_SCALAR_TOKEN) {
632                int plain_implicit = 0;
633                int quoted_implicit = 0;
634                end_mark = token->end_mark;
635                if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
[203]636                        || (tag && strcmp((char *)tag, "!") == 0)) {
[202]637                    plain_implicit = 1;
638                }
639                else if (!tag) {
640                    quoted_implicit = 1;
641                }
[208]642                parser->state = POP(parser, parser->states);
643                SCALAR_EVENT_INIT(*event, anchor, tag,
[202]644                        token->data.scalar.value, token->data.scalar.length,
645                        plain_implicit, quoted_implicit,
646                        token->data.scalar.style, start_mark, end_mark);
[208]647                SKIP_TOKEN(parser);
648                return 1;
[202]649            }
650            else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
651                end_mark = token->end_mark;
652                parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
[208]653                SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
[202]654                        YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
[208]655                return 1;
[202]656            }
657            else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
658                end_mark = token->end_mark;
659                parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
[208]660                MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
[202]661                        YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
[208]662                return 1;
[202]663            }
664            else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
665                end_mark = token->end_mark;
666                parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
[208]667                SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
[202]668                        YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
[208]669                return 1;
[202]670            }
671            else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
672                end_mark = token->end_mark;
673                parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
[208]674                MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
[202]675                        YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
[208]676                return 1;
[202]677            }
678            else if (anchor || tag) {
679                yaml_char_t *value = yaml_malloc(1);
680                if (!value) {
681                    parser->error = YAML_MEMORY_ERROR;
682                    goto error;
683                }
684                value[0] = '\0';
[208]685                parser->state = POP(parser, parser->states);
686                SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
[202]687                        implicit, 0, YAML_PLAIN_SCALAR_STYLE,
688                        start_mark, end_mark);
[208]689                return 1;
[202]690            }
691            else {
692                yaml_parser_set_parser_error_context(parser,
693                        (block ? "while parsing a block node"
694                         : "while parsing a flow node"), start_mark,
695                        "did not found expected node content", token->start_mark);
696                goto error;
697            }
698        }
699    }
700
701error:
702    yaml_free(anchor);
703    yaml_free(tag_handle);
704    yaml_free(tag_suffix);
705    yaml_free(tag);
706
[208]707    return 0;
[202]708}
709
710/*
711 * Parse the productions:
712 * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
713 *                    ********************  *********** *             *********
714 */
715
[208]716static int
717yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
718        yaml_event_t *event, int first)
[202]719{
720    yaml_token_t *token;
721
722    if (first) {
[208]723        token = PEEK_TOKEN(parser);
724        if (!PUSH(parser, parser->marks, token->start_mark))
725            return 0;
726        SKIP_TOKEN(parser);
[202]727    }
728
[208]729    token = PEEK_TOKEN(parser);
730    if (!token) return 0;
[202]731
732    if (token->type == YAML_BLOCK_ENTRY_TOKEN)
733    {
734        yaml_mark_t mark = token->end_mark;
[208]735        SKIP_TOKEN(parser);
736        token = PEEK_TOKEN(parser);
737        if (!token) return 0;
[202]738        if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
739                token->type != YAML_BLOCK_END_TOKEN) {
[208]740            if (!PUSH(parser, parser->states,
[202]741                        YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
[208]742                return 0;
743            return yaml_parser_parse_node(parser, event, 1, 0);
[202]744        }
745        else {
746            parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
[208]747            return yaml_parser_process_empty_scalar(parser, event, mark);
[202]748        }
749    }
750
751    else if (token->type == YAML_BLOCK_END_TOKEN)
752    {
[243]753        yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
[208]754        parser->state = POP(parser, parser->states);
[243]755        dummy_mark = POP(parser, parser->marks);
[208]756        SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
757        SKIP_TOKEN(parser);
758        return 1;
[202]759    }
760
761    else
762    {
[208]763        return yaml_parser_set_parser_error_context(parser,
764                "while parsing a block collection", POP(parser, parser->marks),
[202]765                "did not found expected '-' indicator", token->start_mark);
766    }
767}
768
769/*
770 * Parse the productions:
771 * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
772 *                           *********** *
773 */
774
[208]775static int
776yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
777        yaml_event_t *event)
[202]778{
779    yaml_token_t *token;
780
[208]781    token = PEEK_TOKEN(parser);
782    if (!token) return 0;
[202]783
784    if (token->type == YAML_BLOCK_ENTRY_TOKEN)
785    {
786        yaml_mark_t mark = token->end_mark;
[208]787        SKIP_TOKEN(parser);
788        token = PEEK_TOKEN(parser);
789        if (!token) return 0;
[202]790        if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
[208]791                token->type != YAML_KEY_TOKEN &&
792                token->type != YAML_VALUE_TOKEN &&
[202]793                token->type != YAML_BLOCK_END_TOKEN) {
[208]794            if (!PUSH(parser, parser->states,
[202]795                        YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
[208]796                return 0;
797            return yaml_parser_parse_node(parser, event, 1, 0);
[202]798        }
799        else {
800            parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
[208]801            return yaml_parser_process_empty_scalar(parser, event, mark);
[202]802        }
803    }
804
805    else
806    {
[208]807        parser->state = POP(parser, parser->states);
808        SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
809        return 1;
[202]810    }
811}
812
813/*
814 * Parse the productions:
815 * block_mapping        ::= BLOCK-MAPPING_START
816 *                          *******************
817 *                          ((KEY block_node_or_indentless_sequence?)?
818 *                            *** *
819 *                          (VALUE block_node_or_indentless_sequence?)?)*
820 *
821 *                          BLOCK-END
822 *                          *********
823 */
824
[208]825static int
826yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
827        yaml_event_t *event, int first)
[202]828{
829    yaml_token_t *token;
830
831    if (first) {
[208]832        token = PEEK_TOKEN(parser);
833        if (!PUSH(parser, parser->marks, token->start_mark))
834            return 0;
835        SKIP_TOKEN(parser);
[202]836    }
837
[208]838    token = PEEK_TOKEN(parser);
839    if (!token) return 0;
[202]840
841    if (token->type == YAML_KEY_TOKEN)
842    {
843        yaml_mark_t mark = token->end_mark;
[208]844        SKIP_TOKEN(parser);
845        token = PEEK_TOKEN(parser);
846        if (!token) return 0;
[202]847        if (token->type != YAML_KEY_TOKEN &&
848                token->type != YAML_VALUE_TOKEN &&
849                token->type != YAML_BLOCK_END_TOKEN) {
[208]850            if (!PUSH(parser, parser->states,
[202]851                        YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
[208]852                return 0;
853            return yaml_parser_parse_node(parser, event, 1, 1);
[202]854        }
855        else {
856            parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
[208]857            return yaml_parser_process_empty_scalar(parser, event, mark);
[202]858        }
859    }
860
861    else if (token->type == YAML_BLOCK_END_TOKEN)
862    {
[243]863        yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
[208]864        parser->state = POP(parser, parser->states);
[243]865        dummy_mark = POP(parser, parser->marks);
[208]866        MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
867        SKIP_TOKEN(parser);
868        return 1;
[202]869    }
870
871    else
872    {
[208]873        return yaml_parser_set_parser_error_context(parser,
874                "while parsing a block mapping", POP(parser, parser->marks),
[202]875                "did not found expected key", token->start_mark);
876    }
877}
878
879/*
880 * Parse the productions:
881 * block_mapping        ::= BLOCK-MAPPING_START
882 *
883 *                          ((KEY block_node_or_indentless_sequence?)?
884 *
885 *                          (VALUE block_node_or_indentless_sequence?)?)*
886 *                           ***** *
887 *                          BLOCK-END
888 *
889 */
890
[208]891static int
892yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
893        yaml_event_t *event)
[202]894{
895    yaml_token_t *token;
896
[208]897    token = PEEK_TOKEN(parser);
898    if (!token) return 0;
[202]899
900    if (token->type == YAML_VALUE_TOKEN)
901    {
902        yaml_mark_t mark = token->end_mark;
[208]903        SKIP_TOKEN(parser);
904        token = PEEK_TOKEN(parser);
905        if (!token) return 0;
[202]906        if (token->type != YAML_KEY_TOKEN &&
907                token->type != YAML_VALUE_TOKEN &&
908                token->type != YAML_BLOCK_END_TOKEN) {
[208]909            if (!PUSH(parser, parser->states,
[202]910                        YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
[208]911                return 0;
912            return yaml_parser_parse_node(parser, event, 1, 1);
[202]913        }
914        else {
915            parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
[208]916            return yaml_parser_process_empty_scalar(parser, event, mark);
[202]917        }
918    }
919
920    else
921    {
922        parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
[208]923        return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
[202]924    }
925}
926
[203]927/*
928 * Parse the productions:
929 * flow_sequence        ::= FLOW-SEQUENCE-START
930 *                          *******************
931 *                          (flow_sequence_entry FLOW-ENTRY)*
932 *                           *                   **********
933 *                          flow_sequence_entry?
934 *                          *
935 *                          FLOW-SEQUENCE-END
936 *                          *****************
937 * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
938 *                          *
939 */
940
[208]941static int
942yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
943        yaml_event_t *event, int first)
[203]944{
945    yaml_token_t *token;
[243]946    yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
[202]947
[203]948    if (first) {
[208]949        token = PEEK_TOKEN(parser);
950        if (!PUSH(parser, parser->marks, token->start_mark))
951            return 0;
952        SKIP_TOKEN(parser);
[203]953    }
954
[208]955    token = PEEK_TOKEN(parser);
956    if (!token) return 0;
[203]957
958    if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
959    {
960        if (!first) {
961            if (token->type == YAML_FLOW_ENTRY_TOKEN) {
[208]962                SKIP_TOKEN(parser);
963                token = PEEK_TOKEN(parser);
964                if (!token) return 0;
[203]965            }
966            else {
[208]967                return yaml_parser_set_parser_error_context(parser,
968                        "while parsing a flow sequence", POP(parser, parser->marks),
[203]969                        "did not found expected ',' or ']'", token->start_mark);
970            }
971        }
972
973        if (token->type == YAML_KEY_TOKEN) {
974            parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
[208]975            MAPPING_START_EVENT_INIT(*event, NULL, NULL,
[203]976                    1, YAML_FLOW_MAPPING_STYLE,
977                    token->start_mark, token->end_mark);
[208]978            SKIP_TOKEN(parser);
979            return 1;
[203]980        }
981
982        else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
[208]983            if (!PUSH(parser, parser->states,
[203]984                        YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
[208]985                return 0;
986            return yaml_parser_parse_node(parser, event, 0, 0);
[203]987        }
988    }
989
[208]990    parser->state = POP(parser, parser->states);
[243]991    dummy_mark = POP(parser, parser->marks);
[208]992    SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
993    SKIP_TOKEN(parser);
994    return 1;
[203]995}
996
997/*
998 * Parse the productions:
999 * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1000 *                                      *** *
1001 */
1002
[208]1003static int
1004yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
1005        yaml_event_t *event)
[203]1006{
1007    yaml_token_t *token;
[202]1008
[208]1009    token = PEEK_TOKEN(parser);
1010    if (!token) return 0;
[203]1011
1012    if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
1013            && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
[208]1014        if (!PUSH(parser, parser->states,
[203]1015                    YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
[208]1016            return 0;
1017        return yaml_parser_parse_node(parser, event, 0, 0);
[203]1018    }
1019    else {
[208]1020        yaml_mark_t mark = token->end_mark;
1021        SKIP_TOKEN(parser);
[203]1022        parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
[208]1023        return yaml_parser_process_empty_scalar(parser, event, mark);
[203]1024    }
1025}
1026
1027/*
1028 * Parse the productions:
1029 * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1030 *                                                      ***** *
1031 */
1032
[208]1033static int
1034yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
1035        yaml_event_t *event)
[203]1036{
1037    yaml_token_t *token;
[202]1038
[208]1039    token = PEEK_TOKEN(parser);
1040    if (!token) return 0;
[203]1041
1042    if (token->type == YAML_VALUE_TOKEN) {
[208]1043        SKIP_TOKEN(parser);
1044        token = PEEK_TOKEN(parser);
1045        if (!token) return 0;
[203]1046        if (token->type != YAML_FLOW_ENTRY_TOKEN
1047                && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
[208]1048            if (!PUSH(parser, parser->states,
[203]1049                        YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
[208]1050                return 0;
1051            return yaml_parser_parse_node(parser, event, 0, 0);
[203]1052        }
1053    }
1054    parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
[208]1055    return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
[203]1056}
1057
1058/*
1059 * Parse the productions:
1060 * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1061 *                                                                      *
1062 */
1063
[208]1064static int
1065yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
1066        yaml_event_t *event)
[203]1067{
1068    yaml_token_t *token;
[202]1069
[208]1070    token = PEEK_TOKEN(parser);
1071    if (!token) return 0;
[203]1072
1073    parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
1074
[208]1075    MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
1076    return 1;
[203]1077}
1078
1079/*
1080 * Parse the productions:
1081 * flow_mapping         ::= FLOW-MAPPING-START
1082 *                          ******************
1083 *                          (flow_mapping_entry FLOW-ENTRY)*
1084 *                           *                  **********
1085 *                          flow_mapping_entry?
1086 *                          ******************
1087 *                          FLOW-MAPPING-END
1088 *                          ****************
1089 * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1090 *                          *           *** *
1091 */
1092
[208]1093static int
1094yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
1095        yaml_event_t *event, int first)
[203]1096{
1097    yaml_token_t *token;
[243]1098    yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
[202]1099
[203]1100    if (first) {
[208]1101        token = PEEK_TOKEN(parser);
1102        if (!PUSH(parser, parser->marks, token->start_mark))
1103            return 0;
1104        SKIP_TOKEN(parser);
[203]1105    }
1106
[208]1107    token = PEEK_TOKEN(parser);
1108    if (!token) return 0;
[203]1109
1110    if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1111    {
1112        if (!first) {
1113            if (token->type == YAML_FLOW_ENTRY_TOKEN) {
[208]1114                SKIP_TOKEN(parser);
1115                token = PEEK_TOKEN(parser);
1116                if (!token) return 0;
[203]1117            }
1118            else {
[208]1119                return yaml_parser_set_parser_error_context(parser,
1120                        "while parsing a flow mapping", POP(parser, parser->marks),
[203]1121                        "did not found expected ',' or '}'", token->start_mark);
1122            }
1123        }
1124
1125        if (token->type == YAML_KEY_TOKEN) {
[208]1126            SKIP_TOKEN(parser);
1127            token = PEEK_TOKEN(parser);
1128            if (!token) return 0;
[203]1129            if (token->type != YAML_VALUE_TOKEN
1130                    && token->type != YAML_FLOW_ENTRY_TOKEN
1131                    && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
[208]1132                if (!PUSH(parser, parser->states,
[203]1133                            YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
[208]1134                    return 0;
1135                return yaml_parser_parse_node(parser, event, 0, 0);
[203]1136            }
1137            else {
1138                parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
[208]1139                return yaml_parser_process_empty_scalar(parser, event,
1140                        token->start_mark);
[203]1141            }
1142        }
1143        else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
[208]1144            if (!PUSH(parser, parser->states,
[203]1145                        YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
[208]1146                return 0;
1147            return yaml_parser_parse_node(parser, event, 0, 0);
[203]1148        }
1149    }
1150
[208]1151    parser->state = POP(parser, parser->states);
[243]1152    dummy_mark = POP(parser, parser->marks);
[208]1153    MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1154    SKIP_TOKEN(parser);
1155    return 1;
[203]1156}
1157
1158/*
1159 * Parse the productions:
1160 * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1161 *                                   *                  ***** *
1162 */
1163
[208]1164static int
1165yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
1166        yaml_event_t *event, int empty)
[203]1167{
1168    yaml_token_t *token;
[202]1169
[208]1170    token = PEEK_TOKEN(parser);
1171    if (!token) return 0;
[203]1172
1173    if (empty) {
1174        parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
[208]1175        return yaml_parser_process_empty_scalar(parser, event,
1176                token->start_mark);
[203]1177    }
1178
1179    if (token->type == YAML_VALUE_TOKEN) {
[208]1180        SKIP_TOKEN(parser);
1181        token = PEEK_TOKEN(parser);
1182        if (!token) return 0;
[203]1183        if (token->type != YAML_FLOW_ENTRY_TOKEN
1184                && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
[208]1185            if (!PUSH(parser, parser->states,
[203]1186                        YAML_PARSE_FLOW_MAPPING_KEY_STATE))
[208]1187                return 0;
1188            return yaml_parser_parse_node(parser, event, 0, 0);
[203]1189        }
1190    }
1191
1192    parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
[208]1193    return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
[203]1194}
1195
1196/*
1197 * Generate an empty scalar event.
1198 */
1199
[208]1200static int
1201yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
1202        yaml_mark_t mark)
[203]1203{
1204    yaml_char_t *value;
1205
1206    value = yaml_malloc(1);
1207    if (!value) {
1208        parser->error = YAML_MEMORY_ERROR;
[208]1209        return 0;
[203]1210    }
1211    value[0] = '\0';
1212
[208]1213    SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
[203]1214            1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
1215
[208]1216    return 1;
[203]1217}
1218
1219/*
1220 * Parse directives.
1221 */
1222
1223static int
[208]1224yaml_parser_process_directives(yaml_parser_t *parser,
1225        yaml_version_directive_t **version_directive_ref,
1226        yaml_tag_directive_t **tag_directives_start_ref,
1227        yaml_tag_directive_t **tag_directives_end_ref)
[203]1228{
1229    yaml_tag_directive_t default_tag_directives[] = {
1230        {(yaml_char_t *)"!", (yaml_char_t *)"!"},
1231        {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
1232        {NULL, NULL}
1233    };
1234    yaml_tag_directive_t *default_tag_directive;
[208]1235    yaml_version_directive_t *version_directive = NULL;
1236    struct {
1237        yaml_tag_directive_t *start;
1238        yaml_tag_directive_t *end;
1239        yaml_tag_directive_t *top;
1240    } tag_directives = { NULL, NULL, NULL };
[203]1241    yaml_token_t *token;
1242
[208]1243    if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
1244        goto error;
[203]1245
[208]1246    token = PEEK_TOKEN(parser);
1247    if (!token) goto error;
1248
[203]1249    while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
1250            token->type == YAML_TAG_DIRECTIVE_TOKEN)
1251    {
1252        if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
[208]1253            if (version_directive) {
1254                yaml_parser_set_parser_error(parser,
[203]1255                        "found duplicate %YAML directive", token->start_mark);
[208]1256                goto error;
[203]1257            }
1258            if (token->data.version_directive.major != 1
[216]1259                    || token->data.version_directive.minor != 1) {
[208]1260                yaml_parser_set_parser_error(parser,
[203]1261                        "found incompatible YAML document", token->start_mark);
[208]1262                goto error;
[203]1263            }
[208]1264            version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
1265            if (!version_directive) {
[203]1266                parser->error = YAML_MEMORY_ERROR;
[208]1267                goto error;
[203]1268            }
[208]1269            version_directive->major = token->data.version_directive.major;
1270            version_directive->minor = token->data.version_directive.minor;
[203]1271        }
1272
1273        else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1274            yaml_tag_directive_t value = {
1275                token->data.tag_directive.handle,
1276                token->data.tag_directive.prefix
1277            };
[208]1278            if (!yaml_parser_append_tag_directive(parser, value, 0,
1279                        token->start_mark))
1280                goto error;
1281            if (!PUSH(parser, tag_directives, value))
1282                goto error;
[203]1283        }
1284
[208]1285        SKIP_TOKEN(parser);
1286        token = PEEK_TOKEN(parser);
1287        if (!token) goto error;
1288    }
1289   
[203]1290    for (default_tag_directive = default_tag_directives;
1291            default_tag_directive->handle; default_tag_directive++) {
[208]1292        if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
1293                    token->start_mark))
1294            goto error;
1295    }
1296
1297    if (version_directive_ref) {
1298        *version_directive_ref = version_directive;
1299    }
1300    if (tag_directives_start_ref) {
1301        if (STACK_EMPTY(parser, tag_directives)) {
1302            *tag_directives_start_ref = *tag_directives_end_ref = NULL;
[210]1303            STACK_DEL(parser, tag_directives);
[203]1304        }
[208]1305        else {
1306            *tag_directives_start_ref = tag_directives.start;
[210]1307            *tag_directives_end_ref = tag_directives.top;
[203]1308        }
1309    }
[210]1310    else {
1311        STACK_DEL(parser, tag_directives);
1312    }
[208]1313
[203]1314    return 1;
[208]1315
1316error:
1317    yaml_free(version_directive);
1318    while (!STACK_EMPTY(parser, tag_directives)) {
1319        yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
1320        yaml_free(tag_directive.handle);
1321        yaml_free(tag_directive.prefix);
1322    }
1323    STACK_DEL(parser, tag_directives);
1324    return 0;
[203]1325}
1326
[213]1327/*
1328 * Append a tag directive to the directives stack.
1329 */
1330
[208]1331static int
1332yaml_parser_append_tag_directive(yaml_parser_t *parser,
1333        yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
1334{
1335    yaml_tag_directive_t *tag_directive;
1336    yaml_tag_directive_t copy = { NULL, NULL };
1337
1338    for (tag_directive = parser->tag_directives.start;
1339            tag_directive != parser->tag_directives.top; tag_directive ++) {
1340        if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
1341            if (allow_duplicates)
1342                return 1;
1343            return yaml_parser_set_parser_error(parser,
1344                    "found duplicate %TAG directive", mark);
1345        }
1346    }
1347
[212]1348    copy.handle = yaml_strdup(value.handle);
1349    copy.prefix = yaml_strdup(value.prefix);
[208]1350    if (!copy.handle || !copy.prefix) {
1351        parser->error = YAML_MEMORY_ERROR;
1352        goto error;
1353    }
1354
1355    if (!PUSH(parser, parser->tag_directives, copy))
1356        goto error;
1357
1358    return 1;
1359
1360error:
1361    yaml_free(copy.handle);
1362    yaml_free(copy.prefix);
1363    return 0;
1364}
1365
Note: See TracBrowser for help on using the repository browser.