libsheepy

C lib for handling text files, strings and json like data structure with an object oriented system
git clone https://spartatek.se/git/libsheepy.git
Log | Files | Refs | README | LICENSE

ymlParser.c (45039B)


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