~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/gopkg.in/yaml.v2/emitterc.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package yaml
 
2
 
 
3
import (
 
4
        "bytes"
 
5
)
 
6
 
 
7
// Flush the buffer if needed.
 
8
func flush(emitter *yaml_emitter_t) bool {
 
9
        if emitter.buffer_pos+5 >= len(emitter.buffer) {
 
10
                return yaml_emitter_flush(emitter)
 
11
        }
 
12
        return true
 
13
}
 
14
 
 
15
// Put a character to the output buffer.
 
16
func put(emitter *yaml_emitter_t, value byte) bool {
 
17
        if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
 
18
                return false
 
19
        }
 
20
        emitter.buffer[emitter.buffer_pos] = value
 
21
        emitter.buffer_pos++
 
22
        emitter.column++
 
23
        return true
 
24
}
 
25
 
 
26
// Put a line break to the output buffer.
 
27
func put_break(emitter *yaml_emitter_t) bool {
 
28
        if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
 
29
                return false
 
30
        }
 
31
        switch emitter.line_break {
 
32
        case yaml_CR_BREAK:
 
33
                emitter.buffer[emitter.buffer_pos] = '\r'
 
34
                emitter.buffer_pos += 1
 
35
        case yaml_LN_BREAK:
 
36
                emitter.buffer[emitter.buffer_pos] = '\n'
 
37
                emitter.buffer_pos += 1
 
38
        case yaml_CRLN_BREAK:
 
39
                emitter.buffer[emitter.buffer_pos+0] = '\r'
 
40
                emitter.buffer[emitter.buffer_pos+1] = '\n'
 
41
                emitter.buffer_pos += 2
 
42
        default:
 
43
                panic("unknown line break setting")
 
44
        }
 
45
        emitter.column = 0
 
46
        emitter.line++
 
47
        return true
 
48
}
 
49
 
 
50
// Copy a character from a string into buffer.
 
51
func write(emitter *yaml_emitter_t, s []byte, i *int) bool {
 
52
        if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
 
53
                return false
 
54
        }
 
55
        p := emitter.buffer_pos
 
56
        w := width(s[*i])
 
57
        switch w {
 
58
        case 4:
 
59
                emitter.buffer[p+3] = s[*i+3]
 
60
                fallthrough
 
61
        case 3:
 
62
                emitter.buffer[p+2] = s[*i+2]
 
63
                fallthrough
 
64
        case 2:
 
65
                emitter.buffer[p+1] = s[*i+1]
 
66
                fallthrough
 
67
        case 1:
 
68
                emitter.buffer[p+0] = s[*i+0]
 
69
        default:
 
70
                panic("unknown character width")
 
71
        }
 
72
        emitter.column++
 
73
        emitter.buffer_pos += w
 
74
        *i += w
 
75
        return true
 
76
}
 
77
 
 
78
// Write a whole string into buffer.
 
79
func write_all(emitter *yaml_emitter_t, s []byte) bool {
 
80
        for i := 0; i < len(s); {
 
81
                if !write(emitter, s, &i) {
 
82
                        return false
 
83
                }
 
84
        }
 
85
        return true
 
86
}
 
87
 
 
88
// Copy a line break character from a string into buffer.
 
89
func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool {
 
90
        if s[*i] == '\n' {
 
91
                if !put_break(emitter) {
 
92
                        return false
 
93
                }
 
94
                *i++
 
95
        } else {
 
96
                if !write(emitter, s, i) {
 
97
                        return false
 
98
                }
 
99
                emitter.column = 0
 
100
                emitter.line++
 
101
        }
 
102
        return true
 
103
}
 
104
 
 
105
// Set an emitter error and return false.
 
106
func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool {
 
107
        emitter.error = yaml_EMITTER_ERROR
 
108
        emitter.problem = problem
 
109
        return false
 
110
}
 
111
 
 
112
// Emit an event.
 
113
func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 
114
        emitter.events = append(emitter.events, *event)
 
