Coverage Report

Created: 2025-11-24 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/tools/yaml/emitter.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2006-2016 Kirill Simonov
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
5
 * this software and associated documentation files (the "Software"), to deal in
6
 * the Software without restriction, including without limitation the rights to
7
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8
 * of the Software, and to permit persons to whom the Software is furnished to do
9
 * so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in all
12
 * copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
 * SOFTWARE.
21
 *
22
 */
23
24
#include "yaml_private.h"
25
26
/*
27
 * Flush the buffer if needed.
28
 */
29
30
#define FLUSH(emitter)                                                          \
31
0
    ((emitter->buffer.pointer+5 < emitter->buffer.end)                          \
32
0
     || yaml_emitter_flush(emitter))
33
34
/*
35
 * Put a character to the output buffer.
36
 */
37
38
#define PUT(emitter,value)                                                      \
39
0
    (FLUSH(emitter)                                                             \
40
0
     && (*(emitter->buffer.pointer++) = (yaml_char_t)(value),                   \
41
0
         emitter->column ++,                                                    \
42
0
         1))
43
44
/*
45
 * Put a line break to the output buffer.
46
 */
47
48
#define PUT_BREAK(emitter)                                                      \
49
0
    (FLUSH(emitter)                                                             \
50
0
     && ((emitter->line_break == YAML_CR_BREAK ?                                \
51
0
             (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') :              \
52
0
          emitter->line_break == YAML_LN_BREAK ?                                \
53
0
             (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') :              \
54
0
          emitter->line_break == YAML_CRLN_BREAK ?                              \
55
0
             (*(emitter->buffer.pointer++) = (yaml_char_t) '\r',                \
56
0
              *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0),          \
57
0
         emitter->column = 0,                                                   \
58
0
         emitter->line ++,                                                      \
59
0
         1))
60
61
/*
62
 * Copy a character from a string into buffer.
63
 */
64
65
#define WRITE(emitter,string)                                                   \
66
0
    (FLUSH(emitter)                                                             \
67
0
     && (COPY(emitter->buffer,string),                                          \
68
0
         emitter->column ++,                                                    \
69
0
         1))
70
71
/*
72
 * Copy a line break character from a string into buffer.
73
 */
74
75
#define WRITE_BREAK(emitter,string)                                             \
76
0
    (FLUSH(emitter)                                                             \
77
0
     && (CHECK(string,'\n') ?                                                   \
78
0
         (PUT_BREAK(emitter),                                                   \
79
0
          string.pointer ++,                                                    \
80
0
          1) :                                                                  \
81
0
         (COPY(emitter->buffer,string),                                         \
82
0
          emitter->column = 0,                                                  \
83
0
          emitter->line ++,                                                     \
84
0
          1)))
85
86
/*
87
 * API functions.
88
 */
89
90
YAML_DECLARE(int)
91
yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
92
93
/*
94
 * Utility functions.
95
 */
96
97
static int
98
yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem);
99
100
static int
101
yaml_emitter_need_more_events(yaml_emitter_t *emitter);
102
103
static int
104
yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
105
        yaml_tag_directive_t value, int allow_duplicates);
106
107
static int
108
yaml_emitter_increase_indent(yaml_emitter_t *emitter,
109
        int flow, int indentless);
110
111
/*
112
 * State functions.
113
 */
114
115
static int
116
yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event);
117
118
static int
119
yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
120
        yaml_event_t *event);
121
122
static int
123
yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
124
        yaml_event_t *event, int first);
125
126
static int
127
yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
128
        yaml_event_t *event);
129
130
static int
131
yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
132
        yaml_event_t *event);
133
134
static int
135
yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
136
        yaml_event_t *event, int first);
137
138
static int
139
yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
140
        yaml_event_t *event, int first);
141
142
static int
143
yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
144
        yaml_event_t *event, int simple);
145
146
static int
147
yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
148
        yaml_event_t *event, int first);
149
150
static int
151
yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
152
        yaml_event_t *event, int first);
153
154
static int
155
yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
156
        yaml_event_t *event, int simple);
157
158
static int
159
yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
160
        int root, int sequence, int mapping, int simple_key);
161
162
static int
163
yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event);
164
165
static int
166
yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event);
167
168
static int
169
yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event);
170
171
static int
172
yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event);
173
174
/*
175
 * Checkers.
176
 */
177
178
static int
179
yaml_emitter_check_empty_document(yaml_emitter_t *emitter);
180
181
static int
182
yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter);
183
184
static int
185
yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter);
186
187
static int
188
yaml_emitter_check_simple_key(yaml_emitter_t *emitter);
189
190
static int
191
yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event);
192
193
/*
194
 * Processors.
195
 */
196
197
static int
198
yaml_emitter_process_anchor(yaml_emitter_t *emitter);
199
200
static int
201
yaml_emitter_process_tag(yaml_emitter_t *emitter);
202
203
static int
204
yaml_emitter_process_scalar(yaml_emitter_t *emitter);
205
206
/*
207
 * Analyzers.
208
 */
209
210
static int
211
yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
212
        yaml_version_directive_t version_directive);
213
214
static int
215
yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
216
        yaml_tag_directive_t tag_directive);
217
218
static int
219
yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
220
        yaml_char_t *anchor, int alias);
221
222
static int
223
yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
224
        yaml_char_t *tag);
225
226
static int
227
yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
228
        yaml_char_t *value, size_t length);
229
230
static int
231
yaml_emitter_analyze_event(yaml_emitter_t *emitter,
232
        yaml_event_t *event);
233
234
/*
235
 * Writers.
236
 */
237
238
static int
239
yaml_emitter_write_bom(yaml_emitter_t *emitter);
240
241
static int
242
yaml_emitter_write_indent(yaml_emitter_t *emitter);
243
244
static int
245
yaml_emitter_write_indicator(yaml_emitter_t *emitter,
246
        char *indicator, int need_whitespace,
247
        int is_whitespace, int is_indention);
248
249
static int
250
yaml_emitter_write_anchor(yaml_emitter_t *emitter,
251
        yaml_char_t *value, size_t length);
252
253
static int
254
yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
255
        yaml_char_t *value, size_t length);
256
257
static int
258
yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
259
        yaml_char_t *value, size_t length, int need_whitespace);
260
261
static int
262
yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
263
        yaml_char_t *value, size_t length, int allow_breaks);
264
265
static int
266
yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
267
        yaml_char_t *value, size_t length, int allow_breaks);
268
269
static int
270
yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
271
        yaml_char_t *value, size_t length, int allow_breaks);
272
273
static int
274
yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
275
        yaml_string_t string);
276
277
static int
278
yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
279
        yaml_char_t *value, size_t length);
280
281
static int
282
yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
283
        yaml_char_t *value, size_t length);
284
285
/*
286
 * Set an emitter error and return 0.
287
 */
288
289
static int
290
yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem)
291
0
{
292
0
    emitter->error = YAML_EMITTER_ERROR;
293
0
    emitter->problem = problem;
294
295
0
    return 0;
296
0
}
297
298
/*
299
 * Emit an event.
300
 */
301
302
YAML_DECLARE(int)
303
yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event)
304
0
{
305
0
    if (!ENQUEUE(emitter, emitter->events, *event)) {
306
0
        yaml_event_delete(event);
307
0
        return 0;
308
0
    }
309
310
0
    while (!yaml_emitter_need_more_events(emitter)) {
311
0
        if (!yaml_emitter_analyze_event(emitter, emitter->events.head))
312
0
            return 0;
313
0
        if (!yaml_emitter_state_machine(emitter, emitter->events.head))
314
0
            return 0;
315
0
        yaml_event_delete(&DEQUEUE(emitter, emitter->events));
316
0
    }
317
318
0
    return 1;
319
0
}
320
321
/*
322
 * Check if we need to accumulate more events before emitting.
323
 *
324
 * We accumulate extra
325
 *  - 1 event for DOCUMENT-START
326
 *  - 2 events for SEQUENCE-START
327
 *  - 3 events for MAPPING-START
328
 */
329
330
static int
331
yaml_emitter_need_more_events(yaml_emitter_t *emitter)
332
0
{
333
0
    int level = 0;
334
0
    int accumulate = 0;
335
0
    yaml_event_t *event;
336
337
0
    if (QUEUE_EMPTY(emitter, emitter->events))
338
0
        return 1;
339
340
0
    switch (emitter->events.head->type) {
341
0
        case YAML_DOCUMENT_START_EVENT:
342
0
            accumulate = 1;
343
0
            break;
344
0
        case YAML_SEQUENCE_START_EVENT:
345
0
            accumulate = 2;
346
0
            break;
347
0
        case YAML_MAPPING_START_EVENT:
348
0
            accumulate = 3;
349
0
            break;
350
0
        default:
351
0
            return 0;
352
0
    }
353
354
0
    if (emitter->events.tail - emitter->events.head > accumulate)
355
0
        return 0;
356
357
0
    for (event = emitter->events.head; event != emitter->events.tail; event ++) {
358
0
        switch (event->type) {
359
0
            case YAML_STREAM_START_EVENT:
360
0
            case YAML_DOCUMENT_START_EVENT:
361
0
            case YAML_SEQUENCE_START_EVENT:
362
0
            case YAML_MAPPING_START_EVENT:
363
0
                level += 1;
364
0
                break;
365
0
            case YAML_STREAM_END_EVENT:
366
0
            case YAML_DOCUMENT_END_EVENT:
367
0
            case YAML_SEQUENCE_END_EVENT:
368
0
            case YAML_MAPPING_END_EVENT:
369
0
                level -= 1;
370
0
                break;
371
0
            default:
372
0
                break;
373
0
        }
374
0
        if (!level)
375
0
            return 0;
376
0
    }
377
378
0
    return 1;
379
0
}
380
381
/*
382
 * Append a directive to the directives stack.
383
 */
