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

Revision 212, 43.5 KB checked in by xi, 8 years ago (diff)

Add yaml_emitter_emit_* set of functions.

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