Ruby
2.0.0p247(2013-06-27revision41674)
|
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