File Coverage

parser.c
Criterion Covered Total %
statement 429 558 76.8
branch 304 570 53.3
condition n/a
subroutine n/a
pod n/a
total 733 1128 64.9


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