]> andersk Git - libyaml.git/blob - src/parser.c
Complete the Parser (it requires refactoring though) and fix some bugs.
[libyaml.git] / src / parser.c
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
54 YAML_DECLARE(yaml_event_t *)
55 yaml_parser_get_event(yaml_parser_t *parser);
56
57 YAML_DECLARE(yaml_event_t *)
58 yaml_parser_peek_event(yaml_parser_t *parser);
59
60 /*
61  * Error handling.
62  */
63
64 static int
65 yaml_parser_set_parser_error(yaml_parser_t *parser,
66         const char *problem, yaml_mark_t problem_mark);
67
68 static int
69 yaml_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
77 static int
78 yaml_parser_resize_list(yaml_parser_t *parser, void **buffer, size_t *size,
79         size_t item_size);
80
81 static int
82 yaml_parser_append_tag_directive(yaml_parser_t *parser,
83         yaml_tag_directive_t *tag_directive);
84
85 static int
86 yaml_parser_append_state(yaml_parser_t *parser, yaml_parser_state_t state);
87
88 static int
89 yaml_parser_append_mark(yaml_parser_t *parser, yaml_mark_t mark);
90
91 /*
92  * State functions.
93  */
94
95 static yaml_event_t *
96 yaml_parser_state_machine(yaml_parser_t *parser);
97
98 static yaml_event_t *
99 yaml_parser_parse_stream_start(yaml_parser_t *parser);
100
101 static yaml_event_t *
102 yaml_parser_parse_document_start(yaml_parser_t *parser, int implicit);
103
104 static yaml_event_t *
105 yaml_parser_parse_document_content(yaml_parser_t *parser);
106
107 static yaml_event_t *
108 yaml_parser_parse_document_end(yaml_parser_t *parser);
109
110 static yaml_event_t *
111 yaml_parser_parse_node(yaml_parser_t *parser,
112         int block, int indentless_sequence);
113
114 static yaml_event_t *
115 yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, int first);
116
117 static yaml_event_t *
118 yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser);
119
120 static yaml_event_t *
121 yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, int first);
122
123 static yaml_event_t *
124 yaml_parser_parse_block_mapping_value(yaml_parser_t *parser);
125
126 static yaml_event_t *
127 yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, int first);
128
129 static yaml_event_t *
130 yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser);
131
132 static yaml_event_t *
133 yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser);
134
135 static yaml_event_t *
136 yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser);
137
138 static yaml_event_t *
139 yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, int first);
140
141 static yaml_event_t *
142 yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, int empty);
143
144 /*
145  * Utility functions.
146  */
147
148 static yaml_event_t *
149 yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_mark_t mark);
150
151 static int
152 yaml_parser_process_directives(yaml_parser_t *parser);
153
154 /*
155  * Get the next event and advance the parser.
156  */
157
158 YAML_DECLARE(yaml_event_t *)
159 yaml_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
180 YAML_DECLARE(yaml_event_t *)
181 yaml_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 /*
197  * Set parser error.
198  */
199
200 static int
201 yaml_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
211 static int
212 yaml_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 /*
226  * Double a list.
227  */
228
229 static int
230 yaml_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
252 static int
253 yaml_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 /*
268  * Push a state to the state stack.
269  */
270
271 static int
272 yaml_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
288 static int
289 yaml_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 /*
302  * State dispatcher.
303  */
304
305 static yaml_event_t *
306 yaml_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
384 /*
385  * Parse the production:
386  * stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
387  *              ************
388  */
389
390 static yaml_event_t *
391 yaml_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
422 static yaml_event_t *
423 yaml_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);
445         if (!event) {
446             parser->error = YAML_MEMORY_ERROR;
447             return NULL;
448         }
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);
475         if (!event) {
476             parser->error = YAML_MEMORY_ERROR;
477             return NULL;
478         }
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);
490         if (!event) {
491             parser->error = YAML_MEMORY_ERROR;
492             return NULL;
493         }
494         return event;
495     }
496 }
497
498 /*
499  * Parse the productions:
500  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
501  *                                                    ***********
502  */
503
504 static yaml_event_t *
505 yaml_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
533 static yaml_event_t *
534 yaml_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
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
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     }
572     parser->state = YAML_PARSE_DOCUMENT_START_STATE;
573
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
606 static yaml_event_t *
607 yaml_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     {
624         parser->state = parser->states[--parser->states_length];
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                         }
701                         memcpy(tag, (*tag_directive)->prefix, prefix_len);
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                 }
710                 if (!*tag_directive) {
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;
726             return event;
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)
735                         || (tag && strcmp((char *)tag, "!") == 0)) {
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';
800                 parser->state = parser->states[--parser->states_length];
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
821 error:
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
836 static yaml_event_t *
837 yaml_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];
876         parser->marks_length --;
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
902 static yaml_event_t *
903 yaml_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
953 static yaml_event_t *
954 yaml_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];
994         parser->marks_length --;
995         event = yaml_mapping_end_event_new(token->start_mark, token->end_mark);
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
1026 static yaml_event_t *
1027 yaml_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
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
1076 static yaml_event_t *
1077 yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, int first)
1078 {
1079     yaml_token_t *token;
1080     yaml_event_t *event;
1081
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
1142 static yaml_event_t *
1143 yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser)
1144 {
1145     yaml_token_t *token;
1146     yaml_event_t *event;
1147
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
1172 static yaml_event_t *
1173 yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser)
1174 {
1175     yaml_token_t *token;
1176
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
1202 static yaml_event_t *
1203 yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser)
1204 {
1205     yaml_token_t *token;
1206
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
1229 static yaml_event_t *
1230 yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, int first)
1231 {
1232     yaml_token_t *token;
1233     yaml_event_t *event;
1234
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
1302 static yaml_event_t *
1303 yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, int empty)
1304 {
1305     yaml_token_t *token;
1306     yaml_event_t *event;
1307
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
1337 static yaml_event_t *
1338 yaml_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
1365 static int
1366 yaml_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
This page took 0.149087 seconds and 5 git commands to generate.