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