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