Mercurial > yakumo_izuru > aya
comparison vendor/gopkg.in/yaml.v3/emitterc.go @ 74:d8727551f403 draft
The Empress (III)
* Change the way how versions are handled in version.go (to ease `go
install`)
* Upgrade yaml.v2 to yaml.v3
Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author | yakumo.izuru |
---|---|
date | Mon, 04 Dec 2023 00:54:29 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
73:8533d875a2bb | 74:d8727551f403 |
---|---|
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 } |