Actual source code: parser.c


  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:  */

 42: #include "yaml_private.h"

 44: /*
 45:  * Peek the next token in the token queue.
 46:  */

 48: #define PEEK_TOKEN(parser)                                                      \
 49:     ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ?       \
 50:         parser->tokens.head : NULL)

 52: /*
 53:  * Remove the next token from the queue (must be called after PEEK_TOKEN).
 54:  */

 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 ++)

 63: /*
 64:  * Public API declarations.
 65:  */

 67: YAML_DECLARE(int)
 68: yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);

 70: /*
 71:  * Error handling.
 72:  */

 74: static int
 75: yaml_parser_set_parser_error(yaml_parser_t *parser,
 76:         const char *problem, yaml_mark_t problem_mark);

 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);

 83: /*
 84:  * State functions.
 85:  */

 87: static int
 88: yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);

 90: static int
 91: yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);

 93: static int
 94: yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
 95:         int implicit);

 97: static int
 98: yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);

100: static int
101: yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);

103: static int
104: yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
105:         int block, int indentless_sequence);

107: static int
108: yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
109:         yaml_event_t *event, int first);

111: static int
112: yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
113:         yaml_event_t *event);

115: static int
116: yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
117:         yaml_event_t *event, int first);

119: static int
120: yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
121:         yaml_event_t *event);

123: static int
124: yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
125:         yaml_event_t *event, int first);

127: static int
128: yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
129:         yaml_event_t *event);

131: static int
132: yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
133:         yaml_event_t *event);

135: static int
136: yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
137:         yaml_event_t *event);

139: static int
140: yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
141:         yaml_event_t *event, int first);

143: static int
144: yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
145:         yaml_event_t *event, int empty);

147: /*
148:  * Utility functions.
149:  */

151: static int
152: yaml_parser_process_empty_scalar(yaml_parser_t *parser,
153:         yaml_event_t *event, yaml_mark_t mark);

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);

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);

165: /*
166:  * Get the next event.
167:  */

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. */

175:     /* Erase the event object. */

177:     memset(event, 0, sizeof(yaml_event_t));

179:     /* No events after the end of the stream or error. */

181:     if (parser->stream_end_produced || parser->error ||
182:             parser->state == YAML_PARSE_END_STATE) {
183:         return 1;
184:     }

186:     /* Generate the next event. */

188:     return yaml_parser_state_machine(parser, event);
189: }

191: /*
192:  * Set parser error.
193:  */

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;

203:     return 0;
204: }

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;

217:     return 0;
218: }


221: /*
222:  * State dispatcher.
223:  */

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);

233:         case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
234:             return yaml_parser_parse_document_start(parser, event, 1);

236:         case YAML_PARSE_DOCUMENT_START_STATE:
237:             return yaml_parser_parse_document_start(parser, event, 0);

239:         case YAML_PARSE_DOCUMENT_CONTENT_STATE:
240:             return yaml_parser_parse_document_content(parser, event);

242:         case YAML_PARSE_DOCUMENT_END_STATE:
243:             return yaml_parser_parse_document_end(parser, event);

245:         case YAML_PARSE_BLOCK_NODE_STATE:
246:             return yaml_parser_parse_node(parser, event, 1, 0);

248:         case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
249:             return yaml_parser_parse_node(parser, event, 1, 1);

251:         case YAML_PARSE_FLOW_NODE_STATE:
252:             return yaml_parser_parse_node(parser, event, 0, 0);

254:         case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
255:             return yaml_parser_parse_block_sequence_entry(parser, event, 1);

257:         case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
258:             return yaml_parser_parse_block_sequence_entry(parser, event, 0);

260:         case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
261:             return yaml_parser_parse_indentless_sequence_entry(parser, event);

263:         case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
264:             return yaml_parser_parse_block_mapping_key(parser, event, 1);

266:         case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
267:             return yaml_parser_parse_block_mapping_key(parser, event, 0);

269:         case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
270:             return yaml_parser_parse_block_mapping_value(parser, event);

272:         case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
273:             return yaml_parser_parse_flow_sequence_entry(parser, event, 1);

275:         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
276:             return yaml_parser_parse_flow_sequence_entry(parser, event, 0);

278:         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
279:             return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event);

281:         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
282:             return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event);

284:         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
285:             return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event);

287:         case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
288:             return yaml_parser_parse_flow_mapping_key(parser, event, 1);

