Ruby  2.0.0p481(2014-05-08revision45883)
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         parser->state = POP(parser, parser->states);
00763         (void)POP(parser, parser->marks);
00764         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
00765         SKIP_TOKEN(parser);
00766         return 1;
00767     }
00768 
00769     else
00770     {
00771         return yaml_parser_set_parser_error_context(parser,
00772                 "while parsing a block collection", POP(parser, parser->marks),
00773                 "did not find expected '-' indicator", token->start_mark);
00774     }
00775 }
00776 
00777 /*
00778  * Parse the productions:
00779  * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
00780  *                           *********** *
00781  */
00782 
00783 static int
00784 yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
00785         yaml_event_t *event)
00786 {
00787     yaml_token_t *token;
00788 
00789     token = PEEK_TOKEN(parser);
00790     if (!token) return 0;
00791 
00792     if (token->type == YAML_BLOCK_ENTRY_TOKEN)
00793     {
00794         yaml_mark_t mark = token->end_mark;
00795         SKIP_TOKEN(parser);
00796         token = PEEK_TOKEN(parser);
00797         if (!token) return 0;
00798         if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
00799                 token->type != YAML_KEY_TOKEN &&
00800                 token->type != YAML_VALUE_TOKEN &&
00801                 token->type != YAML_BLOCK_END_TOKEN) {
00802             if (!PUSH(parser, parser->states,
00803                         YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
00804                 return 0;
00805             return yaml_parser_parse_node(parser, event, 1, 0);
00806         }
00807         else {
00808             parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
00809             return yaml_parser_process_empty_scalar(parser, event, mark);
00810         }
00811     }
00812 
00813     else
00814     {
00815         parser->state = POP(parser, parser->states);
00816         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
00817         return 1;
00818     }
00819 }
00820 
00821 /*
00822  * Parse the productions:
00823  * block_mapping        ::= BLOCK-MAPPING_START
00824  *                          *******************
00825  *                          ((KEY block_node_or_indentless_sequence?)?
00826  *                            *** *
00827  *                          (VALUE block_node_or_indentless_sequence?)?)*
00828  *
00829  *                          BLOCK-END
00830  *                          *********
00831  */
00832 
00833 static int
00834 yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
00835         yaml_event_t *event, int first)
00836 {
00837     yaml_token_t *token;
00838 
00839     if (first) {
00840         token = PEEK_TOKEN(parser);
00841         if (!PUSH(parser, parser->marks, token->start_mark))
00842             return 0;
00843         SKIP_TOKEN(parser);
00844     }
00845 
00846     token = PEEK_TOKEN(parser);
00847     if (!token) return 0;
00848 
00849     if (token->type == YAML_KEY_TOKEN)
00850     {
00851         yaml_mark_t mark = token->end_mark;
00852         SKIP_TOKEN(parser);
00853         token = PEEK_TOKEN(parser);
00854         if (!token) return 0;
00855         if (token->type != YAML_KEY_TOKEN &&
00856                 token->type != YAML_VALUE_TOKEN &&
00857                 token->type != YAML_BLOCK_END_TOKEN) {
00858             if (!PUSH(parser, parser->states,
00859                         YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
00860                 return 0;
00861             return yaml_parser_parse_node(parser, event, 1, 1);
00862         }
00863         else {
00864             parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
00865             return yaml_parser_process_empty_scalar(parser, event, mark);
00866         }
00867     }
00868 
00869     else if (token->type == YAML_BLOCK_END_TOKEN)
00870     {
00871         parser->state = POP(parser, parser->states);
00872         (void)POP(parser, parser->marks);
00873         MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
00874         SKIP_TOKEN(parser);
00875         return 1;
00876     }
00877 
00878     else
00879     {
00880         return yaml_parser_set_parser_error_context(parser,
00881                 "while parsing a block mapping", POP(parser, parser->marks),
00882                 "did not find expected key", token->start_mark);
00883     }
00884 }
00885 
00886 /*
00887  * Parse the productions:
00888  * block_mapping        ::= BLOCK-MAPPING_START
00889  *
00890  *                          ((KEY block_node_or_indentless_sequence?)?
00891  *
00892  *                          (VALUE block_node_or_indentless_sequence?)?)*
00893  *                           ***** *
00894  *                          BLOCK-END
00895  *
00896  */
00897 
00898 static int
00899 yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
00900         yaml_event_t *event)
00901 {
00902     yaml_token_t *token;
00903 
00904     token = PEEK_TOKEN(parser);
00905     if (!token) return 0;
00906 
00907     if (token->type == YAML_VALUE_TOKEN)
00908     {
00909         yaml_mark_t mark = token->end_mark;
00910         SKIP_TOKEN(parser);
00911         token = PEEK_TOKEN(parser);
00912         if (!token) return 0;
00913         if (token->type != YAML_KEY_TOKEN &&
00914                 token->type != YAML_VALUE_TOKEN &&
00915                 token->type != YAML_BLOCK_END_TOKEN) {
00916             if (!PUSH(parser, parser->states,
00917                         YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
00918                 return 0;
00919             return yaml_parser_parse_node(parser, event, 1, 1);
00920         }
00921         else {
00922             parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
00923             return yaml_parser_process_empty_scalar(parser, event, mark);
00924         }
00925     }
00926 
00927     else
00928     {
00929         parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
00930         return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
00931     }
00932 }
00933 
00934 /*
00935  * Parse the productions:
00936  * flow_sequence        ::= FLOW-SEQUENCE-START
00937  *                          *******************
00938  *                          (flow_sequence_entry FLOW-ENTRY)*
00939  *                           *                   **********
00940  *                          flow_sequence_entry?
00941  *                          *
00942  *                          FLOW-SEQUENCE-END
00943  *                          *****************
00944  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
00945  *                          *
00946  */
00947 
00948 static int
00949 yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
00950         yaml_event_t *event, int first)
00951 {
00952     yaml_token_t *token;
00953 
00954     if (first) {
00955         token = PEEK_TOKEN(parser);
00956         if (!PUSH(parser, parser->marks, token->start_mark))
00957             return 0;
00958         SKIP_TOKEN(parser);
00959     }
00960 
00961     token = PEEK_TOKEN(parser);
00962     if (!token) return 0;
00963 
00964     if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
00965     {
00966         if (!first) {
00967             if (token->type == YAML_FLOW_ENTRY_TOKEN) {
00968                 SKIP_TOKEN(parser);
00969                 token = PEEK_TOKEN(parser);
00970                 if (!token) return 0;
00971             }
00972             else {
00973                 return yaml_parser_set_parser_error_context(parser,
00974                         "while parsing a flow sequence", POP(parser, parser->marks),
00975                         "did not find expected ',' or ']'", token->start_mark);
00976             }
00977         }
00978 
00979         if (token->type == YAML_KEY_TOKEN) {
00980             parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
00981             MAPPING_START_EVENT_INIT(*event, NULL, NULL,
00982                     1, YAML_FLOW_MAPPING_STYLE,
00983                     token->start_mark, token->end_mark);
00984             SKIP_TOKEN(parser);
00985             return 1;
00986         }
00987 
00988         else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
00989             if (!PUSH(parser, parser->states,
00990                         YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
00991                 return 0;
00992             return yaml_parser_parse_node(parser, event, 0, 0);
00993         }
00994     }
00995 
00996     parser->state = POP(parser, parser->states);
00997     (void)POP(parser, parser->marks);
00998     SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
00999     SKIP_TOKEN(parser);
01000     return 1;
01001 }
01002 
01003 /*
01004  * Parse the productions:
01005  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
01006  *                                      *** *
01007  */
01008 
01009 static int
01010 yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
01011         yaml_event_t *event)
01012 {
01013     yaml_token_t *token;
01014 
01015     token = PEEK_TOKEN(parser);
01016     if (!token) return 0;
01017 
01018     if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
01019             && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
01020         if (!PUSH(parser, parser->states,
01021                     YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
01022             return 0;
01023         return yaml_parser_parse_node(parser, event, 0, 0);
01024     }
01025     else {
01026         yaml_mark_t mark = token->end_mark;
01027         SKIP_TOKEN(parser);
01028         parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
01029         return yaml_parser_process_empty_scalar(parser, event, mark);
01030     }
01031 }
01032 
01033 /*
01034  * Parse the productions:
01035  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
01036  *                                                      ***** *
01037  */
01038 
01039 static int
01040 yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
01041         yaml_event_t *event)
01042 {
01043     yaml_token_t *token;
01044 
01045     token = PEEK_TOKEN(parser);
01046     if (!token) return 0;
01047 
01048     if (token->type == YAML_VALUE_TOKEN) {
01049         SKIP_TOKEN(parser);
01050         token = PEEK_TOKEN(parser);
01051         if (!token) return 0;
01052         if (token->type != YAML_FLOW_ENTRY_TOKEN
01053                 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
01054             if (!PUSH(parser, parser->states,
01055                         YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
01056                 return 0;
01057             return yaml_parser_parse_node(parser, event, 0, 0);
01058         }
01059     }
01060     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
01061     return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
01062 }
01063 
01064 /*
01065  * Parse the productions:
01066  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
01067  *                                                                      *
01068  */
01069 
01070 static int
01071 yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
01072         yaml_event_t *event)
01073 {
01074     yaml_token_t *token;
01075 
01076     token = PEEK_TOKEN(parser);
01077     if (!token) return 0;
01078 
01079     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
01080 
01081     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
01082     return 1;
01083 }
01084 
01085 /*
01086  * Parse the productions:
01087  * flow_mapping         ::= FLOW-MAPPING-START
01088  *                          ******************
01089  *                          (flow_mapping_entry FLOW-ENTRY)*
01090  *                           *                  **********
01091  *                          flow_mapping_entry?
01092  *                          ******************
01093  *                          FLOW-MAPPING-END
01094  *                          ****************
01095  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
01096  *                          *           *** *
01097  */
01098 
01099 static int
01100 yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
01101         yaml_event_t *event, int first)
01102 {
01103     yaml_token_t *token;
01104 
01105     if (first) {
01106         token = PEEK_TOKEN(parser);
01107         if (!PUSH(parser, parser->marks, token->start_mark))
01108             return 0;
01109         SKIP_TOKEN(parser);
01110     }
01111 
01112     token = PEEK_TOKEN(parser);
01113     if (!token) return 0;
01114 
01115     if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
01116     {
01117         if (!first) {
01118             if (token->type == YAML_FLOW_ENTRY_TOKEN) {
01119                 SKIP_TOKEN(parser);
01120                 token = PEEK_TOKEN(parser);
01121                 if (!token) return 0;
01122             }
01123             else {
01124                 return yaml_parser_set_parser_error_context(parser,
01125                         "while parsing a flow mapping", POP(parser, parser->marks),
01126                         "did not find expected ',' or '}'", token->start_mark);
01127             }
01128         }
01129 
01130         if (token->type == YAML_KEY_TOKEN) {
01131             SKIP_TOKEN(parser);
01132             token = PEEK_TOKEN(parser);
01133             if (!token) return 0;
01134             if (token->type != YAML_VALUE_TOKEN
01135                     && token->type != YAML_FLOW_ENTRY_TOKEN
01136                     && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
01137                 if (!PUSH(parser, parser->states,
01138                             YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
01139                     return 0;
01140                 return yaml_parser_parse_node(parser, event, 0, 0);
01141             }
01142             else {
01143                 parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
01144                 return yaml_parser_process_empty_scalar(parser, event,
01145                         token->start_mark);
01146             }
01147         }
01148         else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
01149             if (!PUSH(parser, parser->states,
01150                         YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
01151                 return 0;
01152             return yaml_parser_parse_node(parser, event, 0, 0);
01153         }
01154     }
01155 
01156     parser->state = POP(parser, parser->states);
01157     (void)POP(parser, parser->marks);
01158     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
01159     SKIP_TOKEN(parser);
01160     return 1;
01161 }
01162 
01163 /*
01164  * Parse the productions:
01165  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
01166  *                                   *                  ***** *
01167  */
01168 
01169 static int
01170 yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
01171         yaml_event_t *event, int empty)
01172 {
01173     yaml_token_t *token;
01174 
01175     token = PEEK_TOKEN(parser);
01176     if (!token) return 0;
01177 
01178     if (empty) {
01179         parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
01180         return yaml_parser_process_empty_scalar(parser, event,
01181                 token->start_mark);
01182     }
01183 
01184     if (token->type == YAML_VALUE_TOKEN) {
01185         SKIP_TOKEN(parser);
01186         token = PEEK_TOKEN(parser);
01187         if (!token) return 0;
01188         if (token->type != YAML_FLOW_ENTRY_TOKEN
01189                 && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
01190             if (!PUSH(parser, parser->states,
01191                         YAML_PARSE_FLOW_MAPPING_KEY_STATE))
01192                 return 0;
01193             return yaml_parser_parse_node(parser, event, 0, 0);
01194         }
01195     }
01196 
01197     parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
01198     return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
01199 }
01200 
01201 /*
01202  * Generate an empty scalar event.
01203  */
01204 
01205 static int
01206 yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
01207         yaml_mark_t mark)
01208 {
01209     yaml_char_t *value;
01210 
01211     value = yaml_malloc(1);
01212     if (!value) {
01213         parser->error = YAML_MEMORY_ERROR;
01214         return 0;
01215     }
01216     value[0] = '\0';
01217 
01218     SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
01219             1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
01220 
01221     return 1;
01222 }
01223 
01224 /*
01225  * Parse directives.
01226  */
01227 
01228 static int
01229 yaml_parser_process_directives(yaml_parser_t *parser,
01230         yaml_version_directive_t **version_directive_ref,
01231         yaml_tag_directive_t **tag_directives_start_ref,
01232         yaml_tag_directive_t **tag_directives_end_ref)
01233 {
01234     yaml_tag_directive_t default_tag_directives[] = {
01235         {(yaml_char_t *)"!", (yaml_char_t *)"!"},
01236         {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
01237         {NULL, NULL}
01238     };
01239     yaml_tag_directive_t *default_tag_directive;
01240     yaml_version_directive_t *version_directive = NULL;
01241     struct {
01242         yaml_tag_directive_t *start;
01243         yaml_tag_directive_t *end;
01244         yaml_tag_directive_t *top;
01245     } tag_directives = { NULL, NULL, NULL };
01246     yaml_token_t *token;
01247 
01248     if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
01249         goto error;
01250 
01251     token = PEEK_TOKEN(parser);
01252     if (!token) goto error;
01253 
01254     while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
01255             token->type == YAML_TAG_DIRECTIVE_TOKEN)
01256     {
01257         if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
01258             if (version_directive) {
01259                 yaml_parser_set_parser_error(parser,
01260                         "found duplicate %YAML directive", token->start_mark);
01261                 goto error;
01262             }
01263             if (token->data.version_directive.major != 1
01264                     || token->data.version_directive.minor != 1) {
01265                 yaml_parser_set_parser_error(parser,
01266                         "found incompatible YAML document", token->start_mark);
01267                 goto error;
01268             }
01269             version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
01270             if (!version_directive) {
01271                 parser->error = YAML_MEMORY_ERROR;
01272                 goto error;
01273             }
01274             version_directive->major = token->data.version_directive.major;
01275             version_directive->minor = token->data.version_directive.minor;
01276         }
01277 
01278         else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
01279             yaml_tag_directive_t value;
01280             value.handle = token->data.tag_directive.handle;
01281             value.prefix = token->data.tag_directive.prefix;
01282 
01283             if (!yaml_parser_append_tag_directive(parser, value, 0,
01284                         token->start_mark))
01285                 goto error;
01286             if (!PUSH(parser, tag_directives, value))
01287                 goto error;
01288         }
01289 
01290         SKIP_TOKEN(parser);
01291         token = PEEK_TOKEN(parser);
01292         if (!token) goto error;
01293     }
01294 
01295     for (default_tag_directive = default_tag_directives;
01296             default_tag_directive->handle; default_tag_directive++) {
01297         if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
01298                     token->start_mark))
01299             goto error;
01300     }
01301 
01302     if (version_directive_ref) {
01303         *version_directive_ref = version_directive;
01304     }
01305     if (tag_directives_start_ref) {
01306         if (STACK_EMPTY(parser, tag_directives)) {
01307             *tag_directives_start_ref = *tag_directives_end_ref = NULL;
01308             STACK_DEL(parser, tag_directives);
01309         }
01310         else {
01311             *tag_directives_start_ref = tag_directives.start;
01312             *tag_directives_end_ref = tag_directives.top;
01313         }
01314     }
01315     else {
01316         STACK_DEL(parser, tag_directives);
01317     }
01318 
01319     return 1;
01320 
01321 error:
01322     yaml_free(version_directive);
01323     while (!STACK_EMPTY(parser, tag_directives)) {
01324         yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
01325         yaml_free(tag_directive.handle);
01326         yaml_free(tag_directive.prefix);
01327     }
01328     STACK_DEL(parser, tag_directives);
01329     return 0;
01330 }
01331 
01332 /*
01333  * Append a tag directive to the directives stack.
01334  */
01335 
01336 static int
01337 yaml_parser_append_tag_directive(yaml_parser_t *parser,
01338         yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
01339 {
01340     yaml_tag_directive_t *tag_directive;
01341     yaml_tag_directive_t copy = { NULL, NULL };
01342 
01343     for (tag_directive = parser->tag_directives.start;
01344             tag_directive != parser->tag_directives.top; tag_directive ++) {
01345         if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
01346             if (allow_duplicates)
01347                 return 1;
01348             return yaml_parser_set_parser_error(parser,
01349                     "found duplicate %TAG directive", mark);
01350         }
01351     }
01352 
01353     copy.handle = yaml_strdup(value.handle);
01354     copy.prefix = yaml_strdup(value.prefix);
01355     if (!copy.handle || !copy.prefix) {
01356         parser->error = YAML_MEMORY_ERROR;
01357         goto error;
01358     }
01359 
01360     if (!PUSH(parser, parser->tag_directives, copy))
01361         goto error;
01362 
01363     return 1;
01364 
01365 error:
01366     yaml_free(copy.handle);
01367     yaml_free(copy.prefix);
01368     return 0;
01369 }
01370 
01371