74
|
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 }
|