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

Revision 203, 47.2 KB checked in by xi, 8 years ago (diff)

Complete the Parser (it requires refactoring though) and fix some bugs.

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