115
        for !yaml_emitter_need_more_events(emitter) {
 
116
                event := &emitter.events[emitter.events_head]
 
117
                if !yaml_emitter_analyze_event(emitter, event) {
 
118
                        return false
 
119
                }
 
120
                if !yaml_emitter_state_machine(emitter, event) {
 
121
                        return false
 
122
                }
 
123
                yaml_event_delete(event)
 
124
                emitter.events_head++
 
125
        }
 
126
        return true
 
127
}
 
128
 
 
129
// Check if we need to accumulate more events before emitting.
 
130
//
 
131
// We accumulate extra
 
132
//  - 1 event for DOCUMENT-START
 
133
//  - 2 events for SEQUENCE-START
 
134
//  - 3 events for MAPPING-START
 
135
//
 
136
func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {
 
137
        if emitter.events_head == len(emitter.events) {
 
138
                return true
 
139
        }
 
140
        var accumulate int
 
141
        switch emitter.events[emitter.events_head].typ {
 
142
        case yaml_DOCUMENT_START_EVENT:
 
143
                accumulate = 1
 
144
                break
 
145
        case yaml_SEQUENCE_START_EVENT:
 
146
                accumulate = 2
 
147
                break
 
148
        case yaml_MAPPING_START_EVENT:
 
149
                accumulate = 3
 
150
                break
 
151
        default:
 
152
                return false
 
153
        }
 
154
        if len(emitter.events)-emitter.events_head > accumulate {
 
155
                return false
 
156
        }
 
157
        var level int
 
158
        for i := emitter.events_head; i < len(emitter.events); i++ {
 
159
                switch emitter.events[i].typ {
 
160
                case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT:
 
161
                        level++
 
162
                case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:
 
163
                        level--
 
164
                }
 
165
                if level == 0 {
 
166
                        return false
 
167
                }
 
168
        }
 
169
        return true
 
170
}
 
171
 
 
172
// Append a directive to the directives stack.
 
173
func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool {
 
174
        for i := 0; i < len(emitter.tag_directives); i++ {
 
175
                if bytes.Equal(value.handle, emitter.tag_directives[i].handle) {
 
176
                        if allow_duplicates {
 
177
                                return true
 
178
                        }
 
179
                        return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive")
 
180
                }
 
181
        }
 
182
 
 
183
        // [Go] Do we actually need to copy this given garbage collection
 
184
        // and the lack of deallocating destructors?
 
185
        tag_copy := yaml_tag_directive_t{
 
186
                handle: make([]byte, len(value.handle)),
 
187
                prefix: make([]byte, len(value.prefix)),
 
188
        }
 
189
        copy(tag_copy.handle, value.handle)
 
190
        copy(tag_copy.prefix, value.prefix)
 
191
        emitter.tag_directives = append(emitter.tag_directives, tag_copy)
 
192
        return true
 
193
}
 
194
 
 
195
// Increase the indentation level.
 
196
func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {
 
197
        emitter.indents = append(emitter.indents, emitter.indent)
 
198
        if emitter.indent < 0 {
 
199
                if flow {
 
200
                        emitter.indent = emitter.best_indent
 
201
                } else {
 
202
                        emitter.indent = 0
 
203
                }
 
204
        } else if !indentless {
 
205
                emitter.indent += emitter.best_indent
 
206
        }
 
207
        return true
 
208
}
 
209
 
 
210
// State dispatcher.
 
