#define PUT(emitter,value) \
(FLUSH(emitter) \
&& (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \
- emitter->column ++, \
+ emitter->column++, \
1))
/*
#define WRITE_BREAK(emitter,string) \
(FLUSH(emitter) \
- && (COPY(emitter->buffer,string), \
- emitter->column = 0, \
- emitter->line ++, \
- 1))
+ && (CHECK(string,'\n') ? \
+ (PUT_BREAK(emitter), \
+ string.pointer ++, \
+ 1) : \
+ (COPY(emitter->buffer,string), \
+ emitter->column = 0, \
+ emitter->line ++, \
+ 1)))
/*
* API functions.
static int
yaml_emitter_write_indicator(yaml_emitter_t *emitter,
- char *indicator, int need_whitespace,
+ const char *indicator, int need_whitespace,
int is_whitespace, int is_indention);
static int
static int
yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
- yaml_char_t *value, size_t length);
+ yaml_char_t *value, size_t length, int need_whitespace);
static int
yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
yaml_char_t *value, size_t length, int allow_breaks);
+static int
+yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
+ yaml_string_t string);
+
static int
yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
yaml_char_t *value, size_t length);
return 0;
if (!yaml_emitter_state_machine(emitter, emitter->events.head))
return 0;
- DEQUEUE(emitter, emitter->events);
+ yaml_event_delete(&DEQUEUE(emitter, emitter->events));
}
return 1;
if (emitter->best_width < 0) {
emitter->best_width = INT_MAX;
}
-
+
if (!emitter->line_break) {
emitter->line_break = YAML_LN_BREAK;
}
implicit = 0;
}
+ if ((event->data.document_start.version_directive ||
+ (event->data.document_start.tag_directives.start
+ != event->data.document_start.tag_directives.end)) &&
+ emitter->open_ended)
+ {
+ if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_indent(emitter))
+ return 0;
+ }
+
if (event->data.document_start.version_directive) {
implicit = 0;
if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0))
if (!yaml_emitter_write_indent(emitter))
return 0;
}
-
+
if (event->data.document_start.tag_directives.start
!= event->data.document_start.tag_directives.end) {
implicit = 0;
strlen((char *)tag_directive->handle)))
return 0;
if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix,
- strlen((char *)tag_directive->prefix)))
+ strlen((char *)tag_directive->prefix), 1))
return 0;
if (!yaml_emitter_write_indent(emitter))
return 0;
else if (event->type == YAML_STREAM_END_EVENT)
{
+
if (!yaml_emitter_flush(emitter))
return 0;
emitter->state = YAML_EMIT_DOCUMENT_START_STATE;
+ while (!STACK_EMPTY(emitter, emitter->tag_directives)) {
+ yaml_tag_directive_t tag_directive = POP(emitter,
+ emitter->tag_directives);
+ yaml_free(tag_directive.handle);
+ yaml_free(tag_directive.prefix);
+ }
+
return 1;
}
}
/*
+ *
* Expect a flow item node.
*/
return 1;
}
+ if (!first) {
+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
+ return 0;
+ }
+
if (emitter->canonical || emitter->column > emitter->best_width) {
if (!yaml_emitter_write_indent(emitter))
return 0;
}
- if (PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE))
+ if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE))
return 0;
return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
*/
static int
-yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event)
+yaml_emitter_emit_alias(yaml_emitter_t *emitter, SHIM(yaml_event_t *event))
{
if (!yaml_emitter_process_anchor(emitter))
return 0;
*/
static int
-yaml_emitter_check_empty_document(yaml_emitter_t *emitter)
+yaml_emitter_check_empty_document(SHIM(yaml_emitter_t *emitter))
{
return 0;
}
break;
case YAML_MAPPING_START_EVENT:
- if (!yaml_emitter_check_empty_sequence(emitter))
+ if (!yaml_emitter_check_empty_mapping(emitter))
return 0;
length += emitter->anchor_data.anchor_length
+ emitter->tag_data.handle_length
yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event)
{
yaml_scalar_style_t style = event->data.scalar.style;
+ int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix);
+
+ if (no_tag && !event->data.scalar.plain_implicit
+ && !event->data.scalar.quoted_implicit) {
+ return yaml_emitter_set_emitter_error(emitter,
+ "neither tag nor implicit flags are specified");
+ }
if (style == YAML_ANY_SCALAR_STYLE)
style = YAML_PLAIN_SCALAR_STYLE;
if (!emitter->scalar_data.length
&& (emitter->flow_level || emitter->simple_key_context))
style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
- if (!event->data.scalar.plain_implicit
- && !emitter->tag_data.handle && !emitter->tag_data.suffix)
+ if (no_tag && !event->data.scalar.plain_implicit)
style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
}
if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE)
{
- if (!emitter->scalar_data.block_allowed)
+ if (!emitter->scalar_data.block_allowed
+ || emitter->flow_level || emitter->simple_key_context)
style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
}
- if (!emitter->tag_data.handle && !emitter->tag_data.suffix)
+ if (no_tag && !event->data.scalar.quoted_implicit
+ && style != YAML_PLAIN_SCALAR_STYLE)
{
- if (!event->data.scalar.plain_implicit
- && !event->data.scalar.quoted_implicit) {
- return yaml_emitter_set_emitter_error(emitter,
- "neither tag nor implicit flags are specified");
- }
-
- if (event->data.scalar.plain_implicit
- && style != YAML_PLAIN_SCALAR_STYLE) {
- emitter->tag_data.handle = (yaml_char_t *)"!";
- emitter->tag_data.handle_length = 1;
- }
+ emitter->tag_data.handle = (yaml_char_t *)"!";
+ emitter->tag_data.handle_length = 1;
}
emitter->scalar_data.style = style;
return 0;
if (emitter->tag_data.suffix) {
if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
- emitter->tag_data.suffix_length))
+ emitter->tag_data.suffix_length, 0))
return 0;
}
}
if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0))
return 0;
if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
- emitter->tag_data.suffix_length))
+ emitter->tag_data.suffix_length, 0))
return 0;
if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0))
return 0;
yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
yaml_tag_directive_t tag_directive)
{
- yaml_string_t handle = STRING(tag_directive.handle,
- strlen((char *)tag_directive.handle));
- yaml_string_t prefix = STRING(tag_directive.prefix,
- strlen((char *)tag_directive.prefix));
+ yaml_string_t handle;
+ yaml_string_t prefix;
+ size_t handle_length;
+ size_t prefix_length;
+
+ handle_length = strlen((char *)tag_directive.handle);
+ prefix_length = strlen((char *)tag_directive.prefix);
+ STRING_ASSIGN(handle, tag_directive.handle, handle_length);
+ STRING_ASSIGN(prefix, tag_directive.prefix, prefix_length);
if (handle.start == handle.end) {
return yaml_emitter_set_emitter_error(emitter,
handle.pointer ++;
- while (handle.pointer != handle.end-1) {
+ while (handle.pointer < handle.end-1) {
if (!IS_ALPHA(handle)) {
return yaml_emitter_set_emitter_error(emitter,
"tag handle must contain alphanumerical characters only");
yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
yaml_char_t *anchor, int alias)
{
- yaml_string_t string = STRING(anchor, strlen((char *)anchor));
+ size_t anchor_length;
+ yaml_string_t string;
+
+ anchor_length = strlen((char *)anchor);
+ STRING_ASSIGN(string, anchor, anchor_length);
if (string.start == string.end) {
return yaml_emitter_set_emitter_error(emitter, alias ?
}
MOVE(string);
}
+
+ emitter->anchor_data.anchor = string.start;
+ emitter->anchor_data.anchor_length = string.end - string.start;
+ emitter->anchor_data.alias = alias;
+
+ return 1;
}
/*
yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
yaml_char_t *tag)
{
- yaml_string_t string = STRING(tag, strlen((char *)tag));
+ size_t tag_length;
+ yaml_string_t string;
yaml_tag_directive_t *tag_directive;
+ tag_length = strlen((char *)tag);
+ STRING_ASSIGN(string, tag, tag_length);
+
if (string.start == string.end) {
return yaml_emitter_set_emitter_error(emitter,
"tag value must not be empty");
}
for (tag_directive = emitter->tag_directives.start;
- tag_directive != emitter->tag_directives.end; tag_directive ++) {
+ tag_directive != emitter->tag_directives.top; tag_directive ++) {
size_t prefix_length = strlen((char *)tag_directive->prefix);
- if (prefix_length < (string.end - string.start)
+ if (prefix_length < (size_t)(string.end - string.start)
&& strncmp((char *)tag_directive->prefix, (char *)string.start,
prefix_length) == 0)
{
yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
yaml_char_t *value, size_t length)
{
- yaml_string_t string = STRING(value, length);
+ yaml_string_t string;
int block_indicators = 0;
int flow_indicators = 0;
int line_breaks = 0;
int special_characters = 0;
- int inline_spaces = 0;
- int inline_breaks = 0;
- int leading_spaces = 0;
- int leading_breaks = 0;
- int trailing_spaces = 0;
- int trailing_breaks = 0;
- int inline_breaks_spaces = 0;
- int mixed_breaks_spaces = 0;
-
- int preceeded_by_space = 0;
- int followed_by_space = 0;
- int spaces = 0;
- int breaks = 0;
- int mixed = 0;
- int leading = 0;
+ int leading_space = 0;
+ int leading_break = 0;
+ int trailing_space = 0;
+ int trailing_break = 0;
+ int break_space = 0;
+ int space_break = 0;
+
+ int preceded_by_whitespace = 0;
+ int followed_by_whitespace = 0;
+ int previous_space = 0;
+ int previous_break = 0;
+
+ STRING_ASSIGN(string, value, length);
emitter->scalar_data.value = value;
emitter->scalar_data.length = length;
flow_indicators = 1;
}
- preceeded_by_space = 1;
- followed_by_space = IS_BLANKZ_AT(string, WIDTH(string));
+ preceded_by_whitespace = 1;
+ followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
while (string.pointer != string.end)
{
if (CHECK(string, '?') || CHECK(string, ':')) {
flow_indicators = 1;
- if (followed_by_space) {
+ if (followed_by_whitespace) {
block_indicators = 1;
}
}
- if (CHECK(string, '-') && followed_by_space) {
+ if (CHECK(string, '-') && followed_by_whitespace) {
flow_indicators = 1;
block_indicators = 1;
}
if (CHECK(string, ':')) {
flow_indicators = 1;
- if (followed_by_space) {
+ if (followed_by_whitespace) {
block_indicators = 1;
}
}
- if (CHECK(string, '#') && preceeded_by_space) {
+ if (CHECK(string, '#') && preceded_by_whitespace) {
flow_indicators = 1;
block_indicators = 1;
}
if (IS_SPACE(string))
{
- spaces = 1;
if (string.start == string.pointer) {
- leading = 1;
+ leading_space = 1;
}
+ if (string.pointer+WIDTH(string) == string.end) {
+ trailing_space = 1;
+ }
+ if (previous_break) {
+ break_space = 1;
+ }
+ previous_space = 1;
+ previous_break = 0;
}
-
else if (IS_BREAK(string))
{
- if (spaces) {
- mixed = 1;
- }
- breaks = 1;
if (string.start == string.pointer) {
- leading = 1;
+ leading_break = 1;
}
- }
-
- else if (spaces || breaks)
- {
- if (leading) {
- if (spaces && breaks) {
- mixed_breaks_spaces = 1;
- }
- else if (spaces) {
- leading_spaces = 1;
- }
- else if (breaks) {
- leading_breaks = 1;
- }
+ if (string.pointer+WIDTH(string) == string.end) {
+ trailing_break = 1;
}
- else {
- if (mixed) {
- mixed_breaks_spaces = 1;
- }
- else if (spaces && breaks) {
- inline_breaks_spaces = 1;
- }
- else if (spaces) {
- inline_spaces = 1;
- }
- else if (breaks) {
- inline_breaks = 1;
- }
+ if (previous_space) {
+ space_break = 1;
}
- spaces = breaks = mixed = leading = 0;
+ previous_space = 0;
+ previous_break = 1;
+ }
+ else
+ {
+ previous_space = 0;
+ previous_break = 0;
}
- preceeded_by_space = IS_BLANKZ(string);
+ preceded_by_whitespace = IS_BLANKZ(string);
MOVE(string);
if (string.pointer != string.end) {
- followed_by_space = IS_BLANKZ_AT(string, WIDTH(string));
+ followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
}
}
emitter->scalar_data.single_quoted_allowed = 1;
emitter->scalar_data.block_allowed = 1;
- if (leading_spaces || leading_breaks || trailing_spaces) {
+ if (leading_space || leading_break || trailing_space || trailing_break) {
emitter->scalar_data.flow_plain_allowed = 0;
emitter->scalar_data.block_plain_allowed = 0;
- emitter->scalar_data.block_allowed = 0;
}
- if (trailing_breaks) {
- emitter->scalar_data.flow_plain_allowed = 0;
- emitter->scalar_data.block_plain_allowed = 0;
+ if (trailing_space) {
+ emitter->scalar_data.block_allowed = 0;
}
- if (inline_breaks_spaces) {
+ if (break_space) {
emitter->scalar_data.flow_plain_allowed = 0;
emitter->scalar_data.block_plain_allowed = 0;
emitter->scalar_data.single_quoted_allowed = 0;
}
- if (mixed_breaks_spaces || special_characters) {
+ if (space_break || special_characters) {
emitter->scalar_data.flow_plain_allowed = 0;
emitter->scalar_data.block_plain_allowed = 0;
emitter->scalar_data.single_quoted_allowed = 0;
static int
yaml_emitter_write_indicator(yaml_emitter_t *emitter,
- char *indicator, int need_whitespace,
+ const char *indicator, int need_whitespace,
int is_whitespace, int is_indention)
{
- yaml_string_t string = STRING((yaml_char_t *)indicator, strlen(indicator));
+ size_t indicator_length;
+ yaml_string_t string;
+
+ indicator_length = strlen(indicator);
+ STRING_ASSIGN(string, (yaml_char_t *)indicator, indicator_length);
if (need_whitespace && !emitter->whitespace) {
if (!PUT(emitter, ' ')) return 0;
emitter->whitespace = is_whitespace;
emitter->indention = (emitter->indention && is_indention);
+ emitter->open_ended = 0;
return 1;
}
yaml_emitter_write_anchor(yaml_emitter_t *emitter,
yaml_char_t *value, size_t length)
{
- yaml_string_t string = STRING(value, length);
+ yaml_string_t string;
+ STRING_ASSIGN(string, value, length);
while (string.pointer != string.end) {
if (!WRITE(emitter, string)) return 0;
yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
yaml_char_t *value, size_t length)
{
- yaml_string_t string = STRING(value, length);
+ yaml_string_t string;
+ STRING_ASSIGN(string, value, length);
+
+ if (!emitter->whitespace) {
+ if (!PUT(emitter, ' ')) return 0;
+ }
while (string.pointer != string.end) {
if (!WRITE(emitter, string)) return 0;
static int
yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
- yaml_char_t *value, size_t length)
+ yaml_char_t *value, size_t length,
+ int need_whitespace)
{
- return 0;
+ yaml_string_t string;
+ STRING_ASSIGN(string, value, length);
+
+ if (need_whitespace && !emitter->whitespace) {
+ if (!PUT(emitter, ' ')) return 0;
+ }
+
+ while (string.pointer != string.end) {
+ if (IS_ALPHA(string)
+ || CHECK(string, ';') || CHECK(string, '/')
+ || CHECK(string, '?') || CHECK(string, ':')
+ || CHECK(string, '@') || CHECK(string, '&')
+ || CHECK(string, '=') || CHECK(string, '+')
+ || CHECK(string, '$') || CHECK(string, ',')
+ || CHECK(string, '_') || CHECK(string, '.')
+ || CHECK(string, '~') || CHECK(string, '*')
+ || CHECK(string, '\'') || CHECK(string, '(')
+ || CHECK(string, ')') || CHECK(string, '[')
+ || CHECK(string, ']')) {
+ if (!WRITE(emitter, string)) return 0;
+ }
+ else {
+ int width = WIDTH(string);
+ unsigned int value;
+ while (width --) {
+ value = *(string.pointer++);
+ if (!PUT(emitter, '%')) return 0;
+ if (!PUT(emitter, (value >> 4)
+ + ((value >> 4) < 10 ? '0' : 'A' - 10)))
+ return 0;
+ if (!PUT(emitter, (value & 0x0F)
+ + ((value & 0x0F) < 10 ? '0' : 'A' - 10)))
+ return 0;
+ }
+ }
+ }
+
+ emitter->whitespace = 0;
+ emitter->indention = 0;
+
+ return 1;
}
static int
yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
yaml_char_t *value, size_t length, int allow_breaks)
{
- return 0;
+ yaml_string_t string;
+ int spaces = 0;
+ int breaks = 0;
+
+ STRING_ASSIGN(string, value, length);
+
+ if (!emitter->whitespace) {
+ if (!PUT(emitter, ' ')) return 0;
+ }
+
+ while (string.pointer != string.end)
+ {
+ if (IS_SPACE(string))
+ {
+ if (allow_breaks && !spaces
+ && emitter->column > emitter->best_width
+ && !IS_SPACE_AT(string, 1)) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ MOVE(string);
+ }
+ else {
+ if (!WRITE(emitter, string)) return 0;
+ }
+ spaces = 1;
+ }
+ else if (IS_BREAK(string))
+ {
+ if (!breaks && CHECK(string, '\n')) {
+ if (!PUT_BREAK(emitter)) return 0;
+ }
+ if (!WRITE_BREAK(emitter, string)) return 0;
+ emitter->indention = 1;
+ breaks = 1;
+ }
+ else
+ {
+ if (breaks) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ }
+ if (!WRITE(emitter, string)) return 0;
+ emitter->indention = 0;
+ spaces = 0;
+ breaks = 0;
+ }
+ }
+
+ emitter->whitespace = 0;
+ emitter->indention = 0;
+ if (emitter->root_context)
+ {
+ emitter->open_ended = 1;
+ }
+
+ return 1;
}
static int
yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
yaml_char_t *value, size_t length, int allow_breaks)
{
- return 0;
+ yaml_string_t string;
+ int spaces = 0;
+ int breaks = 0;
+
+ STRING_ASSIGN(string, value, length);
+
+ if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0))
+ return 0;
+
+ while (string.pointer != string.end)
+ {
+ if (IS_SPACE(string))
+ {
+ if (allow_breaks && !spaces
+ && emitter->column > emitter->best_width
+ && string.pointer != string.start
+ && string.pointer != string.end - 1
+ && !IS_SPACE_AT(string, 1)) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ MOVE(string);
+ }
+ else {
+ if (!WRITE(emitter, string)) return 0;
+ }
+ spaces = 1;
+ }
+ else if (IS_BREAK(string))
+ {
+ if (!breaks && CHECK(string, '\n')) {
+ if (!PUT_BREAK(emitter)) return 0;
+ }
+ if (!WRITE_BREAK(emitter, string)) return 0;
+ emitter->indention = 1;
+ breaks = 1;
+ }
+ else
+ {
+ if (breaks) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ }
+ if (CHECK(string, '\'')) {
+ if (!PUT(emitter, '\'')) return 0;
+ }
+ if (!WRITE(emitter, string)) return 0;
+ emitter->indention = 0;
+ spaces = 0;
+ breaks = 0;
+ }
+ }
+
+ if (breaks)
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+
+ if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0))
+ return 0;
+
+ emitter->whitespace = 0;
+ emitter->indention = 0;
+
+ return 1;
}
static int
yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
yaml_char_t *value, size_t length, int allow_breaks)
{
- return 0;
+ yaml_string_t string;
+ int spaces = 0;
+
+ STRING_ASSIGN(string, value, length);
+
+ if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0))
+ return 0;
+
+ while (string.pointer != string.end)
+ {
+ if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string))
+ || IS_BOM(string) || IS_BREAK(string)
+ || CHECK(string, '"') || CHECK(string, '\\'))
+ {
+ unsigned char octet;
+ unsigned int width;
+ unsigned int value;
+ int k;
+
+ octet = string.pointer[0];
+ width = (octet & 0x80) == 0x00 ? 1 :
+ (octet & 0xE0) == 0xC0 ? 2 :
+ (octet & 0xF0) == 0xE0 ? 3 :
+ (octet & 0xF8) == 0xF0 ? 4 : 0;
+ value = (octet & 0x80) == 0x00 ? octet & 0x7F :
+ (octet & 0xE0) == 0xC0 ? octet & 0x1F :
+ (octet & 0xF0) == 0xE0 ? octet & 0x0F :
+ (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
+ for (k = 1; k < (int)width; k ++) {
+ octet = string.pointer[k];
+ value = (value << 6) + (octet & 0x3F);
+ }
+ string.pointer += width;
+
+ if (!PUT(emitter, '\\')) return 0;
+
+ switch (value)
+ {
+ case 0x00:
+ if (!PUT(emitter, '0')) return 0;
+ break;
+
+ case 0x07:
+ if (!PUT(emitter, 'a')) return 0;
+ break;
+
+ case 0x08:
+ if (!PUT(emitter, 'b')) return 0;
+ break;
+
+ case 0x09:
+ if (!PUT(emitter, 't')) return 0;
+ break;
+
+ case 0x0A:
+ if (!PUT(emitter, 'n')) return 0;
+ break;
+
+ case 0x0B:
+ if (!PUT(emitter, 'v')) return 0;
+ break;
+
+ case 0x0C:
+ if (!PUT(emitter, 'f')) return 0;
+ break;
+
+ case 0x0D:
+ if (!PUT(emitter, 'r')) return 0;
+ break;
+
+ case 0x1B:
+ if (!PUT(emitter, 'e')) return 0;
+ break;
+
+ case 0x22:
+ if (!PUT(emitter, '\"')) return 0;
+ break;
+
+ case 0x5C:
+ if (!PUT(emitter, '\\')) return 0;
+ break;
+
+ case 0x85:
+ if (!PUT(emitter, 'N')) return 0;
+ break;
+
+ case 0xA0:
+ if (!PUT(emitter, '_')) return 0;
+ break;
+
+ case 0x2028:
+ if (!PUT(emitter, 'L')) return 0;
+ break;
+
+ case 0x2029:
+ if (!PUT(emitter, 'P')) return 0;
+ break;
+
+ default:
+ if (value <= 0xFF) {
+ if (!PUT(emitter, 'x')) return 0;
+ width = 2;
+ }
+ else if (value <= 0xFFFF) {
+ if (!PUT(emitter, 'u')) return 0;
+ width = 4;
+ }
+ else {
+ if (!PUT(emitter, 'U')) return 0;
+ width = 8;
+ }
+ for (k = (width-1)*4; k >= 0; k -= 4) {
+ int digit = (value >> k) & 0x0F;
+ if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10)))
+ return 0;
+ }
+ }
+ spaces = 0;
+ }
+ else if (IS_SPACE(string))
+ {
+ if (allow_breaks && !spaces
+ && emitter->column > emitter->best_width
+ && string.pointer != string.start
+ && string.pointer != string.end - 1) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ if (IS_SPACE_AT(string, 1)) {
+ if (!PUT(emitter, '\\')) return 0;
+ }
+ MOVE(string);
+ }
+ else {
+ if (!WRITE(emitter, string)) return 0;
+ }
+ spaces = 1;
+ }
+ else
+ {
+ if (!WRITE(emitter, string)) return 0;
+ spaces = 0;
+ }
+ }
+
+ if (!yaml_emitter_write_indicator(emitter, "\"", 0, 0, 0))
+ return 0;
+
+ emitter->whitespace = 0;
+ emitter->indention = 0;
+
+ return 1;
+}
+
+static int
+yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
+ yaml_string_t string)
+{
+ char indent_hint[2];
+ const char *chomp_hint = NULL;
+
+ if (IS_SPACE(string) || IS_BREAK(string))
+ {
+ indent_hint[0] = '0' + (char)emitter->best_indent;
+ indent_hint[1] = '\0';
+ if (!yaml_emitter_write_indicator(emitter, indent_hint, 0, 0, 0))
+ return 0;
+ }
+
+ emitter->open_ended = 0;
+
+ string.pointer = string.end;
+ if (string.start == string.pointer)
+ {
+ chomp_hint = "-";
+ }
+ else
+ {
+ do {
+ string.pointer --;
+ } while ((*string.pointer & 0xC0) == 0x80);
+ if (!IS_BREAK(string))
+ {
+ chomp_hint = "-";
+ }
+ else if (string.start == string.pointer)
+ {
+ chomp_hint = "+";
+ emitter->open_ended = 1;
+ }
+ else
+ {
+ do {
+ string.pointer --;
+ } while ((*string.pointer & 0xC0) == 0x80);
+ if (IS_BREAK(string))
+ {
+ chomp_hint = "+";
+ emitter->open_ended = 1;
+ }
+ }
+ }
+
+ if (chomp_hint)
+ {
+ if (!yaml_emitter_write_indicator(emitter, chomp_hint, 0, 0, 0))
+ return 0;
+ }
+
+ return 1;
}
static int
yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
yaml_char_t *value, size_t length)
{
- return 0;
+ yaml_string_t string;
+ int breaks = 1;
+
+ STRING_ASSIGN(string, value, length);
+
+ if (!yaml_emitter_write_indicator(emitter, "|", 1, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_block_scalar_hints(emitter, string))
+ return 0;
+ if (!PUT_BREAK(emitter)) return 0;
+ emitter->indention = 1;
+ emitter->whitespace = 1;
+
+ while (string.pointer != string.end)
+ {
+ if (IS_BREAK(string))
+ {
+ if (!WRITE_BREAK(emitter, string)) return 0;
+ emitter->indention = 1;
+ breaks = 1;
+ }
+ else
+ {
+ if (breaks) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ }
+ if (!WRITE(emitter, string)) return 0;
+ emitter->indention = 0;
+ breaks = 0;
+ }
+ }
+
+ return 1;
}
static int
yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
yaml_char_t *value, size_t length)
{
- return 0;
-}
+ yaml_string_t string;
+ int breaks = 1;
+ int leading_spaces = 1;
+
+ STRING_ASSIGN(string, value, length);
+ if (!yaml_emitter_write_indicator(emitter, ">", 1, 0, 0))
+ return 0;
+ if (!yaml_emitter_write_block_scalar_hints(emitter, string))
+ return 0;
+ if (!PUT_BREAK(emitter)) return 0;
+ emitter->indention = 1;
+ emitter->whitespace = 1;
+
+ while (string.pointer != string.end)
+ {
+ if (IS_BREAK(string))
+ {
+ if (!breaks && !leading_spaces && CHECK(string, '\n')) {
+ int k = 0;
+ while (IS_BREAK_AT(string, k)) {
+ k += WIDTH_AT(string, k);
+ }
+ if (!IS_BLANKZ_AT(string, k)) {
+ if (!PUT_BREAK(emitter)) return 0;
+ }
+ }
+ if (!WRITE_BREAK(emitter, string)) return 0;
+ emitter->indention = 1;
+ breaks = 1;
+ }
+ else
+ {
+ if (breaks) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ leading_spaces = IS_BLANK(string);
+ }
+ if (!breaks && IS_SPACE(string) && !IS_SPACE_AT(string, 1)
+ && emitter->column > emitter->best_width) {
+ if (!yaml_emitter_write_indent(emitter)) return 0;
+ MOVE(string);
+ }
+ else {
+ if (!WRITE(emitter, string)) return 0;
+ }
+ emitter->indention = 0;
+ breaks = 0;
+ }
+ }
+
+ return 1;
+}