1221420Sdes 2146998Sdes/* 3146998Sdes * The parser implements the following grammar: 4146998Sdes * 5146998Sdes * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END 6146998Sdes * implicit_document ::= block_node DOCUMENT-END* 7146998Sdes * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 8146998Sdes * block_node_or_indentless_sequence ::= 9146998Sdes * ALIAS 10146998Sdes * | properties (block_content | indentless_block_sequence)? 11146998Sdes * | block_content 12146998Sdes * | indentless_block_sequence 13146998Sdes * block_node ::= ALIAS 14146998Sdes * | properties block_content? 15146998Sdes * | block_content 16146998Sdes * flow_node ::= ALIAS 17146998Sdes * | properties flow_content? 18146998Sdes * | flow_content 19146998Sdes * properties ::= TAG ANCHOR? | ANCHOR TAG? 20146998Sdes * block_content ::= block_collection | flow_collection | SCALAR 21146998Sdes * flow_content ::= flow_collection | SCALAR 22146998Sdes * block_collection ::= block_sequence | block_mapping 23146998Sdes * flow_collection ::= flow_sequence | flow_mapping 24146998Sdes * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END 25146998Sdes * indentless_sequence ::= (BLOCK-ENTRY block_node?)+ 26146998Sdes * block_mapping ::= BLOCK-MAPPING_START 27146998Sdes * ((KEY block_node_or_indentless_sequence?)? 28146998Sdes * (VALUE block_node_or_indentless_sequence?)?)* 29221420Sdes * BLOCK-END 30221420Sdes * flow_sequence ::= FLOW-SEQUENCE-START 31221420Sdes * (flow_sequence_entry FLOW-ENTRY)* 32146998Sdes * flow_sequence_entry? 33146998Sdes * FLOW-SEQUENCE-END 34146998Sdes * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 35146998Sdes * flow_mapping ::= FLOW-MAPPING-START 36146998Sdes * (flow_mapping_entry FLOW-ENTRY)* 37146998Sdes * flow_mapping_entry? 38146998Sdes * FLOW-MAPPING-END 39146998Sdes * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 40146998Sdes */ 41146998Sdes 42146998Sdes#include "yaml_private.h" 43146998Sdes 44146998Sdes/* 45146998Sdes * Peek the next token in the token queue. 46146998Sdes */ 47146998Sdes 48146998Sdes#define PEEK_TOKEN(parser) \ 49146998Sdes ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ? \ 50146998Sdes parser->tokens.head : NULL) 51146998Sdes 52221420Sdes/* 53221420Sdes * Remove the next token from the queue (must be called after PEEK_TOKEN). 54146998Sdes */ 55146998Sdes 56146998Sdes#define SKIP_TOKEN(parser) \ 57146998Sdes (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 yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ 763 parser->state = POP(parser, parser->states); 764 dummy_mark = POP(parser, parser->marks); 765 SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); 766 SKIP_TOKEN(parser); 767 return 1; 768 } 769 770 else 771 { 772 return yaml_parser_set_parser_error_context(parser, 773 "while parsing a block collection", POP(parser, parser->marks), 774 "did not find expected '-' indicator", token->start_mark); 775 } 776} 777 778/* 779 * Parse the productions: 780 * indentless_sequence ::= (BLOCK-ENTRY block_node?)+ 781 * *********** * 782 */ 783 784static int 785yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser, 786 yaml_event_t *event) 787{ 788 yaml_token_t *token; 789 790 token = PEEK_TOKEN(parser); 791 if (!token) return 0; 792 793 if (token->type == YAML_BLOCK_ENTRY_TOKEN) 794 { 795 yaml_mark_t mark = token->end_mark; 796 SKIP_TOKEN(parser); 797 token = PEEK_TOKEN(parser); 798 if (!token) return 0; 799 if (token->type != YAML_BLOCK_ENTRY_TOKEN && 800 token->type != YAML_KEY_TOKEN && 801 token->type != YAML_VALUE_TOKEN && 802 token->type != YAML_BLOCK_END_TOKEN) { 803 if (!PUSH(parser, parser->states, 804 YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)) 805 return 0; 806 return yaml_parser_parse_node(parser, event, 1, 0); 807 } 808 else { 809 parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; 810 return yaml_parser_process_empty_scalar(parser, event, mark); 811 } 812 } 813 814 else 815 { 816 parser->state = POP(parser, parser->states); 817 SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark); 818 return 1; 819 } 820} 821 822/* 823 * Parse the productions: 824 * block_mapping ::= BLOCK-MAPPING_START 825 * ******************* 826 * ((KEY block_node_or_indentless_sequence?)? 827 * *** * 828 * (VALUE block_node_or_indentless_sequence?)?)* 829 * 830 * BLOCK-END 831 * ********* 832 */ 833 834static int 835yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, 836 yaml_event_t *event, int first) 837{ 838 yaml_token_t *token; 839 840 if (first) { 841 token = PEEK_TOKEN(parser); 842 if (!PUSH(parser, parser->marks, token->start_mark)) 843 return 0; 844 SKIP_TOKEN(parser); 845 } 846 847 token = PEEK_TOKEN(parser); 848 if (!token) return 0; 849 850 if (token->type == YAML_KEY_TOKEN) 851 { 852 yaml_mark_t mark = token->end_mark; 853 SKIP_TOKEN(parser); 854 token = PEEK_TOKEN(parser); 855 if (!token) return 0; 856 if (token->type != YAML_KEY_TOKEN && 857 token->type != YAML_VALUE_TOKEN && 858 token->type != YAML_BLOCK_END_TOKEN) { 859 if (!PUSH(parser, parser->states, 860 YAML_PARSE_BLOCK_MAPPING_VALUE_STATE)) 861 return 0; 862 return yaml_parser_parse_node(parser, event, 1, 1); 863 } 864 else { 865 parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE; 866 return yaml_parser_process_empty_scalar(parser, event, mark); 867 } 868 } 869 870 else if (token->type == YAML_BLOCK_END_TOKEN) 871 { 872 yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ 873 parser->state = POP(parser, parser->states); 874 dummy_mark = POP(parser, parser->marks); 875 MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); 876 SKIP_TOKEN(parser); 877 return 1; 878 } 879 880 else 881 { 882 return yaml_parser_set_parser_error_context(parser, 883 "while parsing a block mapping", POP(parser, parser->marks), 884 "did not find expected key", token->start_mark); 885 } 886} 887 888/* 889 * Parse the productions: 890 * block_mapping ::= BLOCK-MAPPING_START 891 * 892 * ((KEY block_node_or_indentless_sequence?)? 893 * 894 * (VALUE block_node_or_indentless_sequence?)?)* 895 * ***** * 896 * BLOCK-END 897 * 898 */ 899 900static int 901yaml_parser_parse_block_mapping_value(yaml_parser_t *parser, 902 yaml_event_t *event) 903{ 904 yaml_token_t *token; 905 906 token = PEEK_TOKEN(parser); 907 if (!token) return 0; 908 909 if (token->type == YAML_VALUE_TOKEN) 910 { 911 yaml_mark_t mark = token->end_mark; 912 SKIP_TOKEN(parser); 913 token = PEEK_TOKEN(parser); 914 if (!token) return 0; 915 if (token->type != YAML_KEY_TOKEN && 916 token->type != YAML_VALUE_TOKEN && 917 token->type != YAML_BLOCK_END_TOKEN) { 918 if (!PUSH(parser, parser->states, 919 YAML_PARSE_BLOCK_MAPPING_KEY_STATE)) 920 return 0; 921 return yaml_parser_parse_node(parser, event, 1, 1); 922 } 923 else { 924 parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE; 925 return yaml_parser_process_empty_scalar(parser, event, mark); 926 } 927 } 928 929 else 930 { 931 parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE; 932 return yaml_parser_process_empty_scalar(parser, event, token->start_mark); 933 } 934} 935 936/* 937 * Parse the productions: 938 * flow_sequence ::= FLOW-SEQUENCE-START 939 * ******************* 940 * (flow_sequence_entry FLOW-ENTRY)* 941 * * ********** 942 * flow_sequence_entry? 943 * * 944 * FLOW-SEQUENCE-END 945 * ***************** 946 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 947 * * 948 */ 949 950static int 951yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, 952 yaml_event_t *event, int first) 953{ 954 yaml_token_t *token; 955 yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ 956 957 if (first) { 958 token = PEEK_TOKEN(parser); 959 if (!PUSH(parser, parser->marks, token->start_mark)) 960 return 0; 961 SKIP_TOKEN(parser); 962 } 963 964 token = PEEK_TOKEN(parser); 965 if (!token) return 0; 966 967 if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) 968 { 969 if (!first) { 970 if (token->type == YAML_FLOW_ENTRY_TOKEN) { 971 SKIP_TOKEN(parser); 972 token = PEEK_TOKEN(parser); 973 if (!token) return 0; 974 } 975 else { 976 return yaml_parser_set_parser_error_context(parser, 977 "while parsing a flow sequence", POP(parser, parser->marks), 978 "did not find expected ',' or ']'", token->start_mark); 979 } 980 } 981 982 if (token->type == YAML_KEY_TOKEN) { 983 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE; 984 MAPPING_START_EVENT_INIT(*event, NULL, NULL, 985 1, YAML_FLOW_MAPPING_STYLE, 986 token->start_mark, token->end_mark); 987 SKIP_TOKEN(parser); 988 return 1; 989 } 990 991 else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { 992 if (!PUSH(parser, parser->states, 993 YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE)) 994 return 0; 995 return yaml_parser_parse_node(parser, event, 0, 0); 996 } 997 } 998 999 parser->state = POP(parser, parser->states); 1000 dummy_mark = POP(parser, parser->marks); 1001 SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); 1002 SKIP_TOKEN(parser); 1003 return 1; 1004} 1005 1006/* 1007 * Parse the productions: 1008 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1009 * *** * 1010 */ 1011 1012static int 1013yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser, 1014 yaml_event_t *event) 1015{ 1016 yaml_token_t *token; 1017 1018 token = PEEK_TOKEN(parser); 1019 if (!token) return 0; 1020 1021 if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN 1022 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { 1023 if (!PUSH(parser, parser->states, 1024 YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)) 1025 return 0; 1026 return yaml_parser_parse_node(parser, event, 0, 0); 1027 } 1028 else { 1029 yaml_mark_t mark = token->end_mark; 1030 SKIP_TOKEN(parser); 1031 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE; 1032 return yaml_parser_process_empty_scalar(parser, event, mark); 1033 } 1034} 1035 1036/* 1037 * Parse the productions: 1038 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1039 * ***** * 1040 */ 1041 1042static int 1043yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser, 1044 yaml_event_t *event) 1045{ 1046 yaml_token_t *token; 1047 1048 token = PEEK_TOKEN(parser); 1049 if (!token) return 0; 1050 1051 if (token->type == YAML_VALUE_TOKEN) { 1052 SKIP_TOKEN(parser); 1053 token = PEEK_TOKEN(parser); 1054 if (!token) return 0; 1055 if (token->type != YAML_FLOW_ENTRY_TOKEN 1056 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { 1057 if (!PUSH(parser, parser->states, 1058 YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)) 1059 return 0; 1060 return yaml_parser_parse_node(parser, event, 0, 0); 1061 } 1062 } 1063 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE; 1064 return yaml_parser_process_empty_scalar(parser, event, token->start_mark); 1065} 1066 1067/* 1068 * Parse the productions: 1069 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1070 * * 1071 */ 1072 1073static int 1074yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser, 1075 yaml_event_t *event) 1076{ 1077 yaml_token_t *token; 1078 1079 token = PEEK_TOKEN(parser); 1080 if (!token) return 0; 1081 1082 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE; 1083 1084 MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark); 1085 return 1; 1086} 1087 1088/* 1089 * Parse the productions: 1090 * flow_mapping ::= FLOW-MAPPING-START 1091 * ****************** 1092 * (flow_mapping_entry FLOW-ENTRY)* 1093 * * ********** 1094 * flow_mapping_entry? 1095 * ****************** 1096 * FLOW-MAPPING-END 1097 * **************** 1098 * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1099 * * *** * 1100 */ 1101 1102static int 1103yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, 1104 yaml_event_t *event, int first) 1105{ 1106 yaml_token_t *token; 1107 yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ 1108 1109 if (first) { 1110 token = PEEK_TOKEN(parser); 1111 if (!PUSH(parser, parser->marks, token->start_mark)) 1112 return 0; 1113 SKIP_TOKEN(parser); 1114 } 1115 1116 token = PEEK_TOKEN(parser); 1117 if (!token) return 0; 1118 1119 if (token->type != YAML_FLOW_MAPPING_END_TOKEN) 1120 { 1121 if (!first) { 1122 if (token->type == YAML_FLOW_ENTRY_TOKEN) { 1123 SKIP_TOKEN(parser); 1124 token = PEEK_TOKEN(parser); 1125 if (!token) return 0; 1126 } 1127 else { 1128 return yaml_parser_set_parser_error_context(parser, 1129 "while parsing a flow mapping", POP(parser, parser->marks), 1130 "did not find expected ',' or '}'", token->start_mark); 1131 } 1132 } 1133 1134 if (token->type == YAML_KEY_TOKEN) { 1135 SKIP_TOKEN(parser); 1136 token = PEEK_TOKEN(parser); 1137 if (!token) return 0; 1138 if (token->type != YAML_VALUE_TOKEN 1139 && token->type != YAML_FLOW_ENTRY_TOKEN 1140 && token->type != YAML_FLOW_MAPPING_END_TOKEN) { 1141 if (!PUSH(parser, parser->states, 1142 YAML_PARSE_FLOW_MAPPING_VALUE_STATE)) 1143 return 0; 1144 return yaml_parser_parse_node(parser, event, 0, 0); 1145 } 1146 else { 1147 parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE; 1148 return yaml_parser_process_empty_scalar(parser, event, 1149 token->start_mark); 1150 } 1151 } 1152 else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) { 1153 if (!PUSH(parser, parser->states, 1154 YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)) 1155 return 0; 1156 return yaml_parser_parse_node(parser, event, 0, 0); 1157 } 1158 } 1159 1160 parser->state = POP(parser, parser->states); 1161 dummy_mark = POP(parser, parser->marks); 1162 MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); 1163 SKIP_TOKEN(parser); 1164 return 1; 1165} 1166 1167/* 1168 * Parse the productions: 1169 * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1170 * * ***** * 1171 */ 1172 1173static int 1174yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, 1175 yaml_event_t *event, int empty) 1176{ 1177 yaml_token_t *token; 1178 1179 token = PEEK_TOKEN(parser); 1180 if (!token) return 0; 1181 1182 if (empty) { 1183 parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE; 1184 return yaml_parser_process_empty_scalar(parser, event, 1185 token->start_mark); 1186 } 1187 1188 if (token->type == YAML_VALUE_TOKEN) { 1189 SKIP_TOKEN(parser); 1190 token = PEEK_TOKEN(parser); 1191 if (!token) return 0; 1192 if (token->type != YAML_FLOW_ENTRY_TOKEN 1193 && token->type != YAML_FLOW_MAPPING_END_TOKEN) { 1194 if (!PUSH(parser, parser->states, 1195 YAML_PARSE_FLOW_MAPPING_KEY_STATE)) 1196 return 0; 1197 return yaml_parser_parse_node(parser, event, 0, 0); 1198 } 1199 } 1200 1201 parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE; 1202 return yaml_parser_process_empty_scalar(parser, event, token->start_mark); 1203} 1204 1205/* 1206 * Generate an empty scalar event. 1207 */ 1208 1209static int 1210yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event, 1211 yaml_mark_t mark) 1212{ 1213 yaml_char_t *value; 1214 1215 value = yaml_malloc(1); 1216 if (!value) { 1217 parser->error = YAML_MEMORY_ERROR; 1218 return 0; 1219 } 1220 value[0] = '\0'; 1221 1222 SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0, 1223 1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark); 1224 1225 return 1; 1226} 1227 1228/* 1229 * Parse directives. 1230 */ 1231 1232static int 1233yaml_parser_process_directives(yaml_parser_t *parser, 1234 yaml_version_directive_t **version_directive_ref, 1235 yaml_tag_directive_t **tag_directives_start_ref, 1236 yaml_tag_directive_t **tag_directives_end_ref) 1237{ 1238 yaml_tag_directive_t default_tag_directives[] = { 1239 {(yaml_char_t *)"!", (yaml_char_t *)"!"}, 1240 {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"}, 1241 {NULL, NULL} 1242 }; 1243 yaml_tag_directive_t *default_tag_directive; 1244 yaml_version_directive_t *version_directive = NULL; 1245 struct { 1246 yaml_tag_directive_t *start; 1247 yaml_tag_directive_t *end; 1248 yaml_tag_directive_t *top; 1249 } tag_directives = { NULL, NULL, NULL }; 1250 yaml_token_t *token; 1251 1252 if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE)) 1253 goto error; 1254 1255 token = PEEK_TOKEN(parser); 1256 if (!token) goto error; 1257 1258 while (token->type == YAML_VERSION_DIRECTIVE_TOKEN || 1259 token->type == YAML_TAG_DIRECTIVE_TOKEN) 1260 { 1261 if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) { 1262 if (version_directive) { 1263 yaml_parser_set_parser_error(parser, 1264 "found duplicate %YAML directive", token->start_mark); 1265 goto error; 1266 } 1267 if (token->data.version_directive.major != 1 1268 || token->data.version_directive.minor != 1) { 1269 yaml_parser_set_parser_error(parser, 1270 "found incompatible YAML document", token->start_mark); 1271 goto error; 1272 } 1273 version_directive = yaml_malloc(sizeof(yaml_version_directive_t)); 1274 if (!version_directive) { 1275 parser->error = YAML_MEMORY_ERROR; 1276 goto error; 1277 } 1278 version_directive->major = token->data.version_directive.major; 1279 version_directive->minor = token->data.version_directive.minor; 1280 } 1281 1282 else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) { 1283 yaml_tag_directive_t value; 1284 value.handle = token->data.tag_directive.handle; 1285 value.prefix = token->data.tag_directive.prefix; 1286 1287 if (!yaml_parser_append_tag_directive(parser, value, 0, 1288 token->start_mark)) 1289 goto error; 1290 if (!PUSH(parser, tag_directives, value)) 1291 goto error; 1292 } 1293 1294 SKIP_TOKEN(parser); 1295 token = PEEK_TOKEN(parser); 1296 if (!token) goto error; 1297 } 1298 1299 for (default_tag_directive = default_tag_directives; 1300 default_tag_directive->handle; default_tag_directive++) { 1301 if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1, 1302 token->start_mark)) 1303 goto error; 1304 } 1305 1306 if (version_directive_ref) { 1307 *version_directive_ref = version_directive; 1308 } 1309 if (tag_directives_start_ref) { 1310 if (STACK_EMPTY(parser, tag_directives)) { 1311 *tag_directives_start_ref = *tag_directives_end_ref = NULL; 1312 STACK_DEL(parser, tag_directives); 1313 } 1314 else { 1315 *tag_directives_start_ref = tag_directives.start; 1316 *tag_directives_end_ref = tag_directives.top; 1317 } 1318 } 1319 else { 1320 STACK_DEL(parser, tag_directives); 1321 } 1322 1323 return 1; 1324 1325error: 1326 yaml_free(version_directive); 1327 while (!STACK_EMPTY(parser, tag_directives)) { 1328 yaml_tag_directive_t tag_directive = POP(parser, tag_directives); 1329 yaml_free(tag_directive.handle); 1330 yaml_free(tag_directive.prefix); 1331 } 1332 STACK_DEL(parser, tag_directives); 1333 return 0; 1334} 1335 1336/* 1337 * Append a tag directive to the directives stack. 1338 */ 1339 1340static int 1341yaml_parser_append_tag_directive(yaml_parser_t *parser, 1342 yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark) 1343{ 1344 yaml_tag_directive_t *tag_directive; 1345 yaml_tag_directive_t copy = { NULL, NULL }; 1346 1347 for (tag_directive = parser->tag_directives.start; 1348 tag_directive != parser->tag_directives.top; tag_directive ++) { 1349 if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) { 1350 if (allow_duplicates) 1351 return 1; 1352 return yaml_parser_set_parser_error(parser, 1353 "found duplicate %TAG directive", mark); 1354 } 1355 } 1356 1357 copy.handle = yaml_strdup(value.handle); 1358 copy.prefix = yaml_strdup(value.prefix); 1359 if (!copy.handle || !copy.prefix) { 1360 parser->error = YAML_MEMORY_ERROR; 1361 goto error; 1362 } 1363 1364 if (!PUSH(parser, parser->tag_directives, copy)) 1365 goto error; 1366 1367 return 1; 1368 1369error: 1370 yaml_free(copy.handle); 1371 yaml_free(copy.prefix); 1372 return 0; 1373} 1374 1375