ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/aya/vendor/gopkg.in/yaml.v3/emitterc.go
Revision: 1.1
Committed: Mon Sep 30 00:42:06 2024 UTC (6 weeks, 4 days ago) by yakumo_izuru
Branch: MAIN
CVS Tags: HEAD
Log Message:
Mirrored from https://git.chaotic.ninja/git/yakumo_izuru/aya

File Contents

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