211
func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 
212
        switch emitter.state {
 
213
        default:
 
214
        case yaml_EMIT_STREAM_START_STATE:
 
215
                return yaml_emitter_emit_stream_start(emitter, event)
 
216
 
 
217
        case yaml_EMIT_FIRST_DOCUMENT_START_STATE:
 
218
                return yaml_emitter_emit_document_start(emitter, event, true)
 
219
 
 
220
        case yaml_EMIT_DOCUMENT_START_STATE:
 
221
                return yaml_emitter_emit_document_start(emitter, event, false)
 
222
 
 
223
        case yaml_EMIT_DOCUMENT_CONTENT_STATE:
 
224
                return yaml_emitter_emit_document_content(emitter, event)
 
225
 
 
226
        case yaml_EMIT_DOCUMENT_END_STATE:
 
227
                return yaml_emitter_emit_document_end(emitter, event)
 
228
 
 
229
        case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
 
230
                return yaml_emitter_emit_flow_sequence_item(emitter, event, true)
 
231
 
 
232
        case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:
 
233
                return yaml_emitter_emit_flow_sequence_item(emitter, event, false)
 
234
 
 
235
        case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
 
236
                return yaml_emitter_emit_flow_mapping_key(emitter, event, true)
 
237
 
 
238
        case yaml_EMIT_FLOW_MAPPING_KEY_STATE:
 
239
                return yaml_emitter_emit_flow_mapping_key(emitter, event, false)
 
240
 
 
241
        case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
 
242
                return yaml_emitter_emit_flow_mapping_value(emitter, event, true)
 
243
 
 
244
        case yaml_EMIT_FLOW_MAPPING_VALUE_STATE:
 
245
                return yaml_emitter_emit_flow_mapping_value(emitter, event, false)
 
246
 
 
247
        case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
 
248
                return yaml_emitter_emit_block_sequence_item(emitter, event, true)
 
249
 
 
250
        case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
 
251
                return yaml_emitter_emit_block_sequence_item(emitter, event, false)
 
252
 
 
253
        case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
 
254
                return yaml_emitter_emit_block_mapping_key(emitter, event, true)
 
255
 
 
256
        case yaml_EMIT_BLOCK_MAPPING_KEY_STATE:
 
257
                return yaml_emitter_emit_block_mapping_key(emitter, event, false)
 
258
 
 
259
        case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
 
260
                return yaml_emitter_emit_block_mapping_value(emitter, event, true)
 
261
 
 
262
        case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:
 
263
                return yaml_emitter_emit_block_mapping_value(emitter, event, false)
 
264
 
 
265
        case yaml_EMIT_END_STATE:
 
266
                return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")
 
267
        }
 
268
        panic("invalid emitter state")
 
269
}
 
270
 
 
271
// Expect STREAM-START.
 
272
func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 
273
        if event.typ != yaml_STREAM_START_EVENT {
 
274
                return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START")
 
275
        }
 
276
        if emitter.encoding == yaml_ANY_ENCODING {
 
277
                emitter.encoding = event.encoding
 
278
                if emitter.encoding == yaml_ANY_ENCODING {
 
279
                        emitter.encoding = yaml_UTF8_ENCODING
 
280
                }
 
281
        }
 
282
        if emitter.best_indent < 2 || emitter.best_indent > 9 {
 
283
                emitter.best_indent = 2
 
284
        }
 
285
        if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {
 
286
                emitter.best_width = 80
 
287
        }
 
288
        if emitter.best_width < 0 {
 
289
                emitter.best_width = 1<<31 - 1
 
290
        }
 
291
        if emitter.line_break == yaml_ANY_BREAK {
 
292
                emitter.line_break = yaml_LN_BREAK
 
293
        }
 
294
 
 
295
        emitter.indent = -1
 
296
        emitter.line = 0
 
297
        emitter.column = 0
 
298
        emitter.whitespace = true
 
299
        emitter.indention = true
 
300
 
 
301
        if emitter.encoding != yaml_UTF8_ENCODING {
 
302
                if !yaml_emitter_write_bom(emitter) {
 
303
                        return false
 
304
                }
 
305
        }
 
306
        emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE
 
307
        return true
 
308
}
 
309
 
 
310
// Expect DOCUMENT-START or STREAM-END.
 
311
func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
 
