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