]> andersk Git - libyaml.git/blob - src/parser.c
Add `const` qualifier for `yaml_parser_set_input_string` parameter `input`.
[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         parser->state = POP(parser, parser->states);
754         POP(parser, parser->marks);
755         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
756         SKIP_TOKEN(parser);
757         return 1;
758     }
759
760     else
761     {
762         return yaml_parser_set_parser_error_context(parser,
763                 "while parsing a block collection", POP(parser, parser->marks),
764                 "did not found expected '-' indicator", token->start_mark);
765     }
766 }
767
768 /*
769  * Parse the productions:
770  * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
771  *                           *********** *
772  */
773
774 static int
775 yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
776         yaml_event_t *event)
777 {
778     yaml_token_t *token;
779
780     token = PEEK_TOKEN(parser);
781     if (!token) return 0;
782
783     if (token->type == YAML_BLOCK_ENTRY_TOKEN)
784     {
785         yaml_mark_t mark = token->end_mark;
786         SKIP_TOKEN(parser);
787         token = PEEK_TOKEN(parser);
788         if (!token) return 0;
789         if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
790                 token->type != YAML_KEY_TOKEN &&
791                 token->type != YAML_VALUE_TOKEN &&
792                 token->type != YAML_BLOCK_END_TOKEN) {
793             if (!PUSH(parser, parser->states,
794                         YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
795                 return 0;
796             return yaml_parser_parse_node(parser, event, 1, 0);
797         }
798         else {
799             parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
800             return yaml_parser_process_empty_scalar(parser, event, mark);
801         }
802     }
803
804     else
805     {
806         parser->state = POP(parser, parser->states);
807         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
808         return 1;
809     }
810 }
811
812 /*
813  * Parse the productions:
814  * block_mapping        ::= BLOCK-MAPPING_START
815  *                          *******************
816  *                          ((KEY block_node_or_indentless_sequence?)?
817  *                            *** *
818  *                          (VALUE block_node_or_indentless_sequence?)?)*
819  *
820  *                          BLOCK-END
821  *                          *********
822  */
823
824 static int
825 yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
826         yaml_event_t *event, int first)
827 {
828     yaml_token_t *token;
829
830     if (first) {
831         token = PEEK_TOKEN(parser);
832         if (!PUSH(parser, parser->marks, token->start_mark))
833             return 0;
834         SKIP_TOKEN(parser);
835     }
836
837     token = PEEK_TOKEN(parser);
838     if (!token) return 0;
839
840     if (token->type == YAML_KEY_TOKEN)
841     {
842         yaml_mark_t mark = token->end_mark;
843         SKIP_TOKEN(parser);
844         token = PEEK_TOKEN(parser);
845         if (!token) return 0;
846         if (token->type != YAML_KEY_TOKEN &&
847                 token->type != YAML_VALUE_TOKEN &&
848                 token->type != YAML_BLOCK_END_TOKEN) {
849             if (!PUSH(parser, parser->states,
850                         YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
851                 return 0;
852             return yaml_parser_parse_node(parser, event, 1, 1);
853         }
854         else {
855             parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
856             return yaml_parser_process_empty_scalar(parser, event, mark);
857         }
858     }
859
860     else if (token->type == YAML_BLOCK_END_TOKEN)
861     {
862         parser->state = POP(parser, parser->states);
863         POP(parser, parser->marks);
864         MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
865         SKIP_TOKEN(parser);
866         return 1;
867     }
868
869     else
870     {
871         return yaml_parser_set_parser_error_context(parser,
872                 "while parsing a block mapping", POP(parser, parser->marks),
873                 "did not found expected key", token->start_mark);
874     }
875 }
876
877 /*
878  * Parse the productions:
879  * block_mapping        ::= BLOCK-MAPPING_START
880  *
881  *                          ((KEY block_node_or_indentless_sequence?)?
882  *
883  *                          (VALUE block_node_or_indentless_sequence?)?)*
884  *                           ***** *
885  *                          BLOCK-END
886  *
887  */
888
889 static int
890 yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
891         yaml_event_t *event)
892 {
893     yaml_token_t *token;
894
895     token = PEEK_TOKEN(parser);
896     if (!token) return 0;
897
898     if (token->type == YAML_VALUE_TOKEN)
899     {
900         yaml_mark_t mark = token->end_mark;
901         SKIP_TOKEN(parser);
902         token = PEEK_TOKEN(parser);
903         if (!token) return 0;
904         if (token->type != YAML_KEY_TOKEN &&
905                 token->type != YAML_VALUE_TOKEN &&
906                 token->type != YAML_BLOCK_END_TOKEN) {
907             if (!PUSH(parser, parser->states,
908                         YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
909                 return 0;
910             return yaml_parser_parse_node(parser, event, 1, 1);
911         }
912         else {
913             parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
914             return yaml_parser_process_empty_scalar(parser, event, mark);
915         }
916     }
917
918     else
919     {
920         parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
921         return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
922     }
923 }
924
925 /*
926  * Parse the productions:
927  * flow_sequence        ::= FLOW-SEQUENCE-START
928  *                          *******************
929  *                          (flow_sequence_entry FLOW-ENTRY)*
930  *                           *                   **********
931  *                          flow_sequence_entry?
932  *                          *
933  *                          FLOW-SEQUENCE-END
934  *                          *****************
935  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
936  *                          *
937  */
938
939 static int
940 yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
941         yaml_event_t *event, int first)
942 {
943     yaml_token_t *token;
944
945     if (first) {
946         token = PEEK_TOKEN(parser);
947         if (!PUSH(parser, parser->marks, token->start_mark))
948             return 0;
949         SKIP_TOKEN(parser);
950     }
951
952     token = PEEK_TOKEN(parser);
953     if (!token) return 0;
954
955     if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
956     {
957         if (!first) {
958             if (token->type == YAML_FLOW_ENTRY_TOKEN) {
959                 SKIP_TOKEN(parser);
960                 token = PEEK_TOKEN(parser);
961                 if (!token) return 0;
962             }
963             else {
964                 return yaml_parser_set_parser_error_context(parser,
965                         "while parsing a flow sequence", POP(parser, parser->marks),
966                         "did not found expected ',' or ']'", token->start_mark);
967             }
968         }
969
970         if (token->type == YAML_KEY_TOKEN) {
971             parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
972             MAPPING_START_EVENT_INIT(*event, NULL, NULL,
973                     1, YAML_FLOW_MAPPING_STYLE,
974                     token->start_mark, token->end_mark);
975             SKIP_TOKEN(parser);
976             return 1;
977         }
978
979         else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
980             if (!PUSH(parser, parser->states,
981                         YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
982                 return 0;
983             return yaml_parser_parse_node(parser, event, 0, 0);
984         }
985     }
986
987     parser->state = POP(parser, parser->states);
988     POP(parser, parser->marks);
989     SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
990     SKIP_TOKEN(parser);
991     return 1;
992 }
993
994 /*
995  * Parse the productions:
996  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
997  *                                      *** *
998  */
999
1000 static int
1001 yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
1002         yaml_event_t *event)
1003 {
1004     yaml_token_t *token;
1005
1006     token = PEEK_TOKEN(parser);
1007     if (!token) return 0;
1008
1009     if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
1010             && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1011         if (!PUSH(parser, parser->states,
1012                     YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
1013             return 0;
1014         return yaml_parser_parse_node(parser, event, 0, 0);
1015     }
1016     else {
1017         yaml_mark_t mark = token->end_mark;
1018         SKIP_TOKEN(parser);
1019         parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
1020         return yaml_parser_process_empty_scalar(parser, event, mark);
1021     }
1022 }
1023
1024 /*
1025  * Parse the productions:
1026  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1027  *                                                      ***** *
1028  */
1029
1030 static int
1031 yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
1032         yaml_event_t *event)
1033 {
1034     yaml_token_t *token;
1035
1036     token = PEEK_TOKEN(parser);
1037     if (!token) return 0;
1038
1039     if (token->type == YAML_VALUE_TOKEN) {
1040         SKIP_TOKEN(parser);
1041         token = PEEK_TOKEN(parser);
1042         if (!token) return 0;
1043         if (token->type != YAML_FLOW_ENTRY_TOKEN
1044                 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1045             if (!PUSH(parser, parser->states,
1046                         YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
1047                 return 0;
1048             return yaml_parser_parse_node(parser, event, 0, 0);
1049         }
1050     }
1051     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
1052     return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1053 }
1054
1055 /*
1056  * Parse the productions:
1057  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1058  *                                                                      *
1059  */
1060
1061 static int
1062 yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
1063         yaml_event_t *event)
1064 {
1065     yaml_token_t *token;
1066
1067     token = PEEK_TOKEN(parser);
1068     if (!token) return 0;
1069
1070     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
1071
1072     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
1073     return 1;
1074 }
1075
1076 /*
1077  * Parse the productions:
1078  * flow_mapping         ::= FLOW-MAPPING-START
1079  *                          ******************
1080  *                          (flow_mapping_entry FLOW-ENTRY)*
1081  *                           *                  **********
1082  *                          flow_mapping_entry?
1083  *                          ******************
1084  *                          FLOW-MAPPING-END
1085  *                          ****************
1086  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1087  *                          *           *** *
1088  */
1089
1090 static int
1091 yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
1092         yaml_event_t *event, int first)
1093 {
1094     yaml_token_t *token;
1095
1096     if (first) {
1097         token = PEEK_TOKEN(parser);
1098         if (!PUSH(parser, parser->marks, token->start_mark))
1099             return 0;
1100         SKIP_TOKEN(parser);
1101     }
1102
1103     token = PEEK_TOKEN(parser);
1104     if (!token) return 0;
1105
1106     if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1107     {
1108         if (!first) {
1109             if (token->type == YAML_FLOW_ENTRY_TOKEN) {
1110                 SKIP_TOKEN(parser);
1111                 token = PEEK_TOKEN(parser);
1112                 if (!token) return 0;
1113             }
1114             else {
1115                 return yaml_parser_set_parser_error_context(parser,
1116                         "while parsing a flow mapping", POP(parser, parser->marks),
1117                         "did not found expected ',' or '}'", token->start_mark);
1118             }
1119         }
1120
1121         if (token->type == YAML_KEY_TOKEN) {
1122             SKIP_TOKEN(parser);
1123             token = PEEK_TOKEN(parser);
1124             if (!token) return 0;
1125             if (token->type != YAML_VALUE_TOKEN
1126                     && token->type != YAML_FLOW_ENTRY_TOKEN
1127                     && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1128                 if (!PUSH(parser, parser->states,
1129                             YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
1130                     return 0;
1131                 return yaml_parser_parse_node(parser, event, 0, 0);
1132             }
1133             else {
1134                 parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
1135                 return yaml_parser_process_empty_scalar(parser, event,
1136                         token->start_mark);
1137             }
1138         }
1139         else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1140             if (!PUSH(parser, parser->states,
1141                         YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
1142                 return 0;
1143             return yaml_parser_parse_node(parser, event, 0, 0);
1144         }
1145     }
1146
1147     parser->state = POP(parser, parser->states);
1148     POP(parser, parser->marks);
1149     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1150     SKIP_TOKEN(parser);
1151     return 1;
1152 }
1153
1154 /*
1155  * Parse the productions:
1156  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1157  *                                   *                  ***** *
1158  */
1159
1160 static int
1161 yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
1162         yaml_event_t *event, int empty)
1163 {
1164     yaml_token_t *token;
1165
1166     token = PEEK_TOKEN(parser);
1167     if (!token) return 0;
1168
1169     if (empty) {
1170         parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1171         return yaml_parser_process_empty_scalar(parser, event,
1172                 token->start_mark);
1173     }
1174
1175     if (token->type == YAML_VALUE_TOKEN) {
1176         SKIP_TOKEN(parser);
1177         token = PEEK_TOKEN(parser);
1178         if (!token) return 0;
1179         if (token->type != YAML_FLOW_ENTRY_TOKEN
1180                 && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1181             if (!PUSH(parser, parser->states,
1182                         YAML_PARSE_FLOW_MAPPING_KEY_STATE))
1183                 return 0;
1184             return yaml_parser_parse_node(parser, event, 0, 0);
1185         }
1186     }
1187
1188     parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1189     return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1190 }
1191
1192 /*
1193  * Generate an empty scalar event.
1194  */
1195
1196 static int
1197 yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
1198         yaml_mark_t mark)
1199 {
1200     yaml_char_t *value;
1201
1202     value = yaml_malloc(1);
1203     if (!value) {
1204         parser->error = YAML_MEMORY_ERROR;
1205         return 0;
1206     }
1207     value[0] = '\0';
1208
1209     SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
1210             1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
1211
1212     return 1;
1213 }
1214
1215 /*
1216  * Parse directives.
1217  */
1218
1219 static int
1220 yaml_parser_process_directives(yaml_parser_t *parser,
1221         yaml_version_directive_t **version_directive_ref,
1222         yaml_tag_directive_t **tag_directives_start_ref,
1223         yaml_tag_directive_t **tag_directives_end_ref)
1224 {
1225     yaml_tag_directive_t default_tag_directives[] = {
1226         {(yaml_char_t *)"!", (yaml_char_t *)"!"},
1227         {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
1228         {NULL, NULL}
1229     };
1230     yaml_tag_directive_t *default_tag_directive;
1231     yaml_version_directive_t *version_directive = NULL;
1232     struct {
1233         yaml_tag_directive_t *start;
1234         yaml_tag_directive_t *end;
1235         yaml_tag_directive_t *top;
1236     } tag_directives = { NULL, NULL, NULL };
1237     yaml_token_t *token;
1238
1239     if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
1240         goto error;
1241
1242     token = PEEK_TOKEN(parser);
1243     if (!token) goto error;
1244
1245     while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
1246             token->type == YAML_TAG_DIRECTIVE_TOKEN)
1247     {
1248         if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
1249             if (version_directive) {
1250                 yaml_parser_set_parser_error(parser,
1251                         "found duplicate %YAML directive", token->start_mark);
1252                 goto error;
1253             }
1254             if (token->data.version_directive.major != 1
1255                     || token->data.version_directive.minor != 1) {
1256                 yaml_parser_set_parser_error(parser,
1257                         "found incompatible YAML document", token->start_mark);
1258                 goto error;
1259             }
1260             version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
1261             if (!version_directive) {
1262                 parser->error = YAML_MEMORY_ERROR;
1263                 goto error;
1264             }
1265             version_directive->major = token->data.version_directive.major;
1266             version_directive->minor = token->data.version_directive.minor;
1267         }
1268
1269         else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1270             yaml_tag_directive_t value = {
1271                 token->data.tag_directive.handle,
1272                 token->data.tag_directive.prefix
1273             };
1274             if (!yaml_parser_append_tag_directive(parser, value, 0,
1275                         token->start_mark))
1276                 goto error;
1277             if (!PUSH(parser, tag_directives, value))
1278                 goto error;
1279         }
1280
1281         SKIP_TOKEN(parser);
1282         token = PEEK_TOKEN(parser);
1283         if (!token) goto error;
1284     }
1285     
1286     for (default_tag_directive = default_tag_directives;
1287             default_tag_directive->handle; default_tag_directive++) {
1288         if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
1289                     token->start_mark))
1290             goto error;
1291     }
1292
1293     if (version_directive_ref) {
1294         *version_directive_ref = version_directive;
1295     }
1296     if (tag_directives_start_ref) {
1297         if (STACK_EMPTY(parser, tag_directives)) {
1298             *tag_directives_start_ref = *tag_directives_end_ref = NULL;
1299             STACK_DEL(parser, tag_directives);
1300         }
1301         else {
1302             *tag_directives_start_ref = tag_directives.start;
1303             *tag_directives_end_ref = tag_directives.top;
1304         }
1305     }
1306     else {
1307         STACK_DEL(parser, tag_directives);
1308     }
1309
1310     return 1;
1311
1312 error:
1313     yaml_free(version_directive);
1314     while (!STACK_EMPTY(parser, tag_directives)) {
1315         yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
1316         yaml_free(tag_directive.handle);
1317         yaml_free(tag_directive.prefix);
1318     }
1319     STACK_DEL(parser, tag_directives);
1320     return 0;
1321 }
1322
1323 /*
1324  * Append a tag directive to the directives stack.
1325  */
1326
1327 static int
1328 yaml_parser_append_tag_directive(yaml_parser_t *parser,
1329         yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
1330 {
1331     yaml_tag_directive_t *tag_directive;
1332     yaml_tag_directive_t copy = { NULL, NULL };
1333
1334     for (tag_directive = parser->tag_directives.start;
1335             tag_directive != parser->tag_directives.top; tag_directive ++) {
1336         if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
1337             if (allow_duplicates)
1338                 return 1;
1339             return yaml_parser_set_parser_error(parser,
1340                     "found duplicate %TAG directive", mark);
1341         }
1342     }
1343
1344     copy.handle = yaml_strdup(value.handle);
1345     copy.prefix = yaml_strdup(value.prefix);
1346     if (!copy.handle || !copy.prefix) {
1347         parser->error = YAML_MEMORY_ERROR;
1348         goto error;
1349     }
1350
1351     if (!PUSH(parser, parser->tag_directives, copy))
1352         goto error;
1353
1354     return 1;
1355
1356 error:
1357     yaml_free(copy.handle);
1358     yaml_free(copy.prefix);
1359     return 0;
1360 }
1361
This page took 0.142295 seconds and 5 git commands to generate.