312
 
 
313
        if event.typ == yaml_DOCUMENT_START_EVENT {
 
314
 
 
315
                if event.version_directive != nil {
 
316
                        if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {
 
317
                                return false
 
318
                        }
 
319
                }
 
320
 
 
321
                for i := 0; i < len(event.tag_directives); i++ {
 
322
                        tag_directive := &event.tag_directives[i]
 
323
                        if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) {
 
324
                                return false
 
325
                        }
 
326
                        if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {
 
327
                                return false
 
328
                        }
 
329
                }
 
330
 
 
331
                for i := 0; i < len(default_tag_directives); i++ {
 
332
                        tag_directive := &default_tag_directives[i]
 
333
                        if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) {
 
334
                                return false
 
335
                        }
 
336
                }
 
337
 
 
338
                implicit := event.implicit
 
339
                if !first || emitter.canonical {
 
340
                        implicit = false
 
341
                }
 
342
 
 
343
                if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) {
 
344
                        if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
 
345
                                return false
 
346
                        }
 
347
                        if !yaml_emitter_write_indent(emitter) {
 
348
                                return false
 
349
                        }
 
350
                }
 
351
 
 
352
                if event.version_directive != nil {
 
353
                        implicit = false
 
354
                        if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) {
 
355
                                return false
 
356
                        }
 
357
                        if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) {
 
358
                                return false
 
359
                        }
 
360
                        if !yaml_emitter_write_indent(emitter) {
 
361
                                return false
 
362
                        }
 
363
                }
 
364
 
 
365
                if len(event.tag_directives) > 0 {
 
366
                        implicit = false
 
367
                        for i := 0; i < len(event.tag_directives); i++ {
 
368
                                tag_directive := &event.tag_directives[i]
 
369
                                if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) {
 
370
                                        return false
 
371
                                }
 
372
                                if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {
 
373
                                        return false
 
374
                                }
 
375
                                if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {
 
376
                                        return false
 
377
                                }
 
378
                                if !yaml_emitter_write_indent(emitter) {
 
379
                                        return false
 
380
                                }
 
381
                        }
 
382
                }
 
383
 
 
384
                if yaml_emitter_check_empty_document(emitter) {
 
385
                        implicit = false
 
386
                }
 
387
                if !implicit {
 
388
                        if !yaml_emitter_write_indent(emitter) {
 
389
                                return false
 
390
                        }
 
391
                        if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) {
 
392
                                return false
 
393
                        }
 
394
                        if emitter.canonical {
 
395
                                if !yaml_emitter_write_indent(emitter) {
 
396
                                        return false
 
397
                                }
 
398
                        }
 
399
                }
 
400
 
 
401
                emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE
 
402
                return true
 
403
        }
 
404
 
 
405
        if event.typ == yaml_STREAM_END_EVENT {
 
406
                if emitter.open_ended {
 
407
                        if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
 
408
                                return false
 
409
                        }
 
410
                        if !yaml_emitter_write_indent(emitter) {
 
411
                                return false
 
412
                        }
 
413
                }
 
414
                if !yaml_emitter_flush(emitter) {
 
415
                        return false
 
416
                }
 
417
                emitter.state = yaml_EMIT_END_STATE
 
418
                return true
 
419
        }
 
420
 
 
421
        return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END")
 
422
}
 
423
 
 
424
// Expect the root node.
 
425
func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 
426
        emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE)
 
427
        return yaml_emitter_emit_node(emitter, event, true, false, false, false)
 
428
}
 
429
 
 
430
// Expect DOCUMENT-END.
 
431
func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool {
 
432
        if event.typ != yaml_DOCUMENT_END_EVENT {
 
433
                return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END")
 
434
        }
 
435
        if !yaml_emitter_write_indent(emitter) {
 
436
                return false
 
437
        }
 
438
        if !event.implicit {
 
439
                // [Go] Allocate the slice elsewhere.
 
440
                if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
 
441
                        return false
 
442
                }
 
443
                if !yaml_emitter_write_indent(emitter) {
 
444
                        return false
 
445
                }
 
446
        }
 
447
        if !yaml_emitter_flush(emitter) {
 
448
                return false
 
449
        }
 