384
385
static int
386
yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
387
        yaml_tag_directive_t value, int allow_duplicates)
388
0
{
389
0
    yaml_tag_directive_t *tag_directive;
390
0
    yaml_tag_directive_t copy = { NULL, NULL };
391
392
0
    for (tag_directive = emitter->tag_directives.start;
393
0
            tag_directive != emitter->tag_directives.top; tag_directive ++) {
394
0
        if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
395
0
            if (allow_duplicates)
396
0
                return 1;
397
0
            return yaml_emitter_set_emitter_error(emitter,
398
0
                    "duplicate %TAG directive");
399
0
        }
400
0
    }
401
402
0
    copy.handle = yaml_strdup(value.handle);
403
0
    copy.prefix = yaml_strdup(value.prefix);
404
0
    if (!copy.handle || !copy.prefix) {
405
0
        emitter->error = YAML_MEMORY_ERROR;
406
0
        goto error;
407
0
    }
408
409
0
    if (!PUSH(emitter, emitter->tag_directives, copy))
410
0
        goto error;
411
412
0
    return 1;
413
414
0
error:
415
0
    yaml_free(copy.handle);
416
0
    yaml_free(copy.prefix);
417
0
    return 0;
418
0
}
419
420
/*
421
 * Increase the indentation level.
422
 */
423
424
static int
425
yaml_emitter_increase_indent(yaml_emitter_t *emitter,
426
        int flow, int indentless)
427
0
{
428
0
    if (!PUSH(emitter, emitter->indents, emitter->indent))
429
0
        return 0;
430
431
0
    if (emitter->indent < 0) {
432
0
        emitter->indent = flow ? emitter->best_indent : 0;
433
0
    }
434
0
    else if (!indentless) {
435
0
        emitter->indent += emitter->best_indent;
436
0
    }
437
438
0
    return 1;
439
0
}
440
441
/*
442
 * State dispatcher.
443
 */
444
445
static int
446
yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event)
447
0
{
448
0
    switch (emitter->state)
449
0
    {
450
0
        case YAML_EMIT_STREAM_START_STATE:
451
0
            return yaml_emitter_emit_stream_start(emitter, event);
452
453
0
        case YAML_EMIT_FIRST_DOCUMENT_START_STATE:
454
0
            return yaml_emitter_emit_document_start(emitter, event, 1);
455
456
0
        case YAML_EMIT_DOCUMENT_START_STATE:
457
0
            return yaml_emitter_emit_document_start(emitter, event, 0);
458
459
0
        case YAML_EMIT_DOCUMENT_CONTENT_STATE:
460
0
            return yaml_emitter_emit_document_content(emitter, event);
461
462
0
        case YAML_EMIT_DOCUMENT_END_STATE:
463
0
            return yaml_emitter_emit_document_end(emitter, event);
464
465
0
        case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
466
0
            return yaml_emitter_emit_flow_sequence_item(emitter, event, 1);
467
468
0
        case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE:
469
0
            return yaml_emitter_emit_flow_sequence_item(emitter, event, 0);
470
471
0
        case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
472
0
            return yaml_emitter_emit_flow_mapping_key(emitter, event, 1);
473
474
0
        case YAML_EMIT_FLOW_MAPPING_KEY_STATE:
475
0
            return yaml_emitter_emit_flow_mapping_key(emitter, event, 0);
476
477
0
        case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
478
0
            return yaml_emitter_emit_flow_mapping_value(emitter, event, 1);
479
480
0
        case YAML_EMIT_FLOW_MAPPING_VALUE_STATE:
481
0
            return yaml_emitter_emit_flow_mapping_value(emitter, event, 0);
482
483
0
        case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
484
0
            return yaml_emitter_emit_block_sequence_item(emitter, event, 1);
485
486
0
        case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
487
0
            return yaml_emitter_emit_block_sequence_item(emitter, event, 0);
488
489
0
        case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
490
0
            return yaml_emitter_emit_block_mapping_key(emitter, event, 1);
491
492
0
        case YAML_EMIT_BLOCK_MAPPING_KEY_STATE:
493
0
            return yaml_emitter_emit_block_mapping_key(emitter, event, 0);
494
495
0
        case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
496
0
            return yaml_emitter_emit_block_mapping_value(emitter, event, 1);
497
498
0
        case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE:
499
0
            return yaml_emitter_emit_block_mapping_value(emitter, event, 0);
500
501
0
        case YAML_EMIT_END_STATE:
502
0
            return yaml_emitter_set_emitter_error(emitter,
503
0
                    "expected nothing after STREAM-END");
504
505
0
        default:
506
0
            assert(1);      /* Invalid state. */
507
0
    }
508
509
0
    return 0;
510
0
}
511
512
/*
513
 * Expect STREAM-START.
514
 */
515
516
static int
517
yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
518
        yaml_event_t *event)
519
0
{
520
0
    if (event->type == YAML_STREAM_START_EVENT)
521
0
    {
522
0
        if (!emitter->encoding) {
523
0
            emitter->encoding = event->data.stream_start.encoding;
524
0
        }
525
526
0
        if (!emitter->encoding) {
527
0
            emitter->encoding = YAML_UTF8_ENCODING;
528
0
        }
529
530
0
        if (emitter->best_indent < 2 || emitter->best_indent > 9) {
531
0
            emitter->best_indent  = 2;
532
0
        }
533
534
0
        if (emitter->best_width >= 0
535
0
                && emitter->best_width <= emitter->best_indent*2) {
536
0
            emitter->best_width = 80;
537
0
        }
538
539
0
        if (emitter->best_width < 0) {
540
0
            emitter->best_width = INT_MAX;
541
0
        }
542
        
543
0
        if (!emitter->line_break) {
544
0
            emitter->line_break = YAML_LN_BREAK;
545
0
        }
546
547
0
        emitter->indent = -1;
548
549
0
        emitter->line = 0;
550
0
        emitter->column = 0;
551
0
        emitter->whitespace = 1;
552
0
        emitter->indention = 1;
553
554
0
        if (emitter->encoding != YAML_UTF8_ENCODING) {
555
0
            if (!yaml_emitter_write_bom(emitter))
556
0
                return 0;
557
0
        }
558
559
0
        emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE;
560
561
0
        return 1;
562
0
    }
563
564
0
    return yaml_emitter_set_emitter_error(emitter,
565
0
            "expected STREAM-START");
566
0
}
567
568
/*
569
 * Expect DOCUMENT-START or STREAM-END.
570
 */
571
572
static int
573
yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
574
        yaml_event_t *event, int first)
575
0
{
576
0
    if (event->type == YAML_DOCUMENT_START_EVENT)
577
0
    {
578
0
        yaml_tag_directive_t default_tag_directives[] = {
579
0
            {(yaml_char_t *)"!", (yaml_char_t *)"!"},
580
0
            {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
581
0
            {NULL, NULL}
582
0
        };
583
0
        yaml_tag_directive_t *tag_directive;
584
0
        int implicit;
585
586
0
        if (event->data.document_start.version_directive) {
587
0
            if (!yaml_emitter_analyze_version_directive(emitter,
588
0
                        *event->data.document_start.version_directive))
589
0
                return 0;
590
0
        }
591
592
0
        for (tag_directive = event->data.document_start.tag_directives.start;
593
0
                tag_directive != event->data.document_start.tag_directives.end;
594
0
                tag_directive ++) {
595
0
            if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive))
596
0
                return 0;
597
0
            if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0))
598
0
                return 0;
599
0
        }
600
601
0
        for (tag_directive = default_tag_directives;
602
0
                tag_directive->handle; tag_directive ++) {
603
0
            if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1))
604
0
                return 0;
605
0
        }
606
607
0
        implicit = event->data.document_start.implicit;
608
0
        if (!first || emitter->canonical) {
609
0
            implicit = 0;
610
0
        }
611
612
0
        if ((event->data.document_start.version_directive ||
613
0
                    (event->data.document_start.tag_directives.start
614
0
                     != event->data.document_start.tag_directives.end)) &&
615
0
                emitter->open_ended)
616
0
        {
617
0
            if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
618
0
                return 0;
619
0
            if (!yaml_emitter_write_indent(emitter))
620
0
                return 0;
621
0
        }
622
623
0
        if (event->data.document_start.version_directive) {
624
0
            implicit = 0;
625
0
            if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0))
626
0
                return 0;
627
0
            if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
628
0
                return 0;
629
0
            if (!yaml_emitter_write_indent(emitter))
630
0
                return 0;
631
0
        }
632
        
633
0
        if (event->data.document_start.tag_directives.start
634
0
                != event->data.document_start.tag_directives.end) {
635
0
            implicit = 0;
636
0
            for (tag_directive = event->data.document_start.tag_directives.start;
637
0
                    tag_directive != event->data.document_start.tag_directives.end;
638
0
                    tag_directive ++) {
639
0
                if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0))
640
0
                    return 0;
641
0
                if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle,
642
0
                            strlen((char *)tag_directive->handle)))
643
0
                    return 0;
644
0
                if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix,
645
0
                            strlen((char *)tag_directive->prefix), 1))
646
0
                    return 0;
647
0
                if (!yaml_emitter_write_indent(emitter))
648
0
                    return 0;
649
0
            }
650
0
        }
651
652
0
        if (yaml_emitter_check_empty_document(emitter)) {
653
0
            implicit = 0;
654
0
        }
655
656
0
        if (!implicit) {
657
0
            if (!yaml_emitter_write_indent(emitter))
658
0
                return 0;
659
0
            if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0))
660
0
                return 0;
