1247738Sbapt
2247738Sbapt#include "yaml_private.h"
3247738Sbapt
4247738Sbapt/*
5247738Sbapt * Flush the buffer if needed.
6247738Sbapt */
7247738Sbapt
8247738Sbapt#define FLUSH(emitter)                                                          \
9247738Sbapt    ((emitter->buffer.pointer+5 < emitter->buffer.end)                          \
10247738Sbapt     || yaml_emitter_flush(emitter))
11247738Sbapt
12247738Sbapt/*
13247738Sbapt * Put a character to the output buffer.
14247738Sbapt */
15247738Sbapt
16247738Sbapt#define PUT(emitter,value)                                                      \
17247738Sbapt    (FLUSH(emitter)                                                             \
18247738Sbapt     && (*(emitter->buffer.pointer++) = (yaml_char_t)(value),                   \
19247738Sbapt         emitter->column ++,                                                    \
20247738Sbapt         1))
21247738Sbapt
22247738Sbapt/*
23247738Sbapt * Put a line break to the output buffer.
24247738Sbapt */
25247738Sbapt
26247738Sbapt#define PUT_BREAK(emitter)                                                      \
27247738Sbapt    (FLUSH(emitter)                                                             \
28247738Sbapt     && ((emitter->line_break == YAML_CR_BREAK ?                                \
29247738Sbapt             (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') :              \
30247738Sbapt          emitter->line_break == YAML_LN_BREAK ?                                \
31247738Sbapt             (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') :              \
32247738Sbapt          emitter->line_break == YAML_CRLN_BREAK ?                              \
33247738Sbapt             (*(emitter->buffer.pointer++) = (yaml_char_t) '\r',                \
34247738Sbapt              *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0),          \
35247738Sbapt         emitter->column = 0,                                                   \
36247738Sbapt         emitter->line ++,                                                      \
37247738Sbapt         1))
38247738Sbapt
39247738Sbapt/*
40247738Sbapt * Copy a character from a string into buffer.
41247738Sbapt */
42247738Sbapt
43247738Sbapt#define WRITE(emitter,string)                                                   \
44247738Sbapt    (FLUSH(emitter)                                                             \
45247738Sbapt     && (COPY(emitter->buffer,string),                                          \
46247738Sbapt         emitter->column ++,                                                    \
47247738Sbapt         1))
48247738Sbapt
49247738Sbapt/*
50247738Sbapt * Copy a line break character from a string into buffer.
51247738Sbapt */
52247738Sbapt
53247738Sbapt#define WRITE_BREAK(emitter,string)                                             \
54247738Sbapt    (FLUSH(emitter)                                                             \
55247738Sbapt     && (CHECK(string,'\n') ?                                                   \
56247738Sbapt         (PUT_BREAK(emitter),                                                   \
57247738Sbapt          string.pointer ++,                                                    \
58247738Sbapt          1) :                                                                  \
59247738Sbapt         (COPY(emitter->buffer,string),                                         \
60247738Sbapt          emitter->column = 0,                                                  \
61247738Sbapt          emitter->line ++,                                                     \
62247738Sbapt          1)))
63247738Sbapt
64247738Sbapt/*
65247738Sbapt * API functions.
66247738Sbapt */
67247738Sbapt
68247738SbaptYAML_DECLARE(int)
69247738Sbaptyaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
70247738Sbapt
71247738Sbapt/*
72247738Sbapt * Utility functions.
73247738Sbapt */
74247738Sbapt
75247738Sbaptstatic int
76247738Sbaptyaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem);
77247738Sbapt
78247738Sbaptstatic int
79247738Sbaptyaml_emitter_need_more_events(yaml_emitter_t *emitter);
80247738Sbapt
81247738Sbaptstatic int
82247738Sbaptyaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
83247738Sbapt        yaml_tag_directive_t value, int allow_duplicates);
84247738Sbapt
85247738Sbaptstatic int
86247738Sbaptyaml_emitter_increase_indent(yaml_emitter_t *emitter,
87247738Sbapt        int flow, int indentless);
88247738Sbapt
89247738Sbapt/*
90247738Sbapt * State functions.
91247738Sbapt */
92247738Sbapt
93247738Sbaptstatic int
94247738Sbaptyaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event);
95247738Sbapt
96247738Sbaptstatic int
97247738Sbaptyaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
98247738Sbapt        yaml_event_t *event);
99247738Sbapt
100247738Sbaptstatic int
101247738Sbaptyaml_emitter_emit_document_start(yaml_emitter_t *emitter,
102247738Sbapt        yaml_event_t *event, int first);
103247738Sbapt
104247738Sbaptstatic int
105247738Sbaptyaml_emitter_emit_document_content(yaml_emitter_t *emitter,
106247738Sbapt        yaml_event_t *event);
107247738Sbapt
108247738Sbaptstatic int
109247738Sbaptyaml_emitter_emit_document_end(yaml_emitter_t *emitter,
110247738Sbapt        yaml_event_t *event);
111247738Sbapt
112247738Sbaptstatic int
113247738Sbaptyaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
114247738Sbapt        yaml_event_t *event, int first);
115247738Sbapt
116247738Sbaptstatic int
117247738Sbaptyaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
118247738Sbapt        yaml_event_t *event, int first);
119247738Sbapt
120247738Sbaptstatic int
121247738Sbaptyaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
122247738Sbapt        yaml_event_t *event, int simple);
123247738Sbapt
124247738Sbaptstatic int
125247738Sbaptyaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
126247738Sbapt        yaml_event_t *event, int first);
127247738Sbapt
128247738Sbaptstatic int
129247738Sbaptyaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
130247738Sbapt        yaml_event_t *event, int first);
131247738Sbapt
132247738Sbaptstatic int
133247738Sbaptyaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
134247738Sbapt        yaml_event_t *event, int simple);
135247738Sbapt
136247738Sbaptstatic int
137247738Sbaptyaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
138247738Sbapt        int root, int sequence, int mapping, int simple_key);
139247738Sbapt
140247738Sbaptstatic int
141247738Sbaptyaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event);
142247738Sbapt
143247738Sbaptstatic int
144247738Sbaptyaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event);
145247738Sbapt
146247738Sbaptstatic int
147247738Sbaptyaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event);
148247738Sbapt
149247738Sbaptstatic int
150247738Sbaptyaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event);
151247738Sbapt
152247738Sbapt/*
153247738Sbapt * Checkers.
154247738Sbapt */
155247738Sbapt
156247738Sbaptstatic int
157247738Sbaptyaml_emitter_check_empty_document(yaml_emitter_t *emitter);
158247738Sbapt
159247738Sbaptstatic int
160247738Sbaptyaml_emitter_check_empty_sequence(yaml_emitter_t *emitter);
161247738Sbapt
162247738Sbaptstatic int
163247738Sbaptyaml_emitter_check_empty_mapping(yaml_emitter_t *emitter);
164247738Sbapt
165247738Sbaptstatic int
166247738Sbaptyaml_emitter_check_simple_key(yaml_emitter_t *emitter);
167247738Sbapt
168247738Sbaptstatic int
169247738Sbaptyaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event);
170247738Sbapt
171247738Sbapt/*
172247738Sbapt * Processors.
173247738Sbapt */
174247738Sbapt
175247738Sbaptstatic int
176247738Sbaptyaml_emitter_process_anchor(yaml_emitter_t *emitter);
177247738Sbapt
178247738Sbaptstatic int
179247738Sbaptyaml_emitter_process_tag(yaml_emitter_t *emitter);
180247738Sbapt
181247738Sbaptstatic int
182247738Sbaptyaml_emitter_process_scalar(yaml_emitter_t *emitter);
183247738Sbapt
184247738Sbapt/*
185247738Sbapt * Analyzers.
186247738Sbapt */
187247738Sbapt
188247738Sbaptstatic int
189247738Sbaptyaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
190247738Sbapt        yaml_version_directive_t version_directive);
191247738Sbapt
192247738Sbaptstatic int
193247738Sbaptyaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
194247738Sbapt        yaml_tag_directive_t tag_directive);
195247738Sbapt
196247738Sbaptstatic int
197247738Sbaptyaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
198247738Sbapt        yaml_char_t *anchor, int alias);
199247738Sbapt
200247738Sbaptstatic int
201247738Sbaptyaml_emitter_analyze_tag(yaml_emitter_t *emitter,
202247738Sbapt        yaml_char_t *tag);
203247738Sbapt
204247738Sbaptstatic int
205247738Sbaptyaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
206247738Sbapt        yaml_char_t *value, size_t length);
207247738Sbapt
208247738Sbaptstatic int
209247738Sbaptyaml_emitter_analyze_event(yaml_emitter_t *emitter,
210247738Sbapt        yaml_event_t *event);
211247738Sbapt
212247738Sbapt/*
213247738Sbapt * Writers.
214247738Sbapt */
215247738Sbapt
216247738Sbaptstatic int
217247738Sbaptyaml_emitter_write_bom(yaml_emitter_t *emitter);
218247738Sbapt
219247738Sbaptstatic int
220247738Sbaptyaml_emitter_write_indent(yaml_emitter_t *emitter);
221247738Sbapt
222247738Sbaptstatic int
223247738Sbaptyaml_emitter_write_indicator(yaml_emitter_t *emitter,
224247738Sbapt        char *indicator, int need_whitespace,
225247738Sbapt        int is_whitespace, int is_indention);
226247738Sbapt
227247738Sbaptstatic int
228247738Sbaptyaml_emitter_write_anchor(yaml_emitter_t *emitter,
229247738Sbapt        yaml_char_t *value, size_t length);
230247738Sbapt
231247738Sbaptstatic int
232247738Sbaptyaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
233247738Sbapt        yaml_char_t *value, size_t length);
234247738Sbapt
235247738Sbaptstatic int
236247738Sbaptyaml_emitter_write_tag_content(yaml_emitter_t *emitter,
237247738Sbapt        yaml_char_t *value, size_t length, int need_whitespace);
238247738Sbapt
239247738Sbaptstatic int
240247738Sbaptyaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
241247738Sbapt        yaml_char_t *value, size_t length, int allow_breaks);
242247738Sbapt
243247738Sbaptstatic int
244247738Sbaptyaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
245247738Sbapt        yaml_char_t *value, size_t length, int allow_breaks);
246247738Sbapt
247247738Sbaptstatic int
248247738Sbaptyaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
249247738Sbapt        yaml_char_t *value, size_t length, int allow_breaks);
250247738Sbapt
251247738Sbaptstatic int
252247738Sbaptyaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
253247738Sbapt        yaml_string_t string);
254247738Sbapt
255247738Sbaptstatic int
256247738Sbaptyaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
257247738Sbapt        yaml_char_t *value, size_t length);
258247738Sbapt
259247738Sbaptstatic int
260247738Sbaptyaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
261247738Sbapt        yaml_char_t *value, size_t length);
262247738Sbapt
263247738Sbapt/*
264247738Sbapt * Set an emitter error and return 0.
265247738Sbapt */
266247738Sbapt
267247738Sbaptstatic int
268247738Sbaptyaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem)
269247738Sbapt{
270247738Sbapt    emitter->error = YAML_EMITTER_ERROR;
271247738Sbapt    emitter->problem = problem;
272247738Sbapt
273247738Sbapt    return 0;
274247738Sbapt}
275247738Sbapt
276247738Sbapt/*
277247738Sbapt * Emit an event.
278247738Sbapt */
279247738Sbapt
280247738SbaptYAML_DECLARE(int)
281247738Sbaptyaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event)
282247738Sbapt{
283247738Sbapt    if (!ENQUEUE(emitter, emitter->events, *event)) {
284247738Sbapt        yaml_event_delete(event);
285247738Sbapt        return 0;
286247738Sbapt    }
287247738Sbapt
288247738Sbapt    while (!yaml_emitter_need_more_events(emitter)) {
289247738Sbapt        if (!yaml_emitter_analyze_event(emitter, emitter->events.head))
290247738Sbapt            return 0;
291247738Sbapt        if (!yaml_emitter_state_machine(emitter, emitter->events.head))
292247738Sbapt            return 0;
293247738Sbapt        yaml_event_delete(&DEQUEUE(emitter, emitter->events));
294247738Sbapt    }
295247738Sbapt
296247738Sbapt    return 1;
297247738Sbapt}
298247738Sbapt
299247738Sbapt/*
300247738Sbapt * Check if we need to accumulate more events before emitting.
301247738Sbapt *
302247738Sbapt * We accumulate extra
303247738Sbapt *  - 1 event for DOCUMENT-START
304247738Sbapt *  - 2 events for SEQUENCE-START
305247738Sbapt *  - 3 events for MAPPING-START
306247738Sbapt */
307247738Sbapt
308247738Sbaptstatic int
309247738Sbaptyaml_emitter_need_more_events(yaml_emitter_t *emitter)
310247738Sbapt{
311247738Sbapt    int level = 0;
312247738Sbapt    int accumulate = 0;
313247738Sbapt    yaml_event_t *event;
314247738Sbapt
315247738Sbapt    if (QUEUE_EMPTY(emitter, emitter->events))
316247738Sbapt        return 1;
317247738Sbapt
318247738Sbapt    switch (emitter->events.head->type) {
319247738Sbapt        case YAML_DOCUMENT_START_EVENT:
320247738Sbapt            accumulate = 1;
321247738Sbapt            break;
322247738Sbapt        case YAML_SEQUENCE_START_EVENT:
323247738Sbapt            accumulate = 2;
324247738Sbapt            break;
325247738Sbapt        case YAML_MAPPING_START_EVENT:
326247738Sbapt            accumulate = 3;
327247738Sbapt            break;
328247738Sbapt        default:
329247738Sbapt            return 0;
330247738Sbapt    }
331247738Sbapt
332247738Sbapt    if (emitter->events.tail - emitter->events.head > accumulate)
333247738Sbapt        return 0;
334247738Sbapt
335247738Sbapt    for (event = emitter->events.head; event != emitter->events.tail; event ++) {
336247738Sbapt        switch (event->type) {
337247738Sbapt            case YAML_STREAM_START_EVENT:
338247738Sbapt            case YAML_DOCUMENT_START_EVENT:
339247738Sbapt            case YAML_SEQUENCE_START_EVENT:
340247738Sbapt            case YAML_MAPPING_START_EVENT:
341247738Sbapt                level += 1;
342247738Sbapt                break;
343247738Sbapt            case YAML_STREAM_END_EVENT:
344247738Sbapt            case YAML_DOCUMENT_END_EVENT:
345247738Sbapt            case YAML_SEQUENCE_END_EVENT:
346247738Sbapt            case YAML_MAPPING_END_EVENT:
347247738Sbapt                level -= 1;
348247738Sbapt                break;
349247738Sbapt            default:
350247738Sbapt                break;
351247738Sbapt        }
352247738Sbapt        if (!level)
353247738Sbapt            return 0;
354247738Sbapt    }
355247738Sbapt
356247738Sbapt    return 1;
357247738Sbapt}
358247738Sbapt
359247738Sbapt/*
360247738Sbapt * Append a directive to the directives stack.
361247738Sbapt */
362247738Sbapt
363247738Sbaptstatic int
364247738Sbaptyaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
365247738Sbapt        yaml_tag_directive_t value, int allow_duplicates)
366247738Sbapt{
367247738Sbapt    yaml_tag_directive_t *tag_directive;
368247738Sbapt    yaml_tag_directive_t copy = { NULL, NULL };
369247738Sbapt
370247738Sbapt    for (tag_directive = emitter->tag_directives.start;
371247738Sbapt            tag_directive != emitter->tag_directives.top; tag_directive ++) {
372247738Sbapt        if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
373247738Sbapt            if (allow_duplicates)
374247738Sbapt                return 1;
375247738Sbapt            return yaml_emitter_set_emitter_error(emitter,
376247738Sbapt                    "duplicate %TAG directive");
377247738Sbapt        }
378247738Sbapt    }
379247738Sbapt
380247738Sbapt    copy.handle = yaml_strdup(value.handle);
381247738Sbapt    copy.prefix = yaml_strdup(value.prefix);
382247738Sbapt    if (!copy.handle || !copy.prefix) {
383247738Sbapt        emitter->error = YAML_MEMORY_ERROR;
384247738Sbapt        goto error;
385247738Sbapt    }
386247738Sbapt
387247738Sbapt    if (!PUSH(emitter, emitter->tag_directives, copy))
388247738Sbapt        goto error;
389247738Sbapt
390247738Sbapt    return 1;
391247738Sbapt
392247738Sbapterror:
393247738Sbapt    yaml_free(copy.handle);
394247738Sbapt    yaml_free(copy.prefix);
395247738Sbapt    return 0;
396247738Sbapt}
397247738Sbapt
398247738Sbapt/*
399247738Sbapt * Increase the indentation level.
400247738Sbapt */
401247738Sbapt
402247738Sbaptstatic int
403247738Sbaptyaml_emitter_increase_indent(yaml_emitter_t *emitter,
404247738Sbapt        int flow, int indentless)
405247738Sbapt{
406247738Sbapt    if (!PUSH(emitter, emitter->indents, emitter->indent))
407247738Sbapt        return 0;
408247738Sbapt
409247738Sbapt    if (emitter->indent < 0) {
410247738Sbapt        emitter->indent = flow ? emitter->best_indent : 0;
411247738Sbapt    }
412247738Sbapt    else if (!indentless) {
413247738Sbapt        emitter->indent += emitter->best_indent;
414247738Sbapt    }
415247738Sbapt
416247738Sbapt    return 1;
417247738Sbapt}
418247738Sbapt
419247738Sbapt/*
420247738Sbapt * State dispatcher.
421247738Sbapt */
422247738Sbapt
423247738Sbaptstatic int
424247738Sbaptyaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event)
425247738Sbapt{
426247738Sbapt    switch (emitter->state)
427247738Sbapt    {
428247738Sbapt        case YAML_EMIT_STREAM_START_STATE:
429247738Sbapt            return yaml_emitter_emit_stream_start(emitter, event);
430247738Sbapt
431247738Sbapt        case YAML_EMIT_FIRST_DOCUMENT_START_STATE:
432247738Sbapt            return yaml_emitter_emit_document_start(emitter, event, 1);
433247738Sbapt
434247738Sbapt        case YAML_EMIT_DOCUMENT_START_STATE:
435247738Sbapt            return yaml_emitter_emit_document_start(emitter, event, 0);
436247738Sbapt
437247738Sbapt        case YAML_EMIT_DOCUMENT_CONTENT_STATE:
438247738Sbapt            return yaml_emitter_emit_document_content(emitter, event);
439247738Sbapt
440247738Sbapt        case YAML_EMIT_DOCUMENT_END_STATE:
441247738Sbapt            return yaml_emitter_emit_document_end(emitter, event);
442247738Sbapt
443247738Sbapt        case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
444247738Sbapt            return yaml_emitter_emit_flow_sequence_item(emitter, event, 1);
445247738Sbapt
446247738Sbapt        case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE:
447247738Sbapt            return yaml_emitter_emit_flow_sequence_item(emitter, event, 0);
448247738Sbapt
449247738Sbapt        case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
450247738Sbapt            return yaml_emitter_emit_flow_mapping_key(emitter, event, 1);
451247738Sbapt
452247738Sbapt        case YAML_EMIT_FLOW_MAPPING_KEY_STATE:
453247738Sbapt            return yaml_emitter_emit_flow_mapping_key(emitter, event, 0);
454247738Sbapt
455247738Sbapt        case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
456247738Sbapt            return yaml_emitter_emit_flow_mapping_value(emitter, event, 1);
457247738Sbapt
458247738Sbapt        case YAML_EMIT_FLOW_MAPPING_VALUE_STATE:
459247738Sbapt            return yaml_emitter_emit_flow_mapping_value(emitter, event, 0);
460247738Sbapt
461247738Sbapt        case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
462247738Sbapt            return yaml_emitter_emit_block_sequence_item(emitter, event, 1);
463247738Sbapt
464247738Sbapt        case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
465247738Sbapt            return yaml_emitter_emit_block_sequence_item(emitter, event, 0);
466247738Sbapt
467247738Sbapt        case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
468247738Sbapt            return yaml_emitter_emit_block_mapping_key(emitter, event, 1);
469247738Sbapt
470247738Sbapt        case YAML_EMIT_BLOCK_MAPPING_KEY_STATE:
471247738Sbapt            return yaml_emitter_emit_block_mapping_key(emitter, event, 0);
472247738Sbapt
473247738Sbapt        case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
474247738Sbapt            return yaml_emitter_emit_block_mapping_value(emitter, event, 1);
475247738Sbapt
476247738Sbapt        case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE:
477247738Sbapt            return yaml_emitter_emit_block_mapping_value(emitter, event, 0);
478247738Sbapt
479247738Sbapt        case YAML_EMIT_END_STATE:
480247738Sbapt            return yaml_emitter_set_emitter_error(emitter,
481247738Sbapt                    "expected nothing after STREAM-END");
482247738Sbapt
483247738Sbapt        default:
484247738Sbapt            assert(1);      /* Invalid state. */
485247738Sbapt    }
486247738Sbapt
487247738Sbapt    return 0;
488247738Sbapt}
489247738Sbapt
490247738Sbapt/*
491247738Sbapt * Expect STREAM-START.
492247738Sbapt */
493247738Sbapt
494247738Sbaptstatic int
495247738Sbaptyaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
496247738Sbapt        yaml_event_t *event)
497247738Sbapt{
498247738Sbapt    if (event->type == YAML_STREAM_START_EVENT)
499247738Sbapt    {
500247738Sbapt        if (!emitter->encoding) {
501247738Sbapt            emitter->encoding = event->data.stream_start.encoding;
502247738Sbapt        }
503247738Sbapt
504247738Sbapt        if (!emitter->encoding) {
505247738Sbapt            emitter->encoding = YAML_UTF8_ENCODING;
506247738Sbapt        }
507247738Sbapt
508247738Sbapt        if (emitter->best_indent < 2 || emitter->best_indent > 9) {
509247738Sbapt            emitter->best_indent  = 2;
510247738Sbapt        }
511247738Sbapt
512247738Sbapt        if (emitter->best_width >= 0
513247738Sbapt                && emitter->best_width <= emitter->best_indent*2) {
514247738Sbapt            emitter->best_width = 80;
515247738Sbapt        }
516247738Sbapt
517247738Sbapt        if (emitter->best_width < 0) {
518247738Sbapt            emitter->best_width = INT_MAX;
519247738Sbapt        }
520247738Sbapt
521247738Sbapt        if (!emitter->line_break) {
522247738Sbapt            emitter->line_break = YAML_LN_BREAK;
523247738Sbapt        }
524247738Sbapt
525247738Sbapt        emitter->indent = -1;
526247738Sbapt
527247738Sbapt        emitter->line = 0;
528247738Sbapt        emitter->column = 0;
529247738Sbapt        emitter->whitespace = 1;
530247738Sbapt        emitter->indention = 1;
531247738Sbapt
532247738Sbapt        if (emitter->encoding != YAML_UTF8_ENCODING) {
533247738Sbapt            if (!yaml_emitter_write_bom(emitter))
534247738Sbapt                return 0;
535247738Sbapt        }
536247738Sbapt
537247738Sbapt        emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE;
538247738Sbapt
539247738Sbapt        return 1;
540247738Sbapt    }
541247738Sbapt
542247738Sbapt    return yaml_emitter_set_emitter_error(emitter,
543247738Sbapt            "expected STREAM-START");
544247738Sbapt}
545247738Sbapt
546247738Sbapt/*
547247738Sbapt * Expect DOCUMENT-START or STREAM-END.
548247738Sbapt */
549247738Sbapt
550247738Sbaptstatic int
551247738Sbaptyaml_emitter_emit_document_start(yaml_emitter_t *emitter,
552247738Sbapt        yaml_event_t *event, int first)
553247738Sbapt{
554247738Sbapt    if (event->type == YAML_DOCUMENT_START_EVENT)
555247738Sbapt    {
556247738Sbapt        yaml_tag_directive_t default_tag_directives[] = {
557247738Sbapt            {(yaml_char_t *)"!", (yaml_char_t *)"!"},
558247738Sbapt            {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
559247738Sbapt            {NULL, NULL}
560247738Sbapt        };
561247738Sbapt        yaml_tag_directive_t *tag_directive;
562247738Sbapt        int implicit;
563247738Sbapt
564247738Sbapt        if (event->data.document_start.version_directive) {
565247738Sbapt            if (!yaml_emitter_analyze_version_directive(emitter,
566247738Sbapt                        *event->data.document_start.version_directive))
567247738Sbapt                return 0;
568247738Sbapt        }
569247738Sbapt
570247738Sbapt        for (tag_directive = event->data.document_start.tag_directives.start;
571247738Sbapt                tag_directive != event->data.document_start.tag_directives.end;
572247738Sbapt                tag_directive ++) {
573247738Sbapt            if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive))
574247738Sbapt                return 0;
575247738Sbapt            if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0))
576247738Sbapt                return 0;
577247738Sbapt        }
578247738Sbapt
579247738Sbapt        for (tag_directive = default_tag_directives;
580247738Sbapt                tag_directive->handle; tag_directive ++) {
581247738Sbapt            if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1))
582247738Sbapt                return 0;
583247738Sbapt        }
584247738Sbapt
585247738Sbapt        implicit = event->data.document_start.implicit;
586247738Sbapt        if (!first || emitter->canonical) {
587247738Sbapt            implicit = 0;
588247738Sbapt        }
589247738Sbapt
590247738Sbapt        if ((event->data.document_start.version_directive ||
591247738Sbapt                    (event->data.document_start.tag_directives.start
592247738Sbapt                     != event->data.document_start.tag_directives.end)) &&
593247738Sbapt                emitter->open_ended)
594247738Sbapt        {
595247738Sbapt            if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
596247738Sbapt                return 0;
597247738Sbapt            if (!yaml_emitter_write_indent(emitter))
598247738Sbapt                return 0;
599247738Sbapt        }
600247738Sbapt
601247738Sbapt        if (event->data.document_start.version_directive) {
602247738Sbapt            implicit = 0;
603247738Sbapt            if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0))
604247738Sbapt                return 0;
605247738Sbapt            if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
606247738Sbapt                return 0;
607247738Sbapt            if (!yaml_emitter_write_indent(emitter))
608247738Sbapt                return 0;
609247738Sbapt        }
610247738Sbapt
611247738Sbapt        if (event->data.document_start.tag_directives.start
612247738Sbapt                != event->data.document_start.tag_directives.end) {
613247738Sbapt            implicit = 0;
614247738Sbapt            for (tag_directive = event->data.document_start.tag_directives.start;
615247738Sbapt                    tag_directive != event->data.document_start.tag_directives.end;
616247738Sbapt                    tag_directive ++) {
617247738Sbapt                if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0))
618247738Sbapt                    return 0;
619247738Sbapt                if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle,
620247738Sbapt                            strlen((char *)tag_directive->handle)))
621247738Sbapt                    return 0;
622247738Sbapt                if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix,
623247738Sbapt                            strlen((char *)tag_directive->prefix), 1))
624247738Sbapt                    return 0;
625247738Sbapt                if (!yaml_emitter_write_indent(emitter))
626247738Sbapt                    return 0;
627247738Sbapt            }
628247738Sbapt        }
629247738Sbapt
630247738Sbapt        if (yaml_emitter_check_empty_document(emitter)) {
631247738Sbapt            implicit = 0;
632247738Sbapt        }
633247738Sbapt
634247738Sbapt        if (!implicit) {
635247738Sbapt            if (!yaml_emitter_write_indent(emitter))
636247738Sbapt                return 0;
637247738Sbapt            if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0))
638247738Sbapt                return 0;
639247738Sbapt            if (emitter->canonical) {
640247738Sbapt                if (!yaml_emitter_write_indent(emitter))
641247738Sbapt                    return 0;
642247738Sbapt            }
643247738Sbapt        }
644247738Sbapt
645247738Sbapt        emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE;
646247738Sbapt
647247738Sbapt        return 1;
648247738Sbapt    }
649247738Sbapt
650247738Sbapt    else if (event->type == YAML_STREAM_END_EVENT)
651247738Sbapt    {
652247738Sbapt        if (emitter->open_ended)
653247738Sbapt        {
654247738Sbapt            if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
655247738Sbapt                return 0;
656247738Sbapt            if (!yaml_emitter_write_indent(emitter))
657247738Sbapt                return 0;
658247738Sbapt        }
659247738Sbapt
660247738Sbapt        if (!yaml_emitter_flush(emitter))
661247738Sbapt            return 0;
662247738Sbapt
663247738Sbapt        emitter->state = YAML_EMIT_END_STATE;
664247738Sbapt
665247738Sbapt        return 1;
666247738Sbapt    }
667247738Sbapt
668247738Sbapt    return yaml_emitter_set_emitter_error(emitter,
669247738Sbapt            "expected DOCUMENT-START or STREAM-END");
670247738Sbapt}
671247738Sbapt
672247738Sbapt/*
673247738Sbapt * Expect the root node.
674247738Sbapt */
675247738Sbapt
676247738Sbaptstatic int
677247738Sbaptyaml_emitter_emit_document_content(yaml_emitter_t *emitter,
678247738Sbapt        yaml_event_t *event)
679247738Sbapt{
680247738Sbapt    if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE))
681247738Sbapt        return 0;
682247738Sbapt
683247738Sbapt    return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0);
684247738Sbapt}
685247738Sbapt
686247738Sbapt/*
687247738Sbapt * Expect DOCUMENT-END.
688247738Sbapt */
689247738Sbapt
690247738Sbaptstatic int
691247738Sbaptyaml_emitter_emit_document_end(yaml_emitter_t *emitter,
692247738Sbapt        yaml_event_t *event)
693247738Sbapt{
694247738Sbapt    if (event->type == YAML_DOCUMENT_END_EVENT)
695247738Sbapt    {
696247738Sbapt        if (!yaml_emitter_write_indent(emitter))
697247738Sbapt            return 0;
698247738Sbapt        if (!event->data.document_end.implicit) {
699247738Sbapt            if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
700247738Sbapt                return 0;
701247738Sbapt            if (!yaml_emitter_write_indent(emitter))
702247738Sbapt                return 0;
703247738Sbapt        }
704247738Sbapt        if (!yaml_emitter_flush(emitter))
705247738Sbapt            return 0;
706247738Sbapt
707247738Sbapt        emitter->state = YAML_EMIT_DOCUMENT_START_STATE;
708247738Sbapt
709247738Sbapt        while (!STACK_EMPTY(emitter, emitter->tag_directives)) {
710247738Sbapt            yaml_tag_directive_t tag_directive = POP(emitter,
711247738Sbapt                    emitter->tag_directives);
712247738Sbapt            yaml_free(tag_directive.handle);
713247738Sbapt            yaml_free(tag_directive.prefix);
714247738Sbapt        }
715247738Sbapt
716247738Sbapt        return 1;
717247738Sbapt    }
718247738Sbapt
719247738Sbapt    return yaml_emitter_set_emitter_error(emitter,
720247738Sbapt            "expected DOCUMENT-END");
721247738Sbapt}
722247738Sbapt
723247738Sbapt/*
724247738Sbapt *
725247738Sbapt * Expect a flow item node.
726247738Sbapt */
727247738Sbapt
728247738Sbaptstatic int
729247738Sbaptyaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
730247738Sbapt        yaml_event_t *event, int first)
731247738Sbapt{
732247738Sbapt    if (first)
733247738Sbapt    {
734247738Sbapt        if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0))
735247738Sbapt            return 0;
736247738Sbapt        if (!yaml_emitter_increase_indent(emitter, 1, 0))
737247738Sbapt            return 0;
738247738Sbapt        emitter->flow_level ++;
739247738Sbapt    }
740247738Sbapt
741247738Sbapt    if (event->type == YAML_SEQUENCE_END_EVENT)
742247738Sbapt    {
743247738Sbapt        emitter->flow_level --;
744247738Sbapt        emitter->indent = POP(emitter, emitter->indents);
745247738Sbapt        if (emitter->canonical && !first) {
746247738Sbapt            if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
747247738Sbapt                return 0;
748247738Sbapt            if (!yaml_emitter_write_indent(emitter))
749247738Sbapt                return 0;
750247738Sbapt        }
751247738Sbapt        if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0))
752247738Sbapt            return 0;
753247738Sbapt        emitter->state = POP(emitter, emitter->states);
754247738Sbapt
755247738Sbapt        return 1;
756247738Sbapt    }
757247738Sbapt
758247738Sbapt    if (!first) {
759247738Sbapt        if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
760247738Sbapt            return 0;
761247738Sbapt    }
762247738Sbapt
763247738Sbapt    if (emitter->canonical || emitter->column > emitter->best_width) {
764247738Sbapt        if (!yaml_emitter_write_indent(emitter))
765247738Sbapt            return 0;
766247738Sbapt    }
767247738Sbapt    if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE))
768247738Sbapt        return 0;
769247738Sbapt
770247738Sbapt    return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
771247738Sbapt}
772247738Sbapt
773247738Sbapt/*
774247738Sbapt * Expect a flow key node.
775247738Sbapt */
776247738Sbapt
777247738Sbaptstatic int
778247738Sbaptyaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
779247738Sbapt        yaml_event_t *event, int first)
780247738Sbapt{
781247738Sbapt    if (first)
782247738Sbapt    {
783247738Sbapt        if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0))
784247738Sbapt            return 0;
785247738Sbapt        if (!yaml_emitter_increase_indent(emitter, 1, 0))
786247738Sbapt            return 0;
787247738Sbapt        emitter->flow_level ++;
788247738Sbapt    }
789247738Sbapt
790247738Sbapt    if (event->type == YAML_MAPPING_END_EVENT)
791247738Sbapt    {
792247738Sbapt        emitter->flow_level --;
793247738Sbapt        emitter->indent = POP(emitter, emitter->indents);
794247738Sbapt        if (emitter->canonical && !first) {
795247738Sbapt            if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
796247738Sbapt                return 0;
797247738Sbapt            if (!yaml_emitter_write_indent(emitter))
798247738Sbapt                return 0;
799247738Sbapt        }
800247738Sbapt        if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0))
801247738Sbapt            return 0;
802247738Sbapt        emitter->state = POP(emitter, emitter->states);
803247738Sbapt
804247738Sbapt        return 1;
805247738Sbapt    }
806247738Sbapt
807247738Sbapt    if (!first) {
808247738Sbapt        if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
809247738Sbapt            return 0;
810247738Sbapt    }
811247738Sbapt    if (emitter->canonical || emitter->column > emitter->best_width) {
812247738Sbapt        if (!yaml_emitter_write_indent(emitter))
813247738Sbapt            return 0;
814247738Sbapt    }
815247738Sbapt
816247738Sbapt    if (!emitter->canonical && yaml_emitter_check_simple_key(emitter))
817247738Sbapt    {
818247738Sbapt        if (!PUSH(emitter, emitter->states,
819247738Sbapt                    YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE))
820247738Sbapt            return 0;
821247738Sbapt
822247738Sbapt        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
823247738Sbapt    }
824247738Sbapt    else
825247738Sbapt    {
826247738Sbapt        if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0))
827247738Sbapt            return 0;
828247738Sbapt        if (!PUSH(emitter, emitter->states,
829247738Sbapt                    YAML_EMIT_FLOW_MAPPING_VALUE_STATE))
830247738Sbapt            return 0;
831247738Sbapt
832247738Sbapt        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
833247738Sbapt    }
834247738Sbapt}
835247738Sbapt
836247738Sbapt/*
837247738Sbapt * Expect a flow value node.
838247738Sbapt */
839247738Sbapt
840247738Sbaptstatic int
841247738Sbaptyaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
842247738Sbapt        yaml_event_t *event, int simple)
843247738Sbapt{
844247738Sbapt    if (simple) {
845247738Sbapt        if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
846247738Sbapt            return 0;
847247738Sbapt    }
848247738Sbapt    else {
849247738Sbapt        if (emitter->canonical || emitter->column > emitter->best_width) {
850247738Sbapt            if (!yaml_emitter_write_indent(emitter))
851247738Sbapt                return 0;
852247738Sbapt        }
853247738Sbapt        if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0))
854247738Sbapt            return 0;
855247738Sbapt    }
856247738Sbapt    if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE))
857247738Sbapt        return 0;
858247738Sbapt    return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
859247738Sbapt}
860247738Sbapt
861247738Sbapt/*
862247738Sbapt * Expect a block item node.
863247738Sbapt */
864247738Sbapt
865247738Sbaptstatic int
866247738Sbaptyaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
867247738Sbapt        yaml_event_t *event, int first)
868247738Sbapt{
869247738Sbapt    if (first)
870247738Sbapt    {
871247738Sbapt        if (!yaml_emitter_increase_indent(emitter, 0,
872247738Sbapt                    (emitter->mapping_context && !emitter->indention)))
873247738Sbapt            return 0;
874247738Sbapt    }
875247738Sbapt
876247738Sbapt    if (event->type == YAML_SEQUENCE_END_EVENT)
877247738Sbapt    {
878247738Sbapt        emitter->indent = POP(emitter, emitter->indents);
879247738Sbapt        emitter->state = POP(emitter, emitter->states);
880247738Sbapt
881247738Sbapt        return 1;
882247738Sbapt    }
883247738Sbapt
884247738Sbapt    if (!yaml_emitter_write_indent(emitter))
885247738Sbapt        return 0;
886247738Sbapt    if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1))
887247738Sbapt        return 0;
888247738Sbapt    if (!PUSH(emitter, emitter->states,
889247738Sbapt                YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE))
890247738Sbapt        return 0;
891247738Sbapt
892247738Sbapt    return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
893247738Sbapt}
894247738Sbapt
895247738Sbapt/*
896247738Sbapt * Expect a block key node.
897247738Sbapt */
898247738Sbapt
899247738Sbaptstatic int
900247738Sbaptyaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
901247738Sbapt        yaml_event_t *event, int first)
902247738Sbapt{
903247738Sbapt    if (first)
904247738Sbapt    {
905247738Sbapt        if (!yaml_emitter_increase_indent(emitter, 0, 0))
906247738Sbapt            return 0;
907247738Sbapt    }
908247738Sbapt
909247738Sbapt    if (event->type == YAML_MAPPING_END_EVENT)
910247738Sbapt    {
911247738Sbapt        emitter->indent = POP(emitter, emitter->indents);
912247738Sbapt        emitter->state = POP(emitter, emitter->states);
913247738Sbapt
914247738Sbapt        return 1;
915247738Sbapt    }
916247738Sbapt
917247738Sbapt    if (!yaml_emitter_write_indent(emitter))
918247738Sbapt        return 0;
919247738Sbapt
920247738Sbapt    if (yaml_emitter_check_simple_key(emitter))
921247738Sbapt    {
922247738Sbapt        if (!PUSH(emitter, emitter->states,
923247738Sbapt                    YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE))
924247738Sbapt            return 0;
925247738Sbapt
926247738Sbapt        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
927247738Sbapt    }
928247738Sbapt    else
929247738Sbapt    {
930247738Sbapt        if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1))
931247738Sbapt            return 0;
932247738Sbapt        if (!PUSH(emitter, emitter->states,
933247738Sbapt                    YAML_EMIT_BLOCK_MAPPING_VALUE_STATE))
934247738Sbapt            return 0;
935247738Sbapt
936247738Sbapt        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
937247738Sbapt    }
938247738Sbapt}
939247738Sbapt
940247738Sbapt/*
941247738Sbapt * Expect a block value node.
942247738Sbapt */
943247738Sbapt
944247738Sbaptstatic int
945247738Sbaptyaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
946247738Sbapt        yaml_event_t *event, int simple)
947247738Sbapt{
948247738Sbapt    if (simple) {
949247738Sbapt        if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
950247738Sbapt            return 0;
951247738Sbapt    }
952247738Sbapt    else {
953247738Sbapt        if (!yaml_emitter_write_indent(emitter))
954247738Sbapt            return 0;
955247738Sbapt        if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1))
956247738Sbapt            return 0;
957247738Sbapt    }
958247738Sbapt    if (!PUSH(emitter, emitter->states,
959247738Sbapt                YAML_EMIT_BLOCK_MAPPING_KEY_STATE))
960247738Sbapt        return 0;
961247738Sbapt
962247738Sbapt    return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
963247738Sbapt}
964247738Sbapt
965247738Sbapt/*
966247738Sbapt * Expect a node.
967247738Sbapt */
968247738Sbapt
969247738Sbaptstatic int
970247738Sbaptyaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
971247738Sbapt        int root, int sequence, int mapping, int simple_key)
972247738Sbapt{
973247738Sbapt    emitter->root_context = root;
974247738Sbapt    emitter->sequence_context = sequence;
975247738Sbapt    emitter->mapping_context = mapping;
976247738Sbapt    emitter->simple_key_context = simple_key;
977247738Sbapt
978247738Sbapt    switch (event->type)
979247738Sbapt    {
980247738Sbapt        case YAML_ALIAS_EVENT:
981247738Sbapt            return yaml_emitter_emit_alias(emitter, event);
982247738Sbapt
983247738Sbapt        case YAML_SCALAR_EVENT:
984247738Sbapt            return yaml_emitter_emit_scalar(emitter, event);
985247738Sbapt
986247738Sbapt        case YAML_SEQUENCE_START_EVENT:
987247738Sbapt            return yaml_emitter_emit_sequence_start(emitter, event);
988247738Sbapt
989247738Sbapt        case YAML_MAPPING_START_EVENT:
990247738Sbapt            return yaml_emitter_emit_mapping_start(emitter, event);
991247738Sbapt
992247738Sbapt        default:
993247738Sbapt            return yaml_emitter_set_emitter_error(emitter,
994247738Sbapt                    "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS");
995247738Sbapt    }
996247738Sbapt
997247738Sbapt    return 0;
998247738Sbapt}
999247738Sbapt
1000247738Sbapt/*
1001247738Sbapt * Expect ALIAS.
1002247738Sbapt */
1003247738Sbapt
1004247738Sbaptstatic int
1005247738Sbaptyaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event)
1006247738Sbapt{
1007247738Sbapt    if (!yaml_emitter_process_anchor(emitter))
1008247738Sbapt        return 0;
1009247738Sbapt    emitter->state = POP(emitter, emitter->states);
1010247738Sbapt
1011247738Sbapt    return 1;
1012247738Sbapt}
1013247738Sbapt
1014247738Sbapt/*
1015247738Sbapt * Expect SCALAR.
1016247738Sbapt */
1017247738Sbapt
1018247738Sbaptstatic int
1019247738Sbaptyaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event)
1020247738Sbapt{
1021247738Sbapt    if (!yaml_emitter_select_scalar_style(emitter, event))
1022247738Sbapt        return 0;
1023247738Sbapt    if (!yaml_emitter_process_anchor(emitter))
1024247738Sbapt        return 0;
1025247738Sbapt    if (!yaml_emitter_process_tag(emitter))
1026247738Sbapt        return 0;
1027247738Sbapt    if (!yaml_emitter_increase_indent(emitter, 1, 0))
1028247738Sbapt        return 0;
1029247738Sbapt    if (!yaml_emitter_process_scalar(emitter))
1030247738Sbapt        return 0;
1031247738Sbapt    emitter->indent = POP(emitter, emitter->indents);
1032247738Sbapt    emitter->state = POP(emitter, emitter->states);
1033247738Sbapt
1034247738Sbapt    return 1;
1035247738Sbapt}
1036247738Sbapt
1037247738Sbapt/*
1038247738Sbapt * Expect SEQUENCE-START.
1039247738Sbapt */
1040247738Sbapt
1041247738Sbaptstatic int
1042247738Sbaptyaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event)
1043247738Sbapt{
1044247738Sbapt    if (!yaml_emitter_process_anchor(emitter))
1045247738Sbapt        return 0;
1046247738Sbapt    if (!yaml_emitter_process_tag(emitter))
1047247738Sbapt        return 0;
1048247738Sbapt
1049247738Sbapt    if (emitter->flow_level || emitter->canonical
1050247738Sbapt            || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE
1051247738Sbapt            || yaml_emitter_check_empty_sequence(emitter)) {
1052247738Sbapt        emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE;
1053247738Sbapt    }
1054247738Sbapt    else {
1055247738Sbapt        emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE;
1056247738Sbapt    }
1057247738Sbapt
1058247738Sbapt    return 1;
1059247738Sbapt}
1060247738Sbapt
1061247738Sbapt/*
1062247738Sbapt * Expect MAPPING-START.
1063247738Sbapt */
1064247738Sbapt
1065247738Sbaptstatic int
1066247738Sbaptyaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event)
1067247738Sbapt{
1068247738Sbapt    if (!yaml_emitter_process_anchor(emitter))
1069247738Sbapt        return 0;
1070247738Sbapt    if (!yaml_emitter_process_tag(emitter))
1071247738Sbapt        return 0;
1072247738Sbapt
1073247738Sbapt    if (emitter->flow_level || emitter->canonical
1074247738Sbapt            || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE
1075247738Sbapt            || yaml_emitter_check_empty_mapping(emitter)) {
1076247738Sbapt        emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE;
1077247738Sbapt    }
1078247738Sbapt    else {
1079247738Sbapt        emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE;
1080247738Sbapt    }
1081247738Sbapt
1082247738Sbapt    return 1;
1083247738Sbapt}
1084247738Sbapt
1085247738Sbapt/*
1086247738Sbapt * Check if the document content is an empty scalar.
1087247738Sbapt */
1088247738Sbapt
1089247738Sbaptstatic int
1090247738Sbaptyaml_emitter_check_empty_document(yaml_emitter_t *emitter)
1091247738Sbapt{
1092247738Sbapt    return 0;
1093247738Sbapt}
1094247738Sbapt
1095247738Sbapt/*
1096247738Sbapt * Check if the next events represent an empty sequence.
1097247738Sbapt */
1098247738Sbapt
1099247738Sbaptstatic int
1100247738Sbaptyaml_emitter_check_empty_sequence(yaml_emitter_t *emitter)
1101247738Sbapt{
1102247738Sbapt    if (emitter->events.tail - emitter->events.head < 2)
1103247738Sbapt        return 0;
1104247738Sbapt
1105247738Sbapt    return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT
1106247738Sbapt            && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT);
1107247738Sbapt}
1108247738Sbapt
1109247738Sbapt/*
1110247738Sbapt * Check if the next events represent an empty mapping.
1111247738Sbapt */
1112247738Sbapt
1113247738Sbaptstatic int
1114247738Sbaptyaml_emitter_check_empty_mapping(yaml_emitter_t *emitter)
1115247738Sbapt{
1116247738Sbapt    if (emitter->events.tail - emitter->events.head < 2)
1117247738Sbapt        return 0;
1118247738Sbapt
1119247738Sbapt    return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT
1120247738Sbapt            && emitter->events.head[1].type == YAML_MAPPING_END_EVENT);
1121247738Sbapt}
1122247738Sbapt
1123247738Sbapt/*
1124247738Sbapt * Check if the next node can be expressed as a simple key.
1125247738Sbapt */
1126247738Sbapt
1127247738Sbaptstatic int
1128247738Sbaptyaml_emitter_check_simple_key(yaml_emitter_t *emitter)
1129247738Sbapt{
1130247738Sbapt    yaml_event_t *event = emitter->events.head;
1131247738Sbapt    size_t length = 0;
1132247738Sbapt
1133247738Sbapt    switch (event->type)
1134247738Sbapt    {
1135247738Sbapt        case YAML_ALIAS_EVENT:
1136247738Sbapt            length += emitter->anchor_data.anchor_length;
1137247738Sbapt            break;
1138247738Sbapt
1139247738Sbapt        case YAML_SCALAR_EVENT:
1140247738Sbapt            if (emitter->scalar_data.multiline)
1141247738Sbapt                return 0;
1142247738Sbapt            length += emitter->anchor_data.anchor_length
1143247738Sbapt                + emitter->tag_data.handle_length
1144247738Sbapt                + emitter->tag_data.suffix_length
1145247738Sbapt                + emitter->scalar_data.length;
1146247738Sbapt            break;
1147247738Sbapt
1148247738Sbapt        case YAML_SEQUENCE_START_EVENT:
1149247738Sbapt            if (!yaml_emitter_check_empty_sequence(emitter))
1150247738Sbapt                return 0;
1151247738Sbapt            length += emitter->anchor_data.anchor_length
1152247738Sbapt                + emitter->tag_data.handle_length
1153247738Sbapt                + emitter->tag_data.suffix_length;
1154247738Sbapt            break;
1155247738Sbapt
1156247738Sbapt        case YAML_MAPPING_START_EVENT:
1157247738Sbapt            if (!yaml_emitter_check_empty_mapping(emitter))
1158247738Sbapt                return 0;
1159247738Sbapt            length += emitter->anchor_data.anchor_length
1160247738Sbapt                + emitter->tag_data.handle_length
1161247738Sbapt                + emitter->tag_data.suffix_length;
1162247738Sbapt            break;
1163247738Sbapt
1164247738Sbapt        default:
1165247738Sbapt            return 0;
1166247738Sbapt    }
1167247738Sbapt
1168247738Sbapt    if (length > 128)
1169247738Sbapt        return 0;
1170247738Sbapt
1171247738Sbapt    return 1;
1172247738Sbapt}
1173247738Sbapt
1174247738Sbapt/*
1175247738Sbapt * Determine an acceptable scalar style.
1176247738Sbapt */
1177247738Sbapt
1178247738Sbaptstatic int
1179247738Sbaptyaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event)
1180247738Sbapt{
1181247738Sbapt    yaml_scalar_style_t style = event->data.scalar.style;
1182247738Sbapt    int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix);
1183247738Sbapt
1184247738Sbapt    if (no_tag && !event->data.scalar.plain_implicit
1185247738Sbapt            && !event->data.scalar.quoted_implicit) {
1186247738Sbapt        return yaml_emitter_set_emitter_error(emitter,
1187247738Sbapt                "neither tag nor implicit flags are specified");
1188247738Sbapt    }
1189247738Sbapt
1190247738Sbapt    if (style == YAML_ANY_SCALAR_STYLE)
1191247738Sbapt        style = YAML_PLAIN_SCALAR_STYLE;
1192247738Sbapt
1193247738Sbapt    if (emitter->canonical)
1194247738Sbapt        style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1195247738Sbapt
1196247738Sbapt    if (emitter->simple_key_context && emitter->scalar_data.multiline)
1197247738Sbapt        style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1198247738Sbapt
1199247738Sbapt    if (style == YAML_PLAIN_SCALAR_STYLE)
1200247738Sbapt    {
1201247738Sbapt        if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed)
1202247738Sbapt                || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed))
1203247738Sbapt            style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1204247738Sbapt        if (!emitter->scalar_data.length
1205247738Sbapt                && (emitter->flow_level || emitter->simple_key_context))
1206247738Sbapt            style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1207247738Sbapt        if (no_tag && !event->data.scalar.plain_implicit)
1208247738Sbapt            style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1209247738Sbapt    }
1210247738Sbapt
1211247738Sbapt    if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE)
1212247738Sbapt    {
1213247738Sbapt        if (!emitter->scalar_data.single_quoted_allowed)
1214247738Sbapt            style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1215247738Sbapt    }
1216247738Sbapt
1217247738Sbapt    if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE)
1218247738Sbapt    {
1219247738Sbapt        if (!emitter->scalar_data.block_allowed
1220247738Sbapt                || emitter->flow_level || emitter->simple_key_context)
1221247738Sbapt            style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1222247738Sbapt    }
1223247738Sbapt
1224247738Sbapt    if (no_tag && !event->data.scalar.quoted_implicit
1225247738Sbapt            && style != YAML_PLAIN_SCALAR_STYLE)
1226247738Sbapt    {
1227247738Sbapt        emitter->tag_data.handle = (yaml_char_t *)"!";
1228247738Sbapt        emitter->tag_data.handle_length = 1;
1229247738Sbapt    }
1230247738Sbapt
1231247738Sbapt    emitter->scalar_data.style = style;
1232247738Sbapt
1233247738Sbapt    return 1;
1234247738Sbapt}
1235247738Sbapt
1236247738Sbapt/*
1237247738Sbapt * Write an achor.
1238247738Sbapt */
1239247738Sbapt
1240247738Sbaptstatic int
1241247738Sbaptyaml_emitter_process_anchor(yaml_emitter_t *emitter)
1242247738Sbapt{
1243247738Sbapt    if (!emitter->anchor_data.anchor)
1244247738Sbapt        return 1;
1245247738Sbapt
1246247738Sbapt    if (!yaml_emitter_write_indicator(emitter,
1247247738Sbapt                (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0))
1248247738Sbapt        return 0;
1249247738Sbapt
1250247738Sbapt    return yaml_emitter_write_anchor(emitter,
1251247738Sbapt            emitter->anchor_data.anchor, emitter->anchor_data.anchor_length);
1252247738Sbapt}
1253247738Sbapt
1254247738Sbapt/*
1255247738Sbapt * Write a tag.
1256247738Sbapt */
1257247738Sbapt
1258247738Sbaptstatic int
1259247738Sbaptyaml_emitter_process_tag(yaml_emitter_t *emitter)
1260247738Sbapt{
1261247738Sbapt    if (!emitter->tag_data.handle && !emitter->tag_data.suffix)
1262247738Sbapt        return 1;
1263247738Sbapt
1264247738Sbapt    if (emitter->tag_data.handle)
1265247738Sbapt    {
1266247738Sbapt        if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle,
1267247738Sbapt                    emitter->tag_data.handle_length))
1268247738Sbapt            return 0;
1269247738Sbapt        if (emitter->tag_data.suffix) {
1270247738Sbapt            if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
1271247738Sbapt                        emitter->tag_data.suffix_length, 0))
1272247738Sbapt                return 0;
1273247738Sbapt        }
1274247738Sbapt    }
1275247738Sbapt    else
1276247738Sbapt    {
1277247738Sbapt        if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0))
1278247738Sbapt            return 0;
1279247738Sbapt        if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
1280247738Sbapt                    emitter->tag_data.suffix_length, 0))
1281247738Sbapt            return 0;
1282247738Sbapt        if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0))
1283247738Sbapt            return 0;
1284247738Sbapt    }
1285247738Sbapt
1286247738Sbapt    return 1;
1287247738Sbapt}
1288247738Sbapt
1289247738Sbapt/*
1290247738Sbapt * Write a scalar.
1291247738Sbapt */
1292247738Sbapt
1293247738Sbaptstatic int
1294247738Sbaptyaml_emitter_process_scalar(yaml_emitter_t *emitter)
1295247738Sbapt{
1296247738Sbapt    switch (emitter->scalar_data.style)
1297247738Sbapt    {
1298247738Sbapt        case YAML_PLAIN_SCALAR_STYLE:
1299247738Sbapt            return yaml_emitter_write_plain_scalar(emitter,
1300247738Sbapt                    emitter->scalar_data.value, emitter->scalar_data.length,
1301247738Sbapt                    !emitter->simple_key_context);
1302247738Sbapt
1303247738Sbapt        case YAML_SINGLE_QUOTED_SCALAR_STYLE:
1304247738Sbapt            return yaml_emitter_write_single_quoted_scalar(emitter,
1305247738Sbapt                    emitter->scalar_data.value, emitter->scalar_data.length,
1306247738Sbapt                    !emitter->simple_key_context);
1307247738Sbapt
1308247738Sbapt        case YAML_DOUBLE_QUOTED_SCALAR_STYLE:
1309247738Sbapt            return yaml_emitter_write_double_quoted_scalar(emitter,
1310247738Sbapt                    emitter->scalar_data.value, emitter->scalar_data.length,
1311247738Sbapt                    !emitter->simple_key_context);
1312247738Sbapt
1313247738Sbapt        case YAML_LITERAL_SCALAR_STYLE:
1314247738Sbapt            return yaml_emitter_write_literal_scalar(emitter,
1315247738Sbapt                    emitter->scalar_data.value, emitter->scalar_data.length);
1316247738Sbapt
1317247738Sbapt        case YAML_FOLDED_SCALAR_STYLE:
1318247738Sbapt            return yaml_emitter_write_folded_scalar(emitter,
1319247738Sbapt                    emitter->scalar_data.value, emitter->scalar_data.length);
1320247738Sbapt
1321247738Sbapt        default:
1322247738Sbapt            assert(1);      /* Impossible. */
1323247738Sbapt    }
1324247738Sbapt
1325247738Sbapt    return 0;
1326247738Sbapt}
1327247738Sbapt
1328247738Sbapt/*
1329247738Sbapt * Check if a %YAML directive is valid.
1330247738Sbapt */
1331247738Sbapt
1332247738Sbaptstatic int
1333247738Sbaptyaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
1334247738Sbapt        yaml_version_directive_t version_directive)
1335247738Sbapt{
1336247738Sbapt    if (version_directive.major != 1 || version_directive.minor != 1) {
1337247738Sbapt        return yaml_emitter_set_emitter_error(emitter,
1338247738Sbapt                "incompatible %YAML directive");
1339247738Sbapt    }
1340247738Sbapt
1341247738Sbapt    return 1;
1342247738Sbapt}
1343247738Sbapt
1344247738Sbapt/*
1345247738Sbapt * Check if a %TAG directive is valid.
1346247738Sbapt */
1347247738Sbapt
1348247738Sbaptstatic int
1349247738Sbaptyaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
1350247738Sbapt        yaml_tag_directive_t tag_directive)
1351247738Sbapt{
1352247738Sbapt    yaml_string_t handle;
1353247738Sbapt    yaml_string_t prefix;
1354247738Sbapt    size_t handle_length;
1355247738Sbapt    size_t prefix_length;
1356247738Sbapt
1357247738Sbapt    handle_length = strlen((char *)tag_directive.handle);
1358247738Sbapt    prefix_length = strlen((char *)tag_directive.prefix);
1359247738Sbapt    STRING_ASSIGN(handle, tag_directive.handle, handle_length);
1360247738Sbapt    STRING_ASSIGN(prefix, tag_directive.prefix, prefix_length);
1361247738Sbapt
1362247738Sbapt    if (handle.start == handle.end) {
1363247738Sbapt        return yaml_emitter_set_emitter_error(emitter,
1364247738Sbapt                "tag handle must not be empty");
1365247738Sbapt    }
1366247738Sbapt
1367247738Sbapt    if (handle.start[0] != '!') {
1368247738Sbapt        return yaml_emitter_set_emitter_error(emitter,
1369247738Sbapt                "tag handle must start with '!'");
1370247738Sbapt    }
1371247738Sbapt
1372247738Sbapt    if (handle.end[-1] != '!') {
1373247738Sbapt        return yaml_emitter_set_emitter_error(emitter,
1374247738Sbapt                "tag handle must end with '!'");
1375247738Sbapt    }
1376247738Sbapt
1377247738Sbapt    handle.pointer ++;
1378247738Sbapt
1379247738Sbapt    while (handle.pointer < handle.end-1) {
1380247738Sbapt        if (!IS_ALPHA(handle)) {
1381247738Sbapt            return yaml_emitter_set_emitter_error(emitter,
1382247738Sbapt                    "tag handle must contain alphanumerical characters only");
1383247738Sbapt        }
1384247738Sbapt        MOVE(handle);
1385247738Sbapt    }
1386247738Sbapt
1387247738Sbapt    if (prefix.start == prefix.end) {
1388247738Sbapt        return yaml_emitter_set_emitter_error(emitter,
1389247738Sbapt                "tag prefix must not be empty");
1390247738Sbapt    }
1391247738Sbapt
1392247738Sbapt    return 1;
1393247738Sbapt}
1394247738Sbapt
1395247738Sbapt/*
1396247738Sbapt * Check if an anchor is valid.
1397247738Sbapt */
1398247738Sbapt
1399247738Sbaptstatic int
1400247738Sbaptyaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
1401247738Sbapt        yaml_char_t *anchor, int alias)
1402247738Sbapt{
1403247738Sbapt    size_t anchor_length;
1404247738Sbapt    yaml_string_t string;
1405247738Sbapt
1406247738Sbapt    anchor_length = strlen((char *)anchor);
1407247738Sbapt    STRING_ASSIGN(string, anchor, anchor_length);
1408247738Sbapt
1409247738Sbapt    if (string.start == string.end) {
1410247738Sbapt        return yaml_emitter_set_emitter_error(emitter, alias ?
1411247738Sbapt                "alias value must not be empty" :
1412247738Sbapt                "anchor value must not be empty");
1413247738Sbapt    }
1414247738Sbapt
1415247738Sbapt    while (string.pointer != string.end) {
1416247738Sbapt        if (!IS_ALPHA(string)) {
1417247738Sbapt            return yaml_emitter_set_emitter_error(emitter, alias ?
1418247738Sbapt                    "alias value must contain alphanumerical characters only" :
1419247738Sbapt                    "anchor value must contain alphanumerical characters only");
1420247738Sbapt        }
1421247738Sbapt        MOVE(string);
1422247738Sbapt    }
1423247738Sbapt
1424247738Sbapt    emitter->anchor_data.anchor = string.start;
1425247738Sbapt    emitter->anchor_data.anchor_length = string.end - string.start;
1426247738Sbapt    emitter->anchor_data.alias = alias;
1427247738Sbapt
1428247738Sbapt    return 1;
1429247738Sbapt}
1430247738Sbapt
1431247738Sbapt/*
1432247738Sbapt * Check if a tag is valid.
1433247738Sbapt */
1434247738Sbapt
1435247738Sbaptstatic int
1436247738Sbaptyaml_emitter_analyze_tag(yaml_emitter_t *emitter,
1437247738Sbapt        yaml_char_t *tag)
1438247738Sbapt{
1439247738Sbapt    size_t tag_length;
1440247738Sbapt    yaml_string_t string;
1441247738Sbapt    yaml_tag_directive_t *tag_directive;
1442247738Sbapt
1443247738Sbapt    tag_length = strlen((char *)tag);
1444247738Sbapt    STRING_ASSIGN(string, tag, tag_length);
1445247738Sbapt
1446247738Sbapt    if (string.start == string.end) {
1447247738Sbapt        return yaml_emitter_set_emitter_error(emitter,
1448247738Sbapt                "tag value must not be empty");
1449247738Sbapt    }
1450247738Sbapt
1451247738Sbapt    for (tag_directive = emitter->tag_directives.start;
1452247738Sbapt            tag_directive != emitter->tag_directives.top; tag_directive ++) {
1453247738Sbapt        size_t prefix_length = strlen((char *)tag_directive->prefix);
1454247738Sbapt        if (prefix_length < (size_t)(string.end - string.start)
1455247738Sbapt                && strncmp((char *)tag_directive->prefix, (char *)string.start,
1456247738Sbapt                    prefix_length) == 0)
1457247738Sbapt        {
1458247738Sbapt            emitter->tag_data.handle = tag_directive->handle;
1459247738Sbapt            emitter->tag_data.handle_length =
1460247738Sbapt                strlen((char *)tag_directive->handle);
1461247738Sbapt            emitter->tag_data.suffix = string.start + prefix_length;
1462247738Sbapt            emitter->tag_data.suffix_length =
1463247738Sbapt                (string.end - string.start) - prefix_length;
1464247738Sbapt            return 1;
1465247738Sbapt        }
1466247738Sbapt    }
1467247738Sbapt
1468247738Sbapt    emitter->tag_data.suffix = string.start;
1469247738Sbapt    emitter->tag_data.suffix_length = string.end - string.start;
1470247738Sbapt
1471247738Sbapt    return 1;
1472247738Sbapt}
1473247738Sbapt
1474247738Sbapt/*
1475247738Sbapt * Check if a scalar is valid.
1476247738Sbapt */
1477247738Sbapt
1478247738Sbaptstatic int
1479247738Sbaptyaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
1480247738Sbapt        yaml_char_t *value, size_t length)
1481247738Sbapt{
1482247738Sbapt    yaml_string_t string;
1483247738Sbapt
1484247738Sbapt    int block_indicators = 0;
1485247738Sbapt    int flow_indicators = 0;
1486247738Sbapt    int line_breaks = 0;
1487247738Sbapt    int special_characters = 0;
1488247738Sbapt
1489247738Sbapt    int leading_space = 0;
1490247738Sbapt    int leading_break = 0;
1491247738Sbapt    int trailing_space = 0;
1492247738Sbapt    int trailing_break = 0;
1493247738Sbapt    int break_space = 0;
1494247738Sbapt    int space_break = 0;
1495247738Sbapt
1496247738Sbapt    int preceeded_by_whitespace = 0;
1497247738Sbapt    int followed_by_whitespace = 0;
1498247738Sbapt    int previous_space = 0;
1499247738Sbapt    int previous_break = 0;
1500247738Sbapt
1501247738Sbapt    STRING_ASSIGN(string, value, length);
1502247738Sbapt
1503247738Sbapt    emitter->scalar_data.value = value;
1504247738Sbapt    emitter->scalar_data.length = length;
1505247738Sbapt
1506247738Sbapt    if (string.start == string.end)
1507247738Sbapt    {
1508247738Sbapt        emitter->scalar_data.multiline = 0;
1509247738Sbapt        emitter->scalar_data.flow_plain_allowed = 0;
1510247738Sbapt        emitter->scalar_data.block_plain_allowed = 1;
1511247738Sbapt        emitter->scalar_data.single_quoted_allowed = 1;
1512247738Sbapt        emitter->scalar_data.block_allowed = 0;
1513247738Sbapt
1514247738Sbapt        return 1;
1515247738Sbapt    }
1516247738Sbapt
1517247738Sbapt    if ((CHECK_AT(string, '-', 0)
1518247738Sbapt                && CHECK_AT(string, '-', 1)
1519247738Sbapt                && CHECK_AT(string, '-', 2))
1520247738Sbapt            || (CHECK_AT(string, '.', 0)
1521247738Sbapt                && CHECK_AT(string, '.', 1)
1522247738Sbapt                && CHECK_AT(string, '.', 2))) {
1523247738Sbapt        block_indicators = 1;
1524247738Sbapt        flow_indicators = 1;
1525247738Sbapt    }
1526247738Sbapt
1527247738Sbapt    preceeded_by_whitespace = 1;
1528247738Sbapt    followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
1529247738Sbapt
1530247738Sbapt    while (string.pointer != string.end)
1531247738Sbapt    {
1532247738Sbapt        if (string.start == string.pointer)
1533247738Sbapt        {
1534247738Sbapt            if (CHECK(string, '#') || CHECK(string, ',')
1535247738Sbapt                    || CHECK(string, '[') || CHECK(string, ']')
1536247738Sbapt                    || CHECK(string, '{') || CHECK(string, '}')
1537247738Sbapt                    || CHECK(string, '&') || CHECK(string, '*')
1538247738Sbapt                    || CHECK(string, '!') || CHECK(string, '|')
1539247738Sbapt                    || CHECK(string, '>') || CHECK(string, '\'')
1540247738Sbapt                    || CHECK(string, '"') || CHECK(string, '%')
1541247738Sbapt                    || CHECK(string, '@') || CHECK(string, '`')) {
1542247738Sbapt                flow_indicators = 1;
1543247738Sbapt                block_indicators = 1;
1544247738Sbapt            }
1545247738Sbapt
1546247738Sbapt            if (CHECK(string, '?') || CHECK(string, ':')) {
1547247738Sbapt                flow_indicators = 1;
1548247738Sbapt                if (followed_by_whitespace) {
1549247738Sbapt                    block_indicators = 1;
1550247738Sbapt                }
1551247738Sbapt            }
1552247738Sbapt
1553247738Sbapt            if (CHECK(string, '-') && followed_by_whitespace) {
1554247738Sbapt                flow_indicators = 1;
1555247738Sbapt                block_indicators = 1;
1556247738Sbapt            }
1557247738Sbapt        }
1558247738Sbapt        else
1559247738Sbapt        {
1560247738Sbapt            if (CHECK(string, ',') || CHECK(string, '?')
1561247738Sbapt                    || CHECK(string, '[') || CHECK(string, ']')
1562247738Sbapt                    || CHECK(string, '{') || CHECK(string, '}')) {
1563247738Sbapt                flow_indicators = 1;
1564247738Sbapt            }
1565247738Sbapt
1566247738Sbapt            if (CHECK(string, ':')) {
1567247738Sbapt                flow_indicators = 1;
1568247738Sbapt                if (followed_by_whitespace) {
1569247738Sbapt                    block_indicators = 1;
1570247738Sbapt                }
1571247738Sbapt            }
1572247738Sbapt
1573247738Sbapt            if (CHECK(string, '#') && preceeded_by_whitespace) {
1574247738Sbapt                flow_indicators = 1;
1575247738Sbapt                block_indicators = 1;
1576247738Sbapt            }
1577247738Sbapt        }
1578247738Sbapt
1579247738Sbapt        if (!IS_PRINTABLE(string)
1580247738Sbapt                || (!IS_ASCII(string) && !emitter->unicode)) {
1581247738Sbapt            special_characters = 1;
1582247738Sbapt        }
1583247738Sbapt
1584247738Sbapt        if (IS_BREAK(string)) {
1585247738Sbapt            line_breaks = 1;
1586247738Sbapt        }
1587247738Sbapt
1588247738Sbapt        if (IS_SPACE(string))
1589247738Sbapt        {
1590247738Sbapt            if (string.start == string.pointer) {
1591247738Sbapt                leading_space = 1;
1592247738Sbapt            }
1593247738Sbapt            if (string.pointer+WIDTH(string) == string.end) {
1594247738Sbapt                trailing_space = 1;
1595247738Sbapt            }
1596247738Sbapt            if (previous_break) {
1597247738Sbapt                break_space = 1;
1598247738Sbapt            }
1599247738Sbapt            previous_space = 1;
1600247738Sbapt            previous_break = 0;
1601247738Sbapt        }
1602247738Sbapt        else if (IS_BREAK(string))
1603247738Sbapt        {
1604247738Sbapt            if (string.start == string.pointer) {
1605247738Sbapt                leading_break = 1;
1606247738Sbapt            }
1607247738Sbapt            if (string.pointer+WIDTH(string) == string.end) {
1608247738Sbapt                trailing_break = 1;
1609247738Sbapt            }
1610247738Sbapt            if (previous_space) {
1611247738Sbapt                space_break = 1;
1612247738Sbapt            }
1613247738Sbapt            previous_space = 0;
1614247738Sbapt            previous_break = 1;
1615247738Sbapt        }
1616247738Sbapt        else
1617247738Sbapt        {
1618247738Sbapt            previous_space = 0;
1619247738Sbapt            previous_break = 0;
1620247738Sbapt        }
1621247738Sbapt
1622247738Sbapt        preceeded_by_whitespace = IS_BLANKZ(string);
1623247738Sbapt        MOVE(string);
1624247738Sbapt        if (string.pointer != string.end) {
1625247738Sbapt            followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
1626247738Sbapt        }
1627247738Sbapt    }
1628247738Sbapt
1629247738Sbapt    emitter->scalar_data.multiline = line_breaks;
1630247738Sbapt
1631247738Sbapt    emitter->scalar_data.flow_plain_allowed = 1;
1632247738Sbapt    emitter->scalar_data.block_plain_allowed = 1;
1633247738Sbapt    emitter->scalar_data.single_quoted_allowed = 1;
1634247738Sbapt    emitter->scalar_data.block_allowed = 1;
1635247738Sbapt
1636247738Sbapt    if (leading_space || leading_break || trailing_space || trailing_break) {
1637247738Sbapt        emitter->scalar_data.flow_plain_allowed = 0;
1638247738Sbapt        emitter->scalar_data.block_plain_allowed = 0;
1639247738Sbapt    }
1640247738Sbapt
1641247738Sbapt    if (trailing_space) {
1642247738Sbapt        emitter->scalar_data.block_allowed = 0;
1643247738Sbapt    }
1644247738Sbapt
1645247738Sbapt    if (break_space) {
1646247738Sbapt        emitter->scalar_data.flow_plain_allowed = 0;
1647247738Sbapt        emitter->scalar_data.block_plain_allowed = 0;
1648247738Sbapt        emitter->scalar_data.single_quoted_allowed = 0;
1649247738Sbapt    }
1650247738Sbapt
1651247738Sbapt    if (space_break || special_characters) {
1652247738Sbapt        emitter->scalar_data.flow_plain_allowed = 0;
1653247738Sbapt        emitter->scalar_data.block_plain_allowed = 0;
1654247738Sbapt        emitter->scalar_data.single_quoted_allowed = 0;
1655247738Sbapt        emitter->scalar_data.block_allowed = 0;
1656247738Sbapt    }
1657247738Sbapt
1658247738Sbapt    if (line_breaks) {
1659247738Sbapt        emitter->scalar_data.flow_plain_allowed = 0;
1660247738Sbapt        emitter->scalar_data.block_plain_allowed = 0;
1661247738Sbapt    }
1662247738Sbapt
1663247738Sbapt    if (flow_indicators) {
1664247738Sbapt        emitter->scalar_data.flow_plain_allowed = 0;
1665247738Sbapt    }
1666247738Sbapt
1667247738Sbapt    if (block_indicators) {
1668247738Sbapt        emitter->scalar_data.block_plain_allowed = 0;
1669247738Sbapt    }
1670247738Sbapt
1671247738Sbapt    return 1;
1672247738Sbapt}
1673247738Sbapt
1674247738Sbapt/*
1675247738Sbapt * Check if the event data is valid.
1676247738Sbapt */
1677247738Sbapt
1678247738Sbaptstatic int
1679247738Sbaptyaml_emitter_analyze_event(yaml_emitter_t *emitter,
1680247738Sbapt        yaml_event_t *event)
1681247738Sbapt{
1682247738Sbapt    emitter->anchor_data.anchor = NULL;
1683247738Sbapt    emitter->anchor_data.anchor_length = 0;
1684247738Sbapt    emitter->tag_data.handle = NULL;
1685247738Sbapt    emitter->tag_data.handle_length = 0;
1686247738Sbapt    emitter->tag_data.suffix = NULL;
1687247738Sbapt    emitter->tag_data.suffix_length = 0;
1688247738Sbapt    emitter->scalar_data.value = NULL;
1689247738Sbapt    emitter->scalar_data.length = 0;
1690247738Sbapt
1691247738Sbapt    switch (event->type)
1692247738Sbapt    {
1693247738Sbapt        case YAML_ALIAS_EVENT:
1694247738Sbapt            if (!yaml_emitter_analyze_anchor(emitter,
1695247738Sbapt                        event->data.alias.anchor, 1))
1696247738Sbapt                return 0;
1697247738Sbapt            return 1;
1698247738Sbapt
1699247738Sbapt        case YAML_SCALAR_EVENT:
1700247738Sbapt            if (event->data.scalar.anchor) {
1701247738Sbapt                if (!yaml_emitter_analyze_anchor(emitter,
1702247738Sbapt                            event->data.scalar.anchor, 0))
1703247738Sbapt                    return 0;
1704247738Sbapt            }
1705247738Sbapt            if (event->data.scalar.tag && (emitter->canonical ||
1706247738Sbapt                        (!event->data.scalar.plain_implicit
1707247738Sbapt                         && !event->data.scalar.quoted_implicit))) {
1708247738Sbapt                if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag))
1709247738Sbapt                    return 0;
1710247738Sbapt            }
1711247738Sbapt            if (!yaml_emitter_analyze_scalar(emitter,
1712247738Sbapt                        event->data.scalar.value, event->data.scalar.length))
1713247738Sbapt                return 0;
1714247738Sbapt            return 1;
1715247738Sbapt
1716247738Sbapt        case YAML_SEQUENCE_START_EVENT:
1717247738Sbapt            if (event->data.sequence_start.anchor) {
1718247738Sbapt                if (!yaml_emitter_analyze_anchor(emitter,
1719247738Sbapt                            event->data.sequence_start.anchor, 0))
1720247738Sbapt                    return 0;
1721247738Sbapt            }
1722247738Sbapt            if (event->data.sequence_start.tag && (emitter->canonical ||
1723247738Sbapt                        !event->data.sequence_start.implicit)) {
1724247738Sbapt                if (!yaml_emitter_analyze_tag(emitter,
1725247738Sbapt                            event->data.sequence_start.tag))
1726247738Sbapt                    return 0;
1727247738Sbapt            }
1728247738Sbapt            return 1;
1729247738Sbapt
1730247738Sbapt        case YAML_MAPPING_START_EVENT:
1731247738Sbapt            if (event->data.mapping_start.anchor) {
1732247738Sbapt                if (!yaml_emitter_analyze_anchor(emitter,
1733247738Sbapt                            event->data.mapping_start.anchor, 0))
1734247738Sbapt                    return 0;
1735247738Sbapt            }
1736247738Sbapt            if (event->data.mapping_start.tag && (emitter->canonical ||
1737247738Sbapt                        !event->data.mapping_start.implicit)) {
1738247738Sbapt                if (!yaml_emitter_analyze_tag(emitter,
1739247738Sbapt                            event->data.mapping_start.tag))
1740247738Sbapt                    return 0;
1741247738Sbapt            }
1742247738Sbapt            return 1;
1743247738Sbapt
1744247738Sbapt        default:
1745247738Sbapt            return 1;
1746247738Sbapt    }
1747247738Sbapt}
1748247738Sbapt
1749247738Sbapt/*
1750247738Sbapt * Write the BOM character.
1751247738Sbapt */
1752247738Sbapt
1753247738Sbaptstatic int
1754247738Sbaptyaml_emitter_write_bom(yaml_emitter_t *emitter)
1755247738Sbapt{
1756247738Sbapt    if (!FLUSH(emitter)) return 0;
1757247738Sbapt
1758247738Sbapt    *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF';
1759247738Sbapt    *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB';
1760247738Sbapt    *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF';
1761247738Sbapt
1762247738Sbapt    return 1;
1763247738Sbapt}
1764247738Sbapt
1765247738Sbaptstatic int
1766247738Sbaptyaml_emitter_write_indent(yaml_emitter_t *emitter)
1767247738Sbapt{
1768247738Sbapt    int indent = (emitter->indent >= 0) ? emitter->indent : 0;
1769247738Sbapt
1770247738Sbapt    if (!emitter->indention || emitter->column > indent
1771247738Sbapt            || (emitter->column == indent && !emitter->whitespace)) {
1772247738Sbapt        if (!PUT_BREAK(emitter)) return 0;
1773247738Sbapt    }
1774247738Sbapt
1775247738Sbapt    while (emitter->column < indent) {
1776247738Sbapt        if (!PUT(emitter, ' ')) return 0;
1777247738Sbapt    }
1778247738Sbapt
1779247738Sbapt    emitter->whitespace = 1;
1780247738Sbapt    emitter->indention = 1;
1781247738Sbapt
1782247738Sbapt    return 1;
1783247738Sbapt}
1784247738Sbapt
1785247738Sbaptstatic int
1786247738Sbaptyaml_emitter_write_indicator(yaml_emitter_t *emitter,
1787247738Sbapt        char *indicator, int need_whitespace,
1788247738Sbapt        int is_whitespace, int is_indention)
1789247738Sbapt{
1790247738Sbapt    size_t indicator_length;
1791247738Sbapt    yaml_string_t string;
1792247738Sbapt
1793247738Sbapt    indicator_length = strlen(indicator);
1794247738Sbapt    STRING_ASSIGN(string, (yaml_char_t *)indicator, indicator_length);
1795247738Sbapt
1796247738Sbapt    if (need_whitespace && !emitter->whitespace) {
1797247738Sbapt        if (!PUT(emitter, ' ')) return 0;
1798247738Sbapt    }
1799247738Sbapt
1800247738Sbapt    while (string.pointer != string.end) {
1801247738Sbapt        if (!WRITE(emitter, string)) return 0;
1802247738Sbapt    }
1803247738Sbapt
1804247738Sbapt    emitter->whitespace = is_whitespace;
1805247738Sbapt    emitter->indention = (emitter->indention && is_indention);
1806247738Sbapt    emitter->open_ended = 0;
1807247738Sbapt
1808247738Sbapt    return 1;
1809247738Sbapt}
1810247738Sbapt
1811247738Sbaptstatic int
1812247738Sbaptyaml_emitter_write_anchor(yaml_emitter_t *emitter,
1813247738Sbapt        yaml_char_t *value, size_t length)
1814247738Sbapt{
1815247738Sbapt    yaml_string_t string;
1816247738Sbapt    STRING_ASSIGN(string, value, length);
1817247738Sbapt
1818247738Sbapt    while (string.pointer != string.end) {
1819247738Sbapt        if (!WRITE(emitter, string)) return 0;
1820247738Sbapt    }
1821247738Sbapt
1822247738Sbapt    emitter->whitespace = 0;
1823247738Sbapt    emitter->indention = 0;
1824247738Sbapt
1825247738Sbapt    return 1;
1826247738Sbapt}
1827247738Sbapt
1828247738Sbaptstatic int
1829247738Sbaptyaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
1830247738Sbapt        yaml_char_t *value, size_t length)
1831247738Sbapt{
1832247738Sbapt    yaml_string_t string;
1833247738Sbapt    STRING_ASSIGN(string, value, length);
1834247738Sbapt
1835247738Sbapt    if (!emitter->whitespace) {
1836247738Sbapt        if (!PUT(emitter, ' ')) return 0;
1837247738Sbapt    }
1838247738Sbapt
1839247738Sbapt    while (string.pointer != string.end) {
1840247738Sbapt        if (!WRITE(emitter, string)) return 0;
1841247738Sbapt    }
1842247738Sbapt
1843247738Sbapt    emitter->whitespace = 0;
1844247738Sbapt    emitter->indention = 0;
1845247738Sbapt
1846247738Sbapt    return 1;
1847247738Sbapt}
1848247738Sbapt
1849247738Sbaptstatic int
1850247738Sbaptyaml_emitter_write_tag_content(yaml_emitter_t *emitter,
1851247738Sbapt        yaml_char_t *value, size_t length,
1852247738Sbapt        int need_whitespace)
1853247738Sbapt{
1854247738Sbapt    yaml_string_t string;
1855247738Sbapt    STRING_ASSIGN(string, value, length);
1856247738Sbapt
1857247738Sbapt    if (need_whitespace && !emitter->whitespace) {
1858247738Sbapt        if (!PUT(emitter, ' ')) return 0;
1859247738Sbapt    }
1860247738Sbapt
1861247738Sbapt    while (string.pointer != string.end) {
1862247738Sbapt        if (IS_ALPHA(string)
1863247738Sbapt                || CHECK(string, ';') || CHECK(string, '/')
1864247738Sbapt                || CHECK(string, '?') || CHECK(string, ':')
1865247738Sbapt                || CHECK(string, '@') || CHECK(string, '&')
1866247738Sbapt                || CHECK(string, '=') || CHECK(string, '+')
1867247738Sbapt                || CHECK(string, '$') || CHECK(string, ',')
1868247738Sbapt                || CHECK(string, '_') || CHECK(string, '.')
1869247738Sbapt                || CHECK(string, '~') || CHECK(string, '*')
1870247738Sbapt                || CHECK(string, '\'') || CHECK(string, '(')
1871247738Sbapt                || CHECK(string, ')') || CHECK(string, '[')
1872247738Sbapt                || CHECK(string, ']')) {
1873247738Sbapt            if (!WRITE(emitter, string)) return 0;
1874247738Sbapt        }
1875247738Sbapt        else {
1876247738Sbapt            int width = WIDTH(string);
1877247738Sbapt            unsigned int value;
1878247738Sbapt            while (width --) {
1879247738Sbapt                value = *(string.pointer++);
1880247738Sbapt                if (!PUT(emitter, '%')) return 0;
1881247738Sbapt                if (!PUT(emitter, (value >> 4)
1882247738Sbapt                            + ((value >> 4) < 10 ? '0' : 'A' - 10)))
1883247738Sbapt                    return 0;
1884247738Sbapt                if (!PUT(emitter, (value & 0x0F)
1885247738Sbapt                            + ((value & 0x0F) < 10 ? '0' : 'A' - 10)))
1886247738Sbapt                    return 0;
1887247738Sbapt            }
1888247738Sbapt        }
1889247738Sbapt    }
1890247738Sbapt
1891247738Sbapt    emitter->whitespace = 0;
1892247738Sbapt    emitter->indention = 0;
1893247738Sbapt
1894247738Sbapt    return 1;
1895247738Sbapt}
1896247738Sbapt
1897247738Sbaptstatic int
1898247738Sbaptyaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
1899247738Sbapt        yaml_char_t *value, size_t length, int allow_breaks)
1900247738Sbapt{
1901247738Sbapt    yaml_string_t string;
1902247738Sbapt    int spaces = 0;
1903247738Sbapt    int breaks = 0;
1904247738Sbapt
1905247738Sbapt    STRING_ASSIGN(string, value, length);
1906247738Sbapt
1907247738Sbapt    if (!emitter->whitespace) {
1908247738Sbapt        if (!PUT(emitter, ' ')) return 0;
1909247738Sbapt    }
1910247738Sbapt
1911247738Sbapt    while (string.pointer != string.end)
1912247738Sbapt    {
1913247738Sbapt        if (IS_SPACE(string))
1914247738Sbapt        {
1915247738Sbapt            if (allow_breaks && !spaces
1916247738Sbapt                    && emitter->column > emitter->best_width
1917247738Sbapt                    && !IS_SPACE_AT(string, 1)) {
1918247738Sbapt                if (!yaml_emitter_write_indent(emitter)) return 0;
1919247738Sbapt                MOVE(string);
1920247738Sbapt            }
1921247738Sbapt            else {
1922247738Sbapt                if (!WRITE(emitter, string)) return 0;
1923247738Sbapt            }
1924247738Sbapt            spaces = 1;
1925247738Sbapt        }
1926247738Sbapt        else if (IS_BREAK(string))
1927247738Sbapt        {
1928247738Sbapt            if (!breaks && CHECK(string, '\n')) {
1929247738Sbapt                if (!PUT_BREAK(emitter)) return 0;
1930247738Sbapt            }
1931247738Sbapt            if (!WRITE_BREAK(emitter, string)) return 0;
1932247738Sbapt            emitter->indention = 1;
1933247738Sbapt            breaks = 1;
1934247738Sbapt        }
1935247738Sbapt        else
1936247738Sbapt        {
1937247738Sbapt            if (breaks) {
1938247738Sbapt                if (!yaml_emitter_write_indent(emitter)) return 0;
1939247738Sbapt            }
1940247738Sbapt            if (!WRITE(emitter, string)) return 0;
1941247738Sbapt            emitter->indention = 0;
1942247738Sbapt            spaces = 0;
1943247738Sbapt            breaks = 0;
1944247738Sbapt        }
1945247738Sbapt    }
1946247738Sbapt
1947247738Sbapt    emitter->whitespace = 0;
1948247738Sbapt    emitter->indention = 0;
1949247738Sbapt    if (emitter->root_context)
1950247738Sbapt    {
1951247738Sbapt        emitter->open_ended = 1;
1952247738Sbapt    }
1953247738Sbapt
1954247738Sbapt    return 1;
1955247738Sbapt}
1956247738Sbapt
1957247738Sbaptstatic int
1958247738Sbaptyaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
1959247738Sbapt        yaml_char_t *value, size_t length, int allow_breaks)
1960247738Sbapt{
1961247738Sbapt    yaml_string_t string;
1962247738Sbapt    int spaces = 0;
1963247738Sbapt    int breaks = 0;
1964247738Sbapt
1965247738Sbapt    STRING_ASSIGN(string, value, length);
1966247738Sbapt
1967247738Sbapt    if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0))
1968247738Sbapt        return 0;
1969247738Sbapt
1970247738Sbapt    while (string.pointer != string.end)
1971247738Sbapt    {
1972247738Sbapt        if (IS_SPACE(string))
1973247738Sbapt        {
1974247738Sbapt            if (allow_breaks && !spaces
1975247738Sbapt                    && emitter->column > emitter->best_width
1976247738Sbapt                    && string.pointer != string.start
1977247738Sbapt                    && string.pointer != string.end - 1
1978247738Sbapt                    && !IS_SPACE_AT(string, 1)) {
1979247738Sbapt                if (!yaml_emitter_write_indent(emitter)) return 0;
1980247738Sbapt                MOVE(string);
1981247738Sbapt            }
1982247738Sbapt            else {
1983247738Sbapt                if (!WRITE(emitter, string)) return 0;
1984247738Sbapt            }
1985247738Sbapt            spaces = 1;
1986247738Sbapt        }
1987247738Sbapt        else if (IS_BREAK(string))
1988247738Sbapt        {
1989247738Sbapt            if (!breaks && CHECK(string, '\n')) {
1990247738Sbapt                if (!PUT_BREAK(emitter)) return 0;
1991247738Sbapt            }
1992247738Sbapt            if (!WRITE_BREAK(emitter, string)) return 0;
1993247738Sbapt            emitter->indention = 1;
1994247738Sbapt            breaks = 1;
1995247738Sbapt        }
1996247738Sbapt        else
1997247738Sbapt        {
1998247738Sbapt            if (breaks) {
1999247738Sbapt                if (!yaml_emitter_write_indent(emitter)) return 0;
2000247738Sbapt            }
2001247738Sbapt            if (CHECK(string, '\'')) {
2002247738Sbapt                if (!PUT(emitter, '\'')) return 0;
2003247738Sbapt            }
2004247738Sbapt            if (!WRITE(emitter, string)) return 0;
2005247738Sbapt            emitter->indention = 0;
2006247738Sbapt            spaces = 0;
2007247738Sbapt            breaks = 0;
2008247738Sbapt        }
2009247738Sbapt    }
2010247738Sbapt
2011247738Sbapt    if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0))
2012247738Sbapt        return 0;
2013247738Sbapt
2014247738Sbapt    emitter->whitespace = 0;
2015247738Sbapt    emitter->indention = 0;
2016247738Sbapt
2017247738Sbapt    return 1;
2018247738Sbapt}
2019247738Sbapt
2020247738Sbaptstatic int
2021247738Sbaptyaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
2022247738Sbapt        yaml_char_t *value, size_t length, int allow_breaks)
2023247738Sbapt{
2024247738Sbapt    yaml_string_t string;
2025247738Sbapt    int spaces = 0;
2026247738Sbapt
2027247738Sbapt    STRING_ASSIGN(string, value, length);
2028247738Sbapt
2029247738Sbapt    if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0))
2030247738Sbapt        return 0;
2031247738Sbapt
2032247738Sbapt    while (string.pointer != string.end)
2033247738Sbapt    {
2034247738Sbapt        if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string))
2035247738Sbapt                || IS_BOM(string) || IS_BREAK(string)
2036247738Sbapt                || CHECK(string, '"') || CHECK(string, '\\'))
2037247738Sbapt        {
2038247738Sbapt            unsigned char octet;
2039247738Sbapt            unsigned int width;
2040247738Sbapt            unsigned int value;
2041247738Sbapt            int k;
2042247738Sbapt
2043247738Sbapt            octet = string.pointer[0];
2044247738Sbapt            width = (octet & 0x80) == 0x00 ? 1 :
2045247738Sbapt                    (octet & 0xE0) == 0xC0 ? 2 :
2046247738Sbapt                    (octet & 0xF0) == 0xE0 ? 3 :
2047247738Sbapt                    (octet & 0xF8) == 0xF0 ? 4 : 0;
2048247738Sbapt            value = (octet & 0x80) == 0x00 ? octet & 0x7F :
2049247738Sbapt                    (octet & 0xE0) == 0xC0 ? octet & 0x1F :
2050247738Sbapt                    (octet & 0xF0) == 0xE0 ? octet & 0x0F :
2051247738Sbapt                    (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
2052247738Sbapt            for (k = 1; k < (int)width; k ++) {
2053247738Sbapt                octet = string.pointer[k];
2054247738Sbapt                value = (value << 6) + (octet & 0x3F);
2055247738Sbapt            }
2056247738Sbapt            string.pointer += width;
2057247738Sbapt
2058247738Sbapt            if (!PUT(emitter, '\\')) return 0;
2059247738Sbapt
2060247738Sbapt            switch (value)
2061247738Sbapt            {
2062247738Sbapt                case 0x00:
2063247738Sbapt                    if (!PUT(emitter, '0')) return 0;
2064247738Sbapt                    break;
2065247738Sbapt
2066247738Sbapt                case 0x07:
2067247738Sbapt                    if (!PUT(emitter, 'a')) return 0;
2068247738Sbapt                    break;
2069247738Sbapt
2070247738Sbapt                case 0x08:
2071247738Sbapt                    if (!PUT(emitter, 'b')) return 0;
2072247738Sbapt                    break;
2073247738Sbapt
2074247738Sbapt                case 0x09:
2075247738Sbapt                    if (!PUT(emitter, 't')) return 0;
2076247738Sbapt                    break;
2077247738Sbapt
2078247738Sbapt                case 0x0A:
2079247738Sbapt                    if (!PUT(emitter, 'n')) return 0;
2080247738Sbapt                    break;
2081247738Sbapt
2082247738Sbapt                case 0x0B:
2083247738Sbapt                    if (!PUT(emitter, 'v')) return 0;
2084247738Sbapt                    break;
2085247738Sbapt
2086247738Sbapt                case 0x0C:
2087247738Sbapt                    if (!PUT(emitter, 'f')) return 0;
2088247738Sbapt                    break;
2089247738Sbapt
2090247738Sbapt                case 0x0D:
2091247738Sbapt                    if (!PUT(emitter, 'r')) return 0;
2092247738Sbapt                    break;
2093247738Sbapt
2094247738Sbapt                case 0x1B:
2095247738Sbapt                    if (!PUT(emitter, 'e')) return 0;
2096247738Sbapt                    break;
2097247738Sbapt
2098247738Sbapt                case 0x22:
2099247738Sbapt                    if (!PUT(emitter, '\"')) return 0;
2100247738Sbapt                    break;
2101247738Sbapt
2102247738Sbapt                case 0x5C:
2103247738Sbapt                    if (!PUT(emitter, '\\')) return 0;
2104247738Sbapt                    break;
2105247738Sbapt
2106247738Sbapt                case 0x85:
2107247738Sbapt                    if (!PUT(emitter, 'N')) return 0;
2108247738Sbapt                    break;
2109247738Sbapt
2110247738Sbapt                case 0xA0:
2111247738Sbapt                    if (!PUT(emitter, '_')) return 0;
2112247738Sbapt                    break;
2113247738Sbapt
2114247738Sbapt                case 0x2028:
2115247738Sbapt                    if (!PUT(emitter, 'L')) return 0;
2116247738Sbapt                    break;
2117247738Sbapt
2118247738Sbapt                case 0x2029:
2119247738Sbapt                    if (!PUT(emitter, 'P')) return 0;
2120247738Sbapt                    break;
2121247738Sbapt
2122247738Sbapt                default:
2123247738Sbapt                    if (value <= 0xFF) {
2124247738Sbapt                        if (!PUT(emitter, 'x')) return 0;
2125247738Sbapt                        width = 2;
2126247738Sbapt                    }
2127247738Sbapt                    else if (value <= 0xFFFF) {
2128247738Sbapt                        if (!PUT(emitter, 'u')) return 0;
2129247738Sbapt                        width = 4;
2130247738Sbapt                    }
2131247738Sbapt                    else {
2132247738Sbapt                        if (!PUT(emitter, 'U')) return 0;
2133247738Sbapt                        width = 8;
2134247738Sbapt                    }
2135247738Sbapt                    for (k = (width-1)*4; k >= 0; k -= 4) {
2136247738Sbapt                        int digit = (value >> k) & 0x0F;
2137247738Sbapt                        if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10)))
2138247738Sbapt                            return 0;
2139247738Sbapt                    }
2140247738Sbapt            }
2141247738Sbapt            spaces = 0;
2142247738Sbapt        }
2143247738Sbapt        else if (IS_SPACE(string))
2144247738Sbapt        {
2145247738Sbapt            if (allow_breaks && !spaces
2146247738Sbapt                    && emitter->column > emitter->best_width
2147247738Sbapt                    && string.pointer != string.start
2148247738Sbapt                    && string.pointer != string.end - 1) {
2149247738Sbapt                if (!yaml_emitter_write_indent(emitter)) return 0;
2150247738Sbapt                if (IS_SPACE_AT(string, 1)) {
2151247738Sbapt                    if (!PUT(emitter, '\\')) return 0;
2152247738Sbapt                }
2153247738Sbapt                MOVE(string);
2154247738Sbapt            }
2155247738Sbapt            else {
2156247738Sbapt                if (!WRITE(emitter, string)) return 0;
2157247738Sbapt            }
2158247738Sbapt            spaces = 1;
2159247738Sbapt        }
2160247738Sbapt        else
2161247738Sbapt        {
2162247738Sbapt            if (!WRITE(emitter, string)) return 0;
2163247738Sbapt            spaces = 0;
2164247738Sbapt        }
2165247738Sbapt    }
2166247738Sbapt
2167247738Sbapt    if (!yaml_emitter_write_indicator(emitter, "\"", 0, 0, 0))
2168247738Sbapt        return 0;
2169247738Sbapt
2170247738Sbapt    emitter->whitespace = 0;
2171247738Sbapt    emitter->indention = 0;
2172247738Sbapt
2173247738Sbapt    return 1;
2174247738Sbapt}
2175247738Sbapt
2176247738Sbaptstatic int
2177247738Sbaptyaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
2178247738Sbapt        yaml_string_t string)
2179247738Sbapt{
2180247738Sbapt    char indent_hint[2];
2181247738Sbapt    char *chomp_hint = NULL;
2182247738Sbapt
2183247738Sbapt    if (IS_SPACE(string) || IS_BREAK(string))
2184247738Sbapt    {
2185247738Sbapt        indent_hint[0] = '0' + (char)emitter->best_indent;
2186247738Sbapt        indent_hint[1] = '\0';
2187247738Sbapt        if (!yaml_emitter_write_indicator(emitter, indent_hint, 0, 0, 0))
2188247738Sbapt            return 0;
2189247738Sbapt    }
2190247738Sbapt
2191247738Sbapt    emitter->open_ended = 0;
2192247738Sbapt
2193247738Sbapt    string.pointer = string.end;
2194247738Sbapt    if (string.start == string.pointer)
2195247738Sbapt    {
2196247738Sbapt        chomp_hint = "-";
2197247738Sbapt    }
2198247738Sbapt    else
2199247738Sbapt    {
2200247738Sbapt        do {
2201247738Sbapt            string.pointer --;
2202247738Sbapt        } while ((*string.pointer & 0xC0) == 0x80);
2203247738Sbapt        if (!IS_BREAK(string))
2204247738Sbapt        {
2205247738Sbapt            chomp_hint = "-";
2206247738Sbapt        }
2207247738Sbapt        else if (string.start == string.pointer)
2208247738Sbapt        {
2209247738Sbapt            chomp_hint = "+";
2210247738Sbapt            emitter->open_ended = 1;
2211247738Sbapt        }
2212247738Sbapt        else
2213247738Sbapt        {
2214247738Sbapt            do {
2215247738Sbapt                string.pointer --;
2216247738Sbapt            } while ((*string.pointer & 0xC0) == 0x80);
2217247738Sbapt            if (IS_BREAK(string))
2218247738Sbapt            {
2219247738Sbapt                chomp_hint = "+";
2220247738Sbapt                emitter->open_ended = 1;
2221247738Sbapt            }
2222247738Sbapt        }
2223247738Sbapt    }
2224247738Sbapt
2225247738Sbapt    if (chomp_hint)
2226247738Sbapt    {
2227247738Sbapt        if (!yaml_emitter_write_indicator(emitter, chomp_hint, 0, 0, 0))
2228247738Sbapt            return 0;
2229247738Sbapt    }
2230247738Sbapt
2231247738Sbapt    return 1;
2232247738Sbapt}
2233247738Sbapt
2234247738Sbaptstatic int
2235247738Sbaptyaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
2236247738Sbapt        yaml_char_t *value, size_t length)
2237247738Sbapt{
2238247738Sbapt    yaml_string_t string;
2239247738Sbapt    int breaks = 1;
2240247738Sbapt
2241247738Sbapt    STRING_ASSIGN(string, value, length);
2242247738Sbapt
2243247738Sbapt    if (!yaml_emitter_write_indicator(emitter, "|", 1, 0, 0))
2244247738Sbapt        return 0;
2245247738Sbapt    if (!yaml_emitter_write_block_scalar_hints(emitter, string))
2246247738Sbapt        return 0;
2247247738Sbapt    if (!PUT_BREAK(emitter)) return 0;
2248247738Sbapt    emitter->indention = 1;
2249247738Sbapt    emitter->whitespace = 1;
2250247738Sbapt
2251247738Sbapt    while (string.pointer != string.end)
2252247738Sbapt    {
2253247738Sbapt        if (IS_BREAK(string))
2254247738Sbapt        {
2255247738Sbapt            if (!WRITE_BREAK(emitter, string)) return 0;
2256247738Sbapt            emitter->indention = 1;
2257247738Sbapt            breaks = 1;
2258247738Sbapt        }
2259247738Sbapt        else
2260247738Sbapt        {
2261247738Sbapt            if (breaks) {
2262247738Sbapt                if (!yaml_emitter_write_indent(emitter)) return 0;
2263247738Sbapt            }
2264247738Sbapt            if (!WRITE(emitter, string)) return 0;
2265247738Sbapt            emitter->indention = 0;
2266247738Sbapt            breaks = 0;
2267247738Sbapt        }
2268247738Sbapt    }
2269247738Sbapt
2270247738Sbapt    return 1;
2271247738Sbapt}
2272247738Sbapt
2273247738Sbaptstatic int
2274247738Sbaptyaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
2275247738Sbapt        yaml_char_t *value, size_t length)
2276247738Sbapt{
2277247738Sbapt    yaml_string_t string;
2278247738Sbapt    int breaks = 1;
2279247738Sbapt    int leading_spaces = 1;
2280247738Sbapt
2281247738Sbapt    STRING_ASSIGN(string, value, length);
2282247738Sbapt
2283247738Sbapt    if (!yaml_emitter_write_indicator(emitter, ">", 1, 0, 0))
2284247738Sbapt        return 0;
2285247738Sbapt    if (!yaml_emitter_write_block_scalar_hints(emitter, string))
2286247738Sbapt        return 0;
2287247738Sbapt    if (!PUT_BREAK(emitter)) return 0;
2288247738Sbapt    emitter->indention = 1;
2289247738Sbapt    emitter->whitespace = 1;
2290247738Sbapt
2291247738Sbapt    while (string.pointer != string.end)
2292247738Sbapt    {
2293247738Sbapt        if (IS_BREAK(string))
2294247738Sbapt        {
2295247738Sbapt            if (!breaks && !leading_spaces && CHECK(string, '\n')) {
2296247738Sbapt                int k = 0;
2297247738Sbapt                while (IS_BREAK_AT(string, k)) {
2298247738Sbapt                    k += WIDTH_AT(string, k);
2299247738Sbapt                }
2300247738Sbapt                if (!IS_BLANKZ_AT(string, k)) {
2301247738Sbapt                    if (!PUT_BREAK(emitter)) return 0;
2302247738Sbapt                }
2303247738Sbapt            }
2304247738Sbapt            if (!WRITE_BREAK(emitter, string)) return 0;
2305247738Sbapt            emitter->indention = 1;
2306247738Sbapt            breaks = 1;
2307247738Sbapt        }
2308247738Sbapt        else
2309247738Sbapt        {
2310247738Sbapt            if (breaks) {
2311247738Sbapt                if (!yaml_emitter_write_indent(emitter)) return 0;
2312247738Sbapt                leading_spaces = IS_BLANK(string);
2313247738Sbapt            }
2314247738Sbapt            if (!breaks && IS_SPACE(string) && !IS_SPACE_AT(string, 1)
2315247738Sbapt                    && emitter->column > emitter->best_width) {
2316247738Sbapt                if (!yaml_emitter_write_indent(emitter)) return 0;
2317247738Sbapt                MOVE(string);
2318247738Sbapt            }
2319247738Sbapt            else {
2320247738Sbapt                if (!WRITE(emitter, string)) return 0;
2321247738Sbapt            }
2322247738Sbapt            emitter->indention = 0;
2323247738Sbapt            breaks = 0;
2324247738Sbapt        }
2325247738Sbapt    }
2326247738Sbapt
2327247738Sbapt    return 1;
2328247738Sbapt}
2329247738Sbapt
2330