]> andersk Git - libyaml.git/blob - src/parser.c
Fixed most compiler warnings -Wall -Wextra
[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 find 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 extra document end indicators. */
356
357     if (!implicit)
358     {
359         while (token->type == YAML_DOCUMENT_END_TOKEN) {
360             SKIP_TOKEN(parser);
361             token = PEEK_TOKEN(parser);
362             if (!token) return 0;
363         }
364     }
365
366     /* Parse an implicit document. */
367
368     if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
369             token->type != YAML_TAG_DIRECTIVE_TOKEN &&
370             token->type != YAML_DOCUMENT_START_TOKEN &&
371             token->type != YAML_STREAM_END_TOKEN)
372     {
373         if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
374             return 0;
375         if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
376             return 0;
377         parser->state = YAML_PARSE_BLOCK_NODE_STATE;
378         DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
379                 token->start_mark, token->start_mark);
380         return 1;
381     }
382
383     /* Parse an explicit document. */
384
385     else if (token->type != YAML_STREAM_END_TOKEN)
386     {
387         yaml_mark_t start_mark, end_mark;
388         start_mark = token->start_mark;
389         if (!yaml_parser_process_directives(parser, &version_directive,
390                     &tag_directives.start, &tag_directives.end))
391             return 0;
392         token = PEEK_TOKEN(parser);
393         if (!token) goto error;
394         if (token->type != YAML_DOCUMENT_START_TOKEN) {
395             yaml_parser_set_parser_error(parser,
396                     "did not find expected <document start>", token->start_mark);
397             goto error;
398         }
399         if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
400             goto error;
401         parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
402         end_mark = token->end_mark;
403         DOCUMENT_START_EVENT_INIT(*event, version_directive,
404                 tag_directives.start, tag_directives.end, 0,
405                 start_mark, end_mark);
406         SKIP_TOKEN(parser);
407         version_directive = NULL;
408         tag_directives.start = tag_directives.end = NULL;
409         return 1;
410     }
411
412     /* Parse the stream end. */
413
414     else
415     {
416         parser->state = YAML_PARSE_END_STATE;
417         STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
418         SKIP_TOKEN(parser);
419         return 1;
420     }
421
422 error:
423     yaml_free(version_directive);
424     while (tag_directives.start != tag_directives.end) {
425         yaml_free(tag_directives.end[-1].handle);
426         yaml_free(tag_directives.end[-1].prefix);
427         tag_directives.end --;
428     }
429     yaml_free(tag_directives.start);
430     return 0;
431 }
432
433 /*
434  * Parse the productions:
435  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
436  *                                                    ***********
437  */
438
439 static int
440 yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
441 {
442     yaml_token_t *token;
443
444     token = PEEK_TOKEN(parser);
445     if (!token) return 0;
446
447     if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
448             token->type == YAML_TAG_DIRECTIVE_TOKEN ||
449             token->type == YAML_DOCUMENT_START_TOKEN ||
450             token->type == YAML_DOCUMENT_END_TOKEN ||
451             token->type == YAML_STREAM_END_TOKEN) {
452         parser->state = POP(parser, parser->states);
453         return yaml_parser_process_empty_scalar(parser, event,
454                 token->start_mark);
455     }
456     else {
457         return yaml_parser_parse_node(parser, event, 1, 0);
458     }
459 }
460
461 /*
462  * Parse the productions:
463  * implicit_document    ::= block_node DOCUMENT-END*
464  *                                     *************
465  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
466  *                                                                *************
467  */
468
469 static int
470 yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
471 {
472     yaml_token_t *token;
473     yaml_mark_t start_mark, end_mark;
474     int implicit = 1;
475
476     token = PEEK_TOKEN(parser);
477     if (!token) return 0;
478
479     start_mark = end_mark = token->start_mark;
480
481     if (token->type == YAML_DOCUMENT_END_TOKEN) {
482         end_mark = token->end_mark;
483         SKIP_TOKEN(parser);
484         implicit = 0;
485     }
486
487     while (!STACK_EMPTY(parser, parser->tag_directives)) {
488         yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
489         yaml_free(tag_directive.handle);
490         yaml_free(tag_directive.prefix);
491     }
492
493     parser->state = YAML_PARSE_DOCUMENT_START_STATE;
494     DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
495
496     return 1;
497 }
498
499 /*
500  * Parse the productions:
501  * block_node_or_indentless_sequence    ::=
502  *                          ALIAS
503  *                          *****
504  *                          | properties (block_content | indentless_block_sequence)?
505  *                            **********  *
506  *                          | block_content | indentless_block_sequence
507  *                            *
508  * block_node           ::= ALIAS
509  *                          *****
510  *                          | properties block_content?
511  *                            ********** *
512  *                          | block_content
513  *                            *
514  * flow_node            ::= ALIAS
515  *                          *****
516  *                          | properties flow_content?
517  *                            ********** *
518  *                          | flow_content
519  *                            *
520  * properties           ::= TAG ANCHOR? | ANCHOR TAG?
521  *                          *************************
522  * block_content        ::= block_collection | flow_collection | SCALAR
523  *                                                               ******
524  * flow_content         ::= flow_collection | SCALAR
525  *                                            ******
526  */
527
528 static int
529 yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
530         int block, int indentless_sequence)
531 {
532     yaml_token_t *token;
533     yaml_char_t *anchor = NULL;
534     yaml_char_t *tag_handle = NULL;
535     yaml_char_t *tag_suffix = NULL;
536     yaml_char_t *tag = NULL;
537     yaml_mark_t start_mark, end_mark, tag_mark;
538     int implicit;
539
540     token = PEEK_TOKEN(parser);
541     if (!token) return 0;
542
543     if (token->type == YAML_ALIAS_TOKEN)
544     {
545         parser->state = POP(parser, parser->states);
546         ALIAS_EVENT_INIT(*event, token->data.alias.value,
547                 token->start_mark, token->end_mark);
548         SKIP_TOKEN(parser);
549         return 1;
550     }
551
552     else
553     {
554         start_mark = end_mark = token->start_mark;
555
556         if (token->type == YAML_ANCHOR_TOKEN)
557         {
558             anchor = token->data.anchor.value;
559             start_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             if (token->type == YAML_TAG_TOKEN)
565             {
566                 tag_handle = token->data.tag.handle;
567                 tag_suffix = token->data.tag.suffix;
568                 tag_mark = token->start_mark;
569                 end_mark = token->end_mark;
570                 SKIP_TOKEN(parser);
571                 token = PEEK_TOKEN(parser);
572                 if (!token) goto error;
573             }
574         }
575         else if (token->type == YAML_TAG_TOKEN)
576         {
577             tag_handle = token->data.tag.handle;
578             tag_suffix = token->data.tag.suffix;
579             start_mark = tag_mark = token->start_mark;
580             end_mark = token->end_mark;
581             SKIP_TOKEN(parser);
582             token = PEEK_TOKEN(parser);
583             if (!token) goto error;
584             if (token->type == YAML_ANCHOR_TOKEN)
585             {
586                 anchor = token->data.anchor.value;
587                 end_mark = token->end_mark;
588                 SKIP_TOKEN(parser);
589                 token = PEEK_TOKEN(parser);
590                 if (!token) goto error;
591             }
592         }
593
594         if (tag_handle) {
595             if (!*tag_handle) {
596                 tag = tag_suffix;
597                 yaml_free(tag_handle);
598                 tag_handle = tag_suffix = NULL;
599             }
600             else {
601                 yaml_tag_directive_t *tag_directive;
602                 for (tag_directive = parser->tag_directives.start;
603                         tag_directive != parser->tag_directives.top;
604                         tag_directive ++) {
605                     if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
606                         size_t prefix_len = strlen((char *)tag_directive->prefix);
607                         size_t suffix_len = strlen((char *)tag_suffix);
608                         tag = YAML_MALLOC(prefix_len+suffix_len+1);
609                         if (!tag) {
610                             parser->error = YAML_MEMORY_ERROR;
611                             goto error;
612                         }
613                         memcpy(tag, tag_directive->prefix, prefix_len);
614                         memcpy(tag+prefix_len, tag_suffix, suffix_len);
615                         tag[prefix_len+suffix_len] = '\0';
616                         yaml_free(tag_handle);
617                         yaml_free(tag_suffix);
618                         tag_handle = tag_suffix = NULL;
619                         break;
620                     }
621                 }
622                 if (!tag) {
623                     yaml_parser_set_parser_error_context(parser,
624                             "while parsing a node", start_mark,
625                             "found undefined tag handle", tag_mark);
626                     goto error;
627                 }
628             }
629         }
630
631         implicit = (!tag || !*tag);
632         if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
633             end_mark = token->end_mark;
634             parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
635             SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
636                     YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
637             return 1;
638         }
639         else {
640             if (token->type == YAML_SCALAR_TOKEN) {
641                 int plain_implicit = 0;
642                 int quoted_implicit = 0;
643                 end_mark = token->end_mark;
644                 if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
645                         || (tag && strcmp((char *)tag, "!") == 0)) {
646                     plain_implicit = 1;
647                 }
648                 else if (!tag) {
649                     quoted_implicit = 1;
650                 }
651                 parser->state = POP(parser, parser->states);
652                 SCALAR_EVENT_INIT(*event, anchor, tag,
653                         token->data.scalar.value, token->data.scalar.length,
654                         plain_implicit, quoted_implicit,
655                         token->data.scalar.style, start_mark, end_mark);
656                 SKIP_TOKEN(parser);
657                 return 1;
658             }
659             else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
660                 end_mark = token->end_mark;
661                 parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
662                 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
663                         YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
664                 return 1;
665             }
666             else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
667                 end_mark = token->end_mark;
668                 parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
669                 MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
670                         YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
671                 return 1;
672             }
673             else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
674                 end_mark = token->end_mark;
675                 parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
676                 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
677                         YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
678                 return 1;
679             }
680             else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
681                 end_mark = token->end_mark;
682                 parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
683                 MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
684                         YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
685                 return 1;
686             }
687             else if (anchor || tag) {
688                 yaml_char_t *value = YAML_MALLOC(1);
689                 if (!value) {
690                     parser->error = YAML_MEMORY_ERROR;
691                     goto error;
692                 }
693                 value[0] = '\0';
694                 parser->state = POP(parser, parser->states);
695                 SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
696                         implicit, 0, YAML_PLAIN_SCALAR_STYLE,
697                         start_mark, end_mark);
698                 return 1;
699             }
700             else {
701                 yaml_parser_set_parser_error_context(parser,
702                         (block ? "while parsing a block node"
703                          : "while parsing a flow node"), start_mark,
704                         "did not find expected node content", token->start_mark);
705                 goto error;
706             }
707         }
708     }
709
710 error:
711     yaml_free(anchor);
712     yaml_free(tag_handle);
713     yaml_free(tag_suffix);
714     yaml_free(tag);
715
716     return 0;
717 }
718
719 /*
720  * Parse the productions:
721  * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
722  *                    ********************  *********** *             *********
723  */
724
725 static int
726 yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
727         yaml_event_t *event, int first)
728 {
729     yaml_token_t *token;
730
731     if (first) {
732         token = PEEK_TOKEN(parser);
733         if (!PUSH(parser, parser->marks, token->start_mark))
734             return 0;
735         SKIP_TOKEN(parser);
736     }
737
738     token = PEEK_TOKEN(parser);
739     if (!token) return 0;
740
741     if (token->type == YAML_BLOCK_ENTRY_TOKEN)
742     {
743         yaml_mark_t mark = token->end_mark;
744         SKIP_TOKEN(parser);
745         token = PEEK_TOKEN(parser);
746         if (!token) return 0;
747         if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
748                 token->type != YAML_BLOCK_END_TOKEN) {
749             if (!PUSH(parser, parser->states,
750                         YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
751                 return 0;
752             return yaml_parser_parse_node(parser, event, 1, 0);
753         }
754         else {
755             parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
756             return yaml_parser_process_empty_scalar(parser, event, mark);
757         }
758     }
759
760     else if (token->type == YAML_BLOCK_END_TOKEN)
761     {
762         parser->state = POP(parser, parser->states);
763         (void)POP(parser, parser->marks);
764         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
765         SKIP_TOKEN(parser);
766         return 1;
767     }
768
769     else
770     {
771         return yaml_parser_set_parser_error_context(parser,
772                 "while parsing a block collection", POP(parser, parser->marks),
773                 "did not find expected '-' indicator", token->start_mark);
774     }
775 }
776
777 /*
778  * Parse the productions:
779  * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
780  *                           *********** *
781  */
782
783 static int
784 yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
785         yaml_event_t *event)
786 {
787     yaml_token_t *token;
788
789     token = PEEK_TOKEN(parser);
790     if (!token) return 0;
791
792     if (token->type == YAML_BLOCK_ENTRY_TOKEN)
793     {
794         yaml_mark_t mark = token->end_mark;
795         SKIP_TOKEN(parser);
796         token = PEEK_TOKEN(parser);
797         if (!token) return 0;
798         if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
799                 token->type != YAML_KEY_TOKEN &&
800                 token->type != YAML_VALUE_TOKEN &&
801                 token->type != YAML_BLOCK_END_TOKEN) {
802             if (!PUSH(parser, parser->states,
803                         YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
804                 return 0;
805             return yaml_parser_parse_node(parser, event, 1, 0);
806         }
807         else {
808             parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
809             return yaml_parser_process_empty_scalar(parser, event, mark);
810         }
811     }
812
813     else
814     {
815         parser->state = POP(parser, parser->states);
816         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
817         return 1;
818     }
819 }
820
821 /*
822  * Parse the productions:
823  * block_mapping        ::= BLOCK-MAPPING_START
824  *                          *******************
825  *                          ((KEY block_node_or_indentless_sequence?)?
826  *                            *** *
827  *                          (VALUE block_node_or_indentless_sequence?)?)*
828  *
829  *                          BLOCK-END
830  *                          *********
831  */
832
833 static int
834 yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
835         yaml_event_t *event, int first)
836 {
837     yaml_token_t *token;
838
839     if (first) {
840         token = PEEK_TOKEN(parser);
841         if (!PUSH(parser, parser->marks, token->start_mark))
842             return 0;
843         SKIP_TOKEN(parser);
844     }
845
846     token = PEEK_TOKEN(parser);
847     if (!token) return 0;
848
849     if (token->type == YAML_KEY_TOKEN)
850     {
851         yaml_mark_t mark = token->end_mark;
852         SKIP_TOKEN(parser);
853         token = PEEK_TOKEN(parser);
854         if (!token) return 0;
855         if (token->type != YAML_KEY_TOKEN &&
856                 token->type != YAML_VALUE_TOKEN &&
857                 token->type != YAML_BLOCK_END_TOKEN) {
858             if (!PUSH(parser, parser->states,
859                         YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
860                 return 0;
861             return yaml_parser_parse_node(parser, event, 1, 1);
862         }
863         else {
864             parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
865             return yaml_parser_process_empty_scalar(parser, event, mark);
866         }
867     }
868
869     else if (token->type == YAML_BLOCK_END_TOKEN)
870     {
871         parser->state = POP(parser, parser->states);
872         (void)POP(parser, parser->marks);
873         MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
874         SKIP_TOKEN(parser);
875         return 1;
876     }
877
878     else
879     {
880         return yaml_parser_set_parser_error_context(parser,
881                 "while parsing a block mapping", POP(parser, parser->marks),
882                 "did not find expected key", token->start_mark);
883     }
884 }
885
886 /*
887  * Parse the productions:
888  * block_mapping        ::= BLOCK-MAPPING_START
889  *
890  *                          ((KEY block_node_or_indentless_sequence?)?
891  *
892  *                          (VALUE block_node_or_indentless_sequence?)?)*
893  *                           ***** *
894  *                          BLOCK-END
895  *
896  */
897
898 static int
899 yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
900         yaml_event_t *event)
901 {
902     yaml_token_t *token;
903
904     token = PEEK_TOKEN(parser);
905     if (!token) return 0;
906
907     if (token->type == YAML_VALUE_TOKEN)
908     {
909         yaml_mark_t mark = token->end_mark;
910         SKIP_TOKEN(parser);
911         token = PEEK_TOKEN(parser);
912         if (!token) return 0;
913         if (token->type != YAML_KEY_TOKEN &&
914                 token->type != YAML_VALUE_TOKEN &&
915                 token->type != YAML_BLOCK_END_TOKEN) {
916             if (!PUSH(parser, parser->states,
917                         YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
918                 return 0;
919             return yaml_parser_parse_node(parser, event, 1, 1);
920         }
921         else {
922             parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
923             return yaml_parser_process_empty_scalar(parser, event, mark);
924         }
925     }
926
927     else
928     {
929         parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
930         return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
931     }
932 }
933
934 /*
935  * Parse the productions:
936  * flow_sequence        ::= FLOW-SEQUENCE-START
937  *                          *******************
938  *                          (flow_sequence_entry FLOW-ENTRY)*
939  *                           *                   **********
940  *                          flow_sequence_entry?
941  *                          *
942  *                          FLOW-SEQUENCE-END
943  *                          *****************
944  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
945  *                          *
946  */
947
948 static int
949 yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
950         yaml_event_t *event, int first)
951 {
952     yaml_token_t *token;
953
954     if (first) {
955         token = PEEK_TOKEN(parser);
956         if (!PUSH(parser, parser->marks, token->start_mark))
957             return 0;
958         SKIP_TOKEN(parser);
959     }
960
961     token = PEEK_TOKEN(parser);
962     if (!token) return 0;
963
964     if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
965     {
966         if (!first) {
967             if (token->type == YAML_FLOW_ENTRY_TOKEN) {
968                 SKIP_TOKEN(parser);
969                 token = PEEK_TOKEN(parser);
970                 if (!token) return 0;
971             }
972             else {
973                 return yaml_parser_set_parser_error_context(parser,
974                         "while parsing a flow sequence", POP(parser, parser->marks),
975                         "did not find expected ',' or ']'", token->start_mark);
976             }
977         }
978
979         if (token->type == YAML_KEY_TOKEN) {
980             parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
981             MAPPING_START_EVENT_INIT(*event, NULL, NULL,
982                     1, YAML_FLOW_MAPPING_STYLE,
983                     token->start_mark, token->end_mark);
984             SKIP_TOKEN(parser);
985             return 1;
986         }
987
988         else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
989             if (!PUSH(parser, parser->states,
990                         YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
991                 return 0;
992             return yaml_parser_parse_node(parser, event, 0, 0);
993         }
994     }
995
996     parser->state = POP(parser, parser->states);
997     (void)POP(parser, parser->marks);
998     SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
999     SKIP_TOKEN(parser);
1000     return 1;
1001 }
1002
1003 /*
1004  * Parse the productions:
1005  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1006  *                                      *** *
1007  */
1008
1009 static int
1010 yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
1011         yaml_event_t *event)
1012 {
1013     yaml_token_t *token;
1014
1015     token = PEEK_TOKEN(parser);
1016     if (!token) return 0;
1017
1018     if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
1019             && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1020         if (!PUSH(parser, parser->states,
1021                     YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
1022             return 0;
1023         return yaml_parser_parse_node(parser, event, 0, 0);
1024     }
1025     else {
1026         yaml_mark_t mark = token->end_mark;
1027         SKIP_TOKEN(parser);
1028         parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
1029         return yaml_parser_process_empty_scalar(parser, event, mark);
1030     }
1031 }
1032
1033 /*
1034  * Parse the productions:
1035  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1036  *                                                      ***** *
1037  */
1038
1039 static int
1040 yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
1041         yaml_event_t *event)
1042 {
1043     yaml_token_t *token;
1044
1045     token = PEEK_TOKEN(parser);
1046     if (!token) return 0;
1047
1048     if (token->type == YAML_VALUE_TOKEN) {
1049         SKIP_TOKEN(parser);
1050         token = PEEK_TOKEN(parser);
1051         if (!token) return 0;
1052         if (token->type != YAML_FLOW_ENTRY_TOKEN
1053                 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1054             if (!PUSH(parser, parser->states,
1055                         YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
1056                 return 0;
1057             return yaml_parser_parse_node(parser, event, 0, 0);
1058         }
1059     }
1060     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
1061     return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1062 }
1063
1064 /*
1065  * Parse the productions:
1066  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1067  *                                                                      *
1068  */
1069
1070 static int
1071 yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
1072         yaml_event_t *event)
1073 {
1074     yaml_token_t *token;
1075
1076     token = PEEK_TOKEN(parser);
1077     if (!token) return 0;
1078
1079     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
1080
1081     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
1082     return 1;
1083 }
1084
1085 /*
1086  * Parse the productions:
1087  * flow_mapping         ::= FLOW-MAPPING-START
1088  *                          ******************
1089  *                          (flow_mapping_entry FLOW-ENTRY)*
1090  *                           *                  **********
1091  *                          flow_mapping_entry?
1092  *                          ******************
1093  *                          FLOW-MAPPING-END
1094  *                          ****************
1095  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1096  *                          *           *** *
1097  */
1098
1099 static int
1100 yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
1101         yaml_event_t *event, int first)
1102 {
1103     yaml_token_t *token;
1104
1105     if (first) {
1106         token = PEEK_TOKEN(parser);
1107         if (!PUSH(parser, parser->marks, token->start_mark))
1108             return 0;
1109         SKIP_TOKEN(parser);
1110     }
1111
1112     token = PEEK_TOKEN(parser);
1113     if (!token) return 0;
1114
1115     if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1116     {
1117         if (!first) {
1118             if (token->type == YAML_FLOW_ENTRY_TOKEN) {
1119                 SKIP_TOKEN(parser);
1120                 token = PEEK_TOKEN(parser);
1121                 if (!token) return 0;
1122             }
1123             else {
1124                 return yaml_parser_set_parser_error_context(parser,
1125                         "while parsing a flow mapping", POP(parser, parser->marks),
1126                         "did not find expected ',' or '}'", token->start_mark);
1127             }
1128         }
1129
1130         if (token->type == YAML_KEY_TOKEN) {
1131             SKIP_TOKEN(parser);
1132             token = PEEK_TOKEN(parser);
1133             if (!token) return 0;
1134             if (token->type != YAML_VALUE_TOKEN
1135                     && token->type != YAML_FLOW_ENTRY_TOKEN
1136                     && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1137                 if (!PUSH(parser, parser->states,
1138                             YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
1139                     return 0;
1140                 return yaml_parser_parse_node(parser, event, 0, 0);
1141             }
1142             else {
1143                 parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
1144                 return yaml_parser_process_empty_scalar(parser, event,
1145                         token->start_mark);
1146             }
1147         }
1148         else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1149             if (!PUSH(parser, parser->states,
1150                         YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
1151                 return 0;
1152             return yaml_parser_parse_node(parser, event, 0, 0);
1153         }
1154     }
1155
1156     parser->state = POP(parser, parser->states);
1157     (void)POP(parser, parser->marks);
1158     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1159     SKIP_TOKEN(parser);
1160     return 1;
1161 }
1162
1163 /*
1164  * Parse the productions:
1165  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1166  *                                   *                  ***** *
1167  */
1168
1169 static int
1170 yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
1171         yaml_event_t *event, int empty)
1172 {
1173     yaml_token_t *token;
1174
1175     token = PEEK_TOKEN(parser);
1176     if (!token) return 0;
1177
1178     if (empty) {
1179         parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1180         return yaml_parser_process_empty_scalar(parser, event,
1181                 token->start_mark);
1182     }
1183
1184     if (token->type == YAML_VALUE_TOKEN) {
1185         SKIP_TOKEN(parser);
1186         token = PEEK_TOKEN(parser);
1187         if (!token) return 0;
1188         if (token->type != YAML_FLOW_ENTRY_TOKEN
1189                 && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1190             if (!PUSH(parser, parser->states,
1191                         YAML_PARSE_FLOW_MAPPING_KEY_STATE))
1192                 return 0;
1193             return yaml_parser_parse_node(parser, event, 0, 0);
1194         }
1195     }
1196
1197     parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1198     return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1199 }
1200
1201 /*
1202  * Generate an empty scalar event.
1203  */
1204
1205 static int
1206 yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
1207         yaml_mark_t mark)
1208 {
1209     yaml_char_t *value;
1210
1211     value = YAML_MALLOC(1);
1212     if (!value) {
1213         parser->error = YAML_MEMORY_ERROR;
1214         return 0;
1215     }
1216     value[0] = '\0';
1217
1218     SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
1219             1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
1220
1221     return 1;
1222 }
1223
1224 /*
1225  * Parse directives.
1226  */
1227
1228 static int
1229 yaml_parser_process_directives(yaml_parser_t *parser,
1230         yaml_version_directive_t **version_directive_ref,
1231         yaml_tag_directive_t **tag_directives_start_ref,
1232         yaml_tag_directive_t **tag_directives_end_ref)
1233 {
1234     yaml_tag_directive_t default_tag_directives[] = {
1235         {(yaml_char_t *)"!", (yaml_char_t *)"!"},
1236         {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
1237         {NULL, NULL}
1238     };
1239     yaml_tag_directive_t *default_tag_directive;
1240     yaml_version_directive_t *version_directive = NULL;
1241     struct {
1242         yaml_tag_directive_t *start;
1243         yaml_tag_directive_t *end;
1244         yaml_tag_directive_t *top;
1245     } tag_directives = { NULL, NULL, NULL };
1246     yaml_token_t *token;
1247
1248     if (!STACK_INIT(parser, tag_directives, yaml_tag_directive_t*))
1249         goto error;
1250
1251     token = PEEK_TOKEN(parser);
1252     if (!token) goto error;
1253
1254     while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
1255             token->type == YAML_TAG_DIRECTIVE_TOKEN)
1256     {
1257         if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
1258             if (version_directive) {
1259                 yaml_parser_set_parser_error(parser,
1260                         "found duplicate %YAML directive", token->start_mark);
1261                 goto error;
1262             }
1263             if (token->data.version_directive.major != 1
1264                     || token->data.version_directive.minor != 1) {
1265                 yaml_parser_set_parser_error(parser,
1266                         "found incompatible YAML document", token->start_mark);
1267                 goto error;
1268             }
1269             version_directive = YAML_MALLOC_STATIC(yaml_version_directive_t);
1270             if (!version_directive) {
1271                 parser->error = YAML_MEMORY_ERROR;
1272                 goto error;
1273             }
1274             version_directive->major = token->data.version_directive.major;
1275             version_directive->minor = token->data.version_directive.minor;
1276         }
1277
1278         else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1279             yaml_tag_directive_t value;
1280             value.handle = token->data.tag_directive.handle;
1281             value.prefix = token->data.tag_directive.prefix;
1282
1283             if (!yaml_parser_append_tag_directive(parser, value, 0,
1284                         token->start_mark))
1285                 goto error;
1286             if (!PUSH(parser, tag_directives, value))
1287                 goto error;
1288         }
1289
1290         SKIP_TOKEN(parser);
1291         token = PEEK_TOKEN(parser);
1292         if (!token) goto error;
1293     }
1294
1295     for (default_tag_directive = default_tag_directives;
1296             default_tag_directive->handle; default_tag_directive++) {
1297         if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
1298                     token->start_mark))
1299             goto error;
1300     }
1301
1302     if (version_directive_ref) {
1303         *version_directive_ref = version_directive;
1304     }
1305     if (tag_directives_start_ref) {
1306         if (STACK_EMPTY(parser, tag_directives)) {
1307             *tag_directives_start_ref = *tag_directives_end_ref = NULL;
1308             STACK_DEL(parser, tag_directives);
1309         }
1310         else {
1311             *tag_directives_start_ref = tag_directives.start;
1312             *tag_directives_end_ref = tag_directives.top;
1313         }
1314     }
1315     else {
1316         STACK_DEL(parser, tag_directives);
1317     }
1318
1319     return 1;
1320
1321 error:
1322     yaml_free(version_directive);
1323     while (!STACK_EMPTY(parser, tag_directives)) {
1324         yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
1325         yaml_free(tag_directive.handle);
1326         yaml_free(tag_directive.prefix);
1327     }
1328     STACK_DEL(parser, tag_directives);
1329     return 0;
1330 }
1331
1332 /*
1333  * Append a tag directive to the directives stack.
1334  */
1335
1336 static int
1337 yaml_parser_append_tag_directive(yaml_parser_t *parser,
1338         yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
1339 {
1340     yaml_tag_directive_t *tag_directive;
1341     yaml_tag_directive_t copy = { NULL, NULL };
1342
1343     for (tag_directive = parser->tag_directives.start;
1344             tag_directive != parser->tag_directives.top; tag_directive ++) {
1345         if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
1346             if (allow_duplicates)
1347                 return 1;
1348             return yaml_parser_set_parser_error(parser,
1349                     "found duplicate %TAG directive", mark);
1350         }
1351     }
1352
1353     copy.handle = yaml_strdup(value.handle);
1354     copy.prefix = yaml_strdup(value.prefix);
1355     if (!copy.handle || !copy.prefix) {
1356         parser->error = YAML_MEMORY_ERROR;
1357         goto error;
1358     }
1359
1360     if (!PUSH(parser, parser->tag_directives, copy))
1361         goto error;
1362
1363     return 1;
1364
1365 error:
1366     yaml_free(copy.handle);
1367     yaml_free(copy.prefix);
1368     return 0;
1369 }
1370
This page took 0.141403 seconds and 5 git commands to generate.