1// 2// Copyright (c) 2011-2019 Canonical Ltd 3// Copyright (c) 2006-2010 Kirill Simonov 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy of 6// this software and associated documentation files (the "Software"), to deal in 7// the Software without restriction, including without limitation the rights to 8// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9// of the Software, and to permit persons to whom the Software is furnished to do 10// so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in all 13// copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21// SOFTWARE. 22 23package yaml 24 25import ( 26 "bytes" 27 "fmt" 28) 29 30// Flush the buffer if needed. 31func flush(emitter *yaml_emitter_t) bool { 32 if emitter.buffer_pos+5 >= len(emitter.buffer) { 33 return yaml_emitter_flush(emitter) 34 } 35 return true 36} 37 38// Put a character to the output buffer. 39func put(emitter *yaml_emitter_t, value byte) bool { 40 if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { 41 return false 42 } 43 emitter.buffer[emitter.buffer_pos] = value 44 emitter.buffer_pos++ 45 emitter.column++ 46 return true 47} 48 49// Put a line break to the output buffer. 50func put_break(emitter *yaml_emitter_t) bool { 51 if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { 52 return false 53 } 54 switch emitter.line_break { 55 case yaml_CR_BREAK: 56 emitter.buffer[emitter.buffer_pos] = '\r' 57 emitter.buffer_pos += 1 58 case yaml_LN_BREAK: 59 emitter.buffer[emitter.buffer_pos] = '\n' 60 emitter.buffer_pos += 1 61 case yaml_CRLN_BREAK: 62 emitter.buffer[emitter.buffer_pos+0] = '\r' 63 emitter.buffer[emitter.buffer_pos+1] = '\n' 64 emitter.buffer_pos += 2 65 default: 66 panic("unknown line break setting") 67 } 68 if emitter.column == 0 { 69 emitter.space_above = true 70 } 71 emitter.column = 0 72 emitter.line++ 73 // [Go] Do this here and below and drop from everywhere else (see commented lines). 74 emitter.indention = true 75 return true 76} 77 78// Copy a character from a string into buffer. 79func write(emitter *yaml_emitter_t, s []byte, i *int) bool { 80 if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { 81 return false 82 } 83 p := emitter.buffer_pos 84 w := width(s[*i]) 85 switch w { 86 case 4: 87 emitter.buffer[p+3] = s[*i+3] 88 fallthrough 89 case 3: 90 emitter.buffer[p+2] = s[*i+2] 91 fallthrough 92 case 2: 93 emitter.buffer[p+1] = s[*i+1] 94 fallthrough 95 case 1: 96 emitter.buffer[p+0] = s[*i+0] 97 default: 98 panic("unknown character width") 99 } 100 emitter.column++ 101 emitter.buffer_pos += w 102 *i += w 103 return true 104} 105 106// Write a whole string into buffer. 107func write_all(emitter *yaml_emitter_t, s []byte) bool { 108 for i := 0; i < len(s); { 109 if !write(emitter, s, &i) { 110 return false 111 } 112 } 113 return true 114} 115 116// Copy a line break character from a string into buffer. 117func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool { 118 if s[*i] == '\n' { 119 if !put_break(emitter) { 120 return false 121 } 122 *i++ 123 } else { 124 if !write(emitter, s, i) { 125 return false 126 } 127 if emitter.column == 0 { 128 emitter.space_above = true 129 } 130 emitter.column = 0 131 emitter.line++ 132 // [Go] Do this here and above and drop from everywhere else (see commented lines). 133 emitter.indention = true 134 } 135 return true 136} 137 138// Set an emitter error and return false. 139func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool { 140 emitter.error = yaml_EMITTER_ERROR 141 emitter.problem = problem 142 return false 143} 144 145// Emit an event. 146func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool { 147 emitter.events = append(emitter.events, *event) 148 for !yaml_emitter_need_more_events(emitter) { 149 event := &emitter.events[emitter.events_head] 150 if !yaml_emitter_analyze_event(emitter, event) { 151 return false 152 } 153 if !yaml_emitter_state_machine(emitter, event) { 154 return false 155 } 156 yaml_event_delete(event) 157 emitter.events_head++ 158 } 159 return true 160} 161 162// Check if we need to accumulate more events before emitting. 163// 164// We accumulate extra 165// - 1 event for DOCUMENT-START 166// - 2 events for SEQUENCE-START 167// - 3 events for MAPPING-START 168// 169func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool { 170 if emitter.events_head == len(emitter.events) { 171 return true 172 } 173 var accumulate int 174 switch emitter.events[emitter.events_head].typ { 175 case yaml_DOCUMENT_START_EVENT: 176 accumulate = 1 177 break 178 case yaml_SEQUENCE_START_EVENT: 179 accumulate = 2 180 break 181 case yaml_MAPPING_START_EVENT: 182 accumulate = 3 183 break 184 default: 185 return false 186 } 187 if len(emitter.events)-emitter.events_head > accumulate { 188 return false 189 } 190 var level int 191 for i := emitter.events_head; i < len(emitter.events); i++ { 192 switch emitter.events[i].typ { 193 case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT: 194 level++ 195 case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT: 196 level-- 197 } 198 if level == 0 { 199 return false 200 } 201 } 202 return true 203} 204 205// Append a directive to the directives stack. 206func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool { 207 for i := 0; i < len(emitter.tag_directives); i++ { 208 if bytes.Equal(value.handle, emitter.tag_directives[i].handle) { 209 if allow_duplicates { 210 return true 211 } 212 return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive") 213 } 214 } 215 216 // [Go] Do we actually need to copy this given garbage collection 217 // and the lack of deallocating destructors? 218 tag_copy := yaml_tag_directive_t{ 219 handle: make([]byte, len(value.handle)), 220 prefix: make([]byte, len(value.prefix)), 221 } 222 copy(tag_copy.handle, value.handle) 223 copy(tag_copy.prefix, value.prefix) 224 emitter.tag_directives = append(emitter.tag_directives, tag_copy) 225 return true 226} 227 228// Increase the indentation level. 229func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool { 230 emitter.indents = append(emitter.indents, emitter.indent) 231 if emitter.indent < 0 { 232 if flow { 233 emitter.indent = emitter.best_indent 234 } else { 235 emitter.indent = 0 236 } 237 } else if !indentless { 238 // [Go] This was changed so that indentations are more regular. 239 if emitter.states[len(emitter.states)-1] == yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE { 240 // The first indent inside a sequence will just skip the "- " indicator. 241 emitter.indent += 2 242 } else { 243 // Everything else aligns to the chosen indentation. 244 emitter.indent = emitter.best_indent*((emitter.indent+emitter.best_indent)/emitter.best_indent) 245 } 246 } 247 return true 248} 249 250// State dispatcher. 251func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool { 252 switch emitter.state { 253 default: 254 case yaml_EMIT_STREAM_START_STATE: 255 return yaml_emitter_emit_stream_start(emitter, event) 256 257 case yaml_EMIT_FIRST_DOCUMENT_START_STATE: 258 return yaml_emitter_emit_document_start(emitter, event, true) 259 260 case yaml_EMIT_DOCUMENT_START_STATE: 261 return yaml_emitter_emit_document_start(emitter, event, false) 262 263 case yaml_EMIT_DOCUMENT_CONTENT_STATE: 264 return yaml_emitter_emit_document_content(emitter, event) 265 266 case yaml_EMIT_DOCUMENT_END_STATE: 267 return yaml_emitter_emit_document_end(emitter, event) 268 269 case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: 270 return yaml_emitter_emit_flow_sequence_item(emitter, event, true, false) 271 272 case yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE: 273 return yaml_emitter_emit_flow_sequence_item(emitter, event, false, true) 274 275 case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE: 276 return yaml_emitter_emit_flow_sequence_item(emitter, event, false, false) 277 278 case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: 279 return yaml_emitter_emit_flow_mapping_key(emitter, event, true, false) 280 281 case yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE: 282 return yaml_emitter_emit_flow_mapping_key(emitter, event, false, true) 283 284 case yaml_EMIT_FLOW_MAPPING_KEY_STATE: 285 return yaml_emitter_emit_flow_mapping_key(emitter, event, false, false) 286 287 case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: 288 return yaml_emitter_emit_flow_mapping_value(emitter, event, true) 289 290 case yaml_EMIT_FLOW_MAPPING_VALUE_STATE: 291 return yaml_emitter_emit_flow_mapping_value(emitter, event, false) 292 293 case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: 294 return yaml_emitter_emit_block_sequence_item(emitter, event, true) 295 296 case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE: 297 return yaml_emitter_emit_block_sequence_item(emitter, event, false) 298 299 case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: 300 return yaml_emitter_emit_block_mapping_key(emitter, event, true) 301 302 case yaml_EMIT_BLOCK_MAPPING_KEY_STATE: 303 return yaml_emitter_emit_block_mapping_key(emitter, event, false) 304 305 case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: 306 return yaml_emitter_emit_block_mapping_value(emitter, event, true) 307 308 case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE: 309 return yaml_emitter_emit_block_mapping_value(emitter, event, false) 310 311 case yaml_EMIT_END_STATE: 312 return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END") 313 } 314 panic("invalid emitter state") 315} 316 317// Expect STREAM-START. 318func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { 319 if event.typ != yaml_STREAM_START_EVENT { 320 return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START") 321 } 322 if emitter.encoding == yaml_ANY_ENCODING { 323 emitter.encoding = event.encoding 324 if emitter.encoding == yaml_ANY_ENCODING { 325 emitter.encoding = yaml_UTF8_ENCODING 326 } 327 } 328 if emitter.best_indent < 2 || emitter.best_indent > 9 { 329 emitter.best_indent = 2 330 } 331 if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 { 332 emitter.best_width = 80 333 } 334 if emitter.best_width < 0 { 335 emitter.best_width = 1<<31 - 1 336 } 337 if emitter.line_break == yaml_ANY_BREAK { 338 emitter.line_break = yaml_LN_BREAK 339 } 340 341 emitter.indent = -1 342 emitter.line = 0 343 emitter.column = 0 344 emitter.whitespace = true 345 emitter.indention = true 346 emitter.space_above = true 347 emitter.foot_indent = -1 348 349 if emitter.encoding != yaml_UTF8_ENCODING { 350 if !yaml_emitter_write_bom(emitter) { 351 return false 352 } 353 } 354 emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE 355 return true 356} 357 358// Expect DOCUMENT-START or STREAM-END. 359func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { 360 361 if event.typ == yaml_DOCUMENT_START_EVENT { 362 363 if event.version_directive != nil { 364 if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) { 365 return false 366 } 367 } 368 369 for i := 0; i < len(event.tag_directives); i++ { 370 tag_directive := &event.tag_directives[i] 371 if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) { 372 return false 373 } 374 if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) { 375 return false 376 } 377 } 378 379 for i := 0; i < len(default_tag_directives); i++ { 380 tag_directive := &default_tag_directives[i] 381 if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) { 382 return false 383 } 384 } 385 386 implicit := event.implicit 387 if !first || emitter.canonical { 388 implicit = false 389 } 390 391 if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) { 392 if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { 393 return false 394 } 395 if !yaml_emitter_write_indent(emitter) { 396 return false 397 } 398 } 399 400 if event.version_directive != nil { 401 implicit = false 402 if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) { 403 return false 404 } 405 if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) { 406 return false 407 } 408 if !yaml_emitter_write_indent(emitter) { 409 return false 410 } 411 } 412 413 if len(event.tag_directives) > 0 { 414 implicit = false 415 for i := 0; i < len(event.tag_directives); i++ { 416 tag_directive := &event.tag_directives[i] 417 if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) { 418 return false 419 } 420 if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) { 421 return false 422 } 423 if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) { 424 return false 425 } 426 if !yaml_emitter_write_indent(emitter) { 427 return false 428 } 429 } 430 } 431 432 if yaml_emitter_check_empty_document(emitter) { 433 implicit = false 434 } 435 if !implicit { 436 if !yaml_emitter_write_indent(emitter) { 437 return false 438 } 439 if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) { 440 return false 441 } 442 if emitter.canonical || true { 443 if !yaml_emitter_write_indent(emitter) { 444 return false 445 } 446 } 447 } 448 449 if len(emitter.head_comment) > 0 { 450 if !yaml_emitter_process_head_comment(emitter) { 451 return false 452 } 453 if !put_break(emitter) { 454 return false 455 } 456 } 457 458 emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE 459 return true 460 } 461 462 if event.typ == yaml_STREAM_END_EVENT { 463 if emitter.open_ended { 464 if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { 465 return false 466 } 467 if !yaml_emitter_write_indent(emitter) { 468 return false 469 } 470 } 471 if !yaml_emitter_flush(emitter) { 472 return false 473 } 474 emitter.state = yaml_EMIT_END_STATE 475 return true 476 } 477 478 return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END") 479} 480 481// Expect the root node. 482func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool { 483 emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE) 484 485 if !yaml_emitter_process_head_comment(emitter) { 486 return false 487 } 488 if !yaml_emitter_emit_node(emitter, event, true, false, false, false) { 489 return false 490 } 491 if !yaml_emitter_process_line_comment(emitter) { 492 return false 493 } 494 if !yaml_emitter_process_foot_comment(emitter) { 495 return false 496 } 497 return true 498} 499 500// Expect DOCUMENT-END. 501func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool { 502 if event.typ != yaml_DOCUMENT_END_EVENT { 503 return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END") 504 } 505 // [Go] Force document foot separation. 506 emitter.foot_indent = 0 507 if !yaml_emitter_process_foot_comment(emitter) { 508 return false 509 } 510 emitter.foot_indent = -1 511 if !yaml_emitter_write_indent(emitter) { 512 return false 513 } 514 if !event.implicit { 515 // [Go] Allocate the slice elsewhere. 516 if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { 517 return false 518 } 519 if !yaml_emitter_write_indent(emitter) { 520 return false 521 } 522 } 523 if !yaml_emitter_flush(emitter) { 524 return false 525 } 526 emitter.state = yaml_EMIT_DOCUMENT_START_STATE 527 emitter.tag_directives = emitter.tag_directives[:0] 528 return true 529} 530 531// Expect a flow item node. 532func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool { 533 if first { 534 if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) { 535 return false 536 } 537 if !yaml_emitter_increase_indent(emitter, true, false) { 538 return false 539 } 540 emitter.flow_level++ 541 } 542 543 if event.typ == yaml_SEQUENCE_END_EVENT { 544 if emitter.canonical && !first && !trail { 545 if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { 546 return false 547 } 548 } 549 emitter.flow_level-- 550 emitter.indent = emitter.indents[len(emitter.indents)-1] 551 emitter.indents = emitter.indents[:len(emitter.indents)-1] 552 if emitter.column == 0 || emitter.canonical && !first { 553 if !yaml_emitter_write_indent(emitter) { 554 return false 555 } 556 } 557 if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) { 558 return false 559 } 560 if !yaml_emitter_process_line_comment(emitter) { 561 return false 562 } 563 if !yaml_emitter_process_foot_comment(emitter) { 564 return false 565 } 566 emitter.state = emitter.states[len(emitter.states)-1] 567 emitter.states = emitter.states[:len(emitter.states)-1] 568 569 return true 570 } 571 572 if !first && !trail { 573 if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { 574 return false 575 } 576 } 577 578 if !yaml_emitter_process_head_comment(emitter) { 579 return false 580 } 581 if emitter.column == 0 { 582 if !yaml_emitter_write_indent(emitter) { 583 return false 584 } 585 } 586 587 if emitter.canonical || emitter.column > emitter.best_width { 588 if !yaml_emitter_write_indent(emitter) { 589 return false 590 } 591 } 592 if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 { 593 emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE) 594 } else { 595 emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE) 596 } 597 if !yaml_emitter_emit_node(emitter, event, false, true, false, false) { 598 return false 599 } 600 if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 { 601 if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { 602 return false 603 } 604 } 605 if !yaml_emitter_process_line_comment(emitter) { 606 return false 607 } 608 if !yaml_emitter_process_foot_comment(emitter) { 609 return false 610 } 611 return true 612} 613 614// Expect a flow key node. 615func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool { 616 if first { 617 if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) { 618 return false 619 } 620 if !yaml_emitter_increase_indent(emitter, true, false) { 621 return false 622 } 623 emitter.flow_level++ 624 } 625 626 if event.typ == yaml_MAPPING_END_EVENT { 627 if (emitter.canonical || len(emitter.head_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0) && !first && !trail { 628 if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { 629 return false 630 } 631 } 632 if !yaml_emitter_process_head_comment(emitter) { 633 return false 634 } 635 emitter.flow_level-- 636 emitter.indent = emitter.indents[len(emitter.indents)-1] 637 emitter.indents = emitter.indents[:len(emitter.indents)-1] 638 if emitter.canonical && !first { 639 if !yaml_emitter_write_indent(emitter) { 640 return false 641 } 642 } 643 if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) { 644 return false 645 } 646 if !yaml_emitter_process_line_comment(emitter) { 647 return false 648 } 649 if !yaml_emitter_process_foot_comment(emitter) { 650 return false 651 } 652 emitter.state = emitter.states[len(emitter.states)-1] 653 emitter.states = emitter.states[:len(emitter.states)-1] 654 return true 655 } 656 657 if !first && !trail { 658 if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { 659 return false 660 } 661 } 662 663 if !yaml_emitter_process_head_comment(emitter) { 664 return false 665 } 666 667 if emitter.column == 0 { 668 if !yaml_emitter_write_indent(emitter) { 669 return false 670 } 671 } 672 673 if emitter.canonical || emitter.column > emitter.best_width { 674 if !yaml_emitter_write_indent(emitter) { 675 return false 676 } 677 } 678 679 if !emitter.canonical && yaml_emitter_check_simple_key(emitter) { 680 emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE) 681 return yaml_emitter_emit_node(emitter, event, false, false, true, true) 682 } 683 if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) { 684 return false 685 } 686 emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE) 687 return yaml_emitter_emit_node(emitter, event, false, false, true, false) 688} 689 690// Expect a flow value node. 691func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { 692 if simple { 693 if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { 694 return false 695 } 696 } else { 697 if emitter.canonical || emitter.column > emitter.best_width { 698 if !yaml_emitter_write_indent(emitter) { 699 return false 700 } 701 } 702 if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) { 703 return false 704 } 705 } 706 if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 { 707 emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE) 708 } else { 709 emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE) 710 } 711 if !yaml_emitter_emit_node(emitter, event, false, false, true, false) { 712 return false 713 } 714 if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 { 715 if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { 716 return false 717 } 718 } 719 if !yaml_emitter_process_line_comment(emitter) { 720 return false 721 } 722 if !yaml_emitter_process_foot_comment(emitter) { 723 return false 724 } 725 return true 726} 727 728// Expect a block item node. 729func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { 730 if first { 731 if !yaml_emitter_increase_indent(emitter, false, false) { 732 return false 733 } 734 } 735 if event.typ == yaml_SEQUENCE_END_EVENT { 736 emitter.indent = emitter.indents[len(emitter.indents)-1] 737 emitter.indents = emitter.indents[:len(emitter.indents)-1] 738 emitter.state = emitter.states[len(emitter.states)-1] 739 emitter.states = emitter.states[:len(emitter.states)-1] 740 return true 741 } 742 if !yaml_emitter_process_head_comment(emitter) { 743 return false 744 } 745 if !yaml_emitter_write_indent(emitter) { 746 return false 747 } 748 if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) { 749 return false 750 } 751 emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE) 752 if !yaml_emitter_emit_node(emitter, event, false, true, false, false) { 753 return false 754 } 755 if !yaml_emitter_process_line_comment(emitter) { 756 return false 757 } 758 if !yaml_emitter_process_foot_comment(emitter) { 759 return false 760 } 761 return true 762} 763 764// Expect a block key node. 765func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { 766 if first { 767 if !yaml_emitter_increase_indent(emitter, false, false) { 768 return false 769 } 770 } 771 if !yaml_emitter_process_head_comment(emitter) { 772 return false 773 } 774 if event.typ == yaml_MAPPING_END_EVENT { 775 emitter.indent = emitter.indents[len(emitter.indents)-1] 776 emitter.indents = emitter.indents[:len(emitter.indents)-1] 777 emitter.state = emitter.states[len(emitter.states)-1] 778 emitter.states = emitter.states[:len(emitter.states)-1] 779 return true 780 } 781 if !yaml_emitter_write_indent(emitter) { 782 return false 783 } 784 if len(emitter.line_comment) > 0 { 785 // [Go] A line comment was provided for the key. That's unusual as the 786 // scanner associates line comments with the value. Either way, 787 // save the line comment and render it appropriately later. 788 emitter.key_line_comment = emitter.line_comment 789 emitter.line_comment = nil 790 } 791 if yaml_emitter_check_simple_key(emitter) { 792 emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE) 793 return yaml_emitter_emit_node(emitter, event, false, false, true, true) 794 } 795 if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) { 796 return false 797 } 798 emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE) 799 return yaml_emitter_emit_node(emitter, event, false, false, true, false) 800} 801 802// Expect a block value node. 803func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { 804 if simple { 805 if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { 806 return false 807 } 808 } else { 809 if !yaml_emitter_write_indent(emitter) { 810 return false 811 } 812 if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) { 813 return false 814 } 815 } 816 if len(emitter.key_line_comment) > 0 { 817 // [Go] A line comment was previously provided for the key. Handle it before 818 // the value so the inline comments are placed correctly. 819 if yaml_emitter_silent_nil_event(emitter, event) && len(emitter.line_comment) == 0 { 820 // Nothing other than the line comment will be written on the line. 821 emitter.line_comment = emitter.key_line_comment 822 emitter.key_line_comment = nil 823 } else { 824 // An actual value is coming, so emit the comment line. 825 emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment 826 if !yaml_emitter_process_line_comment(emitter) { 827 return false 828 } 829 emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment 830 // Indent in unless it's a block that will reindent anyway. 831 if event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE || (event.typ != yaml_MAPPING_START_EVENT && event.typ != yaml_SEQUENCE_START_EVENT) { 832 emitter.indent = emitter.best_indent*((emitter.indent+emitter.best_indent)/emitter.best_indent) 833 if !yaml_emitter_write_indent(emitter) { 834 return false 835 } 836 } 837 } 838 } 839 emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE) 840 if !yaml_emitter_emit_node(emitter, event, false, false, true, false) { 841 return false 842 } 843 if !yaml_emitter_process_line_comment(emitter) { 844 return false 845 } 846 if !yaml_emitter_process_foot_comment(emitter) { 847 return false 848 } 849 return true 850} 851 852func yaml_emitter_silent_nil_event(emitter *yaml_emitter_t, event *yaml_event_t) bool { 853 return event.typ == yaml_SCALAR_EVENT && event.implicit && !emitter.canonical && len(emitter.scalar_data.value) == 0 854} 855 856// Expect a node. 857func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t, 858 root bool, sequence bool, mapping bool, simple_key bool) bool { 859 860 emitter.root_context = root 861 emitter.sequence_context = sequence 862 emitter.mapping_context = mapping 863 emitter.simple_key_context = simple_key 864 865 switch event.typ { 866 case yaml_ALIAS_EVENT: 867 return yaml_emitter_emit_alias(emitter, event) 868 case yaml_SCALAR_EVENT: 869 return yaml_emitter_emit_scalar(emitter, event) 870 case yaml_SEQUENCE_START_EVENT: 871 return yaml_emitter_emit_sequence_start(emitter, event) 872 case yaml_MAPPING_START_EVENT: 873 return yaml_emitter_emit_mapping_start(emitter, event) 874 default: 875 return yaml_emitter_set_emitter_error(emitter, 876 fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ)) 877 } 878} 879 880// Expect ALIAS. 881func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool { 882 if !yaml_emitter_process_anchor(emitter) { 883 return false 884 } 885 emitter.state = emitter.states[len(emitter.states)-1] 886 emitter.states = emitter.states[:len(emitter.states)-1] 887 return true 888} 889 890// Expect SCALAR. 891func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool { 892 if !yaml_emitter_select_scalar_style(emitter, event) { 893 return false 894 } 895 if !yaml_emitter_process_anchor(emitter) { 896 return false 897 } 898 if !yaml_emitter_process_tag(emitter) { 899 return false 900 } 901 if !yaml_emitter_increase_indent(emitter, true, false) { 902 return false 903 } 904 if !yaml_emitter_process_scalar(emitter) { 905 return false 906 } 907 emitter.indent = emitter.indents[len(emitter.indents)-1] 908 emitter.indents = emitter.indents[:len(emitter.indents)-1] 909 emitter.state = emitter.states[len(emitter.states)-1] 910 emitter.states = emitter.states[:len(emitter.states)-1] 911 return true 912} 913 914// Expect SEQUENCE-START. 915func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { 916 if !yaml_emitter_process_anchor(emitter) { 917 return false 918 } 919 if !yaml_emitter_process_tag(emitter) { 920 return false 921 } 922 if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE || 923 yaml_emitter_check_empty_sequence(emitter) { 924 emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE 925 } else { 926 emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE 927 } 928 return true 929} 930 931// Expect MAPPING-START. 932func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { 933 if !yaml_emitter_process_anchor(emitter) { 934 return false 935 } 936 if !yaml_emitter_process_tag(emitter) { 937 return false 938 } 939 if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE || 940 yaml_emitter_check_empty_mapping(emitter) { 941 emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE 942 } else { 943 emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE 944 } 945 return true 946} 947 948// Check if the document content is an empty scalar. 949func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool { 950 return false // [Go] Huh? 951} 952 953// Check if the next events represent an empty sequence. 954func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool { 955 if len(emitter.events)-emitter.events_head < 2 { 956 return false 957 } 958 return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT && 959 emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT 960} 961 962// Check if the next events represent an empty mapping. 963func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool { 964 if len(emitter.events)-emitter.events_head < 2 { 965 return false 966 } 967 return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT && 968 emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT 969} 970 971// Check if the next node can be expressed as a simple key. 972func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool { 973 length := 0 974 switch emitter.events[emitter.events_head].typ { 975 case yaml_ALIAS_EVENT: 976 length += len(emitter.anchor_data.anchor) 977 case yaml_SCALAR_EVENT: 978 if emitter.scalar_data.multiline { 979 return false 980 } 981 length += len(emitter.anchor_data.anchor) + 982 len(emitter.tag_data.handle) + 983 len(emitter.tag_data.suffix) + 984 len(emitter.scalar_data.value) 985 case yaml_SEQUENCE_START_EVENT: 986 if !yaml_emitter_check_empty_sequence(emitter) { 987 return false 988 } 989 length += len(emitter.anchor_data.anchor) + 990 len(emitter.tag_data.handle) + 991 len(emitter.tag_data.suffix) 992 case yaml_MAPPING_START_EVENT: 993 if !yaml_emitter_check_empty_mapping(emitter) { 994 return false 995 } 996 length += len(emitter.anchor_data.anchor) + 997 len(emitter.tag_data.handle) + 998 len(emitter.tag_data.suffix) 999 default: 1000 return false 1001 } 1002 return length <= 128 1003} 1004 1005// Determine an acceptable scalar style. 1006func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool { 1007 1008 no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 1009 if no_tag && !event.implicit && !event.quoted_implicit { 1010 return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified") 1011 } 1012 1013 style := event.scalar_style() 1014 if style == yaml_ANY_SCALAR_STYLE { 1015 style = yaml_PLAIN_SCALAR_STYLE 1016 } 1017 if emitter.canonical { 1018 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 1019 } 1020 if emitter.simple_key_context && emitter.scalar_data.multiline { 1021 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 1022 } 1023 1024 if style == yaml_PLAIN_SCALAR_STYLE { 1025 if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed || 1026 emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed { 1027 style = yaml_SINGLE_QUOTED_SCALAR_STYLE 1028 } 1029 if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) { 1030 style = yaml_SINGLE_QUOTED_SCALAR_STYLE 1031 } 1032 if no_tag && !event.implicit { 1033 style = yaml_SINGLE_QUOTED_SCALAR_STYLE 1034 } 1035 } 1036 if style == yaml_SINGLE_QUOTED_SCALAR_STYLE { 1037 if !emitter.scalar_data.single_quoted_allowed { 1038 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 1039 } 1040 } 1041 if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE { 1042 if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context { 1043 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 1044 } 1045 } 1046 1047 if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE { 1048 emitter.tag_data.handle = []byte{'!'} 1049 } 1050 emitter.scalar_data.style = style 1051 return true 1052} 1053 1054// Write an anchor. 1055func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool { 1056 if emitter.anchor_data.anchor == nil { 1057 return true 1058 } 1059 c := []byte{'&'} 1060 if emitter.anchor_data.alias { 1061 c[0] = '*' 1062 } 1063 if !yaml_emitter_write_indicator(emitter, c, true, false, false) { 1064 return false 1065 } 1066 return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor) 1067} 1068 1069// Write a tag. 1070func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool { 1071 if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 { 1072 return true 1073 } 1074 if len(emitter.tag_data.handle) > 0 { 1075 if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) { 1076 return false 1077 } 1078 if len(emitter.tag_data.suffix) > 0 { 1079 if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { 1080 return false 1081 } 1082 } 1083 } else { 1084 // [Go] Allocate these slices elsewhere. 1085 if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) { 1086 return false 1087 } 1088 if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { 1089 return false 1090 } 1091 if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) { 1092 return false 1093 } 1094 } 1095 return true 1096} 1097 1098// Write a scalar. 1099func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool { 1100 switch emitter.scalar_data.style { 1101 case yaml_PLAIN_SCALAR_STYLE: 1102 return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) 1103 1104 case yaml_SINGLE_QUOTED_SCALAR_STYLE: 1105 return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) 1106 1107 case yaml_DOUBLE_QUOTED_SCALAR_STYLE: 1108 return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) 1109 1110 case yaml_LITERAL_SCALAR_STYLE: 1111 return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value) 1112 1113 case yaml_FOLDED_SCALAR_STYLE: 1114 return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value) 1115 } 1116 panic("unknown scalar style") 1117} 1118 1119// Write a head comment. 1120func yaml_emitter_process_head_comment(emitter *yaml_emitter_t) bool { 1121 if len(emitter.tail_comment) > 0 { 1122 if !yaml_emitter_write_indent(emitter) { 1123 return false 1124 } 1125 if !yaml_emitter_write_comment(emitter, emitter.tail_comment) { 1126 return false 1127 } 1128 emitter.tail_comment = emitter.tail_comment[:0] 1129 emitter.foot_indent = emitter.indent 1130 if emitter.foot_indent < 0 { 1131 emitter.foot_indent = 0 1132 } 1133 } 1134 1135 if len(emitter.head_comment) == 0 { 1136 return true 1137 } 1138 if !yaml_emitter_write_indent(emitter) { 1139 return false 1140 } 1141 if !yaml_emitter_write_comment(emitter, emitter.head_comment) { 1142 return false 1143 } 1144 emitter.head_comment = emitter.head_comment[:0] 1145 return true 1146} 1147 1148// Write an line comment. 1149func yaml_emitter_process_line_comment(emitter *yaml_emitter_t) bool { 1150 if len(emitter.line_comment) == 0 { 1151 return true 1152 } 1153 if !emitter.whitespace { 1154 if !put(emitter, ' ') { 1155 return false 1156 } 1157 } 1158 if !yaml_emitter_write_comment(emitter, emitter.line_comment) { 1159 return false 1160 } 1161 emitter.line_comment = emitter.line_comment[:0] 1162 return true 1163} 1164 1165// Write a foot comment. 1166func yaml_emitter_process_foot_comment(emitter *yaml_emitter_t) bool { 1167 if len(emitter.foot_comment) == 0 { 1168 return true 1169 } 1170 if !yaml_emitter_write_indent(emitter) { 1171 return false 1172 } 1173 if !yaml_emitter_write_comment(emitter, emitter.foot_comment) { 1174 return false 1175 } 1176 emitter.foot_comment = emitter.foot_comment[:0] 1177 emitter.foot_indent = emitter.indent 1178 if emitter.foot_indent < 0 { 1179 emitter.foot_indent = 0 1180 } 1181 return true 1182} 1183 1184// Check if a %YAML directive is valid. 1185func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool { 1186 if version_directive.major != 1 || version_directive.minor != 1 { 1187 return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive") 1188 } 1189 return true 1190} 1191 1192// Check if a %TAG directive is valid. 1193func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool { 1194 handle := tag_directive.handle 1195 prefix := tag_directive.prefix 1196 if len(handle) == 0 { 1197 return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty") 1198 } 1199 if handle[0] != '!' { 1200 return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'") 1201 } 1202 if handle[len(handle)-1] != '!' { 1203 return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'") 1204 } 1205 for i := 1; i < len(handle)-1; i += width(handle[i]) { 1206 if !is_alpha(handle, i) { 1207 return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only") 1208 } 1209 } 1210 if len(prefix) == 0 { 1211 return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty") 1212 } 1213 return true 1214} 1215 1216// Check if an anchor is valid. 1217func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool { 1218 if len(anchor) == 0 { 1219 problem := "anchor value must not be empty" 1220 if alias { 1221 problem = "alias value must not be empty" 1222 } 1223 return yaml_emitter_set_emitter_error(emitter, problem) 1224 } 1225 for i := 0; i < len(anchor); i += width(anchor[i]) { 1226 if !is_alpha(anchor, i) { 1227 problem := "anchor value must contain alphanumerical characters only" 1228 if alias { 1229 problem = "alias value must contain alphanumerical characters only" 1230 } 1231 return yaml_emitter_set_emitter_error(emitter, problem) 1232 } 1233 } 1234 emitter.anchor_data.anchor = anchor 1235 emitter.anchor_data.alias = alias 1236 return true 1237} 1238 1239// Check if a tag is valid. 1240func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool { 1241 if len(tag) == 0 { 1242 return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty") 1243 } 1244 for i := 0; i < len(emitter.tag_directives); i++ { 1245 tag_directive := &emitter.tag_directives[i] 1246 if bytes.HasPrefix(tag, tag_directive.prefix) { 1247 emitter.tag_data.handle = tag_directive.handle 1248 emitter.tag_data.suffix = tag[len(tag_directive.prefix):] 1249 return true 1250 } 1251 } 1252 emitter.tag_data.suffix = tag 1253 return true 1254} 1255 1256// Check if a scalar is valid. 1257func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool { 1258 var ( 1259 block_indicators = false 1260 flow_indicators = false 1261 line_breaks = false 1262 special_characters = false 1263 tab_characters = false 1264 1265 leading_space = false 1266 leading_break = false 1267 trailing_space = false 1268 trailing_break = false 1269 break_space = false 1270 space_break = false 1271 1272 preceded_by_whitespace = false 1273 followed_by_whitespace = false 1274 previous_space = false 1275 previous_break = false 1276 ) 1277 1278 emitter.scalar_data.value = value 1279 1280 if len(value) == 0 { 1281 emitter.scalar_data.multiline = false 1282 emitter.scalar_data.flow_plain_allowed = false 1283 emitter.scalar_data.block_plain_allowed = true 1284 emitter.scalar_data.single_quoted_allowed = true 1285 emitter.scalar_data.block_allowed = false 1286 return true 1287 } 1288 1289 if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) { 1290 block_indicators = true 1291 flow_indicators = true 1292 } 1293 1294 preceded_by_whitespace = true 1295 for i, w := 0, 0; i < len(value); i += w { 1296 w = width(value[i]) 1297 followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w) 1298 1299 if i == 0 { 1300 switch value[i] { 1301 case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`': 1302 flow_indicators = true 1303 block_indicators = true 1304 case '?', ':': 1305 flow_indicators = true 1306 if followed_by_whitespace { 1307 block_indicators = true 1308 } 1309 case '-': 1310 if followed_by_whitespace { 1311 flow_indicators = true 1312 block_indicators = true 1313 } 1314 } 1315 } else { 1316 switch value[i] { 1317 case ',', '?', '[', ']', '{', '}': 1318 flow_indicators = true 1319 case ':': 1320 flow_indicators = true 1321 if followed_by_whitespace { 1322 block_indicators = true 1323 } 1324 case '#': 1325 if preceded_by_whitespace { 1326 flow_indicators = true 1327 block_indicators = true 1328 } 1329 } 1330 } 1331 1332 if value[i] == '\t' { 1333 tab_characters = true 1334 } else if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode { 1335 special_characters = true 1336 } 1337 if is_space(value, i) { 1338 if i == 0 { 1339 leading_space = true 1340 } 1341 if i+width(value[i]) == len(value) { 1342 trailing_space = true 1343 } 1344 if previous_break { 1345 break_space = true 1346 } 1347 previous_space = true 1348 previous_break = false 1349 } else if is_break(value, i) { 1350 line_breaks = true 1351 if i == 0 { 1352 leading_break = true 1353 } 1354 if i+width(value[i]) == len(value) { 1355 trailing_break = true 1356 } 1357 if previous_space { 1358 space_break = true 1359 } 1360 previous_space = false 1361 previous_break = true 1362 } else { 1363 previous_space = false 1364 previous_break = false 1365 } 1366 1367 // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition. 1368 preceded_by_whitespace = is_blankz(value, i) 1369 } 1370 1371 emitter.scalar_data.multiline = line_breaks 1372 emitter.scalar_data.flow_plain_allowed = true 1373 emitter.scalar_data.block_plain_allowed = true 1374 emitter.scalar_data.single_quoted_allowed = true 1375 emitter.scalar_data.block_allowed = true 1376 1377 if leading_space || leading_break || trailing_space || trailing_break { 1378 emitter.scalar_data.flow_plain_allowed = false 1379 emitter.scalar_data.block_plain_allowed = false 1380 } 1381 if trailing_space { 1382 emitter.scalar_data.block_allowed = false 1383 } 1384 if break_space { 1385 emitter.scalar_data.flow_plain_allowed = false 1386 emitter.scalar_data.block_plain_allowed = false 1387 emitter.scalar_data.single_quoted_allowed = false 1388 } 1389 if space_break || tab_characters || special_characters { 1390 emitter.scalar_data.flow_plain_allowed = false 1391 emitter.scalar_data.block_plain_allowed = false 1392 emitter.scalar_data.single_quoted_allowed = false 1393 } 1394 if space_break || special_characters { 1395 emitter.scalar_data.block_allowed = false 1396 } 1397 if line_breaks { 1398 emitter.scalar_data.flow_plain_allowed = false 1399 emitter.scalar_data.block_plain_allowed = false 1400 } 1401 if flow_indicators { 1402 emitter.scalar_data.flow_plain_allowed = false 1403 } 1404 if block_indicators { 1405 emitter.scalar_data.block_plain_allowed = false 1406 } 1407 return true 1408} 1409 1410// Check if the event data is valid. 1411func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool { 1412 1413 emitter.anchor_data.anchor = nil 1414 emitter.tag_data.handle = nil 1415 emitter.tag_data.suffix = nil 1416 emitter.scalar_data.value = nil 1417 1418 if len(event.head_comment) > 0 { 1419 emitter.head_comment = event.head_comment 1420 } 1421 if len(event.line_comment) > 0 { 1422 emitter.line_comment = event.line_comment 1423 } 1424 if len(event.foot_comment) > 0 { 1425 emitter.foot_comment = event.foot_comment 1426 } 1427 if len(event.tail_comment) > 0 { 1428 emitter.tail_comment = event.tail_comment 1429 } 1430 1431 switch event.typ { 1432 case yaml_ALIAS_EVENT: 1433 if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) { 1434 return false 1435 } 1436 1437 case yaml_SCALAR_EVENT: 1438 if len(event.anchor) > 0 { 1439 if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { 1440 return false 1441 } 1442 } 1443 if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) { 1444 if !yaml_emitter_analyze_tag(emitter, event.tag) { 1445 return false 1446 } 1447 } 1448 if !yaml_emitter_analyze_scalar(emitter, event.value) { 1449 return false 1450 } 1451 1452 case yaml_SEQUENCE_START_EVENT: 1453 if len(event.anchor) > 0 { 1454 if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { 1455 return false 1456 } 1457 } 1458 if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { 1459 if !yaml_emitter_analyze_tag(emitter, event.tag) { 1460 return false 1461 } 1462 } 1463 1464 case yaml_MAPPING_START_EVENT: 1465 if len(event.anchor) > 0 { 1466 if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { 1467 return false 1468 } 1469 } 1470 if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { 1471 if !yaml_emitter_analyze_tag(emitter, event.tag) { 1472 return false 1473 } 1474 } 1475 } 1476 return true 1477} 1478 1479// Write the BOM character. 1480func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool { 1481 if !flush(emitter) { 1482 return false 1483 } 1484 pos := emitter.buffer_pos 1485 emitter.buffer[pos+0] = '\xEF' 1486 emitter.buffer[pos+1] = '\xBB' 1487 emitter.buffer[pos+2] = '\xBF' 1488 emitter.buffer_pos += 3 1489 return true 1490} 1491 1492func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool { 1493 indent := emitter.indent 1494 if indent < 0 { 1495 indent = 0 1496 } 1497 if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) { 1498 if !put_break(emitter) { 1499 return false 1500 } 1501 } 1502 if emitter.foot_indent == indent { 1503 if !put_break(emitter) { 1504 return false 1505 } 1506 } 1507 for emitter.column < indent { 1508 if !put(emitter, ' ') { 1509 return false 1510 } 1511 } 1512 emitter.whitespace = true 1513 //emitter.indention = true 1514 emitter.space_above = false 1515 emitter.foot_indent = -1 1516 return true 1517} 1518 1519func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool { 1520 if need_whitespace && !emitter.whitespace { 1521 if !put(emitter, ' ') { 1522 return false 1523 } 1524 } 1525 if !write_all(emitter, indicator) { 1526 return false 1527 } 1528 emitter.whitespace = is_whitespace 1529 emitter.indention = (emitter.indention && is_indention) 1530 emitter.open_ended = false 1531 return true 1532} 1533 1534func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool { 1535 if !write_all(emitter, value) { 1536 return false 1537 } 1538 emitter.whitespace = false 1539 emitter.indention = false 1540 return true 1541} 1542 1543func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool { 1544 if !emitter.whitespace { 1545 if !put(emitter, ' ') { 1546 return false 1547 } 1548 } 1549 if !write_all(emitter, value) { 1550 return false 1551 } 1552 emitter.whitespace = false 1553 emitter.indention = false 1554 return true 1555} 1556 1557func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool { 1558 if need_whitespace && !emitter.whitespace { 1559 if !put(emitter, ' ') { 1560 return false 1561 } 1562 } 1563 for i := 0; i < len(value); { 1564 var must_write bool 1565 switch value[i] { 1566 case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']': 1567 must_write = true 1568 default: 1569 must_write = is_alpha(value, i) 1570 } 1571 if must_write { 1572 if !write(emitter, value, &i) { 1573 return false 1574 } 1575 } else { 1576 w := width(value[i]) 1577 for k := 0; k < w; k++ { 1578 octet := value[i] 1579 i++ 1580 if !put(emitter, '%') { 1581 return false 1582 } 1583 1584 c := octet >> 4 1585 if c < 10 { 1586 c += '0' 1587 } else { 1588 c += 'A' - 10 1589 } 1590 if !put(emitter, c) { 1591 return false 1592 } 1593 1594 c = octet & 0x0f 1595 if c < 10 { 1596 c += '0' 1597 } else { 1598 c += 'A' - 10 1599 } 1600 if !put(emitter, c) { 1601 return false 1602 } 1603 } 1604 } 1605 } 1606 emitter.whitespace = false 1607 emitter.indention = false 1608 return true 1609} 1610 1611func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { 1612 if len(value) > 0 && !emitter.whitespace { 1613 if !put(emitter, ' ') { 1614 return false 1615 } 1616 } 1617 1618 spaces := false 1619 breaks := false 1620 for i := 0; i < len(value); { 1621 if is_space(value, i) { 1622 if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) { 1623 if !yaml_emitter_write_indent(emitter) { 1624 return false 1625 } 1626 i += width(value[i]) 1627 } else { 1628 if !write(emitter, value, &i) { 1629 return false 1630 } 1631 } 1632 spaces = true 1633 } else if is_break(value, i) { 1634 if !breaks && value[i] == '\n' { 1635 if !put_break(emitter) { 1636 return false 1637 } 1638 } 1639 if !write_break(emitter, value, &i) { 1640 return false 1641 } 1642 //emitter.indention = true 1643 breaks = true 1644 } else { 1645 if breaks { 1646 if !yaml_emitter_write_indent(emitter) { 1647 return false 1648 } 1649 } 1650 if !write(emitter, value, &i) { 1651 return false 1652 } 1653 emitter.indention = false 1654 spaces = false 1655 breaks = false 1656 } 1657 } 1658 1659 if len(value) > 0 { 1660 emitter.whitespace = false 1661 } 1662 emitter.indention = false 1663 if emitter.root_context { 1664 emitter.open_ended = true 1665 } 1666 1667 return true 1668} 1669 1670func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { 1671 1672 if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) { 1673 return false 1674 } 1675 1676 spaces := false 1677 breaks := false 1678 for i := 0; i < len(value); { 1679 if is_space(value, i) { 1680 if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) { 1681 if !yaml_emitter_write_indent(emitter) { 1682 return false 1683 } 1684 i += width(value[i]) 1685 } else { 1686 if !write(emitter, value, &i) { 1687 return false 1688 } 1689 } 1690 spaces = true 1691 } else if is_break(value, i) { 1692 if !breaks && value[i] == '\n' { 1693 if !put_break(emitter) { 1694 return false 1695 } 1696 } 1697 if !write_break(emitter, value, &i) { 1698 return false 1699 } 1700 //emitter.indention = true 1701 breaks = true 1702 } else { 1703 if breaks { 1704 if !yaml_emitter_write_indent(emitter) { 1705 return false 1706 } 1707 } 1708 if value[i] == '\'' { 1709 if !put(emitter, '\'') { 1710 return false 1711 } 1712 } 1713 if !write(emitter, value, &i) { 1714 return false 1715 } 1716 emitter.indention = false 1717 spaces = false 1718 breaks = false 1719 } 1720 } 1721 if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) { 1722 return false 1723 } 1724 emitter.whitespace = false 1725 emitter.indention = false 1726 return true 1727} 1728 1729func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { 1730 spaces := false 1731 if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) { 1732 return false 1733 } 1734 1735 for i := 0; i < len(value); { 1736 if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) || 1737 is_bom(value, i) || is_break(value, i) || 1738 value[i] == '"' || value[i] == '\\' { 1739 1740 octet := value[i] 1741 1742 var w int 1743 var v rune 1744 switch { 1745 case octet&0x80 == 0x00: 1746 w, v = 1, rune(octet&0x7F) 1747 case octet&0xE0 == 0xC0: 1748 w, v = 2, rune(octet&0x1F) 1749 case octet&0xF0 == 0xE0: 1750 w, v = 3, rune(octet&0x0F) 1751 case octet&0xF8 == 0xF0: 1752 w, v = 4, rune(octet&0x07) 1753 } 1754 for k := 1; k < w; k++ { 1755 octet = value[i+k] 1756 v = (v << 6) + (rune(octet) & 0x3F) 1757 } 1758 i += w 1759 1760 if !put(emitter, '\\') { 1761 return false 1762 } 1763 1764 var ok bool 1765 switch v { 1766 case 0x00: 1767 ok = put(emitter, '0') 1768 case 0x07: 1769 ok = put(emitter, 'a') 1770 case 0x08: 1771 ok = put(emitter, 'b') 1772 case 0x09: 1773 ok = put(emitter, 't') 1774 case 0x0A: 1775 ok = put(emitter, 'n') 1776 case 0x0b: 1777 ok = put(emitter, 'v') 1778 case 0x0c: 1779 ok = put(emitter, 'f') 1780 case 0x0d: 1781 ok = put(emitter, 'r') 1782 case 0x1b: 1783 ok = put(emitter, 'e') 1784 case 0x22: 1785 ok = put(emitter, '"') 1786 case 0x5c: 1787 ok = put(emitter, '\\') 1788 case 0x85: 1789 ok = put(emitter, 'N') 1790 case 0xA0: 1791 ok = put(emitter, '_') 1792 case 0x2028: 1793 ok = put(emitter, 'L') 1794 case 0x2029: 1795 ok = put(emitter, 'P') 1796 default: 1797 if v <= 0xFF { 1798 ok = put(emitter, 'x') 1799 w = 2 1800 } else if v <= 0xFFFF { 1801 ok = put(emitter, 'u') 1802 w = 4 1803 } else { 1804 ok = put(emitter, 'U') 1805 w = 8 1806 } 1807 for k := (w - 1) * 4; ok && k >= 0; k -= 4 { 1808 digit := byte((v >> uint(k)) & 0x0F) 1809 if digit < 10 { 1810 ok = put(emitter, digit+'0') 1811 } else { 1812 ok = put(emitter, digit+'A'-10) 1813 } 1814 } 1815 } 1816 if !ok { 1817 return false 1818 } 1819 spaces = false 1820 } else if is_space(value, i) { 1821 if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 { 1822 if !yaml_emitter_write_indent(emitter) { 1823 return false 1824 } 1825 if is_space(value, i+1) { 1826 if !put(emitter, '\\') { 1827 return false 1828 } 1829 } 1830 i += width(value[i]) 1831 } else if !write(emitter, value, &i) { 1832 return false 1833 } 1834 spaces = true 1835 } else { 1836 if !write(emitter, value, &i) { 1837 return false 1838 } 1839 spaces = false 1840 } 1841 } 1842 if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) { 1843 return false 1844 } 1845 emitter.whitespace = false 1846 emitter.indention = false 1847 return true 1848} 1849 1850func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool { 1851 if is_space(value, 0) || is_break(value, 0) { 1852 indent_hint := []byte{'0' + byte(emitter.best_indent)} 1853 if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) { 1854 return false 1855 } 1856 } 1857 1858 emitter.open_ended = false 1859 1860 var chomp_hint [1]byte 1861 if len(value) == 0 { 1862 chomp_hint[0] = '-' 1863 } else { 1864 i := len(value) - 1 1865 for value[i]&0xC0 == 0x80 { 1866 i-- 1867 } 1868 if !is_break(value, i) { 1869 chomp_hint[0] = '-' 1870 } else if i == 0 { 1871 chomp_hint[0] = '+' 1872 emitter.open_ended = true 1873 } else { 1874 i-- 1875 for value[i]&0xC0 == 0x80 { 1876 i-- 1877 } 1878 if is_break(value, i) { 1879 chomp_hint[0] = '+' 1880 emitter.open_ended = true 1881 } 1882 } 1883 } 1884 if chomp_hint[0] != 0 { 1885 if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) { 1886 return false 1887 } 1888 } 1889 return true 1890} 1891 1892func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool { 1893 if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) { 1894 return false 1895 } 1896 if !yaml_emitter_write_block_scalar_hints(emitter, value) { 1897 return false 1898 } 1899 if !put_break(emitter) { 1900 return false 1901 } 1902 //emitter.indention = true 1903 emitter.whitespace = true 1904 breaks := true 1905 for i := 0; i < len(value); { 1906 if is_break(value, i) { 1907 if !write_break(emitter, value, &i) { 1908 return false 1909 } 1910 //emitter.indention = true 1911 breaks = true 1912 } else { 1913 if breaks { 1914 if !yaml_emitter_write_indent(emitter) { 1915 return false 1916 } 1917 } 1918 if !write(emitter, value, &i) { 1919 return false 1920 } 1921 emitter.indention = false 1922 breaks = false 1923 } 1924 } 1925 1926 return true 1927} 1928 1929func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool { 1930 if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) { 1931 return false 1932 } 1933 if !yaml_emitter_write_block_scalar_hints(emitter, value) { 1934 return false 1935 } 1936 1937 if !put_break(emitter) { 1938 return false 1939 } 1940 //emitter.indention = true 1941 emitter.whitespace = true 1942 1943 breaks := true 1944 leading_spaces := true 1945 for i := 0; i < len(value); { 1946 if is_break(value, i) { 1947 if !breaks && !leading_spaces && value[i] == '\n' { 1948 k := 0 1949 for is_break(value, k) { 1950 k += width(value[k]) 1951 } 1952 if !is_blankz(value, k) { 1953 if !put_break(emitter) { 1954 return false 1955 } 1956 } 1957 } 1958 if !write_break(emitter, value, &i) { 1959 return false 1960 } 1961 //emitter.indention = true 1962 breaks = true 1963 } else { 1964 if breaks { 1965 if !yaml_emitter_write_indent(emitter) { 1966 return false 1967 } 1968 leading_spaces = is_blank(value, i) 1969 } 1970 if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width { 1971 if !yaml_emitter_write_indent(emitter) { 1972 return false 1973 } 1974 i += width(value[i]) 1975 } else { 1976 if !write(emitter, value, &i) { 1977 return false 1978 } 1979 } 1980 emitter.indention = false 1981 breaks = false 1982 } 1983 } 1984 return true 1985} 1986 1987func yaml_emitter_write_comment(emitter *yaml_emitter_t, comment []byte) bool { 1988 breaks := false 1989 pound := false 1990 for i := 0; i < len(comment); { 1991 if is_break(comment, i) { 1992 if !write_break(emitter, comment, &i) { 1993 return false 1994 } 1995 //emitter.indention = true 1996 breaks = true 1997 pound = false 1998 } else { 1999 if breaks && !yaml_emitter_write_indent(emitter) { 2000 return false 2001 } 2002 if !pound { 2003 if comment[i] != '#' && (!put(emitter, '#') || !put(emitter, ' ')) { 2004 return false 2005 } 2006 pound = true 2007 } 2008 if !write(emitter, comment, &i) { 2009 return false 2010 } 2011 emitter.indention = false 2012 breaks = false 2013 } 2014 } 2015 if !breaks && !put_break(emitter) { 2016 return false 2017 } 2018 2019 emitter.whitespace = true 2020 //emitter.indention = true 2021 return true 2022} 2023