290:         case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
291:             return yaml_parser_parse_flow_mapping_key(parser, event, 0);

293:         case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
294:             return yaml_parser_parse_flow_mapping_value(parser, event, 0);

296:         case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
297:             return yaml_parser_parse_flow_mapping_value(parser, event, 1);

299:         default:
300:             assert(1);      /* Invalid state. */
301:     }

303:     return 0;
304: }

306: /*
307:  * Parse the production:
308:  * stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
309:  *              ************
310:  */

312: static int
313: yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
314: {
315:     yaml_token_t *token;

317:     token = PEEK_TOKEN(parser);
318:     if (!token) return 0;

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:     }

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);

330:     return 1;
331: }

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:  */

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 };

352:     token = PEEK_TOKEN(parser);
353:     if (!token) return 0;

355:     /* Parse extra document end indicators. */

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:     }

366:     /* Parse an implicit document. */

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:     }

383:     /* Parse an explicit document. */

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:     }

412:     /* Parse the stream end. */

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:     }

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: }

433: /*
434:  * Parse the productions:
435:  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
436:  *                                                    ***********
437:  */

439: static int
440: yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
441: {
442:     yaml_token_t *token;

444:     token = PEEK_TOKEN(parser);
445:     if (!token) return 0;

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: }

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:  */

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;

476:     token = PEEK_TOKEN(parser);
477:     if (!token) return 0;

479:     start_mark = end_mark = token->start_mark;

481:     if (token->type == YAML_DOCUMENT_END_TOKEN) {
482:         end_mark = token->end_mark;
483:         SKIP_TOKEN(parser);
484:         implicit = 0;
485:     }

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:     }

493:     parser->state = YAML_PARSE_DOCUMENT_START_STATE;
494:     DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);

496:     return 1;
497: }

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:  */

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;

540:     token = PEEK_TOKEN(parser);
541:     if (!token) return 0;

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:     }

552:     else
553:     {
554:         start_mark = end_mark = token->start_mark;

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:         }

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:         }

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:     }

710: error:
711:     yaml_free(anchor);
712:     yaml_free(tag_handle);
713:     yaml_free(tag_suffix);
714:     yaml_free(tag);

716:     return 0;
717: }

719: /*
720:  * Parse the productions:
721:  * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
722:  *                    ********************  *********** *             *********
723:  */

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;

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:     }

738:     token = PEEK_TOKEN(parser);
739:     if (!token) return 0;

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:     }

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:     }

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: }

777: /*
778:  * Parse the productions:
779:  * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
780:  *                           *********** *
781:  */

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;

789:     token = PEEK_TOKEN(parser);
790:     if (!token) return 0;

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:     }

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: }

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:  */

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;

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:     }

846:     token = PEEK_TOKEN(parser);
847:     if (!token) return 0;

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:     }

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:     }

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: }

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:  */

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;

904:     token = PEEK_TOKEN(parser);
905:     if (!token) return 0;

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:     }

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: }

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:  */

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;

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:     }

961:     token = PEEK_TOKEN(parser);
962:     if (!token) return 0;

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:         }

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:         }

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:     }

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: }

1003: /*
1004:  * Parse the productions:
1005:  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1006:  *                                      *** *
1007:  */

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;

1015:     token = PEEK_TOKEN(parser);
1016:     if (!token) return 0;

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: }

1033: /*
1034:  * Parse the productions:
1035:  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1036:  *                                                      ***** *
1037:  */

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;

1045:     token = PEEK_TOKEN(parser);
1046:     if (!token) return 0;

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: }

1064: /*
1065:  * Parse the productions:
1066:  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1067:  *                                                                      *
1068:  */

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;

1076:     token = PEEK_TOKEN(parser);
1077:     if (!token) return 0;

1079:     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;

1081:     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
1082:     return 1;
1083: }

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:  */

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;

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:     }

1112:     token = PEEK_TOKEN(parser);
1113:     if (!token) return 0;

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:         }

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:     }

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: }

1163: /*
1164:  * Parse the productions:
1165:  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1166:  *                                   *                  ***** *
1167:  */

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;

1175:     token = PEEK_TOKEN(parser);
1176:     if (!token) return 0;

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:     }

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:     }

1197:     parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1198:     return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1199: }

1201: /*
1202:  * Generate an empty scalar event.
1203:  */

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;

