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) *version_directive_ref = version_directive;
    1306:     if (tag_directives_start_ref) {
    1307:         if (STACK_EMPTY(parser, tag_directives)) {
    1308:             *tag_directives_start_ref = *tag_directives_end_ref = NULL;
    1309:             STACK_DEL(parser, tag_directives);
    1310:         }
    1311:         else {
    1312:             *tag_directives_start_ref = tag_directives.start;
    1313:             *tag_directives_end_ref = tag_directives.top;
    1314:         }
    1315:     }
    1316:     else {
    1317:         STACK_DEL(parser, tag_directives);
    1318:     }

    1320:     if (!version_directive_ref)
    1321:         yaml_free(version_directive);
    1322:     return 1;

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

    1335: /*
    1336:  * Append a tag directive to the directives stack.
    1337:  */

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

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

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

    1363:     if (!PUSH(parser, parser->tag_directives, copy))
    1364:         goto error;

    1366:     return 1;

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