Ruby  2.0.0p247(2013-06-27revision41674)
ext/psych/yaml/parser.c
Go to the documentation of this file.
00001 
00002 /*
00003  * The parser implements the following grammar:
00004  *
00005  * stream               ::= STREAM-START implicit_document? explicit_document* STREAM-END
00006  * implicit_document    ::= block_node DOCUMENT-END*
00007  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
00008  * block_node_or_indentless_sequence    ::=
00009  *                          ALIAS
00010  *                          | properties (block_content | indentless_block_sequence)?
00011  *                          | block_content
00012  *                          | indentless_block_sequence
00013  * block_node           ::= ALIAS
00014  *                          | properties block_content?
00015  *                          | block_content
00016  * flow_node            ::= ALIAS
00017  *                          | properties flow_content?
00018  *                          | flow_content
00019  * properties           ::= TAG ANCHOR? | ANCHOR TAG?
00020  * block_content        ::= block_collection | flow_collection | SCALAR
00021  * flow_content         ::= flow_collection | SCALAR
00022  * block_collection     ::= block_sequence | block_mapping
00023  * flow_collection      ::= flow_sequence | flow_mapping
00024  * block_sequence       ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
00025  * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
00026  * block_mapping        ::= BLOCK-MAPPING_START
00027  *                          ((KEY block_node_or_indentless_sequence?)?
00028  *                          (VALUE block_node_or_indentless_sequence?)?)*
00029  *                          BLOCK-END
00030  * flow_sequence        ::= FLOW-SEQUENCE-START
00031  *                          (flow_sequence_entry FLOW-ENTRY)*
00032  *                          flow_sequence_entry?
00033  *                          FLOW-SEQUENCE-END
00034  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
00035  * flow_mapping         ::= FLOW-MAPPING-START
00036  *                          (flow_mapping_entry FLOW-ENTRY)*
00037  *                          flow_mapping_entry?
00038  *                          FLOW-MAPPING-END
00039  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
00040  */
00041 
00042 #include "yaml_private.h"
00043 
00044 /*
00045  * Peek the next token in the token queue.
00046  */
00047 
00048 #define PEEK_TOKEN(parser)                                                      \
00049     ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ?       \
00050         parser->tokens.head : NULL)
00051 
00052 /*
00053  * Remove the next token from the queue (must be called after PEEK_TOKEN).
00054  */
00055 
00056 #define SKIP_TOKEN(parser)                                                      \
00057     (parser->token_available = 0,                                               \
00058      parser->tokens_parsed ++,                                                  \
00059      parser->stream_end_produced =                                              \
00060         (parser->tokens.head->type == YAML_STREAM_END_TOKEN),                   \
00061      parser->tokens.head ++)
00062 
00063 /*
00064  * Public API declarations.
00065  */
00066 
00067 YAML_DECLARE(int)
00068 yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
00069 
00070 /*
00071  * Error handling.
00072  */
00073 
00074 static int
00075 yaml_parser_set_parser_error(yaml_parser_t *parser,
00076         const char *problem, yaml_mark_t problem_mark);
00077 
00078 static int
00079 yaml_parser_set_parser_error_context(yaml_parser_t *parser,
00080         const char *context, yaml_mark_t context_mark,
00081         const char *problem, yaml_mark_t problem_mark);
00082 
00083 /*
00084  * State functions.
00085  */
00086 
00087 static int
00088 yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
00089 
00090 static int
00091 yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
00092 
00093 static int
00094 yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
00095         int implicit);
00096 
00097 static int
00098 yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
00099 
00100 static int
00101 yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
00102 
00103 static int
00104 yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
00105         int block, int indentless_sequence);
00106 
00107 static int
00108 yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
00109         yaml_event_t *event, int first);
00110 
00111 static int
00112 yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
00113         yaml_event_t *event);
00114 
00115 static int
00116 yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
00117         yaml_event_t *event, int first);
00118 
00119 static int
00120 yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
00121         yaml_event_t *event);
00122 
00123 static int
00124 yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
00125         yaml_event_t *event, int first);
00126 
00127 static int
00128 yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
00129         yaml_event_t *event);
00130 
00131 static int
00132 yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
00133         yaml_event_t *event);
00134 
00135 static int
00136 yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
00137         yaml_event_t *event);
00138 
00139 static int
00140 yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
00141         yaml_event_t *event, int first);
00142 
00143 static int
00144 yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
00145         yaml_event_t *event, int empty);
00146 
00147 /*
00148  * Utility functions.
00149  */
00150 
00151 static int
00152 yaml_parser_process_empty_scalar(yaml_parser_t *parser,
00153         yaml_event_t *event, yaml_mark_t mark);
00154 
00155 static int
00156 yaml_parser_process_directives(yaml_parser_t *parser,
00157         yaml_version_directive_t **version_directive_ref,
00158         yaml_tag_directive_t **tag_directives_start_ref,
00159         yaml_tag_directive_t **tag_directives_end_ref);
00160 
00161 static int
00162 yaml_parser_append_tag_directive(yaml_parser_t *parser,
00163         yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
00164 
00165 /*
00166  * Get the next event.
00167  */
00168 
00169 YAML_DECLARE(int)
00170 yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
00171 {
00172     assert(parser);     /* Non-NULL parser object is expected. */
00173     assert(event);      /* Non-NULL event object is expected. */
00174 
00175     /* Erase the event object. */
00176 
00177     memset(event, 0, sizeof(yaml_event_t));
00178 
00179     /* No events after the end of the stream or error. */
00180 
00181     if (parser->stream_end_produced || parser->error ||
00182             parser->state == YAML_PARSE_END_STATE) {
00183         return 1;
00184     }
00185 
00186     /* Generate the next event. */
00187 
00188     return yaml_parser_state_machine(parser, event);
00189 }
00190 
00191 /*
00192  * Set parser error.
00193  */
00194 
00195 static int
00196 yaml_parser_set_parser_error(yaml_parser_t *parser,
00197         const char *problem, yaml_mark_t problem_mark)
00198 {
00199     parser->error = YAML_PARSER_ERROR;
00200     parser->problem = problem;
00201     parser->problem_mark = problem_mark;
00202 
00203     return 0;
00204 }
00205 
00206 static int
00207 yaml_parser_set_parser_error_context(yaml_parser_t *parser,
00208         const char *context, yaml_mark_t context_mark,
00209         const char *problem, yaml_mark_t problem_mark)
00210 {
00211     parser->error = YAML_PARSER_ERROR;
00212     parser->context = context;
00213     parser->context_mark = context_mark;
00214     parser->problem = problem;
00215     parser->problem_mark = problem_mark;
00216 
00217     return 0;
00218 }
00219 
00220 
00221 /*
00222  * State dispatcher.
00223  */
00224 
00225 static int
00226 yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
00227 {
00228     switch (parser->state)
00229     {
00230         case YAML_PARSE_STREAM_START_STATE:
00231             return yaml_parser_parse_stream_start(parser, event);
00232 
00233         case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
00234             return yaml_parser_parse_document_start(parser, event, 1);
00235 
00236         case YAML_PARSE_DOCUMENT_START_STATE:
00237             return yaml_parser_parse_document_start(parser, event, 0);
00238 
00239         case YAML_PARSE_DOCUMENT_CONTENT_STATE:
00240             return yaml_parser_parse_document_content(parser, event);
00241 
00242         case YAML_PARSE_DOCUMENT_END_STATE:
00243             return yaml_parser_parse_document_end(parser, event);
00244 
00245         case YAML_PARSE_BLOCK_NODE_STATE:
00246             return yaml_parser_parse_node(parser, event, 1, 0);
00247 
00248         case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
00249             return yaml_parser_parse_node(parser, event, 1, 1);
00250 
00251         case YAML_PARSE_FLOW_NODE_STATE:
00252             return yaml_parser_parse_node(parser, event, 0, 0);
00253 
00254         case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
00255             return yaml_parser_parse_block_sequence_entry(parser, event, 1);
00256 
00257         case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
00258             return yaml_parser_parse_block_sequence_entry(parser, event, 0);
00259 
00260         case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
00261             return yaml_parser_parse_indentless_sequence_entry(parser, event);
00262 
00263         case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
00264             return yaml_parser_parse_block_mapping_key(parser, event, 1);
00265 
00266         case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
00267             return yaml_parser_parse_block_mapping_key(parser, event, 0);
00268 
00269         case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
00270             return yaml_parser_parse_block_mapping_value(parser, event);
00271 
00272         case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
00273             return yaml_parser_parse_flow_sequence_entry(parser, event, 1);
00274 
00275         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
00276             return yaml_parser_parse_flow_sequence_entry(parser, event, 0);
00277 
00278         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
00279             return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event);
00280 
00281         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
00282             return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event);
00283 
00284         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
00285             return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event);
00286 
00287         case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
00288             return yaml_parser_parse_flow_mapping_key(parser, event, 1);
00289 
00290         case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
00291             return yaml_parser_parse_flow_mapping_key(parser, event, 0);
00292 
00293         case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
00294             return yaml_parser_parse_flow_mapping_value(parser, event, 0);
00295 
00296         case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
00297             return yaml_parser_parse_flow_mapping_value(parser, event, 1);
00298 
00299         default:
00300             assert(1);      /* Invalid state. */
00301     }
00302 
00303     return 0;
00304 }
00305 
00306 /*
00307  * Parse the production:
00308  * stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
00309  *              ************
00310  */
00311 
00312 static int
00313 yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
00314 {
00315     yaml_token_t *token;
00316 
00317     token = PEEK_TOKEN(parser);
00318     if (!token) return 0;
00319 
00320     if (token->type != YAML_STREAM_START_TOKEN) {
00321         return yaml_parser_set_parser_error(parser,
00322                 "did not find expected <stream-start>", token->start_mark);
00323     }
00324 
00325     parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
00326     STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding,
00327             token->start_mark, token->start_mark);
00328     SKIP_TOKEN(parser);
00329 
00330     return 1;
00331 }
00332 
00333 /*
00334  * Parse the productions:
00335  * implicit_document    ::= block_node DOCUMENT-END*
00336  *                          *
00337  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
00338  *                          *************************
00339  */
00340 
00341 static int
00342 yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
00343         int implicit)
00344 {
00345     yaml_token_t *token;
00346     yaml_version_directive_t *version_directive = NULL;
00347     struct {
00348         yaml_tag_directive_t *start;
00349         yaml_tag_directive_t *end;
00350     } tag_directives = { NULL, NULL };
00351 
00352     token = PEEK_TOKEN(parser);
00353     if (!token) return 0;
00354 
00355     /* Parse extra document end indicators. */
00356 
00357     if (!implicit)
00358     {
00359         while (token->type == YAML_DOCUMENT_END_TOKEN) {
00360             SKIP_TOKEN(parser);
00361             token = PEEK_TOKEN(parser);
00362             if (!token) return 0;
00363         }
00364     }
00365 
00366     /* Parse an implicit document. */
00367 
00368     if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
00369             token->type != YAML_TAG_DIRECTIVE_TOKEN &&
00370             token->type != YAML_DOCUMENT_START_TOKEN &&
00371             token->type != YAML_STREAM_END_TOKEN)
00372     {
00373         if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
00374             return 0;
00375         if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
00376             return 0;
00377         parser->state = YAML_PARSE_BLOCK_NODE_STATE;
00378         DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
00379                 token->start_mark, token->start_mark);
00380         return 1;
00381     }
00382 
00383     /* Parse an explicit document. */
00384 
00385     else if (token->type != YAML_STREAM_END_TOKEN)
00386     {
00387         yaml_mark_t start_mark, end_mark;
00388         start_mark = token->start_mark;
00389         if (!yaml_parser_process_directives(parser, &version_directive,
00390                     &tag_directives.start, &tag_directives.end))
00391             return 0;
00392         token = PEEK_TOKEN(parser);
00393         if (!token) goto error;
00394         if (token->type != YAML_DOCUMENT_START_TOKEN) {
00395             yaml_parser_set_parser_error(parser,
00396                     "did not find expected <document start>", token->start_mark);
00397             goto error;
00398         }
00399         if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
00400             goto error;
00401         parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
00402         end_mark = token->end_mark;
00403         DOCUMENT_START_EVENT_INIT(*event, version_directive,
00404                 tag_directives.start, tag_directives.end, 0,
00405                 start_mark, end_mark);
00406         SKIP_TOKEN(parser);
00407         version_directive = NULL;
00408         tag_directives.start = tag_directives.end = NULL;
00409         return 1;
00410     }
00411 
00412     /* Parse the stream end. */
00413 
00414     else
00415     {
00416         parser->state = YAML_PARSE_END_STATE;
00417         STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
00418         SKIP_TOKEN(parser);
00419         return 1;
00420     }
00421 
00422 error:
00423     yaml_free(version_directive);
00424     while (tag_directives.start != tag_directives.end) {
00425         yaml_free(tag_directives.end[-1].handle);
00426         yaml_free(tag_directives.end[-1].prefix);
00427         tag_directives.end --;
00428     }
00429     yaml_free(tag_directives.start);
00430     return 0;
00431 }
00432 
00433 /*
00434  * Parse the productions:
00435  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
00436  *                                                    ***********
00437  */
00438 
00439 static int
00440 yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
00441 {
00442     yaml_token_t *token;
00443 
00444     token = PEEK_TOKEN(parser);
00445     if (!token) return 0;
00446 
00447     if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
00448             token->type == YAML_TAG_DIRECTIVE_TOKEN ||
00449             token->type == YAML_DOCUMENT_START_TOKEN ||
00450             token->type == YAML_DOCUMENT_END_TOKEN ||
00451             token->type == YAML_STREAM_END_TOKEN) {
00452         parser->state = POP(parser, parser->states);
00453         return yaml_parser_process_empty_scalar(parser, event,
00454                 token->start_mark);
00455     }
00456     else {
00457         return yaml_parser_parse_node(parser, event, 1, 0);
00458     }
00459 }
00460 
00461 /*
00462  * Parse the productions:
00463  * implicit_document    ::= block_node DOCUMENT-END*
00464  *                                     *************
00465  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
00466  *                                                                *************
00467  */
00468 
00469 static int
00470 yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
00471 {
00472     yaml_token_t *token;
00473     yaml_mark_t start_mark, end_mark;
00474     int implicit = 1;
00475 
00476     token = PEEK_TOKEN(parser);
00477     if (!token) return 0;
00478 
00479     start_mark = end_mark = token->start_mark;
00480 
00481     if (token->type == YAML_DOCUMENT_END_TOKEN) {
00482         end_mark = token->end_mark;
00483         SKIP_TOKEN(parser);
00484         implicit = 0;
00485     }
00486 
00487     while (!STACK_EMPTY(parser, parser->tag_directives)) {
00488         yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
00489         yaml_free(tag_directive.handle);
00490         yaml_free(tag_directive.prefix);
00491     }
00492 
00493     parser->state = YAML_PARSE_DOCUMENT_START_STATE;
00494     DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
00495 
00496     return 1;
00497 }
00498 
00499 /*
00500  * Parse the productions:
00501  * block_node_or_indentless_sequence    ::=
00502  *                          ALIAS
00503  *                          *****
00504  *                          | properties (block_content | indentless_block_sequence)?
00505  *                            **********  *
00506  *                          | block_content | indentless_block_sequence
00507  *                            *
00508  * block_node           ::= ALIAS
00509  *                          *****
00510  *                          | properties block_content?
00511  *                            ********** *
00512  *                          | block_content
00513  *                            *
00514  * flow_node            ::= ALIAS
00515  *                          *****
00516  *                          | properties flow_content?
00517  *                            ********** *
00518  *                          | flow_content
00519  *                            *
00520  * properties           ::= TAG ANCHOR? | ANCHOR TAG?
00521  *                          *************************
00522  * block_content        ::= block_collection | flow_collection | SCALAR
00523  *                                                               ******
00524  * flow_content         ::= flow_collection | SCALAR
00525  *                                            ******
00526  */
00527 
00528 static int
00529 yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
00530         int block, int indentless_sequence)
00531 {
00532     yaml_token_t *token;
00533     yaml_char_t *anchor = NULL;
00534     yaml_char_t *tag_handle = NULL;
00535     yaml_char_t *tag_suffix = NULL;
00536     yaml_char_t *tag = NULL;
00537     yaml_mark_t start_mark, end_mark, tag_mark;
00538     int implicit;
00539 
00540     token = PEEK_TOKEN(parser);
00541     if (!token) return 0;
00542 
00543     if (token->type == YAML_ALIAS_TOKEN)
00544     {
00545         parser->state = POP(parser, parser->states);
00546         ALIAS_EVENT_INIT(*event, token->data.alias.value,
00547                 token->start_mark, token->end_mark);
00548         SKIP_TOKEN(parser);
00549         return 1;
00550     }
00551 
00552     else
00553     {
00554         start_mark = end_mark = token->start_mark;
00555 
00556         if (token->type == YAML_ANCHOR_TOKEN)
00557         {
00558             anchor = token->data.anchor.value;
00559             start_mark = token->start_mark;
00560             end_mark = token->end_mark;
00561             SKIP_TOKEN(parser);
00562             token = PEEK_TOKEN(parser);
00563             if (!token) goto error;
00564             if (token->type == YAML_TAG_TOKEN)
00565             {
00566                 tag_handle = token->data.tag.handle;
00567                 tag_suffix = token->data.tag.suffix;
00568                 tag_mark = token->start_mark;
00569                 end_mark = token->end_mark;
00570                 SKIP_TOKEN(parser);
00571                 token = PEEK_TOKEN(parser);
00572                 if (!token) goto error;
00573             }
00574         }
00575         else if (token->type == YAML_TAG_TOKEN)
00576         {
00577             tag_handle = token->data.tag.handle;
00578             tag_suffix = token->data.tag.suffix;
00579             start_mark = tag_mark = token->start_mark;
00580             end_mark = token->end_mark;
00581             SKIP_TOKEN(parser);
00582             token = PEEK_TOKEN(parser);
00583             if (!token) goto error;
00584             if (token->type == YAML_ANCHOR_TOKEN)
00585             {
00586                 anchor = token->data.anchor.value;
00587                 end_mark = token->end_mark;
00588                 SKIP_TOKEN(parser);
00589                 token = PEEK_TOKEN(parser);
00590                 if (!token) goto error;
00591             }
00592         }
00593 
00594         if (tag_handle) {
00595             if (!*tag_handle) {
00596                 tag = tag_suffix;
00597                 yaml_free(tag_handle);
00598                 tag_handle = tag_suffix = NULL;
00599             }
00600             else {
00601                 yaml_tag_directive_t *tag_directive;
00602                 for (tag_directive = parser->tag_directives.start;
00603                         tag_directive != parser->tag_directives.top;
00604                         tag_directive ++) {
00605                     if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
00606                         size_t prefix_len = strlen((char *)tag_directive->prefix);
00607                         size_t suffix_len = strlen((char *)tag_suffix);
00608                         tag = yaml_malloc(prefix_len+suffix_len+1);
00609                         if (!tag) {
00610                             parser->error = YAML_MEMORY_ERROR;
00611                             goto error;
00612                         }
00613                         memcpy(tag, tag_directive->prefix, prefix_len);
00614                         memcpy(tag+prefix_len, tag_suffix, suffix_len);
00615                         tag[prefix_len+suffix_len] = '\0';
00616                         yaml_free(tag_handle);
00617                         yaml_free(tag_suffix);
00618                         tag_handle = tag_suffix = NULL;
00619                         break;
00620                     }
00621                 }
00622                 if (!tag) {
00623                     yaml_parser_set_parser_error_context(parser,
00624                             "while parsing a node", start_mark,
00625                             "found undefined tag handle", tag_mark);
00626                     goto error;
00627                 }
00628             }
00629         }
00630 
00631         implicit = (!tag || !*tag);
00632         if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
00633             end_mark = token->end_mark;
00634             parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
00635             SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
00636                     YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
00637             return 1;
00638         }
00639         else {
00640             if (token->type == YAML_SCALAR_TOKEN) {
00641                 int plain_implicit = 0;
00642                 int quoted_implicit = 0;
00643                 end_mark = token->end_mark;
00644                 if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
00645                         || (tag && strcmp((char *)tag, "!") == 0)) {
00646                     plain_implicit = 1;
00647                 }
00648                 else if (!tag) {
00649                     quoted_implicit = 1;
00650                 }
00651                 parser->state = POP(parser, parser->states);
00652                 SCALAR_EVENT_INIT(*event, anchor, tag,
00653                         token->data.scalar.value, token->data.scalar.length,
00654                         plain_implicit, quoted_implicit,
00655                         token->data.scalar.style, start_mark, end_mark);
00656                 SKIP_TOKEN(parser);
00657                 return 1;
00658             }
00659             else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
00660                 end_mark = token->end_mark;
00661                 parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
00662                 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
00663                         YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
00664                 return 1;
00665             }
00666             else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
00667                 end_mark = token->end_mark;
00668                 parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
00669                 MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
00670                         YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
00671                 return 1;
00672             }
00673             else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
00674                 end_mark = token->end_mark;
00675                 parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
00676                 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
00677                         YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
00678                 return 1;
00679             }
00680             else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
00681                 end_mark = token->end_mark;
00682                 parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
00683                 MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
00684                         YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
00685                 return 1;
00686             }
00687             else if (anchor || tag) {
00688                 yaml_char_t *value = yaml_malloc(1);
00689                 if (!value) {
00690                     parser->error = YAML_MEMORY_ERROR;
00691                     goto error;
00692                 }
00693                 value[0] = '\0';
00694                 parser->state = POP(parser, parser->states);
00695                 SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
00696                         implicit, 0, YAML_PLAIN_SCALAR_STYLE,
00697                         start_mark, end_mark);
00698                 return 1;
00699             }
00700             else {
00701                 yaml_parser_set_parser_error_context(parser,
00702                         (block ? "while parsing a block node"
00703                          : "while parsing a flow node"), start_mark,
00704                         "did not find expected node content", token->start_mark);
00705                 goto error;
00706             }
00707         }
00708     }
00709 
00710 error:
00711     yaml_free(anchor);
00712     yaml_free(tag_handle);
00713     yaml_free(tag_suffix);
00714     yaml_free(tag);
00715 
00716     return 0;
00717 }
00718 
00719 /*
00720  * Parse the productions:
00721  * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
00722  *                    ********************  *********** *             *********
00723  */
00724 
00725 static int
00726 yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
00727         yaml_event_t *event, int first)
00728 {
00729     yaml_token_t *token;
00730 
00731     if (first) {
00732         token = PEEK_TOKEN(parser);
00733         if (!PUSH(parser, parser->marks, token->start_mark))
00734             return 0;
00735         SKIP_TOKEN(parser);
00736     }
00737 
00738     token = PEEK_TOKEN(parser);
00739     if (!token) return 0;
00740 
00741     if (token->type == YAML_BLOCK_ENTRY_TOKEN)
00742     {
00743         yaml_mark_t mark = token->end_mark;
00744         SKIP_TOKEN(parser);
00745         token = PEEK_TOKEN(parser);
00746         if (!token) return 0;
00747         if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
00748                 token->type != YAML_BLOCK_END_TOKEN) {
00749             if (!PUSH(parser, parser->states,
00750                         YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
00751                 return 0;
00752             return yaml_parser_parse_node(parser, event, 1, 0);
00753         }
00754         else {
00755             parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
00756             return yaml_parser_process_empty_scalar(parser, event, mark);
00757         }
00758     }
00759 
00760     else if (token->type == YAML_BLOCK_END_TOKEN)
00761     {
00762         yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
00763         parser->state = POP(parser, parser->states);
00764         dummy_mark = POP(parser, parser->marks);
00765         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
00766         SKIP_TOKEN(parser);
00767         return 1;
00768     }
00769 
00770     else
00771     {
00772         return yaml_parser_set_parser_error_context(parser,
00773                 "while parsing a block collection", POP(parser, parser->marks),
00774                 "did not find expected '-' indicator", token->start_mark);
00775     }
00776 }
00777 
00778 /*
00779  * Parse the productions:
00780  * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
00781  *                           *********** *
00782  */
00783 
00784 static int
00785 yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
00786         yaml_event_t *event)
00787 {
00788     yaml_token_t *token;
00789 
00790     token = PEEK_TOKEN(parser);
00791     if (!token) return 0;
00792 
00793     if (token->type == YAML_BLOCK_ENTRY_TOKEN)
00794     {
00795         yaml_mark_t mark = token->end_mark;
00796         SKIP_TOKEN(parser);
00797         token = PEEK_TOKEN(parser);
00798         if (!token) return 0;
00799         if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
00800                 token->type != YAML_KEY_TOKEN &&
00801                 token->type != YAML_VALUE_TOKEN &&
00802                 token->type != YAML_BLOCK_END_TOKEN) {
00803             if (!PUSH(parser, parser->states,
00804                         YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
00805                 return 0;
00806             return yaml_parser_parse_node(parser, event, 1, 0);
00807         }
00808         else {
00809             parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
00810             return yaml_parser_process_empty_scalar(parser, event, mark);
00811         }
00812     }
00813 
00814     else
00815     {
00816         parser->state = POP(parser, parser->states);
00817         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
00818         return 1;
00819     }
00820 }
00821 
00822 /*
00823  * Parse the productions:
00824  * block_mapping        ::= BLOCK-MAPPING_START
00825  *                          *******************
00826  *                          ((KEY block_node_or_indentless_sequence?)?
00827  *                            *** *
00828  *                          (VALUE block_node_or_indentless_sequence?)?)*
00829  *
00830  *                          BLOCK-END
00831  *                          *********
00832  */
00833 
00834 static int
00835 yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
00836         yaml_event_t *event, int first)
00837 {
00838     yaml_token_t *token;
00839 
00840     if (first) {
00841         token = PEEK_TOKEN(parser);
00842         if (!PUSH(parser, parser->marks, token->start_mark))
00843             return 0;
00844         SKIP_TOKEN(parser);
00845     }
00846 
00847     token = PEEK_TOKEN(parser);
00848     if (!token) return 0;
00849 
00850     if (token->type == YAML_KEY_TOKEN)
00851     {
00852         yaml_mark_t mark = token->end_mark;
00853         SKIP_TOKEN(parser);
00854         token = PEEK_TOKEN(parser);
00855         if (!token) return 0;
00856         if (token->type != YAML_KEY_TOKEN &&
00857                 token->type != YAML_VALUE_TOKEN &&
00858                 token->type != YAML_BLOCK_END_TOKEN) {
00859             if (!PUSH(parser, parser->states,
00860                         YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
00861                 return 0;
00862             return yaml_parser_parse_node(parser, event, 1, 1);
00863         }
00864         else {
00865             parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
00866             return yaml_parser_process_empty_scalar(parser, event, mark);
00867         }
00868     }
00869 
00870     else if (token->type == YAML_BLOCK_END_TOKEN)
00871     {
00872         yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
00873         parser->state = POP(parser, parser->states);
00874         dummy_mark = POP(parser, parser->marks);
00875         MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
00876         SKIP_TOKEN(parser);
00877         return 1;
00878     }
00879 
00880     else
00881     {
00882         return yaml_parser_set_parser_error_context(parser,
00883                 "while parsing a block mapping", POP(parser, parser->marks),
00884                 "did not find expected key", token->start_mark);
00885     }
00886 }
00887 
00888 /*
00889  * Parse the productions:
00890  * block_mapping        ::= BLOCK-MAPPING_START
00891  *
00892  *                          ((KEY block_node_or_indentless_sequence?)?
00893  *
00894  *                          (VALUE block_node_or_indentless_sequence?)?)*
00895  *                           ***** *
00896  *                          BLOCK-END
00897  *
00898  */
00899 
00900 static int
00901 yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
00902         yaml_event_t *event)
00903 {
00904     yaml_token_t *token;
00905 
00906     token = PEEK_TOKEN(parser);
00907     if (!token) return 0;
00908 
00909     if (token->type == YAML_VALUE_TOKEN)
00910     {
00911         yaml_mark_t mark = token->end_mark;
00912         SKIP_TOKEN(parser);
00913         token = PEEK_TOKEN(parser);
00914         if (!token) return 0;
00915         if (token->type != YAML_KEY_TOKEN &&
00916                 token->type != YAML_VALUE_TOKEN &&
00917                 token->type != YAML_BLOCK_END_TOKEN) {
00918             if (!PUSH(parser, parser->states,
00919                         YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
00920                 return 0;
00921             return yaml_parser_parse_node(parser, event, 1, 1);
00922         }
00923         else {
00924             parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
00925             return yaml_parser_process_empty_scalar(parser, event, mark);
00926         }
00927     }
00928 
00929     else
00930     {
00931         parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
00932         return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
00933     }
00934 }
00935 
00936 /*
00937  * Parse the productions:
00938  * flow_sequence        ::= FLOW-SEQUENCE-START
00939  *                          *******************
00940  *                          (flow_sequence_entry FLOW-ENTRY)*
00941  *                           *                   **********
00942  *                          flow_sequence_entry?
00943  *                          *
00944  *                          FLOW-SEQUENCE-END
00945  *                          *****************
00946  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
00947  *                          *
00948  */
00949 
00950 static int
00951 yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
00952         yaml_event_t *event, int first)
00953 {
00954     yaml_token_t *token;
00955     yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
00956 
00957     if (first) {
00958         token = PEEK_TOKEN(parser);
00959         if (!PUSH(parser, parser->marks, token->start_mark))
00960             return 0;
00961         SKIP_TOKEN(parser);
00962     }
00963 
00964     token = PEEK_TOKEN(parser);
00965     if (!token) return 0;
00966 
00967     if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
00968     {
00969         if (!first) {
00970             if (token->type == YAML_FLOW_ENTRY_TOKEN) {
00971                 SKIP_TOKEN(parser);
00972                 token = PEEK_TOKEN(parser);
00973                 if (!token) return 0;
00974             }
00975             else {
00976                 return yaml_parser_set_parser_error_context(parser,
00977                         "while parsing a flow sequence", POP(parser, parser->marks),
00978                         "did not find expected ',' or ']'", token->start_mark);
00979             }
00980         }
00981 
00982         if (token->type == YAML_KEY_TOKEN) {
00983             parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
00984             MAPPING_START_EVENT_INIT(*event, NULL, NULL,
00985                     1, YAML_FLOW_MAPPING_STYLE,
00986                     token->start_mark, token->end_mark);
00987             SKIP_TOKEN(parser);
00988             return 1;
00989         }
00990 
00991         else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
00992             if (!PUSH(parser, parser->states,
00993                         YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
00994                 return 0;
00995             return yaml_parser_parse_node(parser, event, 0, 0);
00996         }
00997     }
00998 
00999     parser->state = POP(parser, parser->states);
01000     dummy_mark = POP(parser, parser->marks);
01001     SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
01002     SKIP_TOKEN(parser);
01003     return 1;
01004 }
01005 
01006 /*
01007  * Parse the productions:
01008  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
01009  *                                      *** *
01010  */
01011 
01012 static int
01013 yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
01014         yaml_event_t *event)
01015 {
01016     yaml_token_t *token;
01017 
01018     token = PEEK_TOKEN(parser);
01019     if (!token) return 0;
01020 
01021     if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
01022             && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
01023         if (!PUSH(parser, parser->states,
01024                     YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
01025             return 0;
01026         return yaml_parser_parse_node(parser, event, 0, 0);
01027     }
01028     else {
01029         yaml_mark_t mark = token->end_mark;
01030         SKIP_TOKEN(parser);
01031         parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
01032         return yaml_parser_process_empty_scalar(parser, event, mark);
01033     }
01034 }
01035 
01036 /*
01037  * Parse the productions:
01038  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
01039  *                                                      ***** *
01040  */
01041 
01042 static int
01043 yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
01044         yaml_event_t *event)
01045 {
01046     yaml_token_t *token;
01047 
01048     token = PEEK_TOKEN(parser);
01049     if (!token) return 0;
01050 
01051     if (token->type == YAML_VALUE_TOKEN) {
01052         SKIP_TOKEN(parser);
01053         token = PEEK_TOKEN(parser);
01054         if (!token) return 0;
01055         if (token->type != YAML_FLOW_ENTRY_TOKEN
01056                 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
01057             if (!PUSH(parser, parser->states,
01058                         YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
01059                 return 0;
01060             return yaml_parser_parse_node(parser, event, 0, 0);
01061         }
01062     }
01063     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
01064     return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
01065 }
01066 
01067 /*
01068  * Parse the productions:
01069  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
01070  *                                                                      *
01071  */
01072 
01073 static int
01074 yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
01075         yaml_event_t *event)
01076 {
01077     yaml_token_t *token;
01078 
01079     token = PEEK_TOKEN(parser);
01080     if (!token) return 0;
01081 
01082     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
01083 
01084     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
01085     return 1;
01086 }
01087 
01088 /*
01089  * Parse the productions:
01090  * flow_mapping         ::= FLOW-MAPPING-START
01091  *                          ******************
01092  *                          (flow_mapping_entry FLOW-ENTRY)*
01093  *                           *                  **********
01094  *                          flow_mapping_entry?
01095  *                          ******************
01096  *                          FLOW-MAPPING-END
01097  *                          ****************
01098  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
01099  *                          *           *** *
01100  */
01101 
01102 static int
01103 yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
01104         yaml_event_t *event, int first)
01105 {
01106     yaml_token_t *token;
01107     yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
01108 
01109     if (first) {
01110         token = PEEK_TOKEN(parser);
01111         if (!PUSH(parser, parser->marks, token->start_mark))
01112             return 0;
01113         SKIP_TOKEN(parser);
01114     }
01115 
01116     token = PEEK_TOKEN(parser);
01117     if (!token) return 0;
01118 
01119     if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
01120     {
01121         if (!first) {
01122             if (token->type == YAML_FLOW_ENTRY_TOKEN) {
01123                 SKIP_TOKEN(parser);
01124                 token = PEEK_TOKEN(parser);
01125                 if (!token) return 0;
01126             }
01127             else {
01128                 return yaml_parser_set_parser_error_context(parser,
01129                         "while parsing a flow mapping", POP(parser, parser->marks),
01130                         "did not find expected ',' or '}'", token->start_mark);
01131             }
01132         }
01133 
01134         if (token->type == YAML_KEY_TOKEN) {
01135             SKIP_TOKEN(parser);
01136             token = PEEK_TOKEN(parser);
01137             if (!token) return 0;
01138             if (token->type != YAML_VALUE_TOKEN
01139                     && token->type != YAML_FLOW_ENTRY_TOKEN
01140                     && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
01141                 if (!PUSH(parser, parser->states,
01142                             YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
01143                     return 0;
01144                 return yaml_parser_parse_node(parser, event, 0, 0);
01145             }
01146             else {
01147                 parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
01148                 return yaml_parser_process_empty_scalar(parser, event,
01149                         token->start_mark);
01150             }
01151         }
01152         else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
01153             if (!PUSH(parser, parser->states,
01154                         YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
01155                 return 0;
01156             return yaml_parser_parse_node(parser, event, 0, 0);
01157         }
01158     }
01159 
01160     parser->state = POP(parser, parser->states);
01161     dummy_mark = POP(parser, parser->marks);
01162     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
01163     SKIP_TOKEN(parser);
01164     return 1;
01165 }
01166 
01167 /*
01168  * Parse the productions:
01169  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
01170  *                                   *                  ***** *
01171  */
01172 
01173 static int
01174 yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
01175         yaml_event_t *event, int empty)
01176 {
01177     yaml_token_t *token;
01178 
01179     token = PEEK_TOKEN(parser);
01180     if (!token) return 0;
01181 
01182     if (empty) {
01183         parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
01184         return yaml_parser_process_empty_scalar(parser, event,
01185                 token->start_mark);
01186     }
01187 
01188     if (token->type == YAML_VALUE_TOKEN) {
01189         SKIP_TOKEN(parser);
01190         token = PEEK_TOKEN(parser);
01191         if (!token) return 0;
01192         if (token->type != YAML_FLOW_ENTRY_TOKEN
01193                 && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
01194             if (!PUSH(parser, parser->states,
01195                         YAML_PARSE_FLOW_MAPPING_KEY_STATE))
01196                 return 0;
01197             return yaml_parser_parse_node(parser, event, 0, 0);
01198         }
01199     }
01200 
01201     parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
01202     return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
01203 }
01204 
01205 /*
01206  * Generate an empty scalar event.
01207  */
01208 
01209 static int
01210 yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
01211         yaml_mark_t mark)
01212 {
01213     yaml_char_t *value;
01214 
01215     value = yaml_malloc(1);
01216     if (!value) {
01217         parser->error = YAML_MEMORY_ERROR;
01218         return 0;
01219     }
01220     value[0] = '\0';
01221 
01222     SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
01223             1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
01224 
01225     return 1;
01226 }
01227 
01228 /*
01229  * Parse directives.
01230  */
01231 
01232 static int
01233 yaml_parser_process_directives(yaml_parser_t *parser,
01234         yaml_version_directive_t **version_directive_ref,
01235         yaml_tag_directive_t **tag_directives_start_ref,
01236         yaml_tag_directive_t **tag_directives_end_ref)
01237 {
01238     yaml_tag_directive_t default_tag_directives[] = {
01239         {(yaml_char_t *)"!", (yaml_char_t *)"!"},
01240         {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
01241         {NULL, NULL}
01242     };
01243     yaml_tag_directive_t *default_tag_directive;
01244     yaml_version_directive_t *version_directive = NULL;
01245     struct {
01246         yaml_tag_directive_t *start;
01247         yaml_tag_directive_t *end;
01248         yaml_tag_directive_t *top;
01249     } tag_directives = { NULL, NULL, NULL };
01250     yaml_token_t *token;
01251 
01252     if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
01253         goto error;
01254 
01255     token = PEEK_TOKEN(parser);
01256     if (!token) goto error;
01257 
01258     while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
01259             token->type == YAML_TAG_DIRECTIVE_TOKEN)
01260     {
01261         if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
01262             if (version_directive) {
01263                 yaml_parser_set_parser_error(parser,
01264                         "found duplicate %YAML directive", token->start_mark);
01265                 goto error;
01266             }
01267             if (token->data.version_directive.major != 1
01268                     || token->data.version_directive.minor != 1) {
01269                 yaml_parser_set_parser_error(parser,
01270                         "found incompatible YAML document", token->start_mark);
01271                 goto error;
01272             }
01273             version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
01274             if (!version_directive) {
01275                 parser->error = YAML_MEMORY_ERROR;
01276                 goto error;
01277             }
01278             version_directive->major = token->data.version_directive.major;
01279             version_directive->minor = token->data.version_directive.minor;
01280         }
01281 
01282         else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
01283             yaml_tag_directive_t value;
01284             value.handle = token->data.tag_directive.handle;
01285             value.prefix = token->data.tag_directive.prefix;
01286 
01287             if (!yaml_parser_append_tag_directive(parser, value, 0,
01288                         token->start_mark))
01289                 goto error;
01290             if (!PUSH(parser, tag_directives, value))
01291                 goto error;
01292         }
01293 
01294         SKIP_TOKEN(parser);
01295         token = PEEK_TOKEN(parser);
01296         if (!token) goto error;
01297     }
01298 
01299     for (default_tag_directive = default_tag_directives;
01300             default_tag_directive->handle; default_tag_directive++) {
01301         if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
01302                     token->start_mark))
01303             goto error;
01304     }
01305 
01306     if (version_directive_ref) {
01307         *version_directive_ref = version_directive;
01308     }
01309     if (tag_directives_start_ref) {
01310         if (STACK_EMPTY(parser, tag_directives)) {
01311             *tag_directives_start_ref = *tag_directives_end_ref = NULL;
01312             STACK_DEL(parser, tag_directives);
01313         }
01314         else {
01315             *tag_directives_start_ref = tag_directives.start;
01316             *tag_directives_end_ref = tag_directives.top;
01317         }
01318     }
01319     else {
01320         STACK_DEL(parser, tag_directives);
01321     }
01322 
01323     return 1;
01324 
01325 error:
01326     yaml_free(version_directive);
01327     while (!STACK_EMPTY(parser, tag_directives)) {
01328         yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
01329         yaml_free(tag_directive.handle);
01330         yaml_free(tag_directive.prefix);
01331     }
01332     STACK_DEL(parser, tag_directives);
01333     return 0;
01334 }
01335 
01336 /*
01337  * Append a tag directive to the directives stack.
01338  */
01339 
01340 static int
01341 yaml_parser_append_tag_directive(yaml_parser_t *parser,
01342         yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
01343 {
01344     yaml_tag_directive_t *tag_directive;
01345     yaml_tag_directive_t copy = { NULL, NULL };
01346 
01347     for (tag_directive = parser->tag_directives.start;
01348             tag_directive != parser->tag_directives.top; tag_directive ++) {
01349         if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
01350             if (allow_duplicates)
01351                 return 1;
01352             return yaml_parser_set_parser_error(parser,
01353                     "found duplicate %TAG directive", mark);
01354         }
01355     }
01356 
01357     copy.handle = yaml_strdup(value.handle);
01358     copy.prefix = yaml_strdup(value.prefix);
01359     if (!copy.handle || !copy.prefix) {
01360         parser->error = YAML_MEMORY_ERROR;
01361         goto error;
01362     }
01363 
01364     if (!PUSH(parser, parser->tag_directives, copy))
01365         goto error;
01366 
01367     return 1;
01368 
01369 error:
01370     yaml_free(copy.handle);
01371     yaml_free(copy.prefix);
01372     return 0;
01373 }
01374 
01375