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

Revision 210, 47.5 KB checked in by xi, 8 years ago (diff)

Fix some leaks, segfaults and warnings.

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