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