8
// Flush the buffer if needed.
9
func flush(emitter *yaml_emitter_t) bool {
10
if emitter.buffer_pos+5 >= len(emitter.buffer) {
11
return yaml_emitter_flush(emitter)
16
// Put a character to the output buffer.
17
func put(emitter *yaml_emitter_t, value byte) bool {
18
if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
21
emitter.buffer[emitter.buffer_pos] = value
27
// Put a line break to the output buffer.
28
func put_break(emitter *yaml_emitter_t) bool {
29
if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
32
switch emitter.line_break {
34
emitter.buffer[emitter.buffer_pos] = '\r'
35
emitter.buffer_pos += 1
37
emitter.buffer[emitter.buffer_pos] = '\n'
38
emitter.buffer_pos += 1
40
emitter.buffer[emitter.buffer_pos+0] = '\r'
41
emitter.buffer[emitter.buffer_pos+1] = '\n'
42
emitter.buffer_pos += 2
44
panic("unknown line break setting")
51
// Copy a character from a string into buffer.
52
func write(emitter *yaml_emitter_t, s []byte, i *int) bool {
53
if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
56
p := emitter.buffer_pos
60
emitter.buffer[p+3] = s[*i+3]
63
emitter.buffer[p+2] = s[*i+2]
66
emitter.buffer[p+1] = s[*i+1]
69
emitter.buffer[p+0] = s[*i+0]
71
panic("unknown character width")
74
emitter.buffer_pos += w
79
// Write a whole string into buffer.
80
func write_all(emitter *yaml_emitter_t, s []byte) bool {
81
for i := 0; i < len(s); {
82
if !write(emitter, s, &i) {
89
// Copy a line break character from a string into buffer.
90
func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool {
92
if !put_break(emitter) {
97
if !write(emitter, s, i) {
106
// Set an emitter error and return false.
107
func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool {
108
emitter.error = yaml_EMITTER_ERROR
109
emitter.problem = problem
114
func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool {
115
emitter.events = append(emitter.events, *event)
116
for !yaml_emitter_need_more_events(emitter) {
117
event := &emitter.events[emitter.events_head]
118
if !yaml_emitter_analyze_event(emitter, event) {
121
if !yaml_emitter_state_machine(emitter, event) {
124
yaml_event_delete(event)
125
emitter.events_head++
130
// Check if we need to accumulate more events before emitting.
132
// We accumulate extra
133
// - 1 event for DOCUMENT-START
134
// - 2 events for SEQUENCE-START
135
// - 3 events for MAPPING-START
137
func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {
138
if emitter.events_head == len(emitter.events) {
142
switch emitter.events[emitter.events_head].typ {
143
case yaml_DOCUMENT_START_EVENT:
146
case yaml_SEQUENCE_START_EVENT:
149
case yaml_MAPPING_START_EVENT:
155
if len(emitter.events)-emitter.events_head > accumulate {
159
for i := emitter.events_head; i < len(emitter.events); i++ {
160
switch emitter.events[i].typ {
161
case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT:
163
case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:
173
// Append a directive to the directives stack.
174
func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool {
175
for i := 0; i < len(emitter.tag_directives); i++ {
176
if bytes.Equal(value.handle, emitter.tag_directives[i].handle) {
177
if allow_duplicates {
180
return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive")
184
// [Go] Do we actually need to copy this given garbage collection
185
// and the lack of deallocating destructors?
186
tag_copy := yaml_tag_directive_t{
187
handle: make([]byte, len(value.handle)),
188
prefix: make([]byte, len(value.prefix)),
190
copy(tag_copy.handle, value.handle)
191
copy(tag_copy.prefix, value.prefix)
192
emitter.tag_directives = append(emitter.tag_directives, tag_copy)
196
// Increase the indentation level.
197
func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {
198
emitter.indents = append(emitter.indents, emitter.indent)
199
if emitter.indent < 0 {
201
emitter.indent = emitter.best_indent
205
} else if !indentless {
206
emitter.indent += emitter.best_indent
212
func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {
213
switch emitter.state {
215
case yaml_EMIT_STREAM_START_STATE:
216
return yaml_emitter_emit_stream_start(emitter, event)
218
case yaml_EMIT_FIRST_DOCUMENT_START_STATE:
219
return yaml_emitter_emit_document_start(emitter, event, true)
221
case yaml_EMIT_DOCUMENT_START_STATE:
222
return yaml_emitter_emit_document_start(emitter, event, false)
224
case yaml_EMIT_DOCUMENT_CONTENT_STATE:
225
return yaml_emitter_emit_document_content(emitter, event)
227
case yaml_EMIT_DOCUMENT_END_STATE:
228
return yaml_emitter_emit_document_end(emitter, event)
230
case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
231
return yaml_emitter_emit_flow_sequence_item(emitter, event, true)
233
case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:
234
return yaml_emitter_emit_flow_sequence_item(emitter, event, false)
236
case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
237
return yaml_emitter_emit_flow_mapping_key(emitter, event, true)
239
case yaml_EMIT_FLOW_MAPPING_KEY_STATE:
240
return yaml_emitter_emit_flow_mapping_key(emitter, event, false)
242
case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
243
return yaml_emitter_emit_flow_mapping_value(emitter, event, true)
245
case yaml_EMIT_FLOW_MAPPING_VALUE_STATE:
246
return yaml_emitter_emit_flow_mapping_value(emitter, event, false)
248
case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
249
return yaml_emitter_emit_block_sequence_item(emitter, event, true)
251
case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
252
return yaml_emitter_emit_block_sequence_item(emitter, event, false)
254
case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
255
return yaml_emitter_emit_block_mapping_key(emitter, event, true)
257
case yaml_EMIT_BLOCK_MAPPING_KEY_STATE:
258
return yaml_emitter_emit_block_mapping_key(emitter, event, false)
260
case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
261
return yaml_emitter_emit_block_mapping_value(emitter, event, true)
263
case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:
264
return yaml_emitter_emit_block_mapping_value(emitter, event, false)
266
case yaml_EMIT_END_STATE:
267
return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")
269
panic("invalid emitter state")
272
// Expect STREAM-START.
273
func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
274
if event.typ != yaml_STREAM_START_EVENT {
275
return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START")
277
if emitter.encoding == yaml_ANY_ENCODING {
278
emitter.encoding = event.encoding
279
if emitter.encoding == yaml_ANY_ENCODING {
280
emitter.encoding = yaml_UTF8_ENCODING
283
if emitter.best_indent < 2 || emitter.best_indent > 9 {
284
emitter.best_indent = 2
286
if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {
287
emitter.best_width = 80
289
if emitter.best_width < 0 {
290
emitter.best_width = 1<<31 - 1
292
if emitter.line_break == yaml_ANY_BREAK {
293
emitter.line_break = yaml_LN_BREAK
299
emitter.whitespace = true
300
emitter.indention = true
302
if emitter.encoding != yaml_UTF8_ENCODING {
303
if !yaml_emitter_write_bom(emitter) {
307
emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE
311
// Expect DOCUMENT-START or STREAM-END.
312
func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
314
if event.typ == yaml_DOCUMENT_START_EVENT {
316
if event.version_directive != nil {
317
if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {
322
for i := 0; i < len(event.tag_directives); i++ {
323
tag_directive := &event.tag_directives[i]
324
if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) {
327
if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {
332
for i := 0; i < len(default_tag_directives); i++ {
333
tag_directive := &default_tag_directives[i]
334
if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) {
339
implicit := event.implicit
340
if !first || emitter.canonical {
344
if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) {
345
if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
348
if !yaml_emitter_write_indent(emitter) {
353
if event.version_directive != nil {
355
if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) {
358
if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) {
361
if !yaml_emitter_write_indent(emitter) {
366
if len(event.tag_directives) > 0 {
368
for i := 0; i < len(event.tag_directives); i++ {
369
tag_directive := &event.tag_directives[i]
370
if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) {
373
if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {
376
if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {
379
if !yaml_emitter_write_indent(emitter) {
385
if yaml_emitter_check_empty_document(emitter) {
389
if !yaml_emitter_write_indent(emitter) {
392
if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) {
395
if emitter.canonical {
396
if !yaml_emitter_write_indent(emitter) {
402
emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE
406
if event.typ == yaml_STREAM_END_EVENT {
407
if emitter.open_ended {
408
if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
411
if !yaml_emitter_write_indent(emitter) {
415
if !yaml_emitter_flush(emitter) {
418
emitter.state = yaml_EMIT_END_STATE
422
return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END")
425
// Expect the root node.
426
func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool {
427
emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE)
428
return yaml_emitter_emit_node(emitter, event, true, false, false, false)
431
// Expect DOCUMENT-END.
432
func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool {
433
if event.typ != yaml_DOCUMENT_END_EVENT {
434
return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END")
436
if !yaml_emitter_write_indent(emitter) {
440
// [Go] Allocate the slice elsewhere.
441
if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
444
if !yaml_emitter_write_indent(emitter) {
448
if !yaml_emitter_flush(emitter) {
451
emitter.state = yaml_EMIT_DOCUMENT_START_STATE
452
emitter.tag_directives = emitter.tag_directives[:0]
456
// Expect a flow item node.
457
func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
459
if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {
462
if !yaml_emitter_increase_indent(emitter, true, false) {
468
if event.typ == yaml_SEQUENCE_END_EVENT {
470
emitter.indent = emitter.indents[len(emitter.indents)-1]
471
emitter.indents = emitter.indents[:len(emitter.indents)-1]
472
if emitter.canonical && !first {
473
if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
476
if !yaml_emitter_write_indent(emitter) {
480
if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {
483
emitter.state = emitter.states[len(emitter.states)-1]
484
emitter.states = emitter.states[:len(emitter.states)-1]
490
if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
495
if emitter.canonical || emitter.column > emitter.best_width {
496
if !yaml_emitter_write_indent(emitter) {
500
emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)
501
return yaml_emitter_emit_node(emitter, event, false, true, false, false)
504
// Expect a flow key node.
505
func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
507
if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {
510
if !yaml_emitter_increase_indent(emitter, true, false) {
516
if event.typ == yaml_MAPPING_END_EVENT {
518
emitter.indent = emitter.indents[len(emitter.indents)-1]
519
emitter.indents = emitter.indents[:len(emitter.indents)-1]
520
if emitter.canonical && !first {
521
if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
524
if !yaml_emitter_write_indent(emitter) {
528
if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {
531
emitter.state = emitter.states[len(emitter.states)-1]
532
emitter.states = emitter.states[:len(emitter.states)-1]
537
if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
541
if emitter.canonical || emitter.column > emitter.best_width {
542
if !yaml_emitter_write_indent(emitter) {
547
if !emitter.canonical && yaml_emitter_check_simple_key(emitter) {
548
emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)
549
return yaml_emitter_emit_node(emitter, event, false, false, true, true)
551
if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {
554
emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)
555
return yaml_emitter_emit_node(emitter, event, false, false, true, false)
558
// Expect a flow value node.
559
func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
561
if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
565
if emitter.canonical || emitter.column > emitter.best_width {
566
if !yaml_emitter_write_indent(emitter) {
570
if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {
574
emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)
575
return yaml_emitter_emit_node(emitter, event, false, false, true, false)
578
// Expect a block item node.
579
func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
581
if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) {
585
if event.typ == yaml_SEQUENCE_END_EVENT {
586
emitter.indent = emitter.indents[len(emitter.indents)-1]
587
emitter.indents = emitter.indents[:len(emitter.indents)-1]
588
emitter.state = emitter.states[len(emitter.states)-1]
589
emitter.states = emitter.states[:len(emitter.states)-1]
592
if !yaml_emitter_write_indent(emitter) {
595
if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {
598
emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)
599
return yaml_emitter_emit_node(emitter, event, false, true, false, false)
602
// Expect a block key node.
603
func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
605
if !yaml_emitter_increase_indent(emitter, false, false) {
609
if event.typ == yaml_MAPPING_END_EVENT {
610
emitter.indent = emitter.indents[len(emitter.indents)-1]
611
emitter.indents = emitter.indents[:len(emitter.indents)-1]
612
emitter.state = emitter.states[len(emitter.states)-1]
613
emitter.states = emitter.states[:len(emitter.states)-1]
616
if !yaml_emitter_write_indent(emitter) {
619
if yaml_emitter_check_simple_key(emitter) {
620
emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)
621
return yaml_emitter_emit_node(emitter, event, false, false, true, true)
623
if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {
626
emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)
627
return yaml_emitter_emit_node(emitter, event, false, false, true, false)
630
// Expect a block value node.
631
func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
633
if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
637
if !yaml_emitter_write_indent(emitter) {
640
if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {
644
emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)
645
return yaml_emitter_emit_node(emitter, event, false, false, true, false)
649
func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
650
root bool, sequence bool, mapping bool, simple_key bool) bool {
652
emitter.root_context = root
653
emitter.sequence_context = sequence
654
emitter.mapping_context = mapping
655
emitter.simple_key_context = simple_key
658
case yaml_ALIAS_EVENT:
659
return yaml_emitter_emit_alias(emitter, event)
660
case yaml_SCALAR_EVENT:
661
return yaml_emitter_emit_scalar(emitter, event)
662
case yaml_SEQUENCE_START_EVENT:
663
return yaml_emitter_emit_sequence_start(emitter, event)
664
case yaml_MAPPING_START_EVENT:
665
return yaml_emitter_emit_mapping_start(emitter, event)
667
return yaml_emitter_set_emitter_error(emitter,
668
fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))
673
func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool {
674
if !yaml_emitter_process_anchor(emitter) {
677
emitter.state = emitter.states[len(emitter.states)-1]
678
emitter.states = emitter.states[:len(emitter.states)-1]
683
func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool {
684
if !yaml_emitter_select_scalar_style(emitter, event) {
687
if !yaml_emitter_process_anchor(emitter) {
690
if !yaml_emitter_process_tag(emitter) {
693
if !yaml_emitter_increase_indent(emitter, true, false) {
696
if !yaml_emitter_process_scalar(emitter) {
699
emitter.indent = emitter.indents[len(emitter.indents)-1]
700
emitter.indents = emitter.indents[:len(emitter.indents)-1]
701
emitter.state = emitter.states[len(emitter.states)-1]
702
emitter.states = emitter.states[:len(emitter.states)-1]
706
// Expect SEQUENCE-START.
707
func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
708
if !yaml_emitter_process_anchor(emitter) {
711
if !yaml_emitter_process_tag(emitter) {
714
if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE ||
715
yaml_emitter_check_empty_sequence(emitter) {
716
emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE
718
emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE
723
// Expect MAPPING-START.
724
func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
725
if !yaml_emitter_process_anchor(emitter) {
728
if !yaml_emitter_process_tag(emitter) {
731
if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE ||
732
yaml_emitter_check_empty_mapping(emitter) {
733
emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE
735
emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE
740
// Check if the document content is an empty scalar.
741
func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool {
742
return false // [Go] Huh?
745
// Check if the next events represent an empty sequence.
746
func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool {
747
if len(emitter.events)-emitter.events_head < 2 {
750
return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT &&
751
emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT
754
// Check if the next events represent an empty mapping.
755
func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool {
756
if len(emitter.events)-emitter.events_head < 2 {
759
return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT &&
760
emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT
763
// Check if the next node can be expressed as a simple key.
764
func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool {
766
switch emitter.events[emitter.events_head].typ {
767
case yaml_ALIAS_EVENT:
768
length += len(emitter.anchor_data.anchor)
769
case yaml_SCALAR_EVENT:
770
if emitter.scalar_data.multiline {
773
length += len(emitter.anchor_data.anchor) +
774
len(emitter.tag_data.handle) +
775
len(emitter.tag_data.suffix) +
776
len(emitter.scalar_data.value)
777
case yaml_SEQUENCE_START_EVENT:
778
if !yaml_emitter_check_empty_sequence(emitter) {
781
length += len(emitter.anchor_data.anchor) +
782
len(emitter.tag_data.handle) +
783
len(emitter.tag_data.suffix)
784
case yaml_MAPPING_START_EVENT:
785
if !yaml_emitter_check_empty_mapping(emitter) {
788
length += len(emitter.anchor_data.anchor) +
789
len(emitter.tag_data.handle) +
790
len(emitter.tag_data.suffix)
797
// Determine an acceptable scalar style.
798
func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool {
800
no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0
801
if no_tag && !event.implicit && !event.quoted_implicit {
802
return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified")
805
style := event.scalar_style()
806
if style == yaml_ANY_SCALAR_STYLE {
807
style = yaml_PLAIN_SCALAR_STYLE
809
if emitter.canonical {
810
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
812
if emitter.simple_key_context && emitter.scalar_data.multiline {
813
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
816
if style == yaml_PLAIN_SCALAR_STYLE {
817
if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed ||
818
emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed {
819
style = yaml_SINGLE_QUOTED_SCALAR_STYLE
821
if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) {
822
style = yaml_SINGLE_QUOTED_SCALAR_STYLE
824
if no_tag && !event.implicit {
825
style = yaml_SINGLE_QUOTED_SCALAR_STYLE
828
if style == yaml_SINGLE_QUOTED_SCALAR_STYLE {
829
if !emitter.scalar_data.single_quoted_allowed {
830
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
833
if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE {
834
if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context {
835
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
839
if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE {
840
emitter.tag_data.handle = []byte{'!'}
842
emitter.scalar_data.style = style
847
func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
848
if emitter.anchor_data.anchor == nil {
852
if emitter.anchor_data.alias {
855
if !yaml_emitter_write_indicator(emitter, c, true, false, false) {
858
return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor)
862
func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool {
863
if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 {
866
if len(emitter.tag_data.handle) > 0 {
867
if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) {
870
if len(emitter.tag_data.suffix) > 0 {
871
if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
876
// [Go] Allocate these slices elsewhere.
877
if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) {
880
if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
883
if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) {
891
func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool {
892
switch emitter.scalar_data.style {
893
case yaml_PLAIN_SCALAR_STYLE:
894
return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
896
case yaml_SINGLE_QUOTED_SCALAR_STYLE:
897
return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
899
case yaml_DOUBLE_QUOTED_SCALAR_STYLE:
900
return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
902
case yaml_LITERAL_SCALAR_STYLE:
903
return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value)
905
case yaml_FOLDED_SCALAR_STYLE:
906
return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value)
908
panic("unknown scalar style")
911
// Check if a %YAML directive is valid.
912
func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool {
913
if version_directive.major != 1 || version_directive.minor != 1 {
914
return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive")
919
// Check if a %TAG directive is valid.
920
func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool {
921
handle := tag_directive.handle
922
prefix := tag_directive.prefix
923
if len(handle) == 0 {
924
return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty")
926
if handle[0] != '!' {
927
return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'")
929
if handle[len(handle)-1] != '!' {
930
return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'")
932
for i := 1; i < len(handle)-1; i += width(handle[i]) {
933
if !is_alpha(handle, i) {
934
return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only")
937
if len(prefix) == 0 {
938
return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty")
943
// Check if an anchor is valid.
944
func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool {
945
if len(anchor) == 0 {
946
problem := "anchor value must not be empty"
948
problem = "alias value must not be empty"
950
return yaml_emitter_set_emitter_error(emitter, problem)
952
for i := 0; i < len(anchor); i += width(anchor[i]) {
953
if !is_alpha(anchor, i) {
954
problem := "anchor value must contain alphanumerical characters only"
956
problem = "alias value must contain alphanumerical characters only"
958
return yaml_emitter_set_emitter_error(emitter, problem)
961
emitter.anchor_data.anchor = anchor
962
emitter.anchor_data.alias = alias
966
// Check if a tag is valid.
967
func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {
969
return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")
971
for i := 0; i < len(emitter.tag_directives); i++ {
972
tag_directive := &emitter.tag_directives[i]
973
if bytes.HasPrefix(tag, tag_directive.prefix) {
974
emitter.tag_data.handle = tag_directive.handle
975
emitter.tag_data.suffix = tag[len(tag_directive.prefix):]
979
emitter.tag_data.suffix = tag
983
// Check if a scalar is valid.
984
func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
986
block_indicators = false
987
flow_indicators = false
989
special_characters = false
991
leading_space = false
992
leading_break = false
993
trailing_space = false
994
trailing_break = false
998
preceded_by_whitespace = false
999
followed_by_whitespace = false
1000
previous_space = false
1001
previous_break = false
1004
emitter.scalar_data.value = value
1006
if len(value) == 0 {
1007
emitter.scalar_data.multiline = false
1008
emitter.scalar_data.flow_plain_allowed = false
1009
emitter.scalar_data.block_plain_allowed = true
1010
emitter.scalar_data.single_quoted_allowed = true
1011
emitter.scalar_data.block_allowed = false
1015
if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) {
1016
block_indicators = true
1017
flow_indicators = true
1020
preceded_by_whitespace = true
1021
for i, w := 0, 0; i < len(value); i += w {
1023
followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
1027
case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`':
1028
flow_indicators = true
1029
block_indicators = true
1031
flow_indicators = true
1032
if followed_by_whitespace {
1033
block_indicators = true
1036
if followed_by_whitespace {
1037
flow_indicators = true
1038
block_indicators = true
1043
case ',', '?', '[', ']', '{', '}':
1044
flow_indicators = true
1046
flow_indicators = true
1047
if followed_by_whitespace {
1048
block_indicators = true
1051
if preceded_by_whitespace {
1052
flow_indicators = true
1053
block_indicators = true
1058
if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode {
1059
special_characters = true
1061
if is_space(value, i) {
1063
leading_space = true
1065
if i+width(value[i]) == len(value) {
1066
trailing_space = true
1071
previous_space = true
1072
previous_break = false
1073
} else if is_break(value, i) {
1076
leading_break = true
1078
if i+width(value[i]) == len(value) {
1079
trailing_break = true
1084
previous_space = false
1085
previous_break = true
1087
previous_space = false
1088
previous_break = false
1091
// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
1092
preceded_by_whitespace = is_blankz(value, i)
1095
emitter.scalar_data.multiline = line_breaks
1096
emitter.scalar_data.flow_plain_allowed = true
1097
emitter.scalar_data.block_plain_allowed = true
1098
emitter.scalar_data.single_quoted_allowed = true
1099
emitter.scalar_data.block_allowed = true
1101
if leading_space || leading_break || trailing_space || trailing_break {
1102
emitter.scalar_data.flow_plain_allowed = false
1103
emitter.scalar_data.block_plain_allowed = false
1106
emitter.scalar_data.block_allowed = false
1109
emitter.scalar_data.flow_plain_allowed = false
1110
emitter.scalar_data.block_plain_allowed = false
1111
emitter.scalar_data.single_quoted_allowed = false
1113
if space_break || special_characters {
1114
emitter.scalar_data.flow_plain_allowed = false
1115
emitter.scalar_data.block_plain_allowed = false
1116
emitter.scalar_data.single_quoted_allowed = false
1117
emitter.scalar_data.block_allowed = false
1120
emitter.scalar_data.flow_plain_allowed = false
1121
emitter.scalar_data.block_plain_allowed = false
1123
if flow_indicators {
1124
emitter.scalar_data.flow_plain_allowed = false
1126
if block_indicators {
1127
emitter.scalar_data.block_plain_allowed = false
1132
// Check if the event data is valid.
1133
func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {
1135
emitter.anchor_data.anchor = nil
1136
emitter.tag_data.handle = nil
1137
emitter.tag_data.suffix = nil
1138
emitter.scalar_data.value = nil
1141
case yaml_ALIAS_EVENT:
1142
if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) {
1146
case yaml_SCALAR_EVENT:
1147
if len(event.anchor) > 0 {
1148
if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
1152
if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) {
1153
if !yaml_emitter_analyze_tag(emitter, event.tag) {
1157
if !yaml_emitter_analyze_scalar(emitter, event.value) {
1161
case yaml_SEQUENCE_START_EVENT:
1162
if len(event.anchor) > 0 {
1163
if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
1167
if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
1168
if !yaml_emitter_analyze_tag(emitter, event.tag) {
1173
case yaml_MAPPING_START_EVENT:
1174
if len(event.anchor) > 0 {
1175
if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
1179
if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
1180
if !yaml_emitter_analyze_tag(emitter, event.tag) {
1188
// Write the BOM character.
1189
func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {
1190
if !flush(emitter) {
1193
pos := emitter.buffer_pos
1194
emitter.buffer[pos+0] = '\xEF'
1195
emitter.buffer[pos+1] = '\xBB'
1196
emitter.buffer[pos+2] = '\xBF'
1197
emitter.buffer_pos += 3
1201
func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {
1202
indent := emitter.indent
1206
if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {
1207
if !put_break(emitter) {
1211
for emitter.column < indent {
1212
if !put(emitter, ' ') {
1216
emitter.whitespace = true
1217
emitter.indention = true
1221
func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool {
1222
if need_whitespace && !emitter.whitespace {
1223
if !put(emitter, ' ') {
1227
if !write_all(emitter, indicator) {
1230
emitter.whitespace = is_whitespace
1231
emitter.indention = (emitter.indention && is_indention)
1232
emitter.open_ended = false
1236
func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {
1237
if !write_all(emitter, value) {
1240
emitter.whitespace = false
1241
emitter.indention = false
1245
func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {
1246
if !emitter.whitespace {
1247
if !put(emitter, ' ') {
1251
if !write_all(emitter, value) {
1254
emitter.whitespace = false
1255
emitter.indention = false
1259
func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool {
1260
if need_whitespace && !emitter.whitespace {
1261
if !put(emitter, ' ') {
1265
for i := 0; i < len(value); {
1268
case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']':
1271
must_write = is_alpha(value, i)
1274
if !write(emitter, value, &i) {
1278
w := width(value[i])
1279
for k := 0; k < w; k++ {
1282
if !put(emitter, '%') {
1292
if !put(emitter, c) {
1302
if !put(emitter, c) {
1308
emitter.whitespace = false
1309
emitter.indention = false
1313
func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
1314
if !emitter.whitespace {
1315
if !put(emitter, ' ') {
1322
for i := 0; i < len(value); {
1323
if is_space(value, i) {
1324
if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) {
1325
if !yaml_emitter_write_indent(emitter) {
1328
i += width(value[i])
1330
if !write(emitter, value, &i) {
1335
} else if is_break(value, i) {
1336
if !breaks && value[i] == '\n' {
1337
if !put_break(emitter) {
1341
if !write_break(emitter, value, &i) {
1344
emitter.indention = true
1348
if !yaml_emitter_write_indent(emitter) {
1352
if !write(emitter, value, &i) {
1355
emitter.indention = false
1361
emitter.whitespace = false
1362
emitter.indention = false
1363
if emitter.root_context {
1364
emitter.open_ended = true
1370
func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
1372
if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) {
1378
for i := 0; i < len(value); {
1379
if is_space(value, i) {
1380
if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) {
1381
if !yaml_emitter_write_indent(emitter) {
1384
i += width(value[i])
1386
if !write(emitter, value, &i) {
1391
} else if is_break(value, i) {
1392
if !breaks && value[i] == '\n' {
1393
if !put_break(emitter) {
1397
if !write_break(emitter, value, &i) {
1400
emitter.indention = true
1404
if !yaml_emitter_write_indent(emitter) {
1408
if value[i] == '\'' {
1409
if !put(emitter, '\'') {
1413
if !write(emitter, value, &i) {
1416
emitter.indention = false
1421
if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) {
1424
emitter.whitespace = false
1425
emitter.indention = false
1429
func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
1431
if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) {
1435
for i := 0; i < len(value); {
1436
if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) ||
1437
is_bom(value, i) || is_break(value, i) ||
1438
value[i] == '"' || value[i] == '\\' {
1445
case octet&0x80 == 0x00:
1446
w, v = 1, rune(octet&0x7F)
1447
case octet&0xE0 == 0xC0:
1448
w, v = 2, rune(octet&0x1F)
1449
case octet&0xF0 == 0xE0:
1450
w, v = 3, rune(octet&0x0F)
1451
case octet&0xF8 == 0xF0:
1452
w, v = 4, rune(octet&0x07)
1454
for k := 1; k < w; k++ {
1456
v = (v << 6) + (rune(octet) & 0x3F)
1460
if !put(emitter, '\\') {
1467
ok = put(emitter, '0')
1469
ok = put(emitter, 'a')
1471
ok = put(emitter, 'b')
1473
ok = put(emitter, 't')
1475
ok = put(emitter, 'n')
1477
ok = put(emitter, 'v')
1479
ok = put(emitter, 'f')
1481
ok = put(emitter, 'r')
1483
ok = put(emitter, 'e')
1485
ok = put(emitter, '"')
1487
ok = put(emitter, '\\')
1489
ok = put(emitter, 'N')
1491
ok = put(emitter, '_')
1493
ok = put(emitter, 'L')
1495
ok = put(emitter, 'P')
1498
ok = put(emitter, 'x')
1500
} else if v <= 0xFFFF {
1501
ok = put(emitter, 'u')
1504
ok = put(emitter, 'U')
1507
for k := (w - 1) * 4; ok && k >= 0; k -= 4 {
1508
digit := byte((v >> uint(k)) & 0x0F)
1510
ok = put(emitter, digit+'0')
1512
ok = put(emitter, digit+'A'-10)
1520
} else if is_space(value, i) {
1521
if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 {
1522
if !yaml_emitter_write_indent(emitter) {
1525
if is_space(value, i+1) {
1526
if !put(emitter, '\\') {
1530
i += width(value[i])
1531
} else if !write(emitter, value, &i) {
1536
if !write(emitter, value, &i) {
1542
if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) {
1545
emitter.whitespace = false
1546
emitter.indention = false
1550
func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool {
1551
if is_space(value, 0) || is_break(value, 0) {
1552
indent_hint := []byte{'0' + byte(emitter.best_indent)}
1553
if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) {
1558
emitter.open_ended = false
1560
var chomp_hint [1]byte
1561
if len(value) == 0 {
1565
for value[i]&0xC0 == 0x80 {
1568
if !is_break(value, i) {
1572
emitter.open_ended = true
1575
for value[i]&0xC0 == 0x80 {
1578
if is_break(value, i) {
1580
emitter.open_ended = true
1584
if chomp_hint[0] != 0 {
1585
if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {
1592
func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {
1593
if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {
1596
if !yaml_emitter_write_block_scalar_hints(emitter, value) {
1599
if !put_break(emitter) {
1602
emitter.indention = true
1603
emitter.whitespace = true
1605
for i := 0; i < len(value); {
1606
if is_break(value, i) {
1607
if !write_break(emitter, value, &i) {
1610
emitter.indention = true
1614
if !yaml_emitter_write_indent(emitter) {
1618
if !write(emitter, value, &i) {
1621
emitter.indention = false
1629
func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {
1630
if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {
1633
if !yaml_emitter_write_block_scalar_hints(emitter, value) {
1637
if !put_break(emitter) {
1640
emitter.indention = true
1641
emitter.whitespace = true
1644
leading_spaces := true
1645
for i := 0; i < len(value); {
1646
if is_break(value, i) {
1647
if !breaks && !leading_spaces && value[i] == '\n' {
1649
for is_break(value, k) {
1650
k += width(value[k])
1652
if !is_blankz(value, k) {
1653
if !put_break(emitter) {
1658
if !write_break(emitter, value, &i) {
1661
emitter.indention = true
1665
if !yaml_emitter_write_indent(emitter) {
1668
leading_spaces = is_blank(value, i)
1670
if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {
1671
if !yaml_emitter_write_indent(emitter) {
1674
i += width(value[i])
1676
if !write(emitter, value, &i) {
1680
emitter.indention = false