1211:     value = YAML_MALLOC(1);
1212:     if (!value) {
1213:         parser->error = YAML_MEMORY_ERROR;
1214:         return 0;
1215:     }
1216:     value[0] = '\0';

1218:     SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
1219:             1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);

1221:     return 1;
1222: }

1224: /*
1225:  * Parse directives.
1226:  */

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;

1248:     if (!STACK_INIT(parser, tag_directives, yaml_tag_directive_t*))
1249:         goto error;

1251:     token = PEEK_TOKEN(parser);
1252:     if (!token) goto error;

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:                     || (
1265:                         token->data.version_directive.minor != 1
1266:                         && token->data.version_directive.minor != 2
1267:                     )) {
1268:                 yaml_parser_set_parser_error(parser,
1269:                         "found incompatible YAML document", token->start_mark);
1270:                 goto error;
1271:             }
1272:             version_directive = YAML_MALLOC_STATIC(yaml_version_directive_t);
1273:             if (!version_directive) {
1274:                 parser->error = YAML_MEMORY_ERROR;
1275:                 goto error;
1276:             }
1277:             version_directive->major = token->data.version_directive.major;
1278:             version_directive->minor = token->data.version_directive.minor;
1279:         }

1281:         else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1282:             yaml_tag_directive_t value;
1283:             value.handle = token->data.tag_directive.handle;
1284:             value.prefix = token->data.tag_directive.prefix;

1286:             if (!yaml_parser_append_tag_directive(parser, value, 0,
1287:                         token->start_mark))
1288:                 goto error;
1289:             if (!PUSH(parser, tag_directives, value))
1290:                 goto error;
1291:         }

1293:         SKIP_TOKEN(parser);
1294:         token = PEEK_TOKEN(parser);
1295:         if (!token) goto error;
1296:     }

1298:     for (default_tag_directive = default_tag_directives;
1299:             default_tag_directive->handle; default_tag_directive++) {
1300:         if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
1301:                     token->start_mark))
1302:             goto error;
1303:     }

1305:     if (version_directive_ref) {
1306:         *version_directive_ref = version_directive;
1307:     }
1308:     if (tag_directives_start_ref) {
1309:         if (STACK_EMPTY(parser, tag_directives)) {
1310:             *tag_directives_start_ref = *tag_directives_end_ref = NULL;
1311:             STACK_DEL(parser, tag_directives);
1312:         }
1313:         else {
1314:             *tag_directives_start_ref = tag_directives.start;
1315:             *tag_directives_end_ref = tag_directives.top;
1316:         }
1317:     }
1318:     else {
1319:         STACK_DEL(parser, tag_directives);
1320:     }

1322:     if (!version_directive_ref)
1323:         yaml_free(version_directive);
1324:     return 1;

1326: error:
1327:     yaml_free(version_directive);
1328:     while (!STACK_EMPTY(parser, tag_directives)) {
1329:         yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
1330:         yaml_free(tag_directive.handle);
1331:         yaml_free(tag_directive.prefix);
1332:     }
1333:     STACK_DEL(parser, tag_directives);
1334:     return 0;
1335: }

1337: /*
1338:  * Append a tag directive to the directives stack.
1339:  */

1341: static int
1342: yaml_parser_append_tag_directive(yaml_parser_t *parser,
1343:         yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
1344: {
1345:     yaml_tag_directive_t *tag_directive;
1346:     yaml_tag_directive_t copy = { NULL, NULL };

1348:     for (tag_directive = parser->tag_directives.start;
1349:             tag_directive != parser->tag_directives.top; tag_directive ++) {
1350:         if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
1351:             if (allow_duplicates)
1352:                 return 1;
1353:             return yaml_parser_set_parser_error(parser,
1354:                     "found duplicate %TAG directive", mark);
1355:         }
1356:     }

1358:     copy.handle = yaml_strdup(value.handle);
1359:     copy.prefix = yaml_strdup(value.prefix);
1360:     if (!copy.handle || !copy.prefix) {
1361:         parser->error = YAML_MEMORY_ERROR;
1362:         goto error;
1363:     }

1365:     if (!PUSH(parser, parser->tag_directives, copy))
1366:         goto error;

1368:     return 1;

1370: error:
1371:     yaml_free(copy.handle);
1372:     yaml_free(copy.prefix);
1373:     return 0;
1374: }