Mercurial > yakumo_izuru > aya
comparison vendor/gopkg.in/yaml.v2/emitterc.go @ 66:787b5ee0289d draft
Use vendored modules
Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author | yakumo.izuru |
---|---|
date | Sun, 23 Jul 2023 13:18:53 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
65:6d985efa0f7a | 66:787b5ee0289d |
---|---|
1 package yaml | |
2 | |
3 import ( | |
4 "bytes" | |
5 "fmt" | |
6 ) | |
7 | |
8 // Flush the buffer if needed. | |
9 func flush(emitter *yaml_emitter_t) bool { | |
10 if emitter.buffer_pos+5 >= len(emitter.buffer) { | |
11 return yaml_emitter_flush(emitter) | |
12 } | |
13 return true | |
14 } | |
15 | |
16 // Put a character to the output buffer. | |
17 func put(emitter *yaml_emitter_t, value byte) bool { | |
18 if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { | |
19 return false | |
20 } | |
21 emitter.buffer[emitter.buffer_pos] = value | |
22 emitter.buffer_pos++ | |
23 emitter.column++ | |
24 return true | |
25 } | |
26 | |
27 // Put a line break to the output buffer. | |
28 func put_break(emitter *yaml_emitter_t) bool { | |
29 if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { | |
30 return false | |
31 } | |
32 switch emitter.line_break { | |
33 case yaml_CR_BREAK: | |
34 emitter.buffer[emitter.buffer_pos] = '\r' | |
35 emitter.buffer_pos += 1 | |
36 case yaml_LN_BREAK: | |
37 emitter.buffer[emitter.buffer_pos] = '\n' | |
38 emitter.buffer_pos += 1 | |
39 case yaml_CRLN_BREAK: | |
40 emitter.buffer[emitter.buffer_pos+0] = '\r' | |
41 emitter.buffer[emitter.buffer_pos+1] = '\n' | |
42 emitter.buffer_pos += 2 | |
43 default: | |
44 panic("unknown line break setting") | |
45 } | |
46 emitter.column = 0 | |
47 emitter.line++ | |
48 return true | |
49 } | |
50 | |
51 // Copy a character from a string into buffer. | |
52 func write(emitter *yaml_emitter_t, s []byte, i *int) bool { | |
53 if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { | |
54 return false | |
55 } | |
56 p := emitter.buffer_pos | |
57 w := width(s[*i]) | |
58 switch w { | |
59 case 4: | |
60 emitter.buffer[p+3] = s[*i+3] | |
61 fallthrough | |
62 case 3: | |
63 emitter.buffer[p+2] = s[*i+2] | |
64 fallthrough | |
65 case 2: | |
66 emitter.buffer[p+1] = s[*i+1] | |
67 fallthrough | |
68 case 1: | |
69 emitter.buffer[p+0] = s[*i+0] | |
70 default: | |
71 panic("unknown character width") | |
72 } | |
73 emitter.column++ | |
74 emitter.buffer_pos += w | |
75 *i += w | |
76 return true | |
77 } | |
78 | |
79 // Write a whole string into buffer. | |
80 func write_all(emitter *yaml_emitter_t, s []byte) bool { | |
81 for i := 0; i < len(s); { | |
82 if !write(emitter, s, &i) { | |
83 return false | |
84 } | |
85 } | |
86 return true | |
87 } | |
88 | |
89 // Copy a line break character from a string into buffer. | |
90 func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool { | |
91 if s[*i] == '\n' { | |
92 if !put_break(emitter) { | |
93 return false | |
94 } | |
95 *i++ | |
96 } else { | |
97 if !write(emitter, s, i) { | |
98 return false | |
99 } | |
100 emitter.column = 0 | |
101 emitter.line++ | |
102 } | |
103 return true | |
104 } | |
105 | |
106 // Set an emitter error and return false. | |
107 func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool { | |
108 emitter.error = yaml_EMITTER_ERROR | |
109 emitter.problem = problem | |
110 return false | |
111 } | |
112 | |
113 // Emit an event. | |
114 func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool { | |
115 emitter.events = append(emitter.events, *event) | |
116 for !yaml_emitter_need_more_events(emitter) { | |
117 event := &emitter.events[emitter.events_head] | |
118 if !yaml_emitter_analyze_event(emitter, event) { | |
119 return false | |
120 } | |
121 if !yaml_emitter_state_machine(emitter, event) { | |
122 return false | |
123 } | |
124 yaml_event_delete(event) | |
125 emitter.events_head++ | |
126 } | |
127 return true | |
128 } | |
129 | |
130 // Check if we need to accumulate more events before emitting. | |
131 // | |
132 // We accumulate extra | |
133 // - 1 event for DOCUMENT-START | |
134 // - 2 events for SEQUENCE-START | |
135 // - 3 events for MAPPING-START | |
136 // | |
137 func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool { | |
138 if emitter.events_head == len(emitter.events) { | |
139 return true | |
140 } | |
141 var accumulate int | |
142 switch emitter.events[emitter.events_head].typ { | |
143 case yaml_DOCUMENT_START_EVENT: | |
144 accumulate = 1 | |
145 break | |
146 case yaml_SEQUENCE_START_EVENT: | |
147 accumulate = 2 | |
148 break | |
149 case yaml_MAPPING_START_EVENT: | |
150 accumulate = 3 | |
151 break | |
152 default: | |
153 return false | |
154 } | |
155 if len(emitter.events)-emitter.events_head > accumulate { | |
156 return false | |
157 } | |
158 var level int | |
159 for i := emitter.events_head; i < len(emitter.events); i++ { | |
160 switch emitter.events[i].typ { | |
161 case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT: | |
162 level++ | |
163 case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT: | |
164 level-- | |
165 } | |
166 if level == 0 { | |
167 return false | |
168 } | |
169 } | |
170 return true | |
171 } | |
172 | |
173 // Append a directive to the directives stack. | |
174 func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool { | |
175 for i := 0; i < len(emitter.tag_directives); i++ { | |
176 if bytes.Equal(value.handle, emitter.tag_directives[i].handle) { | |
177 if allow_duplicates { | |
178 return true | |
179 } | |
180 return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive") | |
181 } | |
182 } | |
183 | |
184 // [Go] Do we actually need to copy this given garbage collection | |
185 // and the lack of deallocating destructors? | |
186 tag_copy := yaml_tag_directive_t{ | |
187 handle: make([]byte, len(value.handle)), | |
188 prefix: make([]byte, len(value.prefix)), | |
189 } | |
190 copy(tag_copy.handle, value.handle) | |
191 copy(tag_copy.prefix, value.prefix) | |
192 emitter.tag_directives = append(emitter.tag_directives, tag_copy) | |
193 return true | |
194 } | |
195 | |
196 // Increase the indentation level. | |
197 func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool { | |
198 emitter.indents = append(emitter.indents, emitter.indent) | |
199 if emitter.indent < 0 { | |
200 if flow { | |
201 emitter.indent = emitter.best_indent | |
202 } else { | |
203 emitter.indent = 0 | |
204 } | |
205 } else if !indentless { | |
206 emitter.indent += emitter.best_indent | |
207 } | |
208 return true | |
209 } | |
210 | |
211 // State dispatcher. | |
212 func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool { | |
213 switch emitter.state { | |
214 default: | |
215 case yaml_EMIT_STREAM_START_STATE: | |
216 return yaml_emitter_emit_stream_start(emitter, event) | |
217 | |
218 case yaml_EMIT_FIRST_DOCUMENT_START_STATE: | |
219 return yaml_emitter_emit_document_start(emitter, event, true) | |
220 | |
221 case yaml_EMIT_DOCUMENT_START_STATE: | |
222 return yaml_emitter_emit_document_start(emitter, event, false) | |
223 | |
224 case yaml_EMIT_DOCUMENT_CONTENT_STATE: | |
225 return yaml_emitter_emit_document_content(emitter, event) | |
226 | |
227 case yaml_EMIT_DOCUMENT_END_STATE: | |
228 return yaml_emitter_emit_document_end(emitter, event) | |
229 | |
230 case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: | |
231 return yaml_emitter_emit_flow_sequence_item(emitter, event, true) | |
232 | |
233 case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE: | |
234 return yaml_emitter_emit_flow_sequence_item(emitter, event, false) | |
235 | |
236 case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: | |
237 return yaml_emitter_emit_flow_mapping_key(emitter, event, true) | |
238 | |
239 case yaml_EMIT_FLOW_MAPPING_KEY_STATE: | |
240 return yaml_emitter_emit_flow_mapping_key(emitter, event, false) | |
241 | |
242 case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: | |
243 return yaml_emitter_emit_flow_mapping_value(emitter, event, true) | |
244 | |
245 case yaml_EMIT_FLOW_MAPPING_VALUE_STATE: | |
246 return yaml_emitter_emit_flow_mapping_value(emitter, event, false) | |
247 | |
248 case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: | |
249 return yaml_emitter_emit_block_sequence_item(emitter, event, true) | |
250 | |
251 case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE: | |
252 return yaml_emitter_emit_block_sequence_item(emitter, event, false) | |
253 | |
254 case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: | |
255 return yaml_emitter_emit_block_mapping_key(emitter, event, true) | |
256 | |
257 case yaml_EMIT_BLOCK_MAPPING_KEY_STATE: | |
258 return yaml_emitter_emit_block_mapping_key(emitter, event, false) | |
259 | |
260 case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: | |
261 return yaml_emitter_emit_block_mapping_value(emitter, event, true) | |
262 | |
263 case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE: | |
264 return yaml_emitter_emit_block_mapping_value(emitter, event, false) | |
265 | |
266 case yaml_EMIT_END_STATE: | |
267 return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END") | |
268 } | |
269 panic("invalid emitter state") | |
270 } | |
271 | |
272 // Expect STREAM-START. | |
273 func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { | |
274 if event.typ != yaml_STREAM_START_EVENT { | |
275 return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START") | |
276 } | |
277 if emitter.encoding == yaml_ANY_ENCODING { | |
278 emitter.encoding = event.encoding | |
279 if emitter.encoding == yaml_ANY_ENCODING { | |
280 emitter.encoding = yaml_UTF8_ENCODING | |
281 } | |
282 } | |
283 if emitter.best_indent < 2 || emitter.best_indent > 9 { | |
284 emitter.best_indent = 2 | |
285 } | |
286 if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 { | |
287 emitter.best_width = 80 | |
288 } | |
289 if emitter.best_width < 0 { | |
290 emitter.best_width = 1<<31 - 1 | |
291 } | |
292 if emitter.line_break == yaml_ANY_BREAK { | |
293 emitter.line_break = yaml_LN_BREAK | |
294 } | |
295 | |
296 emitter.indent = -1 | |
297 emitter.line = 0 | |
298 emitter.column = 0 | |
299 emitter.whitespace = true | |
300 emitter.indention = true | |
301 | |
302 if emitter.encoding != yaml_UTF8_ENCODING { | |
303 if !yaml_emitter_write_bom(emitter) { | |
304 return false | |
305 } | |
306 } | |
307 emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE | |
308 return true | |
309 } | |
310 | |
311 // Expect DOCUMENT-START or STREAM-END. | |
312 func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { | |
313 | |
314 if event.typ == yaml_DOCUMENT_START_EVENT { | |
315 | |
316 if event.version_directive != nil { | |
317 if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) { | |
318 return false | |
319 } | |
320 } | |
321 | |
322 for i := 0; i < len(event.tag_directives); i++ { | |
323 tag_directive := &event.tag_directives[i] | |
324 if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) { | |
325 return false | |
326 } | |
327 if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) { | |
328 return false | |
329 } | |
330 } | |
331 | |
332 for i := 0; i < len(default_tag_directives); i++ { | |
333 tag_directive := &default_tag_directives[i] | |
334 if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) { | |
335 return false | |
336 } | |
337 } | |
338 | |
339 implicit := event.implicit | |
340 if !first || emitter.canonical { | |
341 implicit = false | |
342 } | |
343 | |
344 if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) { | |
345 if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { | |
346 return false | |
347 } | |
348 if !yaml_emitter_write_indent(emitter) { | |
349 return false | |
350 } | |
351 } | |
352 | |
353 if event.version_directive != nil { | |
354 implicit = false | |
355 if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) { | |
356 return false | |
357 } | |
358 if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) { | |
359 return false | |
360 } | |
361 if !yaml_emitter_write_indent(emitter) { | |
362 return false | |
363 } | |
364 } | |
365 | |
366 if len(event.tag_directives) > 0 { | |
367 implicit = false | |
368 for i := 0; i < len(event.tag_directives); i++ { | |
369 tag_directive := &event.tag_directives[i] | |
370 if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) { | |
371 return false | |
372 } | |
373 if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) { | |
374 return false | |
375 } | |
376 if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) { | |
377 return false | |
378 } | |
379 if !yaml_emitter_write_indent(emitter) { | |
380 return false | |
381 } | |
382 } | |
383 } | |
384 | |
385 if yaml_emitter_check_empty_document(emitter) { | |
386 implicit = false | |
387 } | |
388 if !implicit { | |
389 if !yaml_emitter_write_indent(emitter) { | |
390 return false | |
391 } | |
392 if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) { | |
393 return false | |
394 } | |
395 if emitter.canonical { | |
396 if !yaml_emitter_write_indent(emitter) { | |
397 return false | |
398 } | |
399 } | |
400 } | |
401 | |
402 emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE | |
403 return true | |
404 } | |
405 | |
406 if event.typ == yaml_STREAM_END_EVENT { | |
407 if emitter.open_ended { | |
408 if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { | |
409 return false | |
410 } | |
411 if !yaml_emitter_write_indent(emitter) { | |
412 return false | |
413 } | |
414 } | |
415 if !yaml_emitter_flush(emitter) { | |
416 return false | |
417 } | |
418 emitter.state = yaml_EMIT_END_STATE | |
419 return true | |
420 } | |
421 | |
422 return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END") | |
423 } | |
424 | |
425 // Expect the root node. | |
426 func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool { | |
427 emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE) | |
428 return yaml_emitter_emit_node(emitter, event, true, false, false, false) | |
429 } | |
430 | |
431 // Expect DOCUMENT-END. | |
432 func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool { | |
433 if event.typ != yaml_DOCUMENT_END_EVENT { | |
434 return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END") | |
435 } | |
436 if !yaml_emitter_write_indent(emitter) { | |
437 return false | |
438 } | |
439 if !event.implicit { | |
440 // [Go] Allocate the slice elsewhere. | |
441 if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { | |
442 return false | |
443 } | |
444 if !yaml_emitter_write_indent(emitter) { | |
445 return false | |
446 } | |
447 } | |
448 if !yaml_emitter_flush(emitter) { | |
449 return false | |
450 } | |
451 emitter.state = yaml_EMIT_DOCUMENT_START_STATE | |
452 emitter.tag_directives = emitter.tag_directives[:0] | |
453 return true | |
454 } | |
455 | |
456 // Expect a flow item node. | |
457 func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { | |
458 if first { | |
459 if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) { | |
460 return false | |
461 } | |
462 if !yaml_emitter_increase_indent(emitter, true, false) { | |
463 return false | |
464 } | |
465 emitter.flow_level++ | |
466 } | |
467 | |
468 if event.typ == yaml_SEQUENCE_END_EVENT { | |
469 emitter.flow_level-- | |
470 emitter.indent = emitter.indents[len(emitter.indents)-1] | |
471 emitter.indents = emitter.indents[:len(emitter.indents)-1] | |
472 if emitter.canonical && !first { | |
473 if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { | |
474 return false | |
475 } | |
476 if !yaml_emitter_write_indent(emitter) { | |
477 return false | |
478 } | |
479 } | |
480 if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) { | |
481 return false | |
482 } | |
483 emitter.state = emitter.states[len(emitter.states)-1] | |
484 emitter.states = emitter.states[:len(emitter.states)-1] | |
485 | |
486 return true | |
487 } | |
488 | |
489 if !first { | |
490 if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { | |
491 return false | |
492 } | |
493 } | |
494 | |
495 if emitter.canonical || emitter.column > emitter.best_width { | |
496 if !yaml_emitter_write_indent(emitter) { | |
497 return false | |
498 } | |
499 } | |
500 emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE) | |
501 return yaml_emitter_emit_node(emitter, event, false, true, false, false) | |
502 } | |
503 | |
504 // Expect a flow key node. | |
505 func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { | |
506 if first { | |
507 if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) { | |
508 return false | |
509 } | |
510 if !yaml_emitter_increase_indent(emitter, true, false) { | |
511 return false | |
512 } | |
513 emitter.flow_level++ | |
514 } | |
515 | |
516 if event.typ == yaml_MAPPING_END_EVENT { | |
517 emitter.flow_level-- | |
518 emitter.indent = emitter.indents[len(emitter.indents)-1] | |
519 emitter.indents = emitter.indents[:len(emitter.indents)-1] | |
520 if emitter.canonical && !first { | |
521 if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { | |
522 return false | |
523 } | |
524 if !yaml_emitter_write_indent(emitter) { | |
525 return false | |
526 } | |
527 } | |
528 if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) { | |
529 return false | |
530 } | |
531 emitter.state = emitter.states[len(emitter.states)-1] | |
532 emitter.states = emitter.states[:len(emitter.states)-1] | |
533 return true | |
534 } | |
535 | |
536 if !first { | |
537 if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { | |
538 return false | |
539 } | |
540 } | |
541 if emitter.canonical || emitter.column > emitter.best_width { | |
542 if !yaml_emitter_write_indent(emitter) { | |
543 return false | |
544 } | |
545 } | |
546 | |
547 if !emitter.canonical && yaml_emitter_check_simple_key(emitter) { | |
548 emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE) | |
549 return yaml_emitter_emit_node(emitter, event, false, false, true, true) | |
550 } | |
551 if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) { | |
552 return false | |
553 } | |
554 emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE) | |
555 return yaml_emitter_emit_node(emitter, event, false, false, true, false) | |
556 } | |
557 | |
558 // Expect a flow value node. | |
559 func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { | |
560 if simple { | |
561 if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { | |
562 return false | |
563 } | |
564 } else { | |
565 if emitter.canonical || emitter.column > emitter.best_width { | |
566 if !yaml_emitter_write_indent(emitter) { | |
567 return false | |
568 } | |
569 } | |
570 if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) { | |
571 return false | |
572 } | |
573 } | |
574 emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE) | |
575 return yaml_emitter_emit_node(emitter, event, false, false, true, false) | |
576 } | |
577 | |
578 // Expect a block item node. | |
579 func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { | |
580 if first { | |
581 if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) { | |
582 return false | |
583 } | |
584 } | |
585 if event.typ == yaml_SEQUENCE_END_EVENT { | |
586 emitter.indent = emitter.indents[len(emitter.indents)-1] | |
587 emitter.indents = emitter.indents[:len(emitter.indents)-1] | |
588 emitter.state = emitter.states[len(emitter.states)-1] | |
589 emitter.states = emitter.states[:len(emitter.states)-1] | |
590 return true | |
591 } | |
592 if !yaml_emitter_write_indent(emitter) { | |
593 return false | |
594 } | |
595 if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) { | |
596 return false | |
597 } | |
598 emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE) | |
599 return yaml_emitter_emit_node(emitter, event, false, true, false, false) | |
600 } | |
601 | |
602 // Expect a block key node. | |
603 func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { | |
604 if first { | |
605 if !yaml_emitter_increase_indent(emitter, false, false) { | |
606 return false | |
607 } | |
608 } | |
609 if event.typ == yaml_MAPPING_END_EVENT { | |
610 emitter.indent = emitter.indents[len(emitter.indents)-1] | |
611 emitter.indents = emitter.indents[:len(emitter.indents)-1] | |
612 emitter.state = emitter.states[len(emitter.states)-1] | |
613 emitter.states = emitter.states[:len(emitter.states)-1] | |
614 return true | |
615 } | |
616 if !yaml_emitter_write_indent(emitter) { | |
617 return false | |
618 } | |
619 if yaml_emitter_check_simple_key(emitter) { | |
620 emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE) | |
621 return yaml_emitter_emit_node(emitter, event, false, false, true, true) | |
622 } | |
623 if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) { | |
624 return false | |
625 } | |
626 emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE) | |
627 return yaml_emitter_emit_node(emitter, event, false, false, true, false) | |
628 } | |
629 | |
630 // Expect a block value node. | |
631 func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { | |
632 if simple { | |
633 if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { | |
634 return false | |
635 } | |
636 } else { | |
637 if !yaml_emitter_write_indent(emitter) { | |
638 return false | |
639 } | |
640 if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) { | |
641 return false | |
642 } | |
643 } | |
644 emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE) | |
645 return yaml_emitter_emit_node(emitter, event, false, false, true, false) | |
646 } | |
647 | |
648 // Expect a node. | |
649 func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t, | |
650 root bool, sequence bool, mapping bool, simple_key bool) bool { | |
651 | |
652 emitter.root_context = root | |
653 emitter.sequence_context = sequence | |
654 emitter.mapping_context = mapping | |
655 emitter.simple_key_context = simple_key | |
656 | |
657 switch event.typ { | |
658 case yaml_ALIAS_EVENT: | |
659 return yaml_emitter_emit_alias(emitter, event) | |
660 case yaml_SCALAR_EVENT: | |
661 return yaml_emitter_emit_scalar(emitter, event) | |
662 case yaml_SEQUENCE_START_EVENT: | |
663 return yaml_emitter_emit_sequence_start(emitter, event) | |
664 case yaml_MAPPING_START_EVENT: | |
665 return yaml_emitter_emit_mapping_start(emitter, event) | |
666 default: | |
667 return yaml_emitter_set_emitter_error(emitter, | |
668 fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ)) | |
669 } | |
670 } | |
671 | |
672 // Expect ALIAS. | |
673 func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool { | |
674 if !yaml_emitter_process_anchor(emitter) { | |
675 return false | |
676 } | |
677 emitter.state = emitter.states[len(emitter.states)-1] | |
678 emitter.states = emitter.states[:len(emitter.states)-1] | |
679 return true | |
680 } | |
681 | |
682 // Expect SCALAR. | |
683 func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool { | |
684 if !yaml_emitter_select_scalar_style(emitter, event) { | |
685 return false | |
686 } | |
687 if !yaml_emitter_process_anchor(emitter) { | |
688 return false | |
689 } | |
690 if !yaml_emitter_process_tag(emitter) { | |
691 return false | |
692 } | |
693 if !yaml_emitter_increase_indent(emitter, true, false) { | |
694 return false | |
695 } | |
696 if !yaml_emitter_process_scalar(emitter) { | |
697 return false | |
698 } | |
699 emitter.indent = emitter.indents[len(emitter.indents)-1] | |
700 emitter.indents = emitter.indents[:len(emitter.indents)-1] | |
701 emitter.state = emitter.states[len(emitter.states)-1] | |
702 emitter.states = emitter.states[:len(emitter.states)-1] | |
703 return true | |
704 } | |
705 | |
706 // Expect SEQUENCE-START. | |
707 func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { | |
708 if !yaml_emitter_process_anchor(emitter) { | |
709 return false | |
710 } | |
711 if !yaml_emitter_process_tag(emitter) { | |
712 return false | |
713 } | |
714 if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE || | |
715 yaml_emitter_check_empty_sequence(emitter) { | |
716 emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE | |
717 } else { | |
718 emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE | |
719 } | |
720 return true | |
721 } | |
722 | |
723 // Expect MAPPING-START. | |
724 func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { | |
725 if !yaml_emitter_process_anchor(emitter) { | |
726 return false | |
727 } | |
728 if !yaml_emitter_process_tag(emitter) { | |
729 return false | |
730 } | |
731 if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE || | |
732 yaml_emitter_check_empty_mapping(emitter) { | |
733 emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE | |
734 } else { | |
735 emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE | |
736 } | |
737 return true | |
738 } | |
739 | |
740 // Check if the document content is an empty scalar. | |
741 func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool { | |
742 return false // [Go] Huh? | |
743 } | |
744 | |
745 // Check if the next events represent an empty sequence. | |
746 func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool { | |
747 if len(emitter.events)-emitter.events_head < 2 { | |
748 return false | |
749 } | |
750 return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT && | |
751 emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT | |
752 } | |
753 | |
754 // Check if the next events represent an empty mapping. | |
755 func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool { | |
756 if len(emitter.events)-emitter.events_head < 2 { | |
757 return false | |
758 } | |
759 return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT && | |
760 emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT | |
761 } | |
762 | |
763 // Check if the next node can be expressed as a simple key. | |
764 func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool { | |
765 length := 0 | |
766 switch emitter.events[emitter.events_head].typ { | |
767 case yaml_ALIAS_EVENT: | |
768 length += len(emitter.anchor_data.anchor) | |
769 case yaml_SCALAR_EVENT: | |
770 if emitter.scalar_data.multiline { | |
771 return false | |
772 } | |
773 length += len(emitter.anchor_data.anchor) + | |
774 len(emitter.tag_data.handle) + | |
775 len(emitter.tag_data.suffix) + | |
776 len(emitter.scalar_data.value) | |
777 case yaml_SEQUENCE_START_EVENT: | |
778 if !yaml_emitter_check_empty_sequence(emitter) { | |
779 return false | |
780 } | |
781 length += len(emitter.anchor_data.anchor) + | |
782 len(emitter.tag_data.handle) + | |
783 len(emitter.tag_data.suffix) | |
784 case yaml_MAPPING_START_EVENT: | |
785 if !yaml_emitter_check_empty_mapping(emitter) { | |
786 return false | |
787 } | |
788 length += len(emitter.anchor_data.anchor) + | |
789 len(emitter.tag_data.handle) + | |
790 len(emitter.tag_data.suffix) | |
791 default: | |
792 return false | |
793 } | |
794 return length <= 128 | |
795 } | |
796 | |
797 // Determine an acceptable scalar style. | |
798 func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool { | |
799 | |
800 no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 | |
801 if no_tag && !event.implicit && !event.quoted_implicit { | |
802 return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified") | |
803 } | |
804 | |
805 style := event.scalar_style() | |
806 if style == yaml_ANY_SCALAR_STYLE { | |
807 style = yaml_PLAIN_SCALAR_STYLE | |
808 } | |
809 if emitter.canonical { | |
810 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE | |
811 } | |
812 if emitter.simple_key_context && emitter.scalar_data.multiline { | |
813 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE | |
814 } | |
815 | |
816 if style == yaml_PLAIN_SCALAR_STYLE { | |
817 if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed || | |
818 emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed { | |
819 style = yaml_SINGLE_QUOTED_SCALAR_STYLE | |
820 } | |
821 if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) { | |
822 style = yaml_SINGLE_QUOTED_SCALAR_STYLE | |
823 } | |
824 if no_tag && !event.implicit { | |
825 style = yaml_SINGLE_QUOTED_SCALAR_STYLE | |
826 } | |
827 } | |
828 if style == yaml_SINGLE_QUOTED_SCALAR_STYLE { | |
829 if !emitter.scalar_data.single_quoted_allowed { | |
830 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE | |
831 } | |
832 } | |
833 if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE { | |
834 if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context { | |
835 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE | |
836 } | |
837 } | |
838 | |
839 if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE { | |
840 emitter.tag_data.handle = []byte{'!'} | |
841 } | |
842 emitter.scalar_data.style = style | |
843 return true | |
844 } | |
845 | |
846 // Write an anchor. | |
847 func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool { | |
848 if emitter.anchor_data.anchor == nil { | |
849 return true | |
850 } | |
851 c := []byte{'&'} | |
852 if emitter.anchor_data.alias { | |
853 c[0] = '*' | |
854 } | |
855 if !yaml_emitter_write_indicator(emitter, c, true, false, false) { | |
856 return false | |
857 } | |
858 return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor) | |
859 } | |
860 | |
861 // Write a tag. | |
862 func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool { | |
863 if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 { | |
864 return true | |
865 } | |
866 if len(emitter.tag_data.handle) > 0 { | |
867 if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) { | |
868 return false | |
869 } | |
870 if len(emitter.tag_data.suffix) > 0 { | |
871 if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { | |
872 return false | |
873 } | |
874 } | |
875 } else { | |
876 // [Go] Allocate these slices elsewhere. | |
877 if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) { | |
878 return false | |
879 } | |
880 if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { | |
881 return false | |
882 } | |
883 if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) { | |
884 return false | |
885 } | |
886 } | |
887 return true | |
888 } | |
889 | |
890 // Write a scalar. | |
891 func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool { | |
892 switch emitter.scalar_data.style { | |
893 case yaml_PLAIN_SCALAR_STYLE: | |
894 return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) | |
895 | |
896 case yaml_SINGLE_QUOTED_SCALAR_STYLE: | |
897 return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) | |
898 | |
899 case yaml_DOUBLE_QUOTED_SCALAR_STYLE: | |
900 return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) | |
901 | |
902 case yaml_LITERAL_SCALAR_STYLE: | |
903 return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value) | |
904 | |
905 case yaml_FOLDED_SCALAR_STYLE: | |
906 return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value) | |
907 } | |
908 panic("unknown scalar style") | |
909 } | |
910 | |
911 // Check if a %YAML directive is valid. | |
912 func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool { | |
913 if version_directive.major != 1 || version_directive.minor != 1 { | |
914 return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive") | |
915 } | |
916 return true | |
917 } | |
918 | |
919 // Check if a %TAG directive is valid. | |
920 func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool { | |
921 handle := tag_directive.handle | |
922 prefix := tag_directive.prefix | |
923 if len(handle) == 0 { | |
924 return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty") | |
925 } | |
926 if handle[0] != '!' { | |
927 return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'") | |
928 } | |
929 if handle[len(handle)-1] != '!' { | |
930 return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'") | |
931 } | |
932 for i := 1; i < len(handle)-1; i += width(handle[i]) { | |
933 if !is_alpha(handle, i) { | |
934 return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only") | |
935 } | |
936 } | |
937 if len(prefix) == 0 { | |
938 return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty") | |
939 } | |
940 return true | |
941 } | |
942 | |
943 // Check if an anchor is valid. | |
944 func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool { | |
945 if len(anchor) == 0 { | |
946 problem := "anchor value must not be empty" | |
947 if alias { | |
948 problem = "alias value must not be empty" | |
949 } | |
950 return yaml_emitter_set_emitter_error(emitter, problem) | |
951 } | |
952 for i := 0; i < len(anchor); i += width(anchor[i]) { | |
953 if !is_alpha(anchor, i) { | |
954 problem := "anchor value must contain alphanumerical characters only" | |
955 if alias { | |
956 problem = "alias value must contain alphanumerical characters only" | |
957 } | |
958 return yaml_emitter_set_emitter_error(emitter, problem) | |
959 } | |
960 } | |
961 emitter.anchor_data.anchor = anchor | |
962 emitter.anchor_data.alias = alias | |
963 return true | |
964 } | |
965 | |
966 // Check if a tag is valid. | |
967 func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool { | |
968 if len(tag) == 0 { | |
969 return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty") | |
970 } | |
971 for i := 0; i < len(emitter.tag_directives); i++ { | |
972 tag_directive := &emitter.tag_directives[i] | |
973 if bytes.HasPrefix(tag, tag_directive.prefix) { | |
974 emitter.tag_data.handle = tag_directive.handle | |
975 emitter.tag_data.suffix = tag[len(tag_directive.prefix):] | |
976 return true | |
977 } | |
978 } | |
979 emitter.tag_data.suffix = tag | |
980 return true | |
981 } | |
982 | |
983 // Check if a scalar is valid. | |
984 func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool { | |
985 var ( | |
986 block_indicators = false | |
987 flow_indicators = false | |
988 line_breaks = false | |
989 special_characters = false | |
990 | |
991 leading_space = false | |
992 leading_break = false | |
993 trailing_space = false | |
994 trailing_break = false | |
995 break_space = false | |
996 space_break = false | |
997 | |
998 preceded_by_whitespace = false | |
999 followed_by_whitespace = false | |
1000 previous_space = false | |
1001 previous_break = false | |
1002 ) | |
1003 | |
1004 emitter.scalar_data.value = value | |
1005 | |
1006 if len(value) == 0 { | |
1007 emitter.scalar_data.multiline = false | |
1008 emitter.scalar_data.flow_plain_allowed = false | |
1009 emitter.scalar_data.block_plain_allowed = true | |
1010 emitter.scalar_data.single_quoted_allowed = true | |
1011 emitter.scalar_data.block_allowed = false | |
1012 return true | |
1013 } | |
1014 | |
1015 if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) { | |
1016 block_indicators = true | |
1017 flow_indicators = true | |
1018 } | |
1019 | |
1020 preceded_by_whitespace = true | |
1021 for i, w := 0, 0; i < len(value); i += w { | |
1022 w = width(value[i]) | |
1023 followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w) | |
1024 | |
1025 if i == 0 { | |
1026 switch value[i] { | |
1027 case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`': | |
1028 flow_indicators = true | |
1029 block_indicators = true | |
1030 case '?', ':': | |
1031 flow_indicators = true | |
1032 if followed_by_whitespace { | |
1033 block_indicators = true | |
1034 } | |
1035 case '-': | |
1036 if followed_by_whitespace { | |
1037 flow_indicators = true | |
1038 block_indicators = true | |
1039 } | |
1040 } | |
1041 } else { | |
1042 switch value[i] { | |
1043 case ',', '?', '[', ']', '{', '}': | |
1044 flow_indicators = true | |
1045 case ':': | |
1046 flow_indicators = true | |
1047 if followed_by_whitespace { | |
1048 block_indicators = true | |
1049 } | |
1050 case '#': | |
1051 if preceded_by_whitespace { | |
1052 flow_indicators = true | |
1053 block_indicators = true | |
1054 } | |
1055 } | |
1056 } | |
1057 | |
1058 if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode { | |
1059 special_characters = true | |
1060 } | |
1061 if is_space(value, i) { | |
1062 if i == 0 { | |
1063 leading_space = true | |
1064 } | |
1065 if i+width(value[i]) == len(value) { | |
1066 trailing_space = true | |
1067 } | |
1068 if previous_break { | |
1069 break_space = true | |
1070 } | |
1071 previous_space = true | |
1072 previous_break = false | |
1073 } else if is_break(value, i) { | |
1074 line_breaks = true | |
1075 if i == 0 { | |
1076 leading_break = true | |
1077 } | |
1078 if i+width(value[i]) == len(value) { | |
1079 trailing_break = true | |
1080 } | |
1081 if previous_space { | |
1082 space_break = true | |
1083 } | |
1084 previous_space = false | |
1085 previous_break = true | |
1086 } else { | |
1087 previous_space = false | |
1088 previous_break = false | |
1089 } | |
1090 | |
1091 // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition. | |
1092 preceded_by_whitespace = is_blankz(value, i) | |
1093 } | |
1094 | |
1095 emitter.scalar_data.multiline = line_breaks | |
1096 emitter.scalar_data.flow_plain_allowed = true | |
1097 emitter.scalar_data.block_plain_allowed = true | |
1098 emitter.scalar_data.single_quoted_allowed = true | |
1099 emitter.scalar_data.block_allowed = true | |
1100 | |
1101 if leading_space || leading_break || trailing_space || trailing_break { | |
1102 emitter.scalar_data.flow_plain_allowed = false | |
1103 emitter.scalar_data.block_plain_allowed = false | |
1104 } | |
1105 if trailing_space { | |
1106 emitter.scalar_data.block_allowed = false | |
1107 } | |
1108 if break_space { | |
1109 emitter.scalar_data.flow_plain_allowed = false | |
1110 emitter.scalar_data.block_plain_allowed = false | |
1111 emitter.scalar_data.single_quoted_allowed = false | |
1112 } | |
1113 if space_break || special_characters { | |
1114 emitter.scalar_data.flow_plain_allowed = false | |
1115 emitter.scalar_data.block_plain_allowed = false | |
1116 emitter.scalar_data.single_quoted_allowed = false | |
1117 emitter.scalar_data.block_allowed = false | |
1118 } | |
1119 if line_breaks { | |
1120 emitter.scalar_data.flow_plain_allowed = false | |
1121 emitter.scalar_data.block_plain_allowed = false | |
1122 } | |
1123 if flow_indicators { | |
1124 emitter.scalar_data.flow_plain_allowed = false | |
1125 } | |
1126 if block_indicators { | |
1127 emitter.scalar_data.block_plain_allowed = false | |
1128 } | |
1129 return true | |
1130 } | |
1131 | |
1132 // Check if the event data is valid. | |
1133 func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool { | |
1134 | |
1135 emitter.anchor_data.anchor = nil | |
1136 emitter.tag_data.handle = nil | |
1137 emitter.tag_data.suffix = nil | |
1138 emitter.scalar_data.value = nil | |
1139 | |
1140 switch event.typ { | |
1141 case yaml_ALIAS_EVENT: | |
1142 if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) { | |
1143 return false | |
1144 } | |
1145 | |
1146 case yaml_SCALAR_EVENT: | |
1147 if len(event.anchor) > 0 { | |
1148 if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { | |
1149 return false | |
1150 } | |
1151 } | |
1152 if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) { | |
1153 if !yaml_emitter_analyze_tag(emitter, event.tag) { | |
1154 return false | |
1155 } | |
1156 } | |
1157 if !yaml_emitter_analyze_scalar(emitter, event.value) { | |
1158 return false | |
1159 } | |
1160 | |
1161 case yaml_SEQUENCE_START_EVENT: | |
1162 if len(event.anchor) > 0 { | |
1163 if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { | |
1164 return false | |
1165 } | |
1166 } | |
1167 if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { | |
1168 if !yaml_emitter_analyze_tag(emitter, event.tag) { | |
1169 return false | |
1170 } | |
1171 } | |
1172 | |
1173 case yaml_MAPPING_START_EVENT: | |
1174 if len(event.anchor) > 0 { | |
1175 if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { | |
1176 return false | |
1177 } | |
1178 } | |
1179 if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { | |
1180 if !yaml_emitter_analyze_tag(emitter, event.tag) { | |
1181 return false | |
1182 } | |
1183 } | |
1184 } | |
1185 return true | |
1186 } | |
1187 | |
1188 // Write the BOM character. | |
1189 func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool { | |
1190 if !flush(emitter) { | |
1191 return false | |
1192 } | |
1193 pos := emitter.buffer_pos | |
1194 emitter.buffer[pos+0] = '\xEF' | |
1195 emitter.buffer[pos+1] = '\xBB' | |
1196 emitter.buffer[pos+2] = '\xBF' | |
1197 emitter.buffer_pos += 3 | |
1198 return true | |
1199 } | |
1200 | |
1201 func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool { | |
1202 indent := emitter.indent | |
1203 if indent < 0 { | |
1204 indent = 0 | |
1205 } | |
1206 if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) { | |
1207 if !put_break(emitter) { | |
1208 return false | |
1209 } | |
1210 } | |
1211 for emitter.column < indent { | |
1212 if !put(emitter, ' ') { | |
1213 return false | |
1214 } | |
1215 } | |
1216 emitter.whitespace = true | |
1217 emitter.indention = true | |
1218 return true | |
1219 } | |
1220 | |
1221 func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool { | |
1222 if need_whitespace && !emitter.whitespace { | |
1223 if !put(emitter, ' ') { | |
1224 return false | |
1225 } | |
1226 } | |
1227 if !write_all(emitter, indicator) { | |
1228 return false | |
1229 } | |
1230 emitter.whitespace = is_whitespace | |
1231 emitter.indention = (emitter.indention && is_indention) | |
1232 emitter.open_ended = false | |
1233 return true | |
1234 } | |
1235 | |
1236 func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool { | |
1237 if !write_all(emitter, value) { | |
1238 return false | |
1239 } | |
1240 emitter.whitespace = false | |
1241 emitter.indention = false | |
1242 return true | |
1243 } | |
1244 | |
1245 func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool { | |
1246 if !emitter.whitespace { | |
1247 if !put(emitter, ' ') { | |
1248 return false | |
1249 } | |
1250 } | |
1251 if !write_all(emitter, value) { | |
1252 return false | |
1253 } | |
1254 emitter.whitespace = false | |
1255 emitter.indention = false | |
1256 return true | |
1257 } | |
1258 | |
1259 func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool { | |
1260 if need_whitespace && !emitter.whitespace { | |
1261 if !put(emitter, ' ') { | |
1262 return false | |
1263 } | |
1264 } | |
1265 for i := 0; i < len(value); { | |
1266 var must_write bool | |
1267 switch value[i] { | |
1268 case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']': | |
1269 must_write = true | |
1270 default: | |
1271 must_write = is_alpha(value, i) | |
1272 } | |
1273 if must_write { | |
1274 if !write(emitter, value, &i) { | |
1275 return false | |
1276 } | |
1277 } else { | |
1278 w := width(value[i]) | |
1279 for k := 0; k < w; k++ { | |
1280 octet := value[i] | |
1281 i++ | |
1282 if !put(emitter, '%') { | |
1283 return false | |
1284 } | |
1285 | |
1286 c := octet >> 4 | |
1287 if c < 10 { | |
1288 c += '0' | |
1289 } else { | |
1290 c += 'A' - 10 | |
1291 } | |
1292 if !put(emitter, c) { | |
1293 return false | |
1294 } | |
1295 | |
1296 c = octet & 0x0f | |
1297 if c < 10 { | |
1298 c += '0' | |
1299 } else { | |
1300 c += 'A' - 10 | |
1301 } | |
1302 if !put(emitter, c) { | |
1303 return false | |
1304 } | |
1305 } | |
1306 } | |
1307 } | |
1308 emitter.whitespace = false | |
1309 emitter.indention = false | |
1310 return true | |
1311 } | |
1312 | |
1313 func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { | |
1314 if !emitter.whitespace { | |
1315 if !put(emitter, ' ') { | |
1316 return false | |
1317 } | |
1318 } | |
1319 | |
1320 spaces := false | |
1321 breaks := false | |
1322 for i := 0; i < len(value); { | |
1323 if is_space(value, i) { | |
1324 if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) { | |
1325 if !yaml_emitter_write_indent(emitter) { | |
1326 return false | |
1327 } | |
1328 i += width(value[i]) | |
1329 } else { | |
1330 if !write(emitter, value, &i) { | |
1331 return false | |
1332 } | |
1333 } | |
1334 spaces = true | |
1335 } else if is_break(value, i) { | |
1336 if !breaks && value[i] == '\n' { | |
1337 if !put_break(emitter) { | |
1338 return false | |
1339 } | |
1340 } | |
1341 if !write_break(emitter, value, &i) { | |
1342 return false | |
1343 } | |
1344 emitter.indention = true | |
1345 breaks = true | |
1346 } else { | |
1347 if breaks { | |
1348 if !yaml_emitter_write_indent(emitter) { | |
1349 return false | |
1350 } | |
1351 } | |
1352 if !write(emitter, value, &i) { | |
1353 return false | |
1354 } | |
1355 emitter.indention = false | |
1356 spaces = false | |
1357 breaks = false | |
1358 } | |
1359 } | |
1360 | |
1361 emitter.whitespace = false | |
1362 emitter.indention = false | |
1363 if emitter.root_context { | |
1364 emitter.open_ended = true | |
1365 } | |
1366 | |
1367 return true | |
1368 } | |
1369 | |
1370 func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { | |
1371 | |
1372 if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) { | |
1373 return false | |
1374 } | |
1375 | |
1376 spaces := false | |
1377 breaks := false | |
1378 for i := 0; i < len(value); { | |
1379 if is_space(value, i) { | |
1380 if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) { | |
1381 if !yaml_emitter_write_indent(emitter) { | |
1382 return false | |
1383 } | |
1384 i += width(value[i]) | |
1385 } else { | |
1386 if !write(emitter, value, &i) { | |
1387 return false | |
1388 } | |
1389 } | |
1390 spaces = true | |
1391 } else if is_break(value, i) { | |
1392 if !breaks && value[i] == '\n' { | |
1393 if !put_break(emitter) { | |
1394 return false | |
1395 } | |
1396 } | |
1397 if !write_break(emitter, value, &i) { | |
1398 return false | |
1399 } | |
1400 emitter.indention = true | |
1401 breaks = true | |
1402 } else { | |
1403 if breaks { | |
1404 if !yaml_emitter_write_indent(emitter) { | |
1405 return false | |
1406 } | |
1407 } | |
1408 if value[i] == '\'' { | |
1409 if !put(emitter, '\'') { | |
1410 return false | |
1411 } | |
1412 } | |
1413 if !write(emitter, value, &i) { | |
1414 return false | |
1415 } | |
1416 emitter.indention = false | |
1417 spaces = false | |
1418 breaks = false | |
1419 } | |
1420 } | |
1421 if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) { | |
1422 return false | |
1423 } | |
1424 emitter.whitespace = false | |
1425 emitter.indention = false | |
1426 return true | |
1427 } | |
1428 | |
1429 func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { | |
1430 spaces := false | |
1431 if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) { | |
1432 return false | |
1433 } | |
1434 | |
1435 for i := 0; i < len(value); { | |
1436 if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) || | |
1437 is_bom(value, i) || is_break(value, i) || | |
1438 value[i] == '"' || value[i] == '\\' { | |
1439 | |
1440 octet := value[i] | |
1441 | |
1442 var w int | |
1443 var v rune | |
1444 switch { | |
1445 case octet&0x80 == 0x00: | |
1446 w, v = 1, rune(octet&0x7F) | |
1447 case octet&0xE0 == 0xC0: | |
1448 w, v = 2, rune(octet&0x1F) | |
1449 case octet&0xF0 == 0xE0: | |
1450 w, v = 3, rune(octet&0x0F) | |
1451 case octet&0xF8 == 0xF0: | |
1452 w, v = 4, rune(octet&0x07) | |
1453 } | |
1454 for k := 1; k < w; k++ { | |
1455 octet = value[i+k] | |
1456 v = (v << 6) + (rune(octet) & 0x3F) | |
1457 } | |
1458 i += w | |
1459 | |
1460 if !put(emitter, '\\') { | |
1461 return false | |
1462 } | |
1463 | |
1464 var ok bool | |
1465 switch v { | |
1466 case 0x00: | |
1467 ok = put(emitter, '0') | |
1468 case 0x07: | |
1469 ok = put(emitter, 'a') | |
1470 case 0x08: | |
1471 ok = put(emitter, 'b') | |
1472 case 0x09: | |
1473 ok = put(emitter, 't') | |
1474 case 0x0A: | |
1475 ok = put(emitter, 'n') | |
1476 case 0x0b: | |
1477 ok = put(emitter, 'v') | |
1478 case 0x0c: | |
1479 ok = put(emitter, 'f') | |
1480 case 0x0d: | |
1481 ok = put(emitter, 'r') | |
1482 case 0x1b: | |
1483 ok = put(emitter, 'e') | |
1484 case 0x22: | |
1485 ok = put(emitter, '"') | |
1486 case 0x5c: | |
1487 ok = put(emitter, '\\') | |
1488 case 0x85: | |
1489 ok = put(emitter, 'N') | |
1490 case 0xA0: | |
1491 ok = put(emitter, '_') | |
1492 case 0x2028: | |
1493 ok = put(emitter, 'L') | |
1494 case 0x2029: | |
1495 ok = put(emitter, 'P') | |
1496 default: | |
1497 if v <= 0xFF { | |
1498 ok = put(emitter, 'x') | |
1499 w = 2 | |
1500 } else if v <= 0xFFFF { | |
1501 ok = put(emitter, 'u') | |
1502 w = 4 | |
1503 } else { | |
1504 ok = put(emitter, 'U') | |
1505 w = 8 | |
1506 } | |
1507 for k := (w - 1) * 4; ok && k >= 0; k -= 4 { | |
1508 digit := byte((v >> uint(k)) & 0x0F) | |
1509 if digit < 10 { | |
1510 ok = put(emitter, digit+'0') | |
1511 } else { | |
1512 ok = put(emitter, digit+'A'-10) | |
1513 } | |
1514 } | |
1515 } | |
1516 if !ok { | |
1517 return false | |
1518 } | |
1519 spaces = false | |
1520 } else if is_space(value, i) { | |
1521 if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 { | |
1522 if !yaml_emitter_write_indent(emitter) { | |
1523 return false | |
1524 } | |
1525 if is_space(value, i+1) { | |
1526 if !put(emitter, '\\') { | |
1527 return false | |
1528 } | |
1529 } | |
1530 i += width(value[i]) | |
1531 } else if !write(emitter, value, &i) { | |
1532 return false | |
1533 } | |
1534 spaces = true | |
1535 } else { | |
1536 if !write(emitter, value, &i) { | |
1537 return false | |
1538 } | |
1539 spaces = false | |
1540 } | |
1541 } | |
1542 if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) { | |
1543 return false | |
1544 } | |
1545 emitter.whitespace = false | |
1546 emitter.indention = false | |
1547 return true | |
1548 } | |
1549 | |
1550 func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool { | |
1551 if is_space(value, 0) || is_break(value, 0) { | |
1552 indent_hint := []byte{'0' + byte(emitter.best_indent)} | |
1553 if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) { | |
1554 return false | |
1555 } | |
1556 } | |
1557 | |
1558 emitter.open_ended = false | |
1559 | |
1560 var chomp_hint [1]byte | |
1561 if len(value) == 0 { | |
1562 chomp_hint[0] = '-' | |
1563 } else { | |
1564 i := len(value) - 1 | |
1565 for value[i]&0xC0 == 0x80 { | |
1566 i-- | |
1567 } | |
1568 if !is_break(value, i) { | |
1569 chomp_hint[0] = '-' | |
1570 } else if i == 0 { | |
1571 chomp_hint[0] = '+' | |
1572 emitter.open_ended = true | |
1573 } else { | |
1574 i-- | |
1575 for value[i]&0xC0 == 0x80 { | |
1576 i-- | |
1577 } | |
1578 if is_break(value, i) { | |
1579 chomp_hint[0] = '+' | |
1580 emitter.open_ended = true | |
1581 } | |
1582 } | |
1583 } | |
1584 if chomp_hint[0] != 0 { | |
1585 if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) { | |
1586 return false | |
1587 } | |
1588 } | |
1589 return true | |
1590 } | |
1591 | |
1592 func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool { | |
1593 if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) { | |
1594 return false | |
1595 } | |
1596 if !yaml_emitter_write_block_scalar_hints(emitter, value) { | |
1597 return false | |
1598 } | |
1599 if !put_break(emitter) { | |
1600 return false | |
1601 } | |
1602 emitter.indention = true | |
1603 emitter.whitespace = true | |
1604 breaks := true | |
1605 for i := 0; i < len(value); { | |
1606 if is_break(value, i) { | |
1607 if !write_break(emitter, value, &i) { | |
1608 return false | |
1609 } | |
1610 emitter.indention = true | |
1611 breaks = true | |
1612 } else { | |
1613 if breaks { | |
1614 if !yaml_emitter_write_indent(emitter) { | |
1615 return false | |
1616 } | |
1617 } | |
1618 if !write(emitter, value, &i) { | |
1619 return false | |
1620 } | |
1621 emitter.indention = false | |
1622 breaks = false | |
1623 } | |
1624 } | |
1625 | |
1626 return true | |
1627 } | |
1628 | |
1629 func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool { | |
1630 if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) { | |
1631 return false | |
1632 } | |
1633 if !yaml_emitter_write_block_scalar_hints(emitter, value) { | |
1634 return false | |
1635 } | |
1636 | |
1637 if !put_break(emitter) { | |
1638 return false | |
1639 } | |
1640 emitter.indention = true | |
1641 emitter.whitespace = true | |
1642 | |
1643 breaks := true | |
1644 leading_spaces := true | |
1645 for i := 0; i < len(value); { | |
1646 if is_break(value, i) { | |
1647 if !breaks && !leading_spaces && value[i] == '\n' { | |
1648 k := 0 | |
1649 for is_break(value, k) { | |
1650 k += width(value[k]) | |
1651 } | |
1652 if !is_blankz(value, k) { | |
1653 if !put_break(emitter) { | |
1654 return false | |
1655 } | |
1656 } | |
1657 } | |
1658 if !write_break(emitter, value, &i) { | |
1659 return false | |
1660 } | |
1661 emitter.indention = true | |
1662 breaks = true | |
1663 } else { | |
1664 if breaks { | |
1665 if !yaml_emitter_write_indent(emitter) { | |
1666 return false | |
1667 } | |
1668 leading_spaces = is_blank(value, i) | |
1669 } | |
1670 if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width { | |
1671 if !yaml_emitter_write_indent(emitter) { | |
1672 return false | |
1673 } | |
1674 i += width(value[i]) | |
1675 } else { | |
1676 if !write(emitter, value, &i) { | |
1677 return false | |
1678 } | |
1679 } | |
1680 emitter.indention = false | |
1681 breaks = false | |
1682 } | |
1683 } | |
1684 return true | |
1685 } |