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