661
0
            if (emitter->canonical) {
662
0
                if (!yaml_emitter_write_indent(emitter))
663
0
                    return 0;
664
0
            }
665
0
        }
666
667
0
        emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE;
668
669
0
        return 1;
670
0
    }
671
672
0
    else if (event->type == YAML_STREAM_END_EVENT)
673
0
    {
674
0
        if (emitter->open_ended)
675
0
        {
676
0
            if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
677
0
                return 0;
678
0
            if (!yaml_emitter_write_indent(emitter))
679
0
                return 0;
680
0
        }
681
682
0
        if (!yaml_emitter_flush(emitter))
683
0
            return 0;
684
685
0
        emitter->state = YAML_EMIT_END_STATE;
686
687
0
        return 1;
688
0
    }
689
690
0
    return yaml_emitter_set_emitter_error(emitter,
691
0
            "expected DOCUMENT-START or STREAM-END");
692
0
}
693
694
/*
695
 * Expect the root node.
696
 */
697
698
static int
699
yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
700
        yaml_event_t *event)
701
0
{
702
0
    if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE))
703
0
        return 0;
704
705
0
    return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0);
706
0
}
707
708
/*
709
 * Expect DOCUMENT-END.
710
 */
711
712
static int
713
yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
714
        yaml_event_t *event)
715
0
{
716
0
    if (event->type == YAML_DOCUMENT_END_EVENT)
717
0
    {
718
0
        if (!yaml_emitter_write_indent(emitter))
719
0
            return 0;
720
0
        if (!event->data.document_end.implicit) {
721
0
            if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
722
0
                return 0;
723
0
            if (!yaml_emitter_write_indent(emitter))
724
0
                return 0;
725
0
        }
726
0
        if (!yaml_emitter_flush(emitter))
727
0
            return 0;
728
729
0
        emitter->state = YAML_EMIT_DOCUMENT_START_STATE;
730
731
0
        while (!STACK_EMPTY(emitter, emitter->tag_directives)) {
732
0
            yaml_tag_directive_t tag_directive = POP(emitter,
733
0
                    emitter->tag_directives);
734
0
            yaml_free(tag_directive.handle);
735
0
            yaml_free(tag_directive.prefix);
736
0
        }
737
738
0
        return 1;
739
0
    }
740
741
0
    return yaml_emitter_set_emitter_error(emitter,
742
0
            "expected DOCUMENT-END");
743
0
}
744
745
/*
746
 * 
747
 * Expect a flow item node.
748
 */
749
750
static int
751
yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
752
        yaml_event_t *event, int first)
753
0
{
754
0
    if (first)
755
0
    {
756
0
        if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0))
757
0
            return 0;
758
0
        if (!yaml_emitter_increase_indent(emitter, 1, 0))
759
0
            return 0;
760
0
        emitter->flow_level ++;
761
0
    }
762
763
0
    if (event->type == YAML_SEQUENCE_END_EVENT)
764
0
    {
765
0
        emitter->flow_level --;
766
0
        emitter->indent = POP(emitter, emitter->indents);
767
0
        if (emitter->canonical && !first) {
768
0
            if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
769
0
                return 0;
770
0
            if (!yaml_emitter_write_indent(emitter))
771
0
                return 0;
772
0
        }
773
0
        if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0))
774
0
            return 0;
775
0
        emitter->state = POP(emitter, emitter->states);
776
777
0
        return 1;
778
0
    }
779
780
0
    if (!first) {
781
0
        if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
782
0
            return 0;
783
0
    }
784
785
0
    if (emitter->canonical || emitter->column > emitter->best_width) {
786
0
        if (!yaml_emitter_write_indent(emitter))
787
0
            return 0;
788
0
    }
789
0
    if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE))
790
0
        return 0;
791
792
0
    return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
793
0
}
794
795
/*
796
 * Expect a flow key node.
797
 */
798
799
static int
800
yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
801
        yaml_event_t *event, int first)
802
0
{
803
0
    if (first)
804
0
    {
805
0
        if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0))
806
0
            return 0;
807
0
        if (!yaml_emitter_increase_indent(emitter, 1, 0))
808
0
            return 0;
809
0
        emitter->flow_level ++;
810
0
    }
811
812
0
    if (event->type == YAML_MAPPING_END_EVENT)
813
0
    {
814
0
        emitter->flow_level --;
815
0
        emitter->indent = POP(emitter, emitter->indents);
816
0
        if (emitter->canonical && !first) {
817
0
            if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
818
0
                return 0;
819
0
            if (!yaml_emitter_write_indent(emitter))
820
0
                return 0;
821
0
        }
822
0
        if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0))
823
0
            return 0;
824
0
        emitter->state = POP(emitter, emitter->states);
825
826
0
        return 1;
827
0
    }
828
829
0
    if (!first) {
830
0
        if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
831
0
            return 0;
832
0
    }
833
0
    if (emitter->canonical || emitter->column > emitter->best_width) {
834
0
        if (!yaml_emitter_write_indent(emitter))
835
0
            return 0;
836
0
    }
837
838
0
    if (!emitter->canonical && yaml_emitter_check_simple_key(emitter))
839
0
    {
840
0
        if (!PUSH(emitter, emitter->states,
841
0
                    YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE))
842
0
            return 0;
843
844
0
        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
845
0
    }
846
0
    else
847
0
    {
848
0
        if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0))
849
0
            return 0;
850
0
        if (!PUSH(emitter, emitter->states,
851
0
                    YAML_EMIT_FLOW_MAPPING_VALUE_STATE))
852
0
            return 0;
853
854
0
        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
855
0
    }
856
0
}
857
858
/*
859
 * Expect a flow value node.
860
 */
861
862
static int
863
yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
864
        yaml_event_t *event, int simple)
865
0
{
866
0
    if (simple) {
867
0
        if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
868
0
            return 0;
869
0
    }
870
0
    else {
871
0
        if (emitter->canonical || emitter->column > emitter->best_width) {
872
0
            if (!yaml_emitter_write_indent(emitter))
873
0
                return 0;
874
0
        }
875
0
        if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0))
876
0
            return 0;
877
0
    }
878
0
    if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE))
879
0
        return 0;
880
0
    return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
881
0
}
882
883
/*
884
 * Expect a block item node.
885
 */
886
887
static int
888
yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
889
        yaml_event_t *event, int first)
890
0
{
891
0
    if (first)
892
0
    {
893
0
        if (!yaml_emitter_increase_indent(emitter, 0,
894
0
                    (emitter->mapping_context && !emitter->indention)))
895
0
            return 0;
896
0
    }
897
898
0
    if (event->type == YAML_SEQUENCE_END_EVENT)
899
0
    {
900
0
        emitter->indent = POP(emitter, emitter->indents);
901
0
        emitter->state = POP(emitter, emitter->states);
902
903
0
        return 1;
904
0
    }
905
906
0
    if (!yaml_emitter_write_indent(emitter))
907
0
        return 0;
908
0
    if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1))
909
0
        return 0;
910
0
    if (!PUSH(emitter, emitter->states,
911
0
                YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE))
912
0
        return 0;
913
914
0
    return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
915
0
}
916
917
/*
918
 * Expect a block key node.
919
 */
920
921
static int
922
yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
923
        yaml_event_t *event, int first)
924
0
{
925
0
    if (first)
926
0
    {
927
0
        if (!yaml_emitter_increase_indent(emitter, 0, 0))
928
0
            return 0;
929
0
    }
930
931
0
    if (event->type == YAML_MAPPING_END_EVENT)
932
0
    {
933
0
        emitter->indent = POP(emitter, emitter->indents);
934
0
        emitter->state = POP(emitter, emitter->states);
935
936
0
        return 1;
937
0
    }
938
939
0
    if (!yaml_emitter_write_indent(emitter))
940
0
        return 0;
941
942
0
    if (yaml_emitter_check_simple_key(emitter))
943
0
    {
944
0
        if (!PUSH(emitter, emitter->states,
945
0
                    YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE))
946
0
            return 0;
947
948
0
        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
949
0
    }
950
0
    else
951
0
    {
952
0
        if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1))
953
0
            return 0;
954
0
        if (!PUSH(emitter, emitter->states,
955
0
                    YAML_EMIT_BLOCK_MAPPING_VALUE_STATE))
956
0
            return 0;
957
958
0
        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
959
0
    }
960
0
}
961
962
/*
963
 * Expect a block value node.
964
 */
965
966
static int
967
yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
968
        yaml_event_t *event, int simple)
969
0
{
970
0
    if (simple) {
971
0
        if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
972
0
            return 0;
973
0
    }
974
0
    else {
975
0
        if (!yaml_emitter_write_indent(emitter))
976
0
            return 0;
977
0
        if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1))
978
0
            return 0;
979
0
    }
980
0
    if (!PUSH(emitter, emitter->states,
981
0
                YAML_EMIT_BLOCK_MAPPING_KEY_STATE))
982
0
        return 0;
983
984
0
    return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
985
0
}
986
987
/*
988
 * Expect a node.
989
 */
990
991
static int
992
yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
993
        int root, int sequence, int mapping, int simple_key)
994
0
{
995
0
    emitter->root_context = root;
996
0
    emitter->sequence_context = sequence;
997
0
    emitter->mapping_context = mapping;
998
0
    emitter->simple_key_context = simple_key;
999
1000
0
    switch (event->type)
1001
0
    {
1002
0
        case YAML_ALIAS_EVENT:
1003
0
            return yaml_emitter_emit_alias(emitter, event);
1004
1005
0
        case YAML_SCALAR_EVENT:
1006
0
            return yaml_emitter_emit_scalar(emitter, event);
1007
1008
0
        case YAML_SEQUENCE_START_EVENT:
1009
0
            return yaml_emitter_emit_sequence_start(emitter, event);
1010
1011
0
        case YAML_MAPPING_START_EVENT:
1012
0
            return yaml_emitter_emit_mapping_start(emitter, event);
1013
1014
0
        default:
1015
0
            return yaml_emitter_set_emitter_error(emitter,
1016
0
                    "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS");
1017
0
    }
1018
1019
0
    return 0;
1020
0
}
1021
1022
/*
1023
 * Expect ALIAS.
1024
 */