450
        emitter.state = yaml_EMIT_DOCUMENT_START_STATE
 
451
        emitter.tag_directives = emitter.tag_directives[:0]
 
452
        return true
 
453
}
 
454
 
 
455
// Expect a flow item node.
 
456
func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
 
457
        if first {
 
458
                if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {
 
459
                        return false
 
460
                }
 
461
                if !yaml_emitter_increase_indent(emitter, true, false) {
 
462
                        return false
 
463
                }
 
464
                emitter.flow_level++
 
465
        }
 
466
 
 
467
        if event.typ == yaml_SEQUENCE_END_EVENT {
 
468
                emitter.flow_level--
 
469
                emitter.indent = emitter.indents[len(emitter.indents)-1]
 
470
                emitter.indents = emitter.indents[:len(emitter.indents)-1]
 
471
                if emitter.canonical && !first {
 
472
                        if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
 
473
                                return false
 
474
                        }
 
475
                        if !yaml_emitter_write_indent(emitter) {
 
476
                                return false
 
477
                        }
 
478
                }
 
479
                if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {
 
480
                        return false
 
481
                }
 
482
                emitter.state = emitter.states[len(emitter.states)-1]
 
483
                emitter.states = emitter.states[:len(emitter.states)-1]
 
484
 
 
485
                return true
 
486
        }
 
487
 
 
488
        if !first {
 
489
                if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
 
490
                        return false
 
491
                }
 
492
        }
 
493
 
 
494
        if emitter.canonical || emitter.column > emitter.best_width {
 
495
                if !yaml_emitter_write_indent(emitter) {
 
496
                        return false
 
497
                }
 
498
        }
 
499
        emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)
 
500
        return yaml_emitter_emit_node(emitter, event, false, true, false, false)
 
501
}
 
502
 
 
503
// Expect a flow key node.
 
504
func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
 
505
        if first {
 
506
                if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {
 
507
                        return false
 
508
                }
 
509
                if !yaml_emitter_increase_indent(emitter, true, false) {
 
510
                        return false
 
511
                }
 
512
                emitter.flow_level++
 
513
        }
 
514
 
 
515
        if event.typ == yaml_MAPPING_END_EVENT {
 
516
                emitter.flow_level--
 
517
                emitter.indent = emitter.indents[len(emitter.indents)-1]
 
518
                emitter.indents = emitter.indents[:len(emitter.indents)-1]
 
519
                if emitter.canonical && !first {
 
520
                        if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
 
521
                                return false
 
522
                        }
 
523
                        if !yaml_emitter_write_indent(emitter) {
 
524
                                return false
 
525
                        }
 
526
                }
 
527
                if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {
 
528
                        return false
 
529
                }
 
530
                emitter.state = emitter.states[len(emitter.states)-1]
 
531
                emitter.states = emitter.states[:len(emitter.states)-1]
 
532
                return true
 
533
        }
 
534
 
 
535
        if !first {
 
536
                if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
 
537
                        return false
 
538
                }
 
539
        }
 
540
        if emitter.canonical || emitter.column > emitter.best_width {
 
541
                if !yaml_emitter_write_indent(emitter) {
 
542
                        return false
 
543
                }
 
544
        }
 
545
 
 
546
        if !emitter.canonical && yaml_emitter_check_simple_key(emitter) {
 
547
                emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)
 
548
                return yaml_emitter_emit_node(emitter, event, false, false, true, true)
 
549
        }
 
550
        if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {
 
551
                return false
 
552
        }
 
553
        emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)
 
554
        return yaml_emitter_emit_node(emitter, event, false, false, true, false)
 
555
}
 
556
 
 
557
// Expect a flow value node.
 
558
func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
 
559
        if simple {
 
560
                if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
 
561
                        return false
 
562
                }
 
563
        } else {
 
564
                if emitter.canonical || emitter.column > emitter.best_width {
 
565
                        if !yaml_emitter_write_indent(emitter) {
 
566
                                return false
 
567
                        }
 
568
                }
 
569
                if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {
 
570
                        return false
 
571
                }
 
572
        }
 
