8 #define FLUSH(emitter) \
9 ((emitter->buffer.pointer+5 < emitter->buffer.end) \
10 || yaml_emitter_flush(emitter))
16 #define PUT(emitter,value) \
18 && (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \
26 #define PUT_BREAK(emitter) \
28 && ((emitter->line_break == YAML_CR_BREAK ? \
29 (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') : \
30 emitter->line_break == YAML_LN_BREAK ? \
31 (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') : \
32 emitter->line_break == YAML_CRLN_BREAK ? \
33 (*(emitter->buffer.pointer++) = (yaml_char_t) '\r', \
34 *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0), \
35 emitter->column = 0, \
43 #define WRITE(emitter,string) \
45 && (COPY(emitter->buffer,string), \
53 #define WRITE_BREAK(emitter,string) \
55 && (CHECK(string,'\n') ? \
56 (PUT_BREAK(emitter), \
59 (COPY(emitter->buffer,string), \
60 emitter->column = 0, \
87 int flow,
int indentless);
138 int root,
int sequence,
int mapping,
int simple_key);
224 const char *indicator,
int need_whitespace,
225 int is_whitespace,
int is_indention);
237 yaml_char_t *value,
size_t length,
int need_whitespace);
241 yaml_char_t *value,
size_t length,
int allow_breaks);
245 yaml_char_t *value,
size_t length,
int allow_breaks);
249 yaml_char_t *value,
size_t length,
int allow_breaks);
271 emitter->problem = problem;
283 if (!
ENQUEUE(emitter, emitter->events, *event)) {
336 switch (event->
type) {
372 if (strcmp((
char *)value.
handle, (
char *)tag_directive->
handle) == 0) {
373 if (allow_duplicates)
376 "duplicate %TAG directive");
404 int flow,
int indentless)
409 if (emitter->
indent < 0) {
412 else if (!indentless) {
426 switch (emitter->
state)
481 "expected nothing after STREAM-END");
501 emitter->
encoding =
event->data.stream_start.encoding;
543 "expected STREAM-START");
579 for (tag_directive = default_tag_directives;
580 tag_directive->
handle; tag_directive ++) {
585 implicit =
event->data.document_start.implicit;
669 "expected DOCUMENT-START or STREAM-END");
720 "expected DOCUMENT-END");
971 int root,
int sequence,
int mapping,
int simple_key)
994 "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS");
1133 switch (event->type)
1184 if (no_tag && !event->
data.
scalar.plain_implicit
1187 "neither tag nor implicit flags are specified");
1207 if (no_tag && !event->
data.
scalar.plain_implicit)
1224 if (no_tag && !event->
data.
scalar.quoted_implicit
1336 if (version_directive.
major != 1 || version_directive.
minor != 1) {
1338 "incompatible %YAML directive");
1354 size_t handle_length;
1355 size_t prefix_length;
1364 "tag handle must not be empty");
1367 if (handle.
start[0] !=
'!') {
1369 "tag handle must start with '!'");
1372 if (handle.
end[-1] !=
'!') {
1374 "tag handle must end with '!'");
1382 "tag handle must contain alphanumerical characters only");
1389 "tag prefix must not be empty");
1403 size_t anchor_length;
1406 anchor_length =
strlen((
char *)anchor);
1409 if (
string.start ==
string.
end) {
1411 "alias value must not be empty" :
1412 "anchor value must not be empty");
1415 while (
string.pointer !=
string.end) {
1418 "alias value must contain alphanumerical characters only" :
1419 "anchor value must contain alphanumerical characters only");
1443 tag_length =
strlen((
char *)tag);
1446 if (
string.start ==
string.
end) {
1448 "tag value must not be empty");
1453 size_t prefix_length =
strlen((
char *)tag_directive->
prefix);
1454 if (prefix_length < (
size_t)(
string.end -
string.start)
1455 && strncmp((
char *)tag_directive->
prefix, (
char *)
string.start,
1456 prefix_length) == 0)
1463 (
string.end -
string.start) - prefix_length;
1484 int block_indicators = 0;
1485 int flow_indicators = 0;
1486 int line_breaks = 0;
1487 int special_characters = 0;
1489 int leading_space = 0;
1490 int leading_break = 0;
1491 int trailing_space = 0;
1492 int trailing_break = 0;
1493 int break_space = 0;
1494 int space_break = 0;
1496 int preceeded_by_whitespace = 0;
1497 int followed_by_whitespace = 0;
1498 int previous_space = 0;
1499 int previous_break = 0;
1506 if (
string.start ==
string.
end)
1523 block_indicators = 1;
1524 flow_indicators = 1;
1527 preceeded_by_whitespace = 1;
1530 while (
string.pointer !=
string.end)
1532 if (
string.start ==
string.pointer)
1541 ||
CHECK(
string,
'@') ||
CHECK(
string,
'`')) {
1542 flow_indicators = 1;
1543 block_indicators = 1;
1546 if (
CHECK(
string,
'?') ||
CHECK(
string,
':')) {
1547 flow_indicators = 1;
1548 if (followed_by_whitespace) {
1549 block_indicators = 1;
1553 if (
CHECK(
string,
'-') && followed_by_whitespace) {
1554 flow_indicators = 1;
1555 block_indicators = 1;
1562 ||
CHECK(
string,
'{') ||
CHECK(
string,
'}')) {
1563 flow_indicators = 1;
1566 if (
CHECK(
string,
':')) {
1567 flow_indicators = 1;
1568 if (followed_by_whitespace) {
1569 block_indicators = 1;
1573 if (
CHECK(
string,
'#') && preceeded_by_whitespace) {
1574 flow_indicators = 1;
1575 block_indicators = 1;
1581 special_characters = 1;
1590 if (
string.start ==
string.pointer) {
1593 if (
string.pointer+
WIDTH(
string) ==
string.end) {
1596 if (previous_break) {
1604 if (
string.start ==
string.pointer) {
1607 if (
string.pointer+
WIDTH(
string) ==
string.end) {
1610 if (previous_space) {
1622 preceeded_by_whitespace =
IS_BLANKZ(
string);
1624 if (
string.pointer !=
string.end) {
1636 if (leading_space || leading_break || trailing_space || trailing_break) {
1641 if (trailing_space) {
1651 if (space_break || special_characters) {
1663 if (flow_indicators) {
1667 if (block_indicators) {
1691 switch (event->
type)
1756 if (!
FLUSH(emitter))
return 0;
1768 int indent = (emitter->
indent >= 0) ? emitter->
indent : 0;
1775 while (emitter->
column < indent) {
1776 if (!
PUT(emitter,
' '))
return 0;
1787 const char *indicator,
int need_whitespace,
1788 int is_whitespace,
int is_indention)
1790 size_t indicator_length;
1793 indicator_length =
strlen(indicator);
1796 if (need_whitespace && !emitter->
whitespace) {
1797 if (!
PUT(emitter,
' '))
return 0;
1800 while (
string.pointer !=
string.
end) {
1801 if (!
WRITE(emitter,
string))
return 0;
1818 while (
string.pointer !=
string.
end) {
1819 if (!
WRITE(emitter,
string))
return 0;
1836 if (!
PUT(emitter,
' '))
return 0;
1839 while (
string.pointer !=
string.
end) {
1840 if (!
WRITE(emitter,
string))
return 0;
1852 int need_whitespace)
1857 if (need_whitespace && !emitter->
whitespace) {
1858 if (!
PUT(emitter,
' '))
return 0;
1861 while (
string.pointer !=
string.
end) {
1872 ||
CHECK(
string,
']')) {
1873 if (!
WRITE(emitter,
string))
return 0;
1876 int width =
WIDTH(
string);
1879 value = *(
string.pointer++);
1880 if (!
PUT(emitter,
'%'))
return 0;
1881 if (!
PUT(emitter, (value >> 4)
1882 + ((value >> 4) < 10 ?
'0' :
'A' - 10)))
1884 if (!
PUT(emitter, (value & 0x0F)
1885 + ((value & 0x0F) < 10 ?
'0' :
'A' - 10)))
1908 if (!
PUT(emitter,
' '))
return 0;
1911 while (
string.pointer !=
string.
end)
1915 if (allow_breaks && !spaces
1922 if (!
WRITE(emitter,
string))
return 0;
1928 if (!breaks &&
CHECK(
string,
'\n')) {
1940 if (!
WRITE(emitter,
string))
return 0;
1970 while (
string.pointer !=
string.
end)
1974 if (allow_breaks && !spaces
1976 &&
string.pointer !=
string.start
1977 &&
string.pointer !=
string.end - 1
1983 if (!
WRITE(emitter,
string))
return 0;
1989 if (!breaks &&
CHECK(
string,
'\n')) {
2001 if (
CHECK(
string,
'\'')) {
2002 if (!
PUT(emitter,
'\''))
return 0;
2004 if (!
WRITE(emitter,
string))
return 0;
2032 while (
string.pointer !=
string.
end)
2036 ||
CHECK(
string,
'"') ||
CHECK(
string,
'\\'))
2038 unsigned char octet;
2043 octet =
string.pointer[0];
2044 width = (octet & 0x80) == 0x00 ? 1 :
2045 (octet & 0xE0) == 0xC0 ? 2 :
2046 (octet & 0xF0) == 0xE0 ? 3 :
2047 (octet & 0xF8) == 0xF0 ? 4 : 0;
2048 value = (octet & 0x80) == 0x00 ? octet & 0x7F :
2049 (octet & 0xE0) == 0xC0 ? octet & 0x1F :
2050 (octet & 0xF0) == 0xE0 ? octet & 0x0F :
2051 (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
2052 for (k = 1; k < (
int)width; k ++) {
2053 octet =
string.pointer[k];
2054 value = (value << 6) + (octet & 0x3F);
2056 string.pointer += width;
2058 if (!
PUT(emitter,
'\\'))
return 0;
2063 if (!
PUT(emitter,
'0'))
return 0;
2067 if (!
PUT(emitter,
'a'))
return 0;
2071 if (!
PUT(emitter,
'b'))
return 0;
2075 if (!
PUT(emitter,
't'))
return 0;
2079 if (!
PUT(emitter,
'n'))
return 0;
2083 if (!
PUT(emitter,
'v'))
return 0;
2087 if (!
PUT(emitter,
'f'))
return 0;
2091 if (!
PUT(emitter,
'r'))
return 0;
2095 if (!
PUT(emitter,
'e'))
return 0;
2099 if (!
PUT(emitter,
'\"'))
return 0;
2103 if (!
PUT(emitter,
'\\'))
return 0;
2107 if (!
PUT(emitter,
'N'))
return 0;
2111 if (!
PUT(emitter,
'_'))
return 0;
2115 if (!
PUT(emitter,
'L'))
return 0;
2119 if (!
PUT(emitter,
'P'))
return 0;
2123 if (value <= 0xFF) {
2124 if (!
PUT(emitter,
'x'))
return 0;
2127 else if (value <= 0xFFFF) {
2128 if (!
PUT(emitter,
'u'))
return 0;
2132 if (!
PUT(emitter,
'U'))
return 0;
2135 for (k = (width-1)*4; k >= 0; k -= 4) {
2136 int digit = (value >> k) & 0x0F;
2137 if (!
PUT(emitter, digit + (digit < 10 ?
'0' :
'A'-10)))
2145 if (allow_breaks && !spaces
2147 &&
string.pointer !=
string.start
2148 &&
string.pointer !=
string.end - 1) {
2151 if (!
PUT(emitter,
'\\'))
return 0;
2156 if (!
WRITE(emitter,
string))
return 0;
2162 if (!
WRITE(emitter,
string))
return 0;
2180 char indent_hint[2];
2181 const char *chomp_hint =
NULL;
2185 indent_hint[0] =
'0' + (char)emitter->
best_indent;
2186 indent_hint[1] =
'\0';
2193 string.pointer =
string.end;
2194 if (
string.start ==
string.pointer)
2202 }
while ((*
string.pointer & 0xC0) == 0x80);
2207 else if (
string.start ==
string.pointer)
2216 }
while ((*
string.pointer & 0xC0) == 0x80);
2251 while (
string.pointer !=
string.
end)
2264 if (!
WRITE(emitter,
string))
return 0;
2279 int leading_spaces = 1;
2291 while (
string.pointer !=
string.
end)
2295 if (!breaks && !leading_spaces &&
CHECK(
string,
'\n')) {
2320 if (!
WRITE(emitter,
string))
return 0;
static int yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem)
The double-quoted scalar style.
yaml_strdup(const yaml_char_t *str)
Use LN for line breaks (Unix style).
unsigned char * buffer
The buffer pointer.
size_t anchor_length
The anchor length.
static int yaml_emitter_write_tag_handle(yaml_emitter_t *emitter, yaml_char_t *value, size_t length)
static int yaml_emitter_write_bom(yaml_emitter_t *emitter)
static int yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event)
yaml_event_delete(yaml_event_t *event)
Free any memory allocated for an event object.
size_t strlen(const char *)
static int yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter, yaml_version_directive_t version_directive)
Expect DOCUMENT-START or STREAM-END.
int canonical
If the output is in the canonical style?
static int yaml_emitter_emit_document_content(yaml_emitter_t *emitter, yaml_event_t *event)
int root_context
Is it the document root context?
struct yaml_emitter_s::@55 anchor_data
Anchor analysis.
Expect an item of a block sequence.
int sequence_context
Is it a sequence context?
Expect a value of a block mapping.
struct yaml_event_s::@20::@22 document_start
The document parameters (for YAML_DOCUMENT_START_EVENT).
Cannot allocate or reallocate a block of memory.
Expect the content of a document.
size_t handle_length
The tag handle length.
static int yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter, yaml_event_t *event, int first)
Expect a key of a flow mapping.
#define WRITE(emitter, string)
static int yaml_emitter_check_simple_key(yaml_emitter_t *emitter)
static int yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter, yaml_char_t *value, size_t length, int allow_breaks)
yaml_char_t * suffix
The tag suffix.
static int yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event, int root, int sequence, int mapping, int simple_key)
static int yaml_emitter_process_scalar(yaml_emitter_t *emitter)
Expect the key of a block mapping.
unsigned char yaml_char_t
The character type (UTF-8 octet).
int flow_level
The current flow level.
static int yaml_emitter_emit_document_start(yaml_emitter_t *emitter, yaml_event_t *event, int first)
struct yaml_emitter_s::@57 scalar_data
Scalar analysis.
The version directive data.
yaml_char_t * start
The beginning of the buffer.
static int yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter, yaml_event_t *event, int simple)
int whitespace
If the last character was a whitespace?
#define IS_BREAK_AT(string, offset)
#define PUT(emitter, value)
Expect a value for a simple key of a block mapping.
int open_ended
If an explicit document end is required?
yaml_char_t * prefix
The tag prefix.
size_t length
The scalar length.
#define IS_PRINTABLE(string)
#define IS_SPACE_AT(string, offset)
static int yaml_emitter_process_anchor(yaml_emitter_t *emitter)
Expect the first key of a flow mapping.
static int yaml_emitter_write_indent(yaml_emitter_t *emitter)
static int yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter)
static int yaml_emitter_analyze_anchor(yaml_emitter_t *emitter, yaml_char_t *anchor, int alias)
yaml_event_t * head
The head of the event queue.
static int yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter, yaml_char_t *value, size_t length)
int column
The current column.
yaml_error_type_t error
Error type.
yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event)
Emit an event.
static int yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter, yaml_event_t *event, int first)
#define DEQUEUE(context, queue)
yaml_emitter_state_t * top
The top of the stack.
#define STACK_EMPTY(context, stack)
int indent
The current indentation level.
static int yaml_emitter_emit_document_end(yaml_emitter_t *emitter, yaml_event_t *event)
static int yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter, yaml_char_t *value, size_t length)
int indention
If the last character was an indentation character (' ', '-', '?', ':')?
yaml_emitter_state_t state
The current emitter state.
#define QUEUE_EMPTY(context, queue)
static int yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter, yaml_event_t *event, int first)
int flow_plain_allowed
Can the scalar be expessed in the flow plain style?
int major
The major version number.
enum yaml_scalar_style_e yaml_scalar_style_t
Scalar styles.
Expect a value for a simple key of a flow mapping.
#define CHECK(string, octet)
yaml_encoding_t encoding
The stream encoding.
int line
The current line.
static int yaml_emitter_append_tag_directive(yaml_emitter_t *emitter, yaml_tag_directive_t value, int allow_duplicates)
Cannot emit a YAML stream.
static int yaml_emitter_process_tag(yaml_emitter_t *emitter)
#define YAML_DECLARE(type)
The public API declaration.
static int yaml_emitter_emit_stream_start(yaml_emitter_t *emitter, yaml_event_t *event)
int simple_key_context
Is it a simple mapping key context?
Expect an item of a flow sequence.
static int yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter, yaml_event_t *event, int simple)
#define PUT_BREAK(emitter)
yaml_scalar_style_t style
The output style.
Expect the first item of a block sequence.
struct yaml_emitter_s::@52 events
The event queue.
static int yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event)
#define CHECK_AT(string, octet, offset)
yaml_char_t * handle
The tag handle.
static int yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter, yaml_char_t *value, size_t length, int allow_breaks)
struct yaml_event_s::@20::@23 document_end
The document end parameters (for YAML_DOCUMENT_END_EVENT).
yaml_char_t * anchor
The anchor value.
Expect the first item of a flow sequence.
static int yaml_emitter_write_indicator(yaml_emitter_t *emitter, const char *indicator, int need_whitespace, int is_whitespace, int is_indention)
struct yaml_event_s::@20::@27 mapping_start
The mapping parameters (for YAML_MAPPING_START_EVENT).
#define ENQUEUE(context, queue, value)
yaml_emitter_flush(yaml_emitter_t *emitter)
Flush the accumulated characters to the output.
size_t suffix_length
The tag suffix length.
static int yaml_emitter_check_empty_document(yaml_emitter_t *emitter)
The default UTF-8 encoding.
int single_quoted_allowed
Can the scalar be expressed in the single quoted style?
yaml_char_t * handle
The tag handle.
int block_plain_allowed
Can the scalar be expressed in the block plain style?
struct yaml_event_s::@20::@24 alias
The alias parameters (for YAML_ALIAS_EVENT).
yaml_char_t * value
The scalar value.
static int yaml_emitter_analyze_event(yaml_emitter_t *emitter, yaml_event_t *event)
static int yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter)
#define IS_BLANKZ_AT(string, offset)
static int yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event)
static int yaml_emitter_write_tag_content(yaml_emitter_t *emitter, yaml_char_t *value, size_t length, int need_whitespace)
Expect a value of a flow mapping.
static int yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter, yaml_event_t *event, int first)
int mapping_context
Is it a mapping context?
struct yaml_emitter_s::@53 indents
The stack of indentation levels.
#define WIDTH_AT(string, offset)
static int yaml_emitter_write_anchor(yaml_emitter_t *emitter, yaml_char_t *value, size_t length)
if(RB_TYPE_P(r, T_FLOAT))
int best_indent
The number of indentation spaces.
static int yaml_emitter_analyze_scalar(yaml_emitter_t *emitter, yaml_char_t *value, size_t length)
int multiline
Does the scalar contain line breaks?
Expect the first key of a block mapping.
The literal scalar style.
int minor
The minor version number.
union yaml_event_s::@20 data
The event data.
#define POP(context, stack)
Expect the first DOCUMENT-START or STREAM-END.
yaml_break_t line_break
The preferred line break.
static int yaml_emitter_need_more_events(yaml_emitter_t *emitter)
int block_allowed
Can the scalar be expressed in the literal or folded styles?
static int yaml_emitter_increase_indent(yaml_emitter_t *emitter, int flow, int indentless)
static int yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter, yaml_char_t *value, size_t length, int allow_breaks)
#define IS_BLANKZ(string)
#define assert(condition)
int unicode
Allow unescaped non-ASCII characters?
int best_width
The preferred width of the output lines.
yaml_event_t * tail
The tail of the event queue.
struct yaml_emitter_s::@54 tag_directives
The list of tag directives.
static int yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event)
#define STRING_ASSIGN(value, string, length)
static int yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event)
struct yaml_emitter_s::@51 states
The stack of states.
Let the emitter choose the style.
struct yaml_event_s::@20::@26 sequence_start
The sequence parameters (for YAML_SEQUENCE_START_EVENT).
static int yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter, yaml_string_t string)
struct yaml_emitter_s::@56 tag_data
Tag analysis.
yaml_event_type_t type
The event type.
static int yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event)
struct yaml_event_s::@20::@25 scalar
The scalar parameters (for YAML_SCALAR_EVENT).
#define WRITE_BREAK(emitter, string)
static int yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter, yaml_tag_directive_t tag_directive)
static int yaml_emitter_analyze_tag(yaml_emitter_t *emitter, yaml_char_t *tag)
The single-quoted scalar style.