1025
1026
static int
1027
yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event)
1028
0
{
1029
0
    if (!yaml_emitter_process_anchor(emitter))
1030
0
        return 0;
1031
0
    emitter->state = POP(emitter, emitter->states);
1032
1033
0
    return 1;
1034
0
}
1035
1036
/*
1037
 * Expect SCALAR.
1038
 */
1039
1040
static int
1041
yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event)
1042
0
{
1043
0
    if (!yaml_emitter_select_scalar_style(emitter, event))
1044
0
        return 0;
1045
0
    if (!yaml_emitter_process_anchor(emitter))
1046
0
        return 0;
1047
0
    if (!yaml_emitter_process_tag(emitter))
1048
0
        return 0;
1049
0
    if (!yaml_emitter_increase_indent(emitter, 1, 0))
1050
0
        return 0;
1051
0
    if (!yaml_emitter_process_scalar(emitter))
1052
0
        return 0;
1053
0
    emitter->indent = POP(emitter, emitter->indents);
1054
0
    emitter->state = POP(emitter, emitter->states);
1055
1056
0
    return 1;
1057
0
}
1058
1059
/*
1060
 * Expect SEQUENCE-START.
1061
 */
1062
1063
static int
1064
yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event)
1065
0
{
1066
0
    if (!yaml_emitter_process_anchor(emitter))
1067
0
        return 0;
1068
0
    if (!yaml_emitter_process_tag(emitter))
1069
0
        return 0;
1070
1071
0
    if (emitter->flow_level || emitter->canonical
1072
0
            || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE
1073
0
            || yaml_emitter_check_empty_sequence(emitter)) {
1074
0
        emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE;
1075
0
    }
1076
0
    else {
1077
0
        emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE;
1078
0
    }
1079
1080
0
    return 1;
1081
0
}
1082
1083
/*
1084
 * Expect MAPPING-START.
1085
 */
1086
1087
static int
1088
yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event)
1089
0
{
1090
0
    if (!yaml_emitter_process_anchor(emitter))
1091
0
        return 0;
1092
0
    if (!yaml_emitter_process_tag(emitter))
1093
0
        return 0;
1094
1095
0
    if (emitter->flow_level || emitter->canonical
1096
0
            || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE
1097
0
            || yaml_emitter_check_empty_mapping(emitter)) {
1098
0
        emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE;
1099
0
    }
1100
0
    else {
1101
0
        emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE;
1102
0
    }
1103
1104
0
    return 1;
1105
0
}
1106
1107
/*
1108
 * Check if the document content is an empty scalar.
1109
 */
1110
1111
static int
1112
yaml_emitter_check_empty_document(yaml_emitter_t *emitter)
1113
0
{
1114
0
    return 0;
1115
0
}
1116
1117
/*
1118
 * Check if the next events represent an empty sequence.
1119
 */
1120
1121
static int
1122
yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter)
1123
0
{
1124
0
    if (emitter->events.tail - emitter->events.head < 2)
1125
0
        return 0;
1126
1127
0
    return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT
1128
0
            && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT);
1129
0
}
1130
1131
/*
1132
 * Check if the next events represent an empty mapping.
1133
 */
1134
1135
static int
1136
yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter)
1137
0
{
1138
0
    if (emitter->events.tail - emitter->events.head < 2)
1139
0
        return 0;
1140
1141
0
    return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT
1142
0
            && emitter->events.head[1].type == YAML_MAPPING_END_EVENT);
1143
0
}
1144
1145
/*
1146
 * Check if the next node can be expressed as a simple key.
1147
 */
1148
1149
static int
1150
yaml_emitter_check_simple_key(yaml_emitter_t *emitter)
1151
0
{
1152
0
    yaml_event_t *event = emitter->events.head;
1153
0
    size_t length = 0;
1154
1155
0
    switch (event->type)
1156
0
    {
1157
0
        case YAML_ALIAS_EVENT:
1158
0
            length += emitter->anchor_data.anchor_length;
1159
0
            break;
1160
1161
0
        case YAML_SCALAR_EVENT:
1162
0
            if (emitter->scalar_data.multiline)
1163
0
                return 0;
1164
0
            length += emitter->anchor_data.anchor_length
1165
0
                + emitter->tag_data.handle_length
1166
0
                + emitter->tag_data.suffix_length
1167
0
                + emitter->scalar_data.length;
1168
0
            break;
1169
1170
0
        case YAML_SEQUENCE_START_EVENT:
1171
0
            if (!yaml_emitter_check_empty_sequence(emitter))
1172
0
                return 0;
1173
0
            length += emitter->anchor_data.anchor_length
1174
0
                + emitter->tag_data.handle_length
1175
0
                + emitter->tag_data.suffix_length;
1176
0
            break;
1177
1178
0
        case YAML_MAPPING_START_EVENT:
1179
0
            if (!yaml_emitter_check_empty_mapping(emitter))
1180
0
                return 0;
1181
0
            length += emitter->anchor_data.anchor_length
1182
0
                + emitter->tag_data.handle_length
1183
0
                + emitter->tag_data.suffix_length;
1184
0
            break;
1185
1186
0
        default:
1187
0
            return 0;
1188
0
    }
1189
1190
0
    if (length > 128)
1191
0
        return 0;
1192
1193
0
    return 1;
1194
0
}
1195
1196
/*
1197
 * Determine an acceptable scalar style.
1198
 */
1199
1200
static int
1201
yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event)
1202
0
{
1203
0
    yaml_scalar_style_t style = event->data.scalar.style;
1204
0
    int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix);
1205
1206
0
    if (no_tag && !event->data.scalar.plain_implicit
1207
0
            && !event->data.scalar.quoted_implicit) {
1208
0
        return yaml_emitter_set_emitter_error(emitter,
1209
0
                "neither tag nor implicit flags are specified");
1210
0
    }
1211
1212
0
    if (style == YAML_ANY_SCALAR_STYLE)
1213
0
        style = YAML_PLAIN_SCALAR_STYLE;
1214
1215
0
    if (emitter->canonical)
1216
0
        style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1217
1218
0
    if (emitter->simple_key_context && emitter->scalar_data.multiline)
1219
0
        style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1220
1221
0
    if (style == YAML_PLAIN_SCALAR_STYLE)
1222
0
    {
1223
0
        if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed)
1224
0
                || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed))
1225
0
            style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1226
0
        if (!emitter->scalar_data.length
1227
0
                && (emitter->flow_level || emitter->simple_key_context))
1228
0
            style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1229
0
        if (no_tag && !event->data.scalar.plain_implicit)
1230
0
            style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1231
0
    }
1232
1233
0
    if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE)
1234
0
    {
1235
0
        if (!emitter->scalar_data.single_quoted_allowed)
1236
0
            style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1237
0
    }
1238
1239
0
    if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE)
1240
0
    {
1241
0
        if (!emitter->scalar_data.block_allowed
1242
0
                || emitter->flow_level || emitter->simple_key_context)
1243
0
            style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1244
0
    }
1245
1246
0
    if (no_tag && !event->data.scalar.quoted_implicit
1247
0
            && style != YAML_PLAIN_SCALAR_STYLE)
1248
0
    {
1249
0
        emitter->tag_data.handle = (yaml_char_t *)"!";
1250
0
        emitter->tag_data.handle_length = 1;
1251
0
    }
1252
1253
0
    emitter->scalar_data.style = style;
1254
1255
0
    return 1;
1256
0
}
1257
1258
/*
1259
 * Write an achor.
1260
 */
1261
1262
static int
1263
yaml_emitter_process_anchor(yaml_emitter_t *emitter)
1264
0
{
1265
0
    if (!emitter->anchor_data.anchor)
1266
0
        return 1;
1267
1268
0
    if (!yaml_emitter_write_indicator(emitter,
1269
0
                (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0))
1270
0
        return 0;
1271
1272
0
    return yaml_emitter_write_anchor(emitter,
1273
0
            emitter->anchor_data.anchor, emitter->anchor_data.anchor_length);
1274
0
}
1275
1276
/*
1277
 * Write a tag.
1278
 */
1279
1280
static int
1281
yaml_emitter_process_tag(yaml_emitter_t *emitter)
1282
0
{
1283
0
    if (!emitter->tag_data.handle && !emitter->tag_data.suffix)
1284
0
        return 1;
1285
1286
0
    if (emitter->tag_data.handle)
1287
0
    {
1288
0
        if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle,
1289
0
                    emitter->tag_data.handle_length))
1290
0
            return 0;
1291
0
        if (emitter->tag_data.suffix) {
1292
0
            if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
1293
0
                        emitter->tag_data.suffix_length, 0))
1294
0
                return 0;
1295
0
        }
1296
0
    }
1297
0
    else
1298
0
    {
1299
0
        if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0))
1300
0
            return 0;
1301
0
        if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
1302
0
                    emitter->tag_data.suffix_length, 0))
1303
0
            return 0;
1304
0
        if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0))
1305
0
            return 0;
1306
0
    }
1307
1308
0
    return 1;
1309
0
}
1310
1311
/*
1312
 * Write a scalar.
1313
 */