573
        emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)
 
574
        return yaml_emitter_emit_node(emitter, event, false, false, true, false)
 
575
}
 
576
 
 
577
// Expect a block item node.
 
578
func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
 
579
        if first {
 
580
                if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) {
 
581
                        return false
 
582
                }
 
583
        }
 
584
        if event.typ == yaml_SEQUENCE_END_EVENT {
 
585
                emitter.indent = emitter.indents[len(emitter.indents)-1]
 
586
                emitter.indents = emitter.indents[:len(emitter.indents)-1]
 
587
                emitter.state = emitter.states[len(emitter.states)-1]
 
588
                emitter.states = emitter.states[:len(emitter.states)-1]
 
589
                return true
 
590
        }
 
591
        if !yaml_emitter_write_indent(emitter) {
 
592
                return false
 
593
        }
 
594
        if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {
 
595
                return false
 
596
        }
 
597
        emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)
 
598
        return yaml_emitter_emit_node(emitter, event, false, true, false, false)
 
599
}
 
600
 
 
601
// Expect a block key node.
 
602
func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
 
603
        if first {
 
604
                if !yaml_emitter_increase_indent(emitter, false, false) {
 
605
                        return false
 
606
                }
 
607
        }
 
608
        if event.typ == yaml_MAPPING_END_EVENT {
 
609
                emitter.indent = emitter.indents[len(emitter.indents)-1]
 
610
                emitter.indents = emitter.indents[:len(emitter.indents)-1]
 
611
                emitter.state = emitter.states[len(emitter.states)-1]
 
612
                emitter.states = emitter.states[:len(emitter.states)-1]
 
613
                return true
 
614
        }
 
615
        if !yaml_emitter_write_indent(emitter) {
 
616
                return false
 
617
        }
 
618
        if yaml_emitter_check_simple_key(emitter) {
 
619
                emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)
 
620
                return yaml_emitter_emit_node(emitter, event, false, false, true, true)
 
621
        }
 
622
        if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {
 
623
                return false
 
624
        }
 
625
        emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)
 
626
        return yaml_emitter_emit_node(emitter, event, false, false, true, false)
 
627
}
 
628
 
 
629
// Expect a block value node.
 
630
func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
 
631
        if simple {
 
632
                if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
 
633
                        return false
 
634
                }
 
635
        } else {
 
636
                if !yaml_emitter_write_indent(emitter) {
 
637
                        return false
 
638
                }
 
639
                if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {
 
640
                        return false
 
641
                }
 
642
        }
 
643
        emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)
 
644
        return yaml_emitter_emit_node(emitter, event, false, false, true, false)
 
645
}
 
646
 
 
647
// Expect a node.
 
648
func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
 
649
        root bool, sequence bool, mapping bool, simple_key bool) bool {
 
650
 
 
651
        emitter.root_context = root
 
652
        emitter.sequence_context = sequence
 
653
        emitter.mapping_context = mapping
 
654
        emitter.simple_key_context = simple_key
 
655
 
 
656
        switch event.typ {
 
657
        case yaml_ALIAS_EVENT:
 
658
                return yaml_emitter_emit_alias(emitter, event)
 
659
        case yaml_SCALAR_EVENT:
 
660
                return yaml_emitter_emit_scalar(emitter, event)
 
661
        case yaml_SEQUENCE_START_EVENT:
 
662
                return yaml_emitter_emit_sequence_start(emitter, event)
 
663
        case yaml_MAPPING_START_EVENT:
 
664
                return yaml_emitter_emit_mapping_start(emitter, event)
 
665
        default:
 
666
                return yaml_emitter_set_emitter_error(emitter,
 
667
                        "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS")
 
668
        }
 
669
        return false
 
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 achor.
 
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
                preceeded_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
        preceeded_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 preceeded_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
                preceeded_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
}