1314
1315
static int
1316
yaml_emitter_process_scalar(yaml_emitter_t *emitter)
1317
0
{
1318
0
    switch (emitter->scalar_data.style)
1319
0
    {
1320
0
        case YAML_PLAIN_SCALAR_STYLE:
1321
0
            return yaml_emitter_write_plain_scalar(emitter,
1322
0
                    emitter->scalar_data.value, emitter->scalar_data.length,
1323
0
                    !emitter->simple_key_context);
1324
1325
0
        case YAML_SINGLE_QUOTED_SCALAR_STYLE:
1326
0
            return yaml_emitter_write_single_quoted_scalar(emitter,
1327
0
                    emitter->scalar_data.value, emitter->scalar_data.length,
1328
0
                    !emitter->simple_key_context);
1329
1330
0
        case YAML_DOUBLE_QUOTED_SCALAR_STYLE:
1331
0
            return yaml_emitter_write_double_quoted_scalar(emitter,
1332
0
                    emitter->scalar_data.value, emitter->scalar_data.length,
1333
0
                    !emitter->simple_key_context);
1334
1335
0
        case YAML_LITERAL_SCALAR_STYLE:
1336
0
            return yaml_emitter_write_literal_scalar(emitter,
1337
0
                    emitter->scalar_data.value, emitter->scalar_data.length);
1338
1339
0
        case YAML_FOLDED_SCALAR_STYLE:
1340
0
            return yaml_emitter_write_folded_scalar(emitter,
1341
0
                    emitter->scalar_data.value, emitter->scalar_data.length);
1342
1343
0
        default:
1344
0
            assert(1);      /* Impossible. */
1345
0
    }
1346
1347
0
    return 0;
1348
0
}
1349
1350
/*
1351
 * Check if a %YAML directive is valid.
1352
 */
1353
1354
static int
1355
yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
1356
        yaml_version_directive_t version_directive)
1357
0
{
1358
0
    if (version_directive.major != 1 || version_directive.minor != 1) {
1359
0
        return yaml_emitter_set_emitter_error(emitter,
1360
0
                "incompatible %YAML directive");
1361
0
    }
1362
1363
0
    return 1;
1364
0
}
1365
1366
/*
1367
 * Check if a %TAG directive is valid.
1368
 */
1369
1370
static int
1371
yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
1372
        yaml_tag_directive_t tag_directive)
1373
0
{
1374
0
    yaml_string_t handle;
1375
0
    yaml_string_t prefix;
1376
0
    size_t handle_length;
1377
0
    size_t prefix_length;
1378
1379
0
    handle_length = strlen((char *)tag_directive.handle);
1380
0
    prefix_length = strlen((char *)tag_directive.prefix);
1381
0
    STRING_ASSIGN(handle, tag_directive.handle, handle_length);
1382
0
    STRING_ASSIGN(prefix, tag_directive.prefix, prefix_length);
1383
1384
0
    if (handle.start == handle.end) {
1385
0
        return yaml_emitter_set_emitter_error(emitter,
1386
0
                "tag handle must not be empty");
1387
0
    }
1388
1389
0
    if (handle.start[0] != '!') {
1390
0
        return yaml_emitter_set_emitter_error(emitter,
1391
0
                "tag handle must start with '!'");
1392
0
    }
1393
1394
0
    if (handle.end[-1] != '!') {
1395
0
        return yaml_emitter_set_emitter_error(emitter,
1396
0
                "tag handle must end with '!'");
1397
0
    }
1398
1399
0
    handle.pointer ++;
1400
1401
0
    while (handle.pointer < handle.end-1) {
1402
0
        if (!IS_ALPHA(handle)) {
1403
0
            return yaml_emitter_set_emitter_error(emitter,
1404
0
                    "tag handle must contain alphanumerical characters only");
1405
0
        }
1406
0
        MOVE(handle);
1407
0
    }
1408
1409
0
    if (prefix.start == prefix.end) {
1410
0
        return yaml_emitter_set_emitter_error(emitter,
1411
0
                "tag prefix must not be empty");
1412
0
    }
1413
1414
0
    return 1;
1415
0
}
1416
1417
/*
1418
 * Check if an anchor is valid.
1419
 */
1420
1421
static int
1422
yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
1423
        yaml_char_t *anchor, int alias)
1424
0
{
1425
0
    size_t anchor_length;
1426
0
    yaml_string_t string;
1427
    
1428
0
    anchor_length = strlen((char *)anchor);
1429
0
    STRING_ASSIGN(string, anchor, anchor_length);
1430
1431
0
    if (string.start == string.end) {
1432
0
        return yaml_emitter_set_emitter_error(emitter, alias ?
1433
0
                "alias value must not be empty" :
1434
0
                "anchor value must not be empty");
1435
0
    }
1436
1437
0
    while (string.pointer != string.end) {
1438
0
        if (!IS_ALPHA(string)) {
1439
0
            return yaml_emitter_set_emitter_error(emitter, alias ?
1440
0
                    "alias value must contain alphanumerical characters only" :
1441
0
                    "anchor value must contain alphanumerical characters only");
1442
0
        }
1443
0
        MOVE(string);
1444
0
    }
1445
1446
0
    emitter->anchor_data.anchor = string.start;
1447
0
    emitter->anchor_data.anchor_length = string.end - string.start;
1448
0
    emitter->anchor_data.alias = alias;
1449
1450
0
    return 1;
1451
0
}
1452
1453
/*
1454
 * Check if a tag is valid.
1455
 */
1456
1457
static int
1458
yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
1459
        yaml_char_t *tag)
1460
0
{
1461
0
    size_t tag_length;
1462
0
    yaml_string_t string;
1463
0
    yaml_tag_directive_t *tag_directive;
1464
1465
0
    tag_length = strlen((char *)tag);
1466
0
    STRING_ASSIGN(string, tag, tag_length);
1467
1468
0
    if (string.start == string.end) {
1469
0
        return yaml_emitter_set_emitter_error(emitter,
1470
0
                "tag value must not be empty");
1471
0
    }
1472
1473
0
    for (tag_directive = emitter->tag_directives.start;
1474
0
            tag_directive != emitter->tag_directives.top; tag_directive ++) {
1475
0
        size_t prefix_length = strlen((char *)tag_directive->prefix);
1476
0
        if (prefix_length < (size_t)(string.end - string.start)
1477
0
                && strncmp((char *)tag_directive->prefix, (char *)string.start,
1478
0
                    prefix_length) == 0)
1479
0
        {
1480
0
            emitter->tag_data.handle = tag_directive->handle;
1481
0
            emitter->tag_data.handle_length =
1482
0
                strlen((char *)tag_directive->handle);
1483
0
            emitter->tag_data.suffix = string.start + prefix_length;
1484
0
            emitter->tag_data.suffix_length =
1485
0
                (string.end - string.start) - prefix_length;
1486
0
            return 1;
1487
0
        }
1488
0
    }
1489
1490
0
    emitter->tag_data.suffix = string.start;
1491
0
    emitter->tag_data.suffix_length = string.end - string.start;
1492
1493
0
    return 1;
1494
0
}
1495
1496
/*
1497
 * Check if a scalar is valid.
1498
 */
1499
1500
static int
1501
yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
1502
        yaml_char_t *value, size_t length)
1503
0
{
1504
0
    yaml_string_t string;
1505
1506
0
    int block_indicators = 0;
1507
0
    int flow_indicators = 0;
1508
0
    int line_breaks = 0;
1509
0
    int special_characters = 0;
1510
1511
0
    int leading_space = 0;
1512
0
    int leading_break = 0;
1513
0
    int trailing_space = 0;
1514
0
    int trailing_break = 0;
1515
0
    int break_space = 0;
1516
0
    int space_break = 0;
1517
1518
0
    int preceeded_by_whitespace = 0;
1519
0
    int followed_by_whitespace = 0;
1520
0
    int previous_space = 0;
1521
0
    int previous_break = 0;
1522
1523
0
    STRING_ASSIGN(string, value, length);
1524
1525
0
    emitter->scalar_data.value = value;
1526
0
    emitter->scalar_data.length = length;
1527
1528
0
    if (string.start == string.end)
1529
0
    {
1530
0
        emitter->scalar_data.multiline = 0;
1531
0
        emitter->scalar_data.flow_plain_allowed = 0;
1532
0
        emitter->scalar_data.block_plain_allowed = 1;
1533
0
        emitter->scalar_data.single_quoted_allowed = 1;
1534
0
        emitter->scalar_data.block_allowed = 0;
1535
1536
0
        return 1;
1537
0
    }
1538
1539
0
    if ((CHECK_AT(string, '-', 0)
1540
0
                && CHECK_AT(string, '-', 1)
1541
0
                && CHECK_AT(string, '-', 2))
1542
0
            || (CHECK_AT(string, '.', 0)
1543
0
                && CHECK_AT(string, '.', 1)
1544
0
                && CHECK_AT(string, '.', 2))) {
1545
0
        block_indicators = 1;
1546
0
        flow_indicators = 1;
1547
0
    }
1548
1549
0
    preceeded_by_whitespace = 1;
1550
0
    followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
1551
1552
0
    while (string.pointer != string.end)
1553
0
    {
1554
0
        if (string.start == string.pointer)
1555
0
        {
1556
0
            if (CHECK(string, '#') || CHECK(string, ',')
1557
0
                    || CHECK(string, '[') || CHECK(string, ']')
1558
0
                    || CHECK(string, '{') || CHECK(string, '}')
1559
0
                    || CHECK(string, '&') || CHECK(string, '*')
1560
0
                    || CHECK(string, '!') || CHECK(string, '|')
1561
0
                    || CHECK(string, '>') || CHECK(string, '\'')
1562
0
                    || CHECK(string, '"') || CHECK(string, '%')
1563
0
                    || CHECK(string, '@') || CHECK(string, '`')) {
1564
0
                flow_indicators = 1;
1565
0
                block_indicators = 1;
1566
0
            }
1567
1568
0
            if (CHECK(string, '?') || CHECK(string, ':')) {
1569
0
                flow_indicators = 1;
1570
0
                if (followed_by_whitespace) {
1571
0
                    block_indicators = 1;
1572
0
                }
1573
0
            }
1574
1575
0
            if (CHECK(string, '-') && followed_by_whitespace) {
1576
0
                flow_indicators = 1;
1577
0
                block_indicators = 1;
1578
0
            }
1579
0
        }
1580
0
        else
1581
0
        {
1582
0
            if (CHECK(string, ',') || CHECK(string, '?')
1583
0
                    || CHECK(string, '[') || CHECK(string, ']')
1584
0
                    || CHECK(string, '{') || CHECK(string, '}')) {
1585
0
                flow_indicators = 1;
1586
0
            }
1587
1588
0
            if (CHECK(string, ':')) {
1589
0
                flow_indicators = 1;
1590
0
                if (followed_by_whitespace) {
1591
0
                    block_indicators = 1;
1592
0
                }
1593
0
            }
1594
1595
0
            if (CHECK(string, '#') && preceeded_by_whitespace) {
1596
0
                flow_indicators = 1;
1597
0
                block_indicators = 1;
1598
0
            }
1599
0
        }
1600
1601
0
        if (!IS_PRINTABLE(string)
1602
0
                || (!IS_ASCII(string) && !emitter->unicode)) {
1603
0
            special_characters = 1;
1604
0
        }
1605
1606
0
        if (IS_BREAK(string)) {
1607
0
            line_breaks = 1;
1608
0
        }
1609
1610
0
        if (IS_SPACE(string))
1611
0
        {
1612
0
            if (string.start == string.pointer) {
1613
0
                leading_space = 1;
1614
0
            }
1615
0
            if (string.pointer+WIDTH(string) == string.end) {
1616
0
                trailing_space = 1;
1617
0
            }
1618
0
            if (previous_break) {
1619
0
                break_space = 1;
1620
0
            }
1621
0
            previous_space = 1;
1622
0
            previous_break = 0;
1623
0
        }
1624
0
        else if (IS_BREAK(string))
1625
0
        {
1626
0
            if (string.start == string.pointer) {
1627
0
                leading_break = 1;
1628
0
            }
1629
0
            if (string.pointer+WIDTH(string) == string.end) {
1630
0
                trailing_break = 1;
1631
0
            }
1632
0
            if (previous_space) {
1633
0
                space_break = 1;
1634
0
            }
1635
0
            previous_space = 0;
1636
0
            previous_break = 1;
1637
0
        }
1638
0
        else
1639
0
        {
1640
0
            previous_space = 0;
1641
0
            previous_break = 0;
1642
0
        }
1643
1644
0
        preceeded_by_whitespace = IS_BLANKZ(string);
1645
0
        MOVE(string);
1646
0
        if (string.pointer != string.end) {
1647
0
            followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
1648
0
        }
1649
0
    }
1650
1651
0
    emitter->scalar_data.multiline = line_breaks;
1652
1653
0
    emitter->scalar_data.flow_plain_allowed = 1;
1654
0
    emitter->scalar_data.block_plain_allowed = 1;
1655
0
    emitter->scalar_data.single_quoted_allowed = 1;
1656
0
    emitter->scalar_data.block_allowed = 1;
1657
1658
0
    if (leading_space || leading_break || trailing_space || trailing_break) {
1659
0
        emitter->scalar_data.flow_plain_allowed = 0;
1660
0
        emitter->scalar_data.block_plain_allowed = 0;
1661
0
    }
1662
1663
0
    if (trailing_space) {
1664
0
        emitter->scalar_data.block_allowed = 0;
1665
0
    }
1666
1667
0
    if (break_space) {
1668
0
        emitter->scalar_data.flow_plain_allowed = 0;
1669
0
        emitter->scalar_data.block_plain_allowed = 0;
1670
0
        emitter->scalar_data.single_quoted_allowed = 0;
1671
0
    }
1672
1673
0
    if (space_break || special_characters) {
1674
0
        emitter->scalar_data.flow_plain_allowed = 0;
1675
0
        emitter->scalar_data.block_plain_allowed = 0;
1676
0
        emitter->scalar_data.single_quoted_allowed = 0;
1677
0
        emitter->scalar_data.block_allowed = 0;
1678
0
    }
1679
1680
0
    if (line_breaks) {
1681
0
        emitter->scalar_data.flow_plain_allowed = 0;
1682
0
        emitter->scalar_data.block_plain_allowed = 0;
1683
0
    }
1684
1685
0
    if (flow_indicators) {
1686
0
        emitter->scalar_data.flow_plain_allowed = 0;
1687
0
    }
1688
1689
0
    if (block_indicators) {
1690
0
        emitter->scalar_data.block_plain_allowed = 0;
1691
0
    }
1692
1693
0
    return 1;
1694
0
}
1695
1696
/*
1697
 * Check if the event data is valid.
1698
 */
1699
1700
static int
1701
yaml_emitter_analyze_event(yaml_emitter_t *emitter,
1702
        yaml_event_t *event)
1703
0
{
1704
0
    emitter->anchor_data.anchor = NULL;
1705
0
    emitter->anchor_data.anchor_length = 0;
1706
0
    emitter->tag_data.handle = NULL;
1707
0
    emitter->tag_data.handle_length = 0;
1708
0
    emitter->tag_data.suffix = NULL;
1709
0
    emitter->tag_data.suffix_length = 0;
1710
0
    emitter->scalar_data.value = NULL;
1711
0
    emitter->scalar_data.length = 0;
1712
1713
0
    switch (event->type)
1714
0
    {
1715
0
        case YAML_ALIAS_EVENT:
1716
0
            if (!yaml_emitter_analyze_anchor(emitter,
1717
0
                        event->data.alias.anchor, 1))
1718
0
                return 0;
1719
0
            return 1;
1720
1721
0
        case YAML_SCALAR_EVENT:
1722
0
            if (event->data.scalar.anchor) {
1723
0
                if (!yaml_emitter_analyze_anchor(emitter,
1724
0
                            event->data.scalar.anchor, 0))
1725
0
                    return 0;
1726
0
            }
1727
0
            if (event->data.scalar.tag && (emitter->canonical ||
1728
0
                        (!event->data.scalar.plain_implicit
1729
0
                         && !event->data.scalar.quoted_implicit))) {
1730
0
                if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag))
1731
0
                    return 0;
1732
0
            }
1733
0
            if (!yaml_emitter_analyze_scalar(emitter,
1734
0
                        event->data.scalar.value, event->data.scalar.length))
1735
0
                return 0;
1736
0
            return 1;
1737
1738
0
        case YAML_SEQUENCE_START_EVENT:
1739
0
            if (event->data.sequence_start.anchor) {
1740
0
                if (!yaml_emitter_analyze_anchor(emitter,
1741
0
                            event->data.sequence_start.anchor, 0))
1742
0
                    return 0;
1743
0
            }
1744
0
            if (event->data.sequence_start.tag && (emitter->canonical ||
1745
0
                        !event->data.sequence_start.implicit)) {
1746
0
                if (!yaml_emitter_analyze_tag(emitter,
1747
0
                            event->data.sequence_start.tag))
1748
0
                    return 0;
1749
0
            }
1750
0
            return 1;
1751
1752
0
        case YAML_MAPPING_START_EVENT:
1753
0
            if (event->data.mapping_start.anchor) {
1754
0
                if (!yaml_emitter_analyze_anchor(emitter,
1755
0
                            event->data.mapping_start.anchor, 0))
1756
0
                    return 0;
1757
0
            }
1758
0
            if (event->data.mapping_start.tag && (emitter->canonical ||
1759
0
                        !event->data.mapping_start.implicit)) {
1760
0
                if (!yaml_emitter_analyze_tag(emitter,
1761
0
                            event->data.mapping_start.tag))
1762
0
                    return 0;
1763
0
            }
1764
0
            return 1;
1765
1766
0
        default:
1767
0
            return 1;
1768
0
    }
1769
0
}
1770
1771
/*
1772
 * Write the BOM character.
1773
 */
1774
1775
static int
1776
yaml_emitter_write_bom(yaml_emitter_t *emitter)
1777
0
{
1778
0
    if (!FLUSH(emitter)) return 0;
1779
1780
0
    *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF';
1781
0
    *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB';
1782
0
    *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF';
1783
1784
0
    return 1;
1785
0
}
1786
1787
static int
1788
yaml_emitter_write_indent(yaml_emitter_t *emitter)
1789
0
{
1790
0
    int indent = (emitter->indent >= 0) ? emitter->indent : 0;
1791
1792
0
    if (!emitter->indention || emitter->column > indent
1793
0
            || (emitter->column == indent && !emitter->whitespace)) {
1794
0
        if (!PUT_BREAK(emitter)) return 0;
1795
0
    }
1796
1797
0
    while (emitter->column < indent) {
1798
0
        if (!PUT(emitter, ' ')) return 0;
1799
0
    }
1800
1801
0
    emitter->whitespace = 1;
1802
0
    emitter->indention = 1;
1803
1804
0
    return 1;
1805
0
}
1806
1807
static int
1808
yaml_emitter_write_indicator(yaml_emitter_t *emitter,
1809
        char *indicator, int need_whitespace,
1810
        int is_whitespace, int is_indention)
1811
0
{
1812
0
    size_t indicator_length;
1813
0
    yaml_string_t string;
1814
1815
0
    indicator_length = strlen(indicator);
1816
0
    STRING_ASSIGN(string, (yaml_char_t *)indicator, indicator_length);
1817
1818
0
    if (need_whitespace && !emitter->whitespace) {
1819
0
        if (!PUT(emitter, ' ')) return 0;
1820
0
    }
1821
1822
0
    while (string.pointer != string.end) {
1823
0
        if (!WRITE(emitter, string)) return 0;
1824
0
    }
1825
1826
0
    emitter->whitespace = is_whitespace;
1827
0
    emitter->indention = (emitter->indention && is_indention);
1828
0
    emitter->open_ended = 0;
1829
1830
0
    return 1;
1831
0
}
1832
1833
static int
1834
yaml_emitter_write_anchor(yaml_emitter_t *emitter,
1835
        yaml_char_t *value, size_t length)
1836
0
{
1837
0
    yaml_string_t string;
1838
0
    STRING_ASSIGN(string, value, length);
1839
1840
0
    while (string.pointer != string.end) {
1841
0
        if (!WRITE(emitter, string)) return 0;
1842
0
    }
1843
1844
0
    emitter->whitespace = 0;
1845
0
    emitter->indention = 0;
1846
1847
0
    return 1;
1848
0
}
1849
1850
static int
1851
yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
1852
        yaml_char_t *value, size_t length)
1853
0
{
1854
0
    yaml_string_t string;
1855
0
    STRING_ASSIGN(string, value, length);
1856
1857
0
    if (!emitter->whitespace) {
1858
0
        if (!PUT(emitter, ' ')) return 0;
1859
0
    }
1860
1861
0
    while (string.pointer != string.end) {
1862
0
        if (!WRITE(emitter, string)) return 0;
1863
0
    }
1864
1865
0
    emitter->whitespace = 0;
1866
0
    emitter->indention = 0;
1867
1868
0
    return 1;
1869
0
}
1870
1871
static int
1872
yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
1873
        yaml_char_t *value, size_t length,
1874
        int need_whitespace)
1875
0
{
1876
0
    yaml_string_t string;
1877
0
    STRING_ASSIGN(string, value, length);
1878
1879
0
    if (need_whitespace && !emitter->whitespace) {
1880
0
        if (!PUT(emitter, ' ')) return 0;
1881
0
    }
1882
1883
0
    while (string.pointer != string.end) {
1884
0
        if (IS_ALPHA(string)
1885
0
                || CHECK(string, ';') || CHECK(string, '/')
1886
0
                || CHECK(string, '?') || CHECK(string, ':')
1887
0
                || CHECK(string, '@') || CHECK(string, '&')
1888
0
                || CHECK(string, '=') || CHECK(string, '+')
1889
0
                || CHECK(string, '$') || CHECK(string, ',')
1890
0
                || CHECK(string, '_') || CHECK(string, '.')
1891
0
                || CHECK(string, '~') || CHECK(string, '*')
1892
0
                || CHECK(string, '\'') || CHECK(string, '(')
1893
0
                || CHECK(string, ')') || CHECK(string, '[')
1894
0
                || CHECK(string, ']')) {
1895
0
            if (!WRITE(emitter, string)) return 0;
1896
0
        }
1897
0
        else {
1898
0
            int width = WIDTH(string);
1899
0
            unsigned int value;
1900
0
            while (width --) {
1901
0
                value = *(string.pointer++);
1902
0
                if (!PUT(emitter, '%')) return 0;
1903
0
                if (!PUT(emitter, (value >> 4)
1904
0
                            + ((value >> 4) < 10 ? '0' : 'A' - 10)))
1905
0
                    return 0;
1906
0
                if (!PUT(emitter, (value & 0x0F)
1907
0
                            + ((value & 0x0F) < 10 ? '0' : 'A' - 10)))
1908
0
                    return 0;
1909
0
            }
1910
0
        }
1911
0
    }
1912
1913
0
    emitter->whitespace = 0;
1914
0
    emitter->indention = 0;
1915
1916
0
    return 1;
1917
0
}
1918
1919
static int
1920
yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
1921
        yaml_char_t *value, size_t length, int allow_breaks)
1922
0
{
1923
0
    yaml_string_t string;
1924
0
    int spaces = 0;
1925
0
    int breaks = 0;
1926
1927
0
    STRING_ASSIGN(string, value, length);
1928
1929
0
    if (!emitter->whitespace) {
1930
0
        if (!PUT(emitter, ' ')) return 0;
1931
0
    }
1932
1933
0
    while (string.pointer != string.end)
1934
0
    {
1935
0
        if (IS_SPACE(string))
1936
0
        {
1937
0
            if (allow_breaks && !spaces
1938
0
                    && emitter->column > emitter->best_width
1939
0
                    && !IS_SPACE_AT(string, 1)) {
1940
0
                if (!yaml_emitter_write_indent(emitter)) return 0;
1941
0
                MOVE(string);
1942
0
            }
1943
0
            else {
1944
0
                if (!WRITE(emitter, string)) return 0;
1945
0
            }
1946
0
            spaces = 1;
1947
0
        }
1948
0
        else if (IS_BREAK(string))
1949
0
        {
1950
0
            if (!breaks && CHECK(string, '\n')) {
1951
0
                if (!PUT_BREAK(emitter)) return 0;
1952
0
            }
1953
0
            if (!WRITE_BREAK(emitter, string)) return 0;
1954
0
            emitter->indention = 1;
1955
0
            breaks = 1;
1956
0
        }
1957
0
        else
1958
0
        {
1959
0
            if (breaks) {
1960
0
                if (!yaml_emitter_write_indent(emitter)) return 0;
1961
0
            }
1962
0
            if (!WRITE(emitter, string)) return 0;
1963
0
            emitter->indention = 0;
1964
0
            spaces = 0;
1965
0
            breaks = 0;
1966
0
        }
1967
0
    }
1968
1969
0
    emitter->whitespace = 0;
1970
0
    emitter->indention = 0;
1971
0
    if (emitter->root_context)
1972
0
    {
1973
0
        emitter->open_ended = 1;
1974
0
    }
1975
1976
0
    return 1;
1977
0
}
1978
1979
static int
1980
yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
1981
        yaml_char_t *value, size_t length, int allow_breaks)
1982
0
{
1983
0
    yaml_string_t string;
1984
0
    int spaces = 0;
1985
0
    int breaks = 0;
1986
1987
0
    STRING_ASSIGN(string, value, length);
1988
1989
0
    if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0))
1990
0
        return 0;
1991
1992
0
    while (string.pointer != string.end)
1993
0
    {
1994
0
        if (IS_SPACE(string))
1995
0
        {
1996
0
            if (allow_breaks && !spaces
1997
0
                    && emitter->column > emitter->best_width
1998
0
                    && string.pointer != string.start
1999
0
                    && string.pointer != string.end - 1
2000
0
                    && !IS_SPACE_AT(string, 1)) {
2001
0
                if (!yaml_emitter_write_indent(emitter)) return 0;
2002
0
                MOVE(string);
2003
0
            }
2004
0
            else {
2005
0
                if (!WRITE(emitter, string)) return 0;
2006
0
            }
2007
0
            spaces = 1;
2008
0
        }
2009
0
        else if (IS_BREAK(string))
2010
0
        {
2011
0
            if (!breaks && CHECK(string, '\n')) {
2012
0
                if (!PUT_BREAK(emitter)) return 0;
2013
0
            }
2014
0
            if (!WRITE_BREAK(emitter, string)) return 0;
2015
0
            emitter->indention = 1;
2016
0
            breaks = 1;
2017
0
        }
2018
0
        else
2019
0
        {
2020
0
            if (breaks) {
2021
0
                if (!yaml_emitter_write_indent(emitter)) return 0;
2022
0
            }
2023
0
            if (CHECK(string, '\'')) {
2024
0
                if (!PUT(emitter, '\'')) return 0;
2025
0
            }
2026
0
            if (!WRITE(emitter, string)) return 0;
2027
0
            emitter->indention = 0;
2028
0
            spaces = 0;
2029
0
            breaks = 0;
2030
0
        }
2031
0
    }
2032
2033
0
    if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0))
2034
0
        return 0;
2035
2036
0
    emitter->whitespace = 0;
2037
0
    emitter->indention = 0;
2038
2039
0
    return 1;
2040
0
}
2041
2042
static int
2043
yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
2044
        yaml_char_t *value, size_t length, int allow_breaks)
2045
0
{
2046
0
    yaml_string_t string;
2047
0
    int spaces = 0;
2048
2049
0
    STRING_ASSIGN(string, value, length);
2050
2051
0
    if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0))
2052
0
        return 0;
2053
2054
0
    while (string.pointer != string.end)
2055
0
    {
2056
0
        if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string))
2057
0
                || IS_BOM(string) || IS_BREAK(string)
2058
0
                || CHECK(string, '"') || CHECK(string, '\\'))
2059
0
        {
2060
0
            unsigned char octet;
2061
0
            unsigned int width;
2062
0
            unsigned int value;
2063
0
            int k;
2064
2065
0
            octet = string.pointer[0];
2066
0
            width = (octet & 0x80) == 0x00 ? 1 :
2067
0
                    (octet & 0xE0) == 0xC0 ? 2 :
2068
0
                    (octet & 0xF0) == 0xE0 ? 3 :
2069
0
                    (octet & 0xF8) == 0xF0 ? 4 : 0;
2070
0
            value = (octet & 0x80) == 0x00 ? octet & 0x7F :
2071
0
                    (octet & 0xE0) == 0xC0 ? octet & 0x1F :
2072
0
                    (octet & 0xF0) == 0xE0 ? octet & 0x0F :
2073
0
                    (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
2074
0
            for (k = 1; k < (int)width; k ++) {
2075
0
                octet = string.pointer[k];
2076
0
                value = (value << 6) + (octet & 0x3F);
2077
0
            }
2078
0
            string.pointer += width;
2079
2080
0
            if (!PUT(emitter, '\\')) return 0;
2081
2082
0
            switch (value)
2083
0
            {
2084
0
                case 0x00:
2085
0
                    if (!PUT(emitter, '0')) return 0;
2086
0
                    break;
2087
2088
0
                case 0x07:
2089
0
                    if (!PUT(emitter, 'a')) return 0;
2090
0
                    break;
2091
2092
0
                case 0x08:
2093
0
                    if (!PUT(emitter, 'b')) return 0;
2094
0
                    break;
2095
2096
0
                case 0x09:
2097
0
                    if (!PUT(emitter, 't')) return 0;
2098
0
                    break;
2099
2100
0
                case 0x0A:
2101
0
                    if (!PUT(emitter, 'n')) return 0;
2102
0
                    break;
2103
2104
0
                case 0x0B:
2105
0
                    if (!PUT(emitter, 'v')) return 0;
2106
0
                    break;
2107
2108
0
                case 0x0C:
2109
0
                    if (!PUT(emitter, 'f')) return 0;
2110
0
                    break;
2111
2112
0
                case 0x0D:
2113
0
                    if (!PUT(emitter, 'r')) return 0;
2114
0
                    break;
2115
2116
0
                case 0x1B:
2117
0
                    if (!PUT(emitter, 'e')) return 0;
2118
0
                    break;
2119
2120
0
                case 0x22:
2121
0
                    if (!PUT(emitter, '\"')) return 0;
2122
0
                    break;
2123
2124
0
                case 0x5C:
2125
0
                    if (!PUT(emitter, '\\')) return 0;
2126
0
                    break;
2127
2128
0
                case 0x85:
2129
0
                    if (!PUT(emitter, 'N')) return 0;
2130
0
                    break;
2131
2132
0
                case 0xA0:
2133
0
                    if (!PUT(emitter, '_')) return 0;
2134
0
                    break;
2135
2136
0
                case 0x2028:
2137
0
                    if (!PUT(emitter, 'L')) return 0;
2138
0
                    break;
2139
2140
0
                case 0x2029:
2141
0
                    if (!PUT(emitter, 'P')) return 0;
2142
0
                    break;
2143
2144
0
                default:
2145
0
                    if (value <= 0xFF) {
2146
0
                        if (!PUT(emitter, 'x')) return 0;
2147
0
                        width = 2;
2148
0
                    }
2149
0
                    else if (value <= 0xFFFF) {
2150
0
                        if (!PUT(emitter, 'u')) return 0;
2151
0
                        width = 4;
2152
0
                    }
2153
0
                    else {
2154
0
                        if (!PUT(emitter, 'U')) return 0;
2155
0
                        width = 8;
2156
0
                    }
2157
0
                    for (k = (width-1)*4; k >= 0; k -= 4) {
2158
0
                        int digit = (value >> k) & 0x0F;
2159
0
                        if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10)))
2160
0
                            return 0;
2161
0
                    }
2162
0
            }
2163
0
            spaces = 0;
2164
0
        }
2165
0
        else if (IS_SPACE(string))
2166
0
        {
2167
0
            if (allow_breaks && !spaces
2168
0
                    && emitter->column > emitter->best_width
2169
0
                    && string.pointer != string.start
2170
0
                    && string.pointer != string.end - 1) {
2171
0
                if (!yaml_emitter_write_indent(emitter)) return 0;
2172
0
                if (IS_SPACE_AT(string, 1)) {
2173
0
                    if (!PUT(emitter, '\\')) return 0;
2174
0
                }
2175
0
                MOVE(string);
2176
0
            }
2177
0
            else {
2178
0
                if (!WRITE(emitter, string)) return 0;
2179
0
            }
2180
0
            spaces = 1;
2181
0
        }
2182
0
        else
2183
0
        {
2184
0
            if (!WRITE(emitter, string)) return 0;
2185
0
            spaces = 0;
2186
0
        }
2187
0
    }
2188
2189
0
    if (!yaml_emitter_write_indicator(emitter, "\"", 0, 0, 0))
2190
0
        return 0;
2191
2192
0
    emitter->whitespace = 0;
2193
0
    emitter->indention = 0;
2194
2195
0
    return 1;
2196
0
}
2197
2198
static int
2199
yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
2200
        yaml_string_t string)
2201
0
{
2202
0
    char indent_hint[2];
2203
0
    char *chomp_hint = NULL;
2204
2205
0
    if (IS_SPACE(string) || IS_BREAK(string))
2206
0
    {
2207
0
        indent_hint[0] = '0' + (char)emitter->best_indent;
2208
0
        indent_hint[1] = '\0';
2209
0
        if (!yaml_emitter_write_indicator(emitter, indent_hint, 0, 0, 0))
2210
0
            return 0;
2211
0
    }
2212
2213
0
    emitter->open_ended = 0;
2214
2215
0
    string.pointer = string.end;
2216
0
    if (string.start == string.pointer)
2217
0
    {
2218
0
        chomp_hint = "-";
2219
0
    }
2220
0
    else
2221
0
    {
2222
0
        do {
2223
0
            string.pointer --;
2224
0
        } while ((*string.pointer & 0xC0) == 0x80);
2225
0
        if (!IS_BREAK(string))
2226
0
        {
2227
0
            chomp_hint = "-";
2228
0
        }
2229
0
        else if (string.start == string.pointer)
2230
0
        {
2231
0
            chomp_hint = "+";
2232
0
            emitter->open_ended = 1;
2233
0
        }
2234
0
        else
2235
0
        {
2236
0
            do {
2237
0
                string.pointer --;
2238
0
            } while ((*string.pointer & 0xC0) == 0x80);
2239
0
            if (IS_BREAK(string))
2240
0
            {
2241
0
                chomp_hint = "+";
2242
0
                emitter->open_ended = 1;
2243
0
            }
2244
0
        }
2245
0
    }
2246
2247
0
    if (chomp_hint)
2248
0
    {
2249
0
        if (!yaml_emitter_write_indicator(emitter, chomp_hint, 0, 0, 0))
2250
0
            return 0;
2251
0
    }
2252
2253
0
    return 1;
2254
0
}
2255
2256
static int
2257
yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
2258
        yaml_char_t *value, size_t length)
2259
0
{
2260
0
    yaml_string_t string;
2261
0
    int breaks = 1;
2262
2263
0
    STRING_ASSIGN(string, value, length);
2264
2265
0
    if (!yaml_emitter_write_indicator(emitter, "|", 1, 0, 0))
2266
0
        return 0;
2267
0
    if (!yaml_emitter_write_block_scalar_hints(emitter, string))
2268
0
        return 0;
2269
0
    if (!PUT_BREAK(emitter)) return 0;
2270
0
    emitter->indention = 1;
2271
0
    emitter->whitespace = 1;
2272
2273
0
    while (string.pointer != string.end)
2274
0
    {
2275
0
        if (IS_BREAK(string))
2276
0
        {
2277
0
            if (!WRITE_BREAK(emitter, string)) return 0;
2278
0
            emitter->indention = 1;
2279
0
            breaks = 1;
2280
0
        }
2281
0
        else
2282
0
        {
2283
0
            if (breaks) {
2284
0
                if (!yaml_emitter_write_indent(emitter)) return 0;
2285
0
            }
2286
0
            if (!WRITE(emitter, string)) return 0;
2287
0
            emitter->indention = 0;
2288
0
            breaks = 0;
2289
0
        }
2290
0
    }
2291
2292
0
    return 1;
2293
0
}
2294
2295
static int
2296
yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
2297
        yaml_char_t *value, size_t length)
2298
0
{
2299
0
    yaml_string_t string;
2300
0
    int breaks = 1;
2301
0
    int leading_spaces = 1;
2302
2303
0
    STRING_ASSIGN(string, value, length);
2304
2305
0
    if (!yaml_emitter_write_indicator(emitter, ">", 1, 0, 0))
2306
0
        return 0;
2307
0
    if (!yaml_emitter_write_block_scalar_hints(emitter, string))
2308
0
        return 0;
2309
0
    if (!PUT_BREAK(emitter)) return 0;
2310
0
    emitter->indention = 1;
2311
0
    emitter->whitespace = 1;
2312
2313
0
    while (string.pointer != string.end)
2314
0
    {
2315
0
        if (IS_BREAK(string))
2316
0
        {
2317
0
            if (!breaks && !leading_spaces && CHECK(string, '\n')) {
2318
0
                int k = 0;
2319
0
                while (IS_BREAK_AT(string, k)) {
2320
0
                    k += WIDTH_AT(string, k);
2321
0
                }
2322
0
                if (!IS_BLANKZ_AT(string, k)) {
2323
0
                    if (!PUT_BREAK(emitter)) return 0;
2324
0
                }
2325
0
            }
2326
0
            if (!WRITE_BREAK(emitter, string)) return 0;
2327
0
            emitter->indention = 1;
2328
0
            breaks = 1;
2329
0
        }
2330
0
        else
2331
0
        {
2332
0
            if (breaks) {
2333
0
                if (!yaml_emitter_write_indent(emitter)) return 0;
2334
0
                leading_spaces = IS_BLANK(string);
2335
0
            }
2336
0
            if (!breaks && IS_SPACE(string) && !IS_SPACE_AT(string, 1)
2337
0
                    && emitter->column > emitter->best_width) {
2338
0
                if (!yaml_emitter_write_indent(emitter)) return 0;
2339
0
                MOVE(string);
2340
0
            }
2341
0
            else {
2342
0
                if (!WRITE(emitter, string)) return 0;
2343
0
            }
2344
0
            emitter->indention = 0;
2345
0
            breaks = 0;
2346
0
        }
2347
0
    }
2348
2349
0
    return 1;
2350
0
}
2351