reader.c fully ported.
diff --git a/api_c.go b/api_c.go
index 46a303d..50b162d 100644
--- a/api_c.go
+++ b/api_c.go
@@ -5,70 +5,9 @@
"os"
)
-///*
-// * Extend a string.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_string_extend(yaml_char_t **start,
-// yaml_char_t **pointer, yaml_char_t **end)
-//{
-// yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2);
-//
-// if (!new_start) return 0;
-//
-// memset(new_start + (*end - *start), 0, *end - *start);
-//
-// *pointer = new_start + (*pointer - *start);
-// *end = new_start + (*end - *start)*2;
-// *start = new_start;
-//
-// return 1;
-//}
-//
-///*
-// * Append a string B to a string A.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_string_join(
-// yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
-// yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end)
-//{
-// if (*b_start == *b_pointer)
-// return 1;
-//
-// while (*a_end - *a_pointer <= *b_pointer - *b_start) {
-// if (!yaml_string_extend(a_start, a_pointer, a_end))
-// return 0;
-// }
-//
-// memcpy(*a_pointer, *b_start, *b_pointer - *b_start);
-// *a_pointer += *b_pointer - *b_start;
-//
-// return 1;
-//}
-//
-///*
-// * Extend a stack.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_stack_extend(void **start, void **top, void **end)
-//{
-// void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
-//
-// if (!new_start) return 0;
-//
-// *top = (char *)new_start + ((char *)*top - (char *)*start);
-// *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
-// *start = new_start;
-//
-// return 1;
-//}
-
func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
//fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens))
+
// Check if we can move the queue at the beginning of the buffer.
if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) {
if parser.tokens_head != len(parser.tokens) {
@@ -87,21 +26,23 @@
// Create a new parser object.
func yaml_parser_initialize(parser *yaml_parser_t) bool {
- // [Go] These should be initialized lazily, and probably start with smaller sizes.
- parser.raw_buffer = make([]byte, 0, input_raw_buffer_size)
- parser.buffer = make([]byte, 0, input_buffer_size)
- parser.tokens = make([]yaml_token_t, 0, initial_queue_size)
- parser.indents = make([]int, 0, initial_stack_size)
- parser.simple_keys = make([]yaml_simple_key_t, 0, initial_stack_size)
- parser.states = make([]yaml_parser_state_t, 0, initial_stack_size)
- parser.marks = make([]yaml_mark_t, 0, initial_stack_size)
- parser.tag_directives = make([]yaml_tag_directive_t, 0, initial_stack_size)
+ // [Go] These should be initialized lazily instead.
+ *parser = yaml_parser_t{
+ raw_buffer: make([]byte, 0, input_raw_buffer_size),
+ buffer: make([]byte, 0, input_buffer_size),
+ tokens: make([]yaml_token_t, 0, initial_queue_size),
+ indents: make([]int, 0, initial_stack_size),
+ simple_keys: make([]yaml_simple_key_t, 0, initial_stack_size),
+ states: make([]yaml_parser_state_t, 0, initial_stack_size),
+ marks: make([]yaml_mark_t, 0, initial_stack_size),
+ tag_directives: make([]yaml_tag_directive_t, 0, initial_stack_size),
+ }
return true
}
// Destroy a parser object.
func yaml_parser_delete(parser *yaml_parser_t) {
- *parser = yaml_parser_t{}
+ *parser = yaml_parser_t{}
}
// String read handler.
@@ -138,248 +79,102 @@
parser.input_file = file
}
-///*
-// * Set the source encoding.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
-//{
-// assert(parser); // Non-NULL parser object expected.
-// assert(!parser.encoding); // Encoding is already set or detected.
-//
-// parser.encoding = encoding;
-//}
-//
-///*
-// * Create a new emitter object.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_initialize(yaml_emitter_t *emitter)
-//{
-// assert(emitter); // Non-NULL emitter object expected.
-//
-// memset(emitter, 0, sizeof(yaml_emitter_t));
-// if (!BUFFER_INIT(emitter, emitter.buffer, OUTPUT_BUFFER_SIZE))
-// goto error;
-// if (!BUFFER_INIT(emitter, emitter.raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
-// goto error;
-// if (!STACK_INIT(emitter, emitter.states, INITIAL_STACK_SIZE))
-// goto error;
-// if (!QUEUE_INIT(emitter, emitter.events, INITIAL_QUEUE_SIZE))
-// goto error;
-// if (!STACK_INIT(emitter, emitter.indents, INITIAL_STACK_SIZE))
-// goto error;
-// if (!STACK_INIT(emitter, emitter.tag_directives, INITIAL_STACK_SIZE))
-// goto error;
-//
-// return 1;
-//
-//error:
-//
-// BUFFER_DEL(emitter, emitter.buffer);
-// BUFFER_DEL(emitter, emitter.raw_buffer);
-// STACK_DEL(emitter, emitter.states);
-// QUEUE_DEL(emitter, emitter.events);
-// STACK_DEL(emitter, emitter.indents);
-// STACK_DEL(emitter, emitter.tag_directives);
-//
-// return 0;
-//}
-//
-///*
-// * Destroy an emitter object.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_delete(yaml_emitter_t *emitter)
-//{
-// assert(emitter); // Non-NULL emitter object expected.
-//
-// BUFFER_DEL(emitter, emitter.buffer);
-// BUFFER_DEL(emitter, emitter.raw_buffer);
-// STACK_DEL(emitter, emitter.states);
-// while (!QUEUE_EMPTY(emitter, emitter.events)) {
-// yaml_event_delete(&DEQUEUE(emitter, emitter.events));
-// }
-// QUEUE_DEL(emitter, emitter.events);
-// STACK_DEL(emitter, emitter.indents);
-// while (!STACK_EMPTY(empty, emitter.tag_directives)) {
-// yaml_tag_directive_t tag_directive = POP(emitter, emitter.tag_directives);
-// yaml_free(tag_directive.handle);
-// yaml_free(tag_directive.prefix);
-// }
-// STACK_DEL(emitter, emitter.tag_directives);
-// yaml_free(emitter.anchors);
-//
-// memset(emitter, 0, sizeof(yaml_emitter_t));
-//}
-//
-///*
-// * String write handler.
-// */
-//
-//static int
-//yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
-//{
-// yaml_emitter_t *emitter = data;
-//
-// if (emitter.output.string.size + *emitter.output.string.size_written
-// < size) {
-// memcpy(emitter.output.string.buffer
-// + *emitter.output.string.size_written,
-// buffer,
-// emitter.output.string.size
-// - *emitter.output.string.size_written);
-// *emitter.output.string.size_written = emitter.output.string.size;
-// return 0;
-// }
-//
-// memcpy(emitter.output.string.buffer
-// + *emitter.output.string.size_written, buffer, size);
-// *emitter.output.string.size_written += size;
-// return 1;
-//}
-//
-///*
-// * File write handler.
-// */
-//
-//static int
-//yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
-//{
-// yaml_emitter_t *emitter = data;
-//
-// return (fwrite(buffer, 1, size, emitter.output.file) == size);
-//}
-///*
-// * Set a string output.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_output_string(yaml_emitter_t *emitter,
-// unsigned char *output, size_t size, size_t *size_written)
-//{
-// assert(emitter); // Non-NULL emitter object expected.
-// assert(!emitter.write_handler); // You can set the output only once.
-// assert(output); // Non-NULL output string expected.
-//
-// emitter.write_handler = yaml_string_write_handler;
-// emitter.write_handler_data = emitter;
-//
-// emitter.output.string.buffer = output;
-// emitter.output.string.size = size;
-// emitter.output.string.size_written = size_written;
-// *size_written = 0;
-//}
-//
-///*
-// * Set a file output.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file)
-//{
-// assert(emitter); // Non-NULL emitter object expected.
-// assert(!emitter.write_handler); // You can set the output only once.
-// assert(file); // Non-NULL file object expected.
-//
-// emitter.write_handler = yaml_file_write_handler;
-// emitter.write_handler_data = emitter;
-//
-// emitter.output.file = file;
-//}
-//
-///*
-// * Set a generic output handler.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_output(yaml_emitter_t *emitter,
-// yaml_write_handler_t *handler, void *data)
-//{
-// assert(emitter); // Non-NULL emitter object expected.
-// assert(!emitter.write_handler); // You can set the output only once.
-// assert(handler); // Non-NULL handler object expected.
-//
-// emitter.write_handler = handler;
-// emitter.write_handler_data = data;
-//}
-//
-///*
-// * Set the output encoding.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding)
-//{
-// assert(emitter); // Non-NULL emitter object expected.
-// assert(!emitter.encoding); // You can set encoding only once.
-//
-// emitter.encoding = encoding;
-//}
-//
-///*
-// * Set the canonical output style.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical)
-//{
-// assert(emitter); // Non-NULL emitter object expected.
-//
-// emitter.canonical = (canonical != 0);
-//}
-//
-///*
-// * Set the indentation increment.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent)
-//{
-// assert(emitter); // Non-NULL emitter object expected.
-//
-// emitter.best_indent = (1 < indent && indent < 10) ? indent : 2;
-//}
-//
-///*
-// * Set the preferred line width.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_width(yaml_emitter_t *emitter, int width)
-//{
-// assert(emitter); // Non-NULL emitter object expected.
-//
-// emitter.best_width = (width >= 0) ? width : -1;
-//}
-//
-///*
-// * Set if unescaped non-ASCII characters are allowed.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode)
-//{
-// assert(emitter); // Non-NULL emitter object expected.
-//
-// emitter.unicode = (unicode != 0);
-//}
-//
-///*
-// * Set the preferred line break character.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break)
-//{
-// assert(emitter); // Non-NULL emitter object expected.
-//
-// emitter.line_break = line_break;
-//}
-//
+// Set the source encoding.
+func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
+ if parser.encoding != yaml_ANY_ENCODING {
+ panic("must set the encoding only once")
+ }
+ parser.encoding = encoding
+}
+
+// Create a new emitter object.
+func yaml_emitter_initialize(emitter *yaml_emitter_t) bool {
+ // [Go] These should be initialized lazily instead.
+ *emitter = yaml_emitter_t{
+ buffer: make([]byte, 0, output_buffer_size),
+ raw_buffer: make([]byte, 0, output_raw_buffer_size),
+ states: make([]yaml_emitter_state_t, 0, initial_stack_size),
+ events: make([]yaml_event_t, 0, initial_queue_size),
+ indents: make([]int, 0, initial_stack_size),
+ tag_directives: make([]yaml_tag_directive_t, 0, initial_stack_size),
+ }
+ return true
+}
+
+// Destroy an emitter object.
+func yaml_emitter_delete(emitter *yaml_emitter_t) {
+ *emitter = yaml_emitter_t{}
+}
+
+// String write handler.
+func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
+ *emitter.output_buffer = append(*emitter.output_buffer, buffer...)
+ return nil
+}
+
+// File write handler.
+func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
+ _, err := emitter.output_file.Write(buffer)
+ return err
+}
+
+// Set a string output.
+func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) {
+ if emitter.write_handler != nil {
+ panic("must set the output target only once")
+ }
+ emitter.write_handler = yaml_string_write_handler
+ emitter.output_buffer = output_buffer
+}
+
+// Set a file output.
+func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) {
+ if emitter.write_handler != nil {
+ panic("must set the output target only once")
+ }
+ emitter.write_handler = yaml_file_write_handler
+ emitter.output_file = file
+}
+
+// Set the output encoding.
+func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) {
+ if emitter.encoding != yaml_ANY_ENCODING {
+ panic("must set the output encoding only once")
+ }
+ emitter.encoding = encoding
+}
+
+// Set the canonical output style.
+func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) {
+ emitter.canonical = canonical
+}
+
+//// Set the indentation increment.
+func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) {
+ if indent < 2 || indent > 9 {
+ indent = 2
+ }
+ emitter.best_indent = indent
+}
+
+// Set the preferred line width.
+func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) {
+ if width < 0 {
+ width = -1
+ }
+ emitter.best_width = width
+}
+
+// Set if unescaped non-ASCII characters are allowed.
+func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) {
+ emitter.unicode = unicode
+}
+
+// Set the preferred line break character.
+func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
+ emitter.line_break = line_break
+}
+
///*
// * Destroy a token object.
// */
@@ -465,340 +260,175 @@
// return 1;
//}
//
-///*
-// * Create STREAM-START.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_stream_start_event_initialize(yaml_event_t *event,
-// yaml_encoding_t encoding)
-//{
-// yaml_mark_t mark = { 0, 0, 0 };
-//
-// assert(event); // Non-NULL event object is expected.
-//
-// STREAM_START_EVENT_INIT(*event, encoding, mark, mark);
- //*event = yaml_event_t{
- // typ: yaml_STREAM_START_EVENT,
- // start_mark: mark,
- // end_mark: mark,
- //}
- //event.stream_start.encoding = encoding
-//
-// return 1;
-//}
-//
-///*
-// * Create STREAM-END.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_stream_end_event_initialize(yaml_event_t *event)
-//{
-// yaml_mark_t mark = { 0, 0, 0 };
-//
-// assert(event); // Non-NULL event object is expected.
-//
-// STREAM_END_EVENT_INIT(*event, mark, mark);
- //*event = yaml_event_t{
- // typ: yaml_STREAM_END_EVENT,
- // start_mark: mark,
- // end_mark: mark,
- //}
-//
-// return 1;
-//}
-//
-///*
-// * Create DOCUMENT-START.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_start_event_initialize(yaml_event_t *event,
-// yaml_version_directive_t *version_directive,
-// yaml_tag_directive_t *tag_directives_start,
-// yaml_tag_directive_t *tag_directives_end,
-// int implicit)
-//{
-// struct {
-// yaml_error_type_t error;
-// } context;
-// yaml_mark_t mark = { 0, 0, 0 };
-// yaml_version_directive_t *version_directive_copy = NULL;
-// struct {
-// yaml_tag_directive_t *start;
-// yaml_tag_directive_t *end;
-// yaml_tag_directive_t *top;
-// } tag_directives_copy = { NULL, NULL, NULL };
-// yaml_tag_directive_t value = { NULL, NULL };
-//
-// assert(event); // Non-NULL event object is expected.
-// assert((tag_directives_start && tag_directives_end) ||
-// (tag_directives_start == tag_directives_end));
-// // Valid tag directives are expected.
-//
-// if (version_directive) {
-// version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
-// if (!version_directive_copy) goto error;
-// version_directive_copy.major = version_directive.major;
-// version_directive_copy.minor = version_directive.minor;
-// }
-//
-// if (tag_directives_start != tag_directives_end) {
-// yaml_tag_directive_t *tag_directive;
-// if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
-// goto error;
-// for (tag_directive = tag_directives_start;
-// tag_directive != tag_directives_end; tag_directive ++) {
-// assert(tag_directive.handle);
-// assert(tag_directive.prefix);
-// if (!yaml_check_utf8(tag_directive.handle,
-// strlen((char *)tag_directive.handle)))
-// goto error;
-// if (!yaml_check_utf8(tag_directive.prefix,
-// strlen((char *)tag_directive.prefix)))
-// goto error;
-// value.handle = yaml_strdup(tag_directive.handle);
-// value.prefix = yaml_strdup(tag_directive.prefix);
-// if (!value.handle || !value.prefix) goto error;
-// if (!PUSH(&context, tag_directives_copy, value))
-// goto error;
-// value.handle = NULL;
-// value.prefix = NULL;
-// }
-// }
-//
-// DOCUMENT_START_EVENT_INIT(*event, version_directive_copy,
-// tag_directives_copy.start, tag_directives_copy.top,
-// implicit, mark, mark);
- //*event = yaml_event_t{
- // typ: yaml_DOCUMENT_START_EVENT,
- // start_mark: mark,
- // end_mark: mark,
- //}
- //event.document_start.version_directive = version_directive_copy
- //event.document_start.tag_directives = tag_directives
- //event.document_start.implicit = implicit
-//
-// return 1;
-//
-//error:
-// yaml_free(version_directive_copy);
-// while (!STACK_EMPTY(context, tag_directives_copy)) {
-// yaml_tag_directive_t value = POP(context, tag_directives_copy);
-// yaml_free(value.handle);
-// yaml_free(value.prefix);
-// }
-// STACK_DEL(context, tag_directives_copy);
-// yaml_free(value.handle);
-// yaml_free(value.prefix);
-//
-// return 0;
-//}
-//
-///*
-// * Create DOCUMENT-END.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_end_event_initialize(yaml_event_t *event, int implicit)
-//{
-// yaml_mark_t mark = { 0, 0, 0 };
-//
-// assert(event); // Non-NULL emitter object is expected.
-//
-// DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark);
-//
-// return 1;
-//}
-//
+
+// Create STREAM-START.
+func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_STREAM_START_EVENT,
+ }
+ event.stream_start.encoding = encoding
+ return true
+}
+
+// Create STREAM-END.
+func yaml_stream_end_event_initialize(event *yaml_event_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_STREAM_END_EVENT,
+ }
+ return true
+}
+
+// Create DOCUMENT-START.
+func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t,
+ tag_directives []yaml_tag_directive_t, implicit bool) bool {
+
+ // [Go] It doesn't sound necessary to perform these copies
+ // given that with garbage collection ownership is handled.
+ var version_directive_copy *yaml_version_directive_t
+ var tag_directives_copy []yaml_tag_directive_t
+ if version_directive != nil {
+ copy := *version_directive
+ version_directive_copy = ©
+ }
+ if len(tag_directives) > 0 {
+ tag_directives_copy = append([]yaml_tag_directive_t(nil), tag_directives...)
+ }
+
+ *event = yaml_event_t{
+ typ: yaml_DOCUMENT_START_EVENT,
+ }
+ event.document_start.version_directive = version_directive_copy
+ event.document_start.tag_directives = tag_directives_copy
+ event.document_start.implicit = implicit
+ return true
+}
+
+// Create DOCUMENT-END.
+func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool {
+ *event = yaml_event_t{
+ typ: yaml_DOCUMENT_END_EVENT,
+ }
+ event.document_end.implicit = implicit
+ return true
+}
+
///*
// * Create ALIAS.
// */
//
//YAML_DECLARE(int)
-//yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor)
+//yaml_alias_event_initialize(event *yaml_event_t, anchor *yaml_char_t)
//{
-// yaml_mark_t mark = { 0, 0, 0 };
-// yaml_char_t *anchor_copy = NULL;
+// mark yaml_mark_t = { 0, 0, 0 }
+// anchor_copy *yaml_char_t = NULL
//
-// assert(event); // Non-NULL event object is expected.
-// assert(anchor); // Non-NULL anchor is expected.
+// assert(event) // Non-NULL event object is expected.
+// assert(anchor) // Non-NULL anchor is expected.
//
-// if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0;
+// if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0
//
-// anchor_copy = yaml_strdup(anchor);
+// anchor_copy = yaml_strdup(anchor)
// if (!anchor_copy)
-// return 0;
+// return 0
//
-// ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark);
+// ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark)
//
-// return 1;
+// return 1
//}
-//
-///*
-// * Create SCALAR.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_scalar_event_initialize(yaml_event_t *event,
-// yaml_char_t *anchor, yaml_char_t *tag,
-// yaml_char_t *value, int length,
-// int plain_implicit, int quoted_implicit,
-// yaml_scalar_style_t style)
-//{
-// yaml_mark_t mark = { 0, 0, 0 };
-// yaml_char_t *anchor_copy = NULL;
-// yaml_char_t *tag_copy = NULL;
-// yaml_char_t *value_copy = NULL;
-//
-// assert(event); // Non-NULL event object is expected.
-// assert(value); // Non-NULL anchor is expected.
-//
-// if (anchor) {
-// if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
-// anchor_copy = yaml_strdup(anchor);
-// if (!anchor_copy) goto error;
-// }
-//
-// if (tag) {
-// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
-// tag_copy = yaml_strdup(tag);
-// if (!tag_copy) goto error;
-// }
-//
-// if (length < 0) {
-// length = strlen((char *)value);
-// }
-//
-// if (!yaml_check_utf8(value, length)) goto error;
-// value_copy = yaml_malloc(length+1);
-// if (!value_copy) goto error;
-// memcpy(value_copy, value, length);
-// value_copy[length] = '\0';
-//
-// SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length,
-// plain_implicit, quoted_implicit, style, mark, mark);
-//
-// return 1;
-//
-//error:
-// yaml_free(anchor_copy);
-// yaml_free(tag_copy);
-// yaml_free(value_copy);
-//
-// return 0;
-//}
-//
-///*
-// * Create SEQUENCE-START.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_sequence_start_event_initialize(yaml_event_t *event,
-// yaml_char_t *anchor, yaml_char_t *tag, int implicit,
-// yaml_sequence_style_t style)
-//{
-// yaml_mark_t mark = { 0, 0, 0 };
-// yaml_char_t *anchor_copy = NULL;
-// yaml_char_t *tag_copy = NULL;
-//
-// assert(event); // Non-NULL event object is expected.
-//
-// if (anchor) {
-// if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
-// anchor_copy = yaml_strdup(anchor);
-// if (!anchor_copy) goto error;
-// }
-//
-// if (tag) {
-// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
-// tag_copy = yaml_strdup(tag);
-// if (!tag_copy) goto error;
-// }
-//
-// SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy,
-// implicit, style, mark, mark);
-//
-// return 1;
-//
-//error:
-// yaml_free(anchor_copy);
-// yaml_free(tag_copy);
-//
-// return 0;
-//}
-//
-///*
-// * Create SEQUENCE-END.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_sequence_end_event_initialize(yaml_event_t *event)
-//{
-// yaml_mark_t mark = { 0, 0, 0 };
-//
-// assert(event); // Non-NULL event object is expected.
-//
-// SEQUENCE_END_EVENT_INIT(*event, mark, mark);
-//
-// return 1;
-//}
-//
-///*
-// * Create MAPPING-START.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_mapping_start_event_initialize(yaml_event_t *event,
-// yaml_char_t *anchor, yaml_char_t *tag, int implicit,
-// yaml_mapping_style_t style)
-//{
-// yaml_mark_t mark = { 0, 0, 0 };
-// yaml_char_t *anchor_copy = NULL;
-// yaml_char_t *tag_copy = NULL;
-//
-// assert(event); // Non-NULL event object is expected.
-//
-// if (anchor) {
-// if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
-// anchor_copy = yaml_strdup(anchor);
-// if (!anchor_copy) goto error;
-// }
-//
-// if (tag) {
-// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
-// tag_copy = yaml_strdup(tag);
-// if (!tag_copy) goto error;
-// }
-//
-// MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy,
-// implicit, style, mark, mark);
-//
-// return 1;
-//
-//error:
-// yaml_free(anchor_copy);
-// yaml_free(tag_copy);
-//
-// return 0;
-//}
-//
-///*
-// * Create MAPPING-END.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_mapping_end_event_initialize(yaml_event_t *event)
-//{
-// yaml_mark_t mark = { 0, 0, 0 };
-//
-// assert(event); // Non-NULL event object is expected.
-//
-// MAPPING_END_EVENT_INIT(*event, mark, mark);
-//
-// return 1;
-//}
+
+// Create SCALAR.
+func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte,
+ plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool {
+ var anchor_copy, tag_copy, value_copy []byte
+
+ // [Go] These copies are probably not necessary in Go, where
+ // ownership of data is more flexible due to garbage collection.
+ if len(anchor) > 0 {
+ //if !yaml_check_utf8(anchor) { return false }
+ anchor_copy = append([]byte(nil), anchor...)
+ }
+ if len(tag) > 0 {
+ //if !yaml_check_utf8(tag) { return false }
+ tag_copy = append([]byte(nil), tag...)
+ }
+ //if !yaml_check_utf8(value) { return false }
+ value_copy = append([]byte(nil), value...)
+
+ *event = yaml_event_t{
+ typ: yaml_SCALAR_EVENT,
+ }
+ event.scalar.anchor = anchor_copy
+ event.scalar.tag = tag_copy
+ event.scalar.value = value_copy
+ event.scalar.plain_implicit = plain_implicit
+ event.scalar.quoted_implicit = quoted_implicit
+ event.scalar.style = style
+ return true
+}
+
+// Create SEQUENCE-START.
+func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool {
+ // [Go] These copies are probably not necessary in Go, where
+ // ownership of data is more flexible due to garbage collection.
+ var anchor_copy, tag_copy []byte
+ if len(anchor) > 0 {
+ //if !yaml_check_utf8(anchor) { return false }
+ anchor_copy = append([]byte(nil), anchor...)
+ }
+ if len(tag) > 0 {
+ //if !yaml_check_utf8(tag) { return false }
+ tag_copy = append([]byte(nil), tag...)
+ }
+
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_START_EVENT,
+ }
+ event.sequence_start.anchor = anchor_copy
+ event.sequence_start.tag = tag_copy
+ event.sequence_start.implicit = implicit
+ event.sequence_start.style = style
+ return true
+}
+
+// Create SEQUENCE-END.
+func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_END_EVENT,
+ }
+ return true
+}
+
+// Create MAPPING-START.
+func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool {
+ // [Go] These copies are probably not necessary in Go, where
+ // ownership of data is more flexible due to garbage collection.
+ var anchor_copy, tag_copy []byte
+ if len(anchor) > 0 {
+ //if !yaml_check_utf8(anchor) { return false }
+ anchor_copy = append([]byte(nil), anchor...)
+ }
+ if len(tag) > 0 {
+ //if !yaml_check_utf8(tag) { return false }
+ tag_copy = append([]byte(nil), tag...)
+ }
+
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_START_EVENT,
+ }
+ event.mapping_start.anchor = anchor_copy
+ event.mapping_start.tag = tag_copy
+ event.mapping_start.implicit = implicit
+ event.mapping_start.style = style
+ return true
+}
+
+// Create MAPPING-END.
+func yaml_mapping_end_event_initialize(event *yaml_event_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_END_EVENT,
+ }
+ return true
+}
// Destroy an event object.
func yaml_event_delete(event *yaml_event_t) {
@@ -810,86 +440,86 @@
// */
//
//YAML_DECLARE(int)
-//yaml_document_initialize(yaml_document_t *document,
-// yaml_version_directive_t *version_directive,
-// yaml_tag_directive_t *tag_directives_start,
-// yaml_tag_directive_t *tag_directives_end,
-// int start_implicit, int end_implicit)
+//yaml_document_initialize(document *yaml_document_t,
+// version_directive *yaml_version_directive_t,
+// tag_directives_start *yaml_tag_directive_t,
+// tag_directives_end *yaml_tag_directive_t,
+// start_implicit int, end_implicit int)
//{
// struct {
-// yaml_error_type_t error;
-// } context;
+// error yaml_error_type_t
+// } context
// struct {
-// yaml_node_t *start;
-// yaml_node_t *end;
-// yaml_node_t *top;
-// } nodes = { NULL, NULL, NULL };
-// yaml_version_directive_t *version_directive_copy = NULL;
+// start *yaml_node_t
+// end *yaml_node_t
+// top *yaml_node_t
+// } nodes = { NULL, NULL, NULL }
+// version_directive_copy *yaml_version_directive_t = NULL
// struct {
-// yaml_tag_directive_t *start;
-// yaml_tag_directive_t *end;
-// yaml_tag_directive_t *top;
-// } tag_directives_copy = { NULL, NULL, NULL };
-// yaml_tag_directive_t value = { NULL, NULL };
-// yaml_mark_t mark = { 0, 0, 0 };
+// start *yaml_tag_directive_t
+// end *yaml_tag_directive_t
+// top *yaml_tag_directive_t
+// } tag_directives_copy = { NULL, NULL, NULL }
+// value yaml_tag_directive_t = { NULL, NULL }
+// mark yaml_mark_t = { 0, 0, 0 }
//
-// assert(document); // Non-NULL document object is expected.
+// assert(document) // Non-NULL document object is expected.
// assert((tag_directives_start && tag_directives_end) ||
-// (tag_directives_start == tag_directives_end));
+// (tag_directives_start == tag_directives_end))
// // Valid tag directives are expected.
//
-// if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error;
+// if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error
//
// if (version_directive) {
-// version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
-// if (!version_directive_copy) goto error;
-// version_directive_copy.major = version_directive.major;
-// version_directive_copy.minor = version_directive.minor;
+// version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t))
+// if (!version_directive_copy) goto error
+// version_directive_copy.major = version_directive.major
+// version_directive_copy.minor = version_directive.minor
// }
//
// if (tag_directives_start != tag_directives_end) {
-// yaml_tag_directive_t *tag_directive;
+// tag_directive *yaml_tag_directive_t
// if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
-// goto error;
-// for (tag_directive = tag_directives_start;
+// goto error
+// for (tag_directive = tag_directives_start
// tag_directive != tag_directives_end; tag_directive ++) {
-// assert(tag_directive.handle);
-// assert(tag_directive.prefix);
+// assert(tag_directive.handle)
+// assert(tag_directive.prefix)
// if (!yaml_check_utf8(tag_directive.handle,
// strlen((char *)tag_directive.handle)))
-// goto error;
+// goto error
// if (!yaml_check_utf8(tag_directive.prefix,
// strlen((char *)tag_directive.prefix)))
-// goto error;
-// value.handle = yaml_strdup(tag_directive.handle);
-// value.prefix = yaml_strdup(tag_directive.prefix);
-// if (!value.handle || !value.prefix) goto error;
+// goto error
+// value.handle = yaml_strdup(tag_directive.handle)
+// value.prefix = yaml_strdup(tag_directive.prefix)
+// if (!value.handle || !value.prefix) goto error
// if (!PUSH(&context, tag_directives_copy, value))
-// goto error;
-// value.handle = NULL;
-// value.prefix = NULL;
+// goto error
+// value.handle = NULL
+// value.prefix = NULL
// }
// }
//
// DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
// tag_directives_copy.start, tag_directives_copy.top,
-// start_implicit, end_implicit, mark, mark);
+// start_implicit, end_implicit, mark, mark)
//
-// return 1;
+// return 1
//
//error:
-// STACK_DEL(&context, nodes);
-// yaml_free(version_directive_copy);
+// STACK_DEL(&context, nodes)
+// yaml_free(version_directive_copy)
// while (!STACK_EMPTY(&context, tag_directives_copy)) {
-// yaml_tag_directive_t value = POP(&context, tag_directives_copy);
-// yaml_free(value.handle);
-// yaml_free(value.prefix);
+// value yaml_tag_directive_t = POP(&context, tag_directives_copy)
+// yaml_free(value.handle)
+// yaml_free(value.prefix)
// }
-// STACK_DEL(&context, tag_directives_copy);
-// yaml_free(value.handle);
-// yaml_free(value.prefix);
+// STACK_DEL(&context, tag_directives_copy)
+// yaml_free(value.handle)
+// yaml_free(value.prefix)
//
-// return 0;
+// return 0
//}
//
///*
@@ -897,46 +527,46 @@
// */
//
//YAML_DECLARE(void)
-//yaml_document_delete(yaml_document_t *document)
+//yaml_document_delete(document *yaml_document_t)
//{
// struct {
-// yaml_error_type_t error;
-// } context;
-// yaml_tag_directive_t *tag_directive;
+// error yaml_error_type_t
+// } context
+// tag_directive *yaml_tag_directive_t
//
-// context.error = YAML_NO_ERROR; // Eliminate a compliler warning.
+// context.error = YAML_NO_ERROR // Eliminate a compliler warning.
//
-// assert(document); // Non-NULL document object is expected.
+// assert(document) // Non-NULL document object is expected.
//
// while (!STACK_EMPTY(&context, document.nodes)) {
-// yaml_node_t node = POP(&context, document.nodes);
-// yaml_free(node.tag);
+// node yaml_node_t = POP(&context, document.nodes)
+// yaml_free(node.tag)
// switch (node.type) {
// case YAML_SCALAR_NODE:
-// yaml_free(node.data.scalar.value);
-// break;
+// yaml_free(node.data.scalar.value)
+// break
// case YAML_SEQUENCE_NODE:
-// STACK_DEL(&context, node.data.sequence.items);
-// break;
+// STACK_DEL(&context, node.data.sequence.items)
+// break
// case YAML_MAPPING_NODE:
-// STACK_DEL(&context, node.data.mapping.pairs);
-// break;
+// STACK_DEL(&context, node.data.mapping.pairs)
+// break
// default:
-// assert(0); // Should not happen.
+// assert(0) // Should not happen.
// }
// }
-// STACK_DEL(&context, document.nodes);
+// STACK_DEL(&context, document.nodes)
//
-// yaml_free(document.version_directive);
-// for (tag_directive = document.tag_directives.start;
-// tag_directive != document.tag_directives.end;
+// yaml_free(document.version_directive)
+// for (tag_directive = document.tag_directives.start
+// tag_directive != document.tag_directives.end
// tag_directive++) {
-// yaml_free(tag_directive.handle);
-// yaml_free(tag_directive.prefix);
+// yaml_free(tag_directive.handle)
+// yaml_free(tag_directive.prefix)
// }
-// yaml_free(document.tag_directives.start);
+// yaml_free(document.tag_directives.start)
//
-// memset(document, 0, sizeof(yaml_document_t));
+// memset(document, 0, sizeof(yaml_document_t))
//}
//
///**
@@ -944,14 +574,14 @@
// */
//
//YAML_DECLARE(yaml_node_t *)
-//yaml_document_get_node(yaml_document_t *document, int index)
+//yaml_document_get_node(document *yaml_document_t, index int)
//{
-// assert(document); // Non-NULL document object is expected.
+// assert(document) // Non-NULL document object is expected.
//
// if (index > 0 && document.nodes.start + index <= document.nodes.top) {
-// return document.nodes.start + index - 1;
+// return document.nodes.start + index - 1
// }
-// return NULL;
+// return NULL
//}
//
///**
@@ -959,14 +589,14 @@
// */
//
//YAML_DECLARE(yaml_node_t *)
-//yaml_document_get_root_node(yaml_document_t *document)
+//yaml_document_get_root_node(document *yaml_document_t)
//{
-// assert(document); // Non-NULL document object is expected.
+// assert(document) // Non-NULL document object is expected.
//
// if (document.nodes.top != document.nodes.start) {
-// return document.nodes.start;
+// return document.nodes.start
// }
-// return NULL;
+// return NULL
//}
//
///*
@@ -974,49 +604,49 @@
// */
//
//YAML_DECLARE(int)
-//yaml_document_add_scalar(yaml_document_t *document,
-// yaml_char_t *tag, yaml_char_t *value, int length,
-// yaml_scalar_style_t style)
+//yaml_document_add_scalar(document *yaml_document_t,
+// tag *yaml_char_t, value *yaml_char_t, length int,
+// style yaml_scalar_style_t)
//{
// struct {
-// yaml_error_type_t error;
-// } context;
-// yaml_mark_t mark = { 0, 0, 0 };
-// yaml_char_t *tag_copy = NULL;
-// yaml_char_t *value_copy = NULL;
-// yaml_node_t node;
+// error yaml_error_type_t
+// } context
+// mark yaml_mark_t = { 0, 0, 0 }
+// tag_copy *yaml_char_t = NULL
+// value_copy *yaml_char_t = NULL
+// node yaml_node_t
//
-// assert(document); // Non-NULL document object is expected.
-// assert(value); // Non-NULL value is expected.
+// assert(document) // Non-NULL document object is expected.
+// assert(value) // Non-NULL value is expected.
//
// if (!tag) {
-// tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG;
+// tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG
// }
//
-// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
-// tag_copy = yaml_strdup(tag);
-// if (!tag_copy) goto error;
+// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
+// tag_copy = yaml_strdup(tag)
+// if (!tag_copy) goto error
//
// if (length < 0) {
-// length = strlen((char *)value);
+// length = strlen((char *)value)
// }
//
-// if (!yaml_check_utf8(value, length)) goto error;
-// value_copy = yaml_malloc(length+1);
-// if (!value_copy) goto error;
-// memcpy(value_copy, value, length);
-// value_copy[length] = '\0';
+// if (!yaml_check_utf8(value, length)) goto error
+// value_copy = yaml_malloc(length+1)
+// if (!value_copy) goto error
+// memcpy(value_copy, value, length)
+// value_copy[length] = '\0'
//
-// SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark);
-// if (!PUSH(&context, document.nodes, node)) goto error;
+// SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark)
+// if (!PUSH(&context, document.nodes, node)) goto error
//
-// return document.nodes.top - document.nodes.start;
+// return document.nodes.top - document.nodes.start
//
//error:
-// yaml_free(tag_copy);
-// yaml_free(value_copy);
+// yaml_free(tag_copy)
+// yaml_free(value_copy)
//
-// return 0;
+// return 0
//}
//
///*
@@ -1024,44 +654,44 @@
// */
//
//YAML_DECLARE(int)
-//yaml_document_add_sequence(yaml_document_t *document,
-// yaml_char_t *tag, yaml_sequence_style_t style)
+//yaml_document_add_sequence(document *yaml_document_t,
+// tag *yaml_char_t, style yaml_sequence_style_t)
//{
// struct {
-// yaml_error_type_t error;
-// } context;
-// yaml_mark_t mark = { 0, 0, 0 };
-// yaml_char_t *tag_copy = NULL;
+// error yaml_error_type_t
+// } context
+// mark yaml_mark_t = { 0, 0, 0 }
+// tag_copy *yaml_char_t = NULL
// struct {
-// yaml_node_item_t *start;
-// yaml_node_item_t *end;
-// yaml_node_item_t *top;
-// } items = { NULL, NULL, NULL };
-// yaml_node_t node;
+// start *yaml_node_item_t
+// end *yaml_node_item_t
+// top *yaml_node_item_t
+// } items = { NULL, NULL, NULL }
+// node yaml_node_t
//
-// assert(document); // Non-NULL document object is expected.
+// assert(document) // Non-NULL document object is expected.
//
// if (!tag) {
-// tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG;
+// tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG
// }
//
-// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
-// tag_copy = yaml_strdup(tag);
-// if (!tag_copy) goto error;
+// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
+// tag_copy = yaml_strdup(tag)
+// if (!tag_copy) goto error
//
-// if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error;
+// if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error
//
// SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
-// style, mark, mark);
-// if (!PUSH(&context, document.nodes, node)) goto error;
+// style, mark, mark)
+// if (!PUSH(&context, document.nodes, node)) goto error
//
-// return document.nodes.top - document.nodes.start;
+// return document.nodes.top - document.nodes.start
//
//error:
-// STACK_DEL(&context, items);
-// yaml_free(tag_copy);
+// STACK_DEL(&context, items)
+// yaml_free(tag_copy)
//
-// return 0;
+// return 0
//}
//
///*
@@ -1069,44 +699,44 @@
// */
//
//YAML_DECLARE(int)
-//yaml_document_add_mapping(yaml_document_t *document,
-// yaml_char_t *tag, yaml_mapping_style_t style)
+//yaml_document_add_mapping(document *yaml_document_t,
+// tag *yaml_char_t, style yaml_mapping_style_t)
//{
// struct {
-// yaml_error_type_t error;
-// } context;
-// yaml_mark_t mark = { 0, 0, 0 };
-// yaml_char_t *tag_copy = NULL;
+// error yaml_error_type_t
+// } context
+// mark yaml_mark_t = { 0, 0, 0 }
+// tag_copy *yaml_char_t = NULL
// struct {
-// yaml_node_pair_t *start;
-// yaml_node_pair_t *end;
-// yaml_node_pair_t *top;
-// } pairs = { NULL, NULL, NULL };
-// yaml_node_t node;
+// start *yaml_node_pair_t
+// end *yaml_node_pair_t
+// top *yaml_node_pair_t
+// } pairs = { NULL, NULL, NULL }
+// node yaml_node_t
//
-// assert(document); // Non-NULL document object is expected.
+// assert(document) // Non-NULL document object is expected.
//
// if (!tag) {
-// tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG;
+// tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG
// }
//
-// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
-// tag_copy = yaml_strdup(tag);
-// if (!tag_copy) goto error;
+// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
+// tag_copy = yaml_strdup(tag)
+// if (!tag_copy) goto error
//
-// if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error;
+// if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error
//
// MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
-// style, mark, mark);
-// if (!PUSH(&context, document.nodes, node)) goto error;
+// style, mark, mark)
+// if (!PUSH(&context, document.nodes, node)) goto error
//
-// return document.nodes.top - document.nodes.start;
+// return document.nodes.top - document.nodes.start
//
//error:
-// STACK_DEL(&context, pairs);
-// yaml_free(tag_copy);
+// STACK_DEL(&context, pairs)
+// yaml_free(tag_copy)
//
-// return 0;
+// return 0
//}
//
///*
@@ -1114,27 +744,27 @@
// */
//
//YAML_DECLARE(int)
-//yaml_document_append_sequence_item(yaml_document_t *document,
-// int sequence, int item)
+//yaml_document_append_sequence_item(document *yaml_document_t,
+// sequence int, item int)
//{
// struct {
-// yaml_error_type_t error;
-// } context;
+// error yaml_error_type_t
+// } context
//
-// assert(document); // Non-NULL document is required.
+// assert(document) // Non-NULL document is required.
// assert(sequence > 0
-// && document.nodes.start + sequence <= document.nodes.top);
+// && document.nodes.start + sequence <= document.nodes.top)
// // Valid sequence id is required.
-// assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE);
+// assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE)
// // A sequence node is required.
-// assert(item > 0 && document.nodes.start + item <= document.nodes.top);
+// assert(item > 0 && document.nodes.start + item <= document.nodes.top)
// // Valid item id is required.
//
// if (!PUSH(&context,
// document.nodes.start[sequence-1].data.sequence.items, item))
-// return 0;
+// return 0
//
-// return 1;
+// return 1
//}
//
///*
@@ -1142,34 +772,34 @@
// */
//
//YAML_DECLARE(int)
-//yaml_document_append_mapping_pair(yaml_document_t *document,
-// int mapping, int key, int value)
+//yaml_document_append_mapping_pair(document *yaml_document_t,
+// mapping int, key int, value int)
//{
// struct {
-// yaml_error_type_t error;
-// } context;
+// error yaml_error_type_t
+// } context
//
-// yaml_node_pair_t pair;
+// pair yaml_node_pair_t
//
-// assert(document); // Non-NULL document is required.
+// assert(document) // Non-NULL document is required.
// assert(mapping > 0
-// && document.nodes.start + mapping <= document.nodes.top);
+// && document.nodes.start + mapping <= document.nodes.top)
// // Valid mapping id is required.
-// assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE);
+// assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE)
// // A mapping node is required.
-// assert(key > 0 && document.nodes.start + key <= document.nodes.top);
+// assert(key > 0 && document.nodes.start + key <= document.nodes.top)
// // Valid key id is required.
-// assert(value > 0 && document.nodes.start + value <= document.nodes.top);
+// assert(value > 0 && document.nodes.start + value <= document.nodes.top)
// // Valid value id is required.
//
-// pair.key = key;
-// pair.value = value;
+// pair.key = key
+// pair.value = value
//
// if (!PUSH(&context,
// document.nodes.start[mapping-1].data.mapping.pairs, pair))
-// return 0;
+// return 0
//
-// return 1;
+// return 1
//}
//
//
diff --git a/emitter_c.go b/emitter_c.go
new file mode 100644
index 0000000..a97d406
--- /dev/null
+++ b/emitter_c.go
@@ -0,0 +1,2330 @@
+package goyaml
+
+//#include "yaml_private.h"
+//
+///*
+// * Flush the buffer if needed.
+// */
+//
+//#define FLUSH(emitter) \
+// ((emitter->buffer.pointer+5 < emitter->buffer.end) \
+// || yaml_emitter_flush(emitter))
+//
+///*
+// * Put a character to the output buffer.
+// */
+//
+//#define PUT(emitter,value) \
+// (FLUSH(emitter) \
+// && (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \
+// emitter->column ++, \
+// 1))
+//
+///*
+// * Put a line break to the output buffer.
+// */
+//
+//#define PUT_BREAK(emitter) \
+// (FLUSH(emitter) \
+// && ((emitter->line_break == YAML_CR_BREAK ? \
+// (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') : \
+// emitter->line_break == YAML_LN_BREAK ? \
+// (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') : \
+// emitter->line_break == YAML_CRLN_BREAK ? \
+// (*(emitter->buffer.pointer++) = (yaml_char_t) '\r', \
+// *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0), \
+// emitter->column = 0, \
+// emitter->line ++, \
+// 1))
+//
+///*
+// * Copy a character from a string into buffer.
+// */
+//
+//#define WRITE(emitter,string) \
+// (FLUSH(emitter) \
+// && (COPY(emitter->buffer,string), \
+// emitter->column ++, \
+// 1))
+//
+///*
+// * Copy a line break character from a string into buffer.
+// */
+//
+//#define WRITE_BREAK(emitter,string) \
+// (FLUSH(emitter) \
+// && (CHECK(string,'\n') ? \
+// (PUT_BREAK(emitter), \
+// string.pointer ++, \
+// 1) : \
+// (COPY(emitter->buffer,string), \
+// emitter->column = 0, \
+// emitter->line ++, \
+// 1)))
+//
+///*
+// * API functions.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+///*
+// * Utility functions.
+// */
+//
+//static int
+//yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem);
+//
+//static int
+//yaml_emitter_need_more_events(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
+// yaml_tag_directive_t value, int allow_duplicates);
+//
+//static int
+//yaml_emitter_increase_indent(yaml_emitter_t *emitter,
+// int flow, int indentless);
+//
+///*
+// * State functions.
+// */
+//
+//static int
+//yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
+// yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
+// yaml_event_t *event, int first);
+//
+//static int
+//yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
+// yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
+// yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
+// yaml_event_t *event, int first);
+//
+//static int
+//yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
+// yaml_event_t *event, int first);
+//
+//static int
+//yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
+// yaml_event_t *event, int simple);
+//
+//static int
+//yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
+// yaml_event_t *event, int first);
+//
+//static int
+//yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
+// yaml_event_t *event, int first);
+//
+//static int
+//yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
+// yaml_event_t *event, int simple);
+//
+//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_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+//static int
+//yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+///*
+// * Checkers.
+// */
+//
+//static int
+//yaml_emitter_check_empty_document(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_check_simple_key(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event);
+//
+///*
+// * Processors.
+// */
+//
+//static int
+//yaml_emitter_process_anchor(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_process_tag(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_process_scalar(yaml_emitter_t *emitter);
+//
+///*
+// * Analyzers.
+// */
+//
+//static int
+//yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
+// yaml_version_directive_t version_directive);
+//
+//static int
+//yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
+// yaml_tag_directive_t tag_directive);
+//
+//static int
+//yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
+// yaml_char_t *anchor, int alias);
+//
+//static int
+//yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
+// yaml_char_t *tag);
+//
+//static int
+//yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
+// yaml_char_t *value, size_t length);
+//
+//static int
+//yaml_emitter_analyze_event(yaml_emitter_t *emitter,
+// yaml_event_t *event);
+//
+///*
+// * Writers.
+// */
+//
+//static int
+//yaml_emitter_write_bom(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_write_indent(yaml_emitter_t *emitter);
+//
+//static int
+//yaml_emitter_write_indicator(yaml_emitter_t *emitter,
+// char *indicator, int need_whitespace,
+// int is_whitespace, int is_indention);
+//
+//static int
+//yaml_emitter_write_anchor(yaml_emitter_t *emitter,
+// yaml_char_t *value, size_t length);
+//
+//static int
+//yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
+// yaml_char_t *value, size_t length);
+//
+//static int
+//yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
+// yaml_char_t *value, size_t length, int need_whitespace);
+//
+//static int
+//yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
+// yaml_char_t *value, size_t length, int allow_breaks);
+//
+//static int
+//yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
+// yaml_char_t *value, size_t length, int allow_breaks);
+//
+//static int
+//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);
+//
+//static int
+//yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
+// yaml_char_t *value, size_t length);
+//
+///*
+// * Set an emitter error and return 0.
+// */
+//
+//static int
+//yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem)
+//{
+// emitter->error = YAML_EMITTER_ERROR;
+// emitter->problem = problem;
+//
+// return 0;
+//}
+//
+///*
+// * Emit an event.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+// if (!ENQUEUE(emitter, emitter->events, *event)) {
+// yaml_event_delete(event);
+// return 0;
+// }
+//
+// while (!yaml_emitter_need_more_events(emitter)) {
+// if (!yaml_emitter_analyze_event(emitter, emitter->events.head))
+// return 0;
+// if (!yaml_emitter_state_machine(emitter, emitter->events.head))
+// return 0;
+// yaml_event_delete(&DEQUEUE(emitter, emitter->events));
+// }
+//
+// return 1;
+//}
+//
+///*
+// * Check if we need to accumulate more events before emitting.
+// *
+// * We accumulate extra
+// * - 1 event for DOCUMENT-START
+// * - 2 events for SEQUENCE-START
+// * - 3 events for MAPPING-START
+// */
+//
+//static int
+//yaml_emitter_need_more_events(yaml_emitter_t *emitter)
+//{
+// int level = 0;
+// int accumulate = 0;
+// yaml_event_t *event;
+//
+// if (QUEUE_EMPTY(emitter, emitter->events))
+// return 1;
+//
+// switch (emitter->events.head->type) {
+// case YAML_DOCUMENT_START_EVENT:
+// accumulate = 1;
+// break;
+// case YAML_SEQUENCE_START_EVENT:
+// accumulate = 2;
+// break;
+// case YAML_MAPPING_START_EVENT:
+// accumulate = 3;
+// break;
+// default:
+// return 0;
+// }
+//
+// if (emitter->events.tail - emitter->events.head > accumulate)
+// return 0;
+//
+// for (event = emitter->events.head; event != emitter->events.tail; event ++) {
+// switch (event->type) {
+// case YAML_STREAM_START_EVENT:
+// case YAML_DOCUMENT_START_EVENT:
+// case YAML_SEQUENCE_START_EVENT:
+// case YAML_MAPPING_START_EVENT:
+// level += 1;
+// break;
+// case YAML_STREAM_END_EVENT:
+// case YAML_DOCUMENT_END_EVENT:
+// case YAML_SEQUENCE_END_EVENT:
+// case YAML_MAPPING_END_EVENT:
+// level -= 1;
+// break;
+// default:
+// break;
+// }
+// if (!level)
+// return 0;
+// }
+//
+// return 1;
+//}
+//
+///*
+// * Append a directive to the directives stack.
+// */
+//
+//static int
+//yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
+// yaml_tag_directive_t value, int allow_duplicates)
+//{
+// yaml_tag_directive_t *tag_directive;
+// yaml_tag_directive_t copy = { NULL, NULL };
+//
+// for (tag_directive = emitter->tag_directives.start;
+// tag_directive != emitter->tag_directives.top; tag_directive ++) {
+// if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
+// if (allow_duplicates)
+// return 1;
+// return yaml_emitter_set_emitter_error(emitter,
+// "duplicate %TAG directive");
+// }
+// }
+//
+// copy.handle = yaml_strdup(value.handle);
+// copy.prefix = yaml_strdup(value.prefix);
+// if (!copy.handle || !copy.prefix) {
+// emitter->error = YAML_MEMORY_ERROR;
+// goto error;
+// }
+//
+// if (!PUSH(emitter, emitter->tag_directives, copy))
+// goto error;
+//
+// return 1;
+//
+//error:
+// yaml_free(copy.handle);
+// yaml_free(copy.prefix);
+// return 0;
+//}
+//
+///*
+// * Increase the indentation level.
+// */
+//
+//static int
+//yaml_emitter_increase_indent(yaml_emitter_t *emitter,
+// int flow, int indentless)
+//{
+// if (!PUSH(emitter, emitter->indents, emitter->indent))
+// return 0;
+//
+// if (emitter->indent < 0) {
+// emitter->indent = flow ? emitter->best_indent : 0;
+// }
+// else if (!indentless) {
+// emitter->indent += emitter->best_indent;
+// }
+//
+// return 1;
+//}
+//
+///*
+// * State dispatcher.
+// */
+//
+//static int
+//yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+// switch (emitter->state)
+// {
+// case YAML_EMIT_STREAM_START_STATE:
+// return yaml_emitter_emit_stream_start(emitter, event);
+//
+// case YAML_EMIT_FIRST_DOCUMENT_START_STATE:
+// return yaml_emitter_emit_document_start(emitter, event, 1);
+//
+// case YAML_EMIT_DOCUMENT_START_STATE:
+// return yaml_emitter_emit_document_start(emitter, event, 0);
+//
+// case YAML_EMIT_DOCUMENT_CONTENT_STATE:
+// return yaml_emitter_emit_document_content(emitter, event);
+//
+// case YAML_EMIT_DOCUMENT_END_STATE:
+// return yaml_emitter_emit_document_end(emitter, event);
+//
+// case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
+// return yaml_emitter_emit_flow_sequence_item(emitter, event, 1);
+//
+// case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE:
+// return yaml_emitter_emit_flow_sequence_item(emitter, event, 0);
+//
+// case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
+// return yaml_emitter_emit_flow_mapping_key(emitter, event, 1);
+//
+// case YAML_EMIT_FLOW_MAPPING_KEY_STATE:
+// return yaml_emitter_emit_flow_mapping_key(emitter, event, 0);
+//
+// case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
+// return yaml_emitter_emit_flow_mapping_value(emitter, event, 1);
+//
+// case YAML_EMIT_FLOW_MAPPING_VALUE_STATE:
+// return yaml_emitter_emit_flow_mapping_value(emitter, event, 0);
+//
+// case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
+// return yaml_emitter_emit_block_sequence_item(emitter, event, 1);
+//
+// case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
+// return yaml_emitter_emit_block_sequence_item(emitter, event, 0);
+//
+// case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
+// return yaml_emitter_emit_block_mapping_key(emitter, event, 1);
+//
+// case YAML_EMIT_BLOCK_MAPPING_KEY_STATE:
+// return yaml_emitter_emit_block_mapping_key(emitter, event, 0);
+//
+// case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
+// return yaml_emitter_emit_block_mapping_value(emitter, event, 1);
+//
+// case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE:
+// return yaml_emitter_emit_block_mapping_value(emitter, event, 0);
+//
+// case YAML_EMIT_END_STATE:
+// return yaml_emitter_set_emitter_error(emitter,
+// "expected nothing after STREAM-END");
+//
+// default:
+// assert(1); /* Invalid state. */
+// }
+//
+// return 0;
+//}
+//
+///*
+// * Expect STREAM-START.
+// */
+//
+//static int
+//yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
+// yaml_event_t *event)
+//{
+// if (event->type == YAML_STREAM_START_EVENT)
+// {
+// if (!emitter->encoding) {
+// emitter->encoding = event->data.stream_start.encoding;
+// }
+//
+// if (!emitter->encoding) {
+// emitter->encoding = YAML_UTF8_ENCODING;
+// }
+//
+// if (emitter->best_indent < 2 || emitter->best_indent > 9) {
+// emitter->best_indent = 2;
+// }
+//
+// if (emitter->best_width >= 0
+// && emitter->best_width <= emitter->best_indent*2) {
+// emitter->best_width = 80;
+// }
+//
+// if (emitter->best_width < 0) {
+// emitter->best_width = INT_MAX;
+// }
+//
+// if (!emitter->line_break) {
+// emitter->line_break = YAML_LN_BREAK;
+// }
+//
+// emitter->indent = -1;
+//
+// emitter->line = 0;
+// emitter->column = 0;
+// emitter->whitespace = 1;
+// emitter->indention = 1;
+//
+// if (emitter->encoding != YAML_UTF8_ENCODING) {
+// if (!yaml_emitter_write_bom(emitter))
+// return 0;
+// }
+//
+// emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE;
+//
+// return 1;
+// }
+//
+// return yaml_emitter_set_emitter_error(emitter,
+// "expected STREAM-START");
+//}
+//
+///*
+// * Expect DOCUMENT-START or STREAM-END.
+// */
+//
+//static int
+//yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
+// yaml_event_t *event, int first)
+//{
+// if (event->type == YAML_DOCUMENT_START_EVENT)
+// {
+// yaml_tag_directive_t default_tag_directives[] = {
+// {(yaml_char_t *)"!", (yaml_char_t *)"!"},
+// {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
+// {NULL, NULL}
+// };
+// yaml_tag_directive_t *tag_directive;
+// int implicit;
+//
+// if (event->data.document_start.version_directive) {
+// if (!yaml_emitter_analyze_version_directive(emitter,
+// *event->data.document_start.version_directive))
+// return 0;
+// }
+//
+// for (tag_directive = event->data.document_start.tag_directives.start;
+// tag_directive != event->data.document_start.tag_directives.end;
+// tag_directive ++) {
+// if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive))
+// return 0;
+// if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0))
+// return 0;
+// }
+//
+// for (tag_directive = default_tag_directives;
+// tag_directive->handle; tag_directive ++) {
+// if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1))
+// return 0;
+// }
+//
+// implicit = event->data.document_start.implicit;
+// if (!first || emitter->canonical) {
+// 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))
+// return 0;
+// if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
+// return 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;
+// for (tag_directive = event->data.document_start.tag_directives.start;
+// tag_directive != event->data.document_start.tag_directives.end;
+// tag_directive ++) {
+// if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0))
+// return 0;
+// if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle,
+// strlen((char *)tag_directive->handle)))
+// return 0;
+// if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix,
+// strlen((char *)tag_directive->prefix), 1))
+// return 0;
+// if (!yaml_emitter_write_indent(emitter))
+// return 0;
+// }
+// }
+//
+// if (yaml_emitter_check_empty_document(emitter)) {
+// implicit = 0;
+// }
+//
+// if (!implicit) {
+// if (!yaml_emitter_write_indent(emitter))
+// return 0;
+// if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0))
+// return 0;
+// if (emitter->canonical) {
+// if (!yaml_emitter_write_indent(emitter))
+// return 0;
+// }
+// }
+//
+// emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE;
+//
+// return 1;
+// }
+//
+// else if (event->type == YAML_STREAM_END_EVENT)
+// {
+// if (emitter->open_ended)
+// {
+// if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
+// return 0;
+// if (!yaml_emitter_write_indent(emitter))
+// return 0;
+// }
+//
+// if (!yaml_emitter_flush(emitter))
+// return 0;
+//
+// emitter->state = YAML_EMIT_END_STATE;
+//
+// return 1;
+// }
+//
+// return yaml_emitter_set_emitter_error(emitter,
+// "expected DOCUMENT-START or STREAM-END");
+//}
+//
+///*
+// * Expect the root node.
+// */
+//
+//static int
+//yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
+// yaml_event_t *event)
+//{
+// if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE))
+// return 0;
+//
+// return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0);
+//}
+//
+///*
+// * Expect DOCUMENT-END.
+// */
+//
+//static int
+//yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
+// yaml_event_t *event)
+//{
+// if (event->type == YAML_DOCUMENT_END_EVENT)
+// {
+// if (!yaml_emitter_write_indent(emitter))
+// return 0;
+// if (!event->data.document_end.implicit) {
+// if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
+// return 0;
+// if (!yaml_emitter_write_indent(emitter))
+// return 0;
+// }
+// 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;
+// }
+//
+// return yaml_emitter_set_emitter_error(emitter,
+// "expected DOCUMENT-END");
+//}
+//
+///*
+// *
+// * Expect a flow item node.
+// */
+//
+//static int
+//yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
+// yaml_event_t *event, int first)
+//{
+// if (first)
+// {
+// if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0))
+// return 0;
+// if (!yaml_emitter_increase_indent(emitter, 1, 0))
+// return 0;
+// emitter->flow_level ++;
+// }
+//
+// if (event->type == YAML_SEQUENCE_END_EVENT)
+// {
+// emitter->flow_level --;
+// emitter->indent = POP(emitter, emitter->indents);
+// if (emitter->canonical && !first) {
+// if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
+// return 0;
+// if (!yaml_emitter_write_indent(emitter))
+// return 0;
+// }
+// if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0))
+// return 0;
+// emitter->state = POP(emitter, emitter->states);
+//
+// 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))
+// return 0;
+//
+// return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
+//}
+//
+///*
+// * Expect a flow key node.
+// */
+//
+//static int
+//yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
+// yaml_event_t *event, int first)
+//{
+// if (first)
+// {
+// if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0))
+// return 0;
+// if (!yaml_emitter_increase_indent(emitter, 1, 0))
+// return 0;
+// emitter->flow_level ++;
+// }
+//
+// if (event->type == YAML_MAPPING_END_EVENT)
+// {
+// emitter->flow_level --;
+// emitter->indent = POP(emitter, emitter->indents);
+// if (emitter->canonical && !first) {
+// if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
+// return 0;
+// if (!yaml_emitter_write_indent(emitter))
+// return 0;
+// }
+// if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0))
+// return 0;
+// emitter->state = POP(emitter, emitter->states);
+//
+// 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 (!emitter->canonical && yaml_emitter_check_simple_key(emitter))
+// {
+// if (!PUSH(emitter, emitter->states,
+// YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE))
+// return 0;
+//
+// return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
+// }
+// else
+// {
+// if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0))
+// return 0;
+// if (!PUSH(emitter, emitter->states,
+// YAML_EMIT_FLOW_MAPPING_VALUE_STATE))
+// return 0;
+//
+// return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
+// }
+//}
+//
+///*
+// * Expect a flow value node.
+// */
+//
+//static int
+//yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
+// yaml_event_t *event, int simple)
+//{
+// if (simple) {
+// if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
+// return 0;
+// }
+// else {
+// if (emitter->canonical || emitter->column > emitter->best_width) {
+// if (!yaml_emitter_write_indent(emitter))
+// return 0;
+// }
+// if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0))
+// return 0;
+// }
+// if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE))
+// return 0;
+// return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
+//}
+//
+///*
+// * Expect a block item node.
+// */
+//
+//static int
+//yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
+// yaml_event_t *event, int first)
+//{
+// if (first)
+// {
+// if (!yaml_emitter_increase_indent(emitter, 0,
+// (emitter->mapping_context && !emitter->indention)))
+// return 0;
+// }
+//
+// if (event->type == YAML_SEQUENCE_END_EVENT)
+// {
+// emitter->indent = POP(emitter, emitter->indents);
+// emitter->state = POP(emitter, emitter->states);
+//
+// return 1;
+// }
+//
+// if (!yaml_emitter_write_indent(emitter))
+// return 0;
+// if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1))
+// return 0;
+// if (!PUSH(emitter, emitter->states,
+// YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE))
+// return 0;
+//
+// return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
+//}
+//
+///*
+// * Expect a block key node.
+// */
+//
+//static int
+//yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
+// yaml_event_t *event, int first)
+//{
+// if (first)
+// {
+// if (!yaml_emitter_increase_indent(emitter, 0, 0))
+// return 0;
+// }
+//
+// if (event->type == YAML_MAPPING_END_EVENT)
+// {
+// emitter->indent = POP(emitter, emitter->indents);
+// emitter->state = POP(emitter, emitter->states);
+//
+// return 1;
+// }
+//
+// if (!yaml_emitter_write_indent(emitter))
+// return 0;
+//
+// if (yaml_emitter_check_simple_key(emitter))
+// {
+// if (!PUSH(emitter, emitter->states,
+// YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE))
+// return 0;
+//
+// return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
+// }
+// else
+// {
+// if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1))
+// return 0;
+// if (!PUSH(emitter, emitter->states,
+// YAML_EMIT_BLOCK_MAPPING_VALUE_STATE))
+// return 0;
+//
+// return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
+// }
+//}
+//
+///*
+// * Expect a block value node.
+// */
+//
+//static int
+//yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
+// yaml_event_t *event, int simple)
+//{
+// if (simple) {
+// if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
+// return 0;
+// }
+// else {
+// if (!yaml_emitter_write_indent(emitter))
+// return 0;
+// if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1))
+// return 0;
+// }
+// if (!PUSH(emitter, emitter->states,
+// YAML_EMIT_BLOCK_MAPPING_KEY_STATE))
+// return 0;
+//
+// return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
+//}
+//
+///*
+// * Expect a node.
+// */
+//
+//static int
+//yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
+// int root, int sequence, int mapping, int simple_key)
+//{
+// emitter->root_context = root;
+// emitter->sequence_context = sequence;
+// emitter->mapping_context = mapping;
+// emitter->simple_key_context = simple_key;
+//
+// switch (event->type)
+// {
+// case YAML_ALIAS_EVENT:
+// return yaml_emitter_emit_alias(emitter, event);
+//
+// case YAML_SCALAR_EVENT:
+// return yaml_emitter_emit_scalar(emitter, event);
+//
+// case YAML_SEQUENCE_START_EVENT:
+// return yaml_emitter_emit_sequence_start(emitter, event);
+//
+// case YAML_MAPPING_START_EVENT:
+// return yaml_emitter_emit_mapping_start(emitter, event);
+//
+// default:
+// return yaml_emitter_set_emitter_error(emitter,
+// "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS");
+// }
+//
+// return 0;
+//}
+//
+///*
+// * Expect ALIAS.
+// */
+//
+//static int
+//yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+// if (!yaml_emitter_process_anchor(emitter))
+// return 0;
+// emitter->state = POP(emitter, emitter->states);
+//
+// return 1;
+//}
+//
+///*
+// * Expect SCALAR.
+// */
+//
+//static int
+//yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+// if (!yaml_emitter_select_scalar_style(emitter, event))
+// return 0;
+// if (!yaml_emitter_process_anchor(emitter))
+// return 0;
+// if (!yaml_emitter_process_tag(emitter))
+// return 0;
+// if (!yaml_emitter_increase_indent(emitter, 1, 0))
+// return 0;
+// if (!yaml_emitter_process_scalar(emitter))
+// return 0;
+// emitter->indent = POP(emitter, emitter->indents);
+// emitter->state = POP(emitter, emitter->states);
+//
+// return 1;
+//}
+//
+///*
+// * Expect SEQUENCE-START.
+// */
+//
+//static int
+//yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+// if (!yaml_emitter_process_anchor(emitter))
+// return 0;
+// if (!yaml_emitter_process_tag(emitter))
+// return 0;
+//
+// if (emitter->flow_level || emitter->canonical
+// || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE
+// || yaml_emitter_check_empty_sequence(emitter)) {
+// emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE;
+// }
+// else {
+// emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE;
+// }
+//
+// return 1;
+//}
+//
+///*
+// * Expect MAPPING-START.
+// */
+//
+//static int
+//yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event)
+//{
+// if (!yaml_emitter_process_anchor(emitter))
+// return 0;
+// if (!yaml_emitter_process_tag(emitter))
+// return 0;
+//
+// if (emitter->flow_level || emitter->canonical
+// || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE
+// || yaml_emitter_check_empty_mapping(emitter)) {
+// emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE;
+// }
+// else {
+// emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE;
+// }
+//
+// return 1;
+//}
+//
+///*
+// * Check if the document content is an empty scalar.
+// */
+//
+//static int
+//yaml_emitter_check_empty_document(yaml_emitter_t *emitter)
+//{
+// return 0;
+//}
+//
+///*
+// * Check if the next events represent an empty sequence.
+// */
+//
+//static int
+//yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter)
+//{
+// if (emitter->events.tail - emitter->events.head < 2)
+// return 0;
+//
+// return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT
+// && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT);
+//}
+//
+///*
+// * Check if the next events represent an empty mapping.
+// */
+//
+//static int
+//yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter)
+//{
+// if (emitter->events.tail - emitter->events.head < 2)
+// return 0;
+//
+// return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT
+// && emitter->events.head[1].type == YAML_MAPPING_END_EVENT);
+//}
+//
+///*
+// * Check if the next node can be expressed as a simple key.
+// */
+//
+//static int
+//yaml_emitter_check_simple_key(yaml_emitter_t *emitter)
+//{
+// yaml_event_t *event = emitter->events.head;
+// size_t length = 0;
+//
+// switch (event->type)
+// {
+// case YAML_ALIAS_EVENT:
+// length += emitter->anchor_data.anchor_length;
+// break;
+//
+// case YAML_SCALAR_EVENT:
+// if (emitter->scalar_data.multiline)
+// return 0;
+// length += emitter->anchor_data.anchor_length
+// + emitter->tag_data.handle_length
+// + emitter->tag_data.suffix_length
+// + emitter->scalar_data.length;
+// break;
+//
+// case YAML_SEQUENCE_START_EVENT:
+// if (!yaml_emitter_check_empty_sequence(emitter))
+// return 0;
+// length += emitter->anchor_data.anchor_length
+// + emitter->tag_data.handle_length
+// + emitter->tag_data.suffix_length;
+// break;
+//
+// case YAML_MAPPING_START_EVENT:
+// if (!yaml_emitter_check_empty_mapping(emitter))
+// return 0;
+// length += emitter->anchor_data.anchor_length
+// + emitter->tag_data.handle_length
+// + emitter->tag_data.suffix_length;
+// break;
+//
+// default:
+// return 0;
+// }
+//
+// if (length > 128)
+// return 0;
+//
+// return 1;
+//}
+//
+///*
+// * Determine an acceptable scalar style.
+// */
+//
+//static int
+//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->canonical)
+// style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+//
+// if (emitter->simple_key_context && emitter->scalar_data.multiline)
+// style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+//
+// if (style == YAML_PLAIN_SCALAR_STYLE)
+// {
+// if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed)
+// || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed))
+// style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
+// if (!emitter->scalar_data.length
+// && (emitter->flow_level || emitter->simple_key_context))
+// style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
+// if (no_tag && !event->data.scalar.plain_implicit)
+// style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
+// }
+//
+// if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE)
+// {
+// if (!emitter->scalar_data.single_quoted_allowed)
+// style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+// }
+//
+// if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE)
+// {
+// if (!emitter->scalar_data.block_allowed
+// || emitter->flow_level || emitter->simple_key_context)
+// style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+// }
+//
+// if (no_tag && !event->data.scalar.quoted_implicit
+// && style != YAML_PLAIN_SCALAR_STYLE)
+// {
+// emitter->tag_data.handle = (yaml_char_t *)"!";
+// emitter->tag_data.handle_length = 1;
+// }
+//
+// emitter->scalar_data.style = style;
+//
+// return 1;
+//}
+//
+///*
+// * Write an achor.
+// */
+//
+//static int
+//yaml_emitter_process_anchor(yaml_emitter_t *emitter)
+//{
+// if (!emitter->anchor_data.anchor)
+// return 1;
+//
+// if (!yaml_emitter_write_indicator(emitter,
+// (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0))
+// return 0;
+//
+// return yaml_emitter_write_anchor(emitter,
+// emitter->anchor_data.anchor, emitter->anchor_data.anchor_length);
+//}
+//
+///*
+// * Write a tag.
+// */
+//
+//static int
+//yaml_emitter_process_tag(yaml_emitter_t *emitter)
+//{
+// if (!emitter->tag_data.handle && !emitter->tag_data.suffix)
+// return 1;
+//
+// if (emitter->tag_data.handle)
+// {
+// if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle,
+// emitter->tag_data.handle_length))
+// return 0;
+// if (emitter->tag_data.suffix) {
+// if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
+// emitter->tag_data.suffix_length, 0))
+// return 0;
+// }
+// }
+// else
+// {
+// 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, 0))
+// return 0;
+// if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0))
+// return 0;
+// }
+//
+// return 1;
+//}
+//
+///*
+// * Write a scalar.
+// */
+//
+//static int
+//yaml_emitter_process_scalar(yaml_emitter_t *emitter)
+//{
+// switch (emitter->scalar_data.style)
+// {
+// case YAML_PLAIN_SCALAR_STYLE:
+// return yaml_emitter_write_plain_scalar(emitter,
+// emitter->scalar_data.value, emitter->scalar_data.length,
+// !emitter->simple_key_context);
+//
+// case YAML_SINGLE_QUOTED_SCALAR_STYLE:
+// return yaml_emitter_write_single_quoted_scalar(emitter,
+// emitter->scalar_data.value, emitter->scalar_data.length,
+// !emitter->simple_key_context);
+//
+// case YAML_DOUBLE_QUOTED_SCALAR_STYLE:
+// return yaml_emitter_write_double_quoted_scalar(emitter,
+// emitter->scalar_data.value, emitter->scalar_data.length,
+// !emitter->simple_key_context);
+//
+// case YAML_LITERAL_SCALAR_STYLE:
+// return yaml_emitter_write_literal_scalar(emitter,
+// emitter->scalar_data.value, emitter->scalar_data.length);
+//
+// case YAML_FOLDED_SCALAR_STYLE:
+// return yaml_emitter_write_folded_scalar(emitter,
+// emitter->scalar_data.value, emitter->scalar_data.length);
+//
+// default:
+// assert(1); /* Impossible. */
+// }
+//
+// return 0;
+//}
+//
+///*
+// * Check if a %YAML directive is valid.
+// */
+//
+//static int
+//yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
+// yaml_version_directive_t version_directive)
+//{
+// if (version_directive.major != 1 || version_directive.minor != 1) {
+// return yaml_emitter_set_emitter_error(emitter,
+// "incompatible %YAML directive");
+// }
+//
+// return 1;
+//}
+//
+///*
+// * Check if a %TAG directive is valid.
+// */
+//
+//static int
+//yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
+// yaml_tag_directive_t tag_directive)
+//{
+// 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,
+// "tag handle must not be empty");
+// }
+//
+// if (handle.start[0] != '!') {
+// return yaml_emitter_set_emitter_error(emitter,
+// "tag handle must start with '!'");
+// }
+//
+// if (handle.end[-1] != '!') {
+// return yaml_emitter_set_emitter_error(emitter,
+// "tag handle must end with '!'");
+// }
+//
+// handle.pointer ++;
+//
+// while (handle.pointer < handle.end-1) {
+// if (!IS_ALPHA(handle)) {
+// return yaml_emitter_set_emitter_error(emitter,
+// "tag handle must contain alphanumerical characters only");
+// }
+// MOVE(handle);
+// }
+//
+// if (prefix.start == prefix.end) {
+// return yaml_emitter_set_emitter_error(emitter,
+// "tag prefix must not be empty");
+// }
+//
+// return 1;
+//}
+//
+///*
+// * Check if an anchor is valid.
+// */
+//
+//static int
+//yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
+// yaml_char_t *anchor, int alias)
+//{
+// 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 ?
+// "alias value must not be empty" :
+// "anchor value must not be empty");
+// }
+//
+// while (string.pointer != string.end) {
+// if (!IS_ALPHA(string)) {
+// return yaml_emitter_set_emitter_error(emitter, alias ?
+// "alias value must contain alphanumerical characters only" :
+// "anchor value must contain alphanumerical characters only");
+// }
+// MOVE(string);
+// }
+//
+// emitter->anchor_data.anchor = string.start;
+// emitter->anchor_data.anchor_length = string.end - string.start;
+// emitter->anchor_data.alias = alias;
+//
+// return 1;
+//}
+//
+///*
+// * Check if a tag is valid.
+// */
+//
+//static int
+//yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
+// yaml_char_t *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.top; tag_directive ++) {
+// size_t prefix_length = strlen((char *)tag_directive->prefix);
+// if (prefix_length < (size_t)(string.end - string.start)
+// && strncmp((char *)tag_directive->prefix, (char *)string.start,
+// prefix_length) == 0)
+// {
+// emitter->tag_data.handle = tag_directive->handle;
+// emitter->tag_data.handle_length =
+// strlen((char *)tag_directive->handle);
+// emitter->tag_data.suffix = string.start + prefix_length;
+// emitter->tag_data.suffix_length =
+// (string.end - string.start) - prefix_length;
+// return 1;
+// }
+// }
+//
+// emitter->tag_data.suffix = string.start;
+// emitter->tag_data.suffix_length = string.end - string.start;
+//
+// return 1;
+//}
+//
+///*
+// * Check if a scalar is valid.
+// */
+//
+//static int
+//yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
+// yaml_char_t *value, size_t length)
+//{
+// yaml_string_t string;
+//
+// int block_indicators = 0;
+// int flow_indicators = 0;
+// int line_breaks = 0;
+// int special_characters = 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 preceeded_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;
+//
+// if (string.start == string.end)
+// {
+// emitter->scalar_data.multiline = 0;
+// emitter->scalar_data.flow_plain_allowed = 0;
+// emitter->scalar_data.block_plain_allowed = 1;
+// emitter->scalar_data.single_quoted_allowed = 1;
+// emitter->scalar_data.block_allowed = 0;
+//
+// return 1;
+// }
+//
+// if ((CHECK_AT(string, '-', 0)
+// && CHECK_AT(string, '-', 1)
+// && CHECK_AT(string, '-', 2))
+// || (CHECK_AT(string, '.', 0)
+// && CHECK_AT(string, '.', 1)
+// && CHECK_AT(string, '.', 2))) {
+// block_indicators = 1;
+// flow_indicators = 1;
+// }
+//
+// preceeded_by_whitespace = 1;
+// followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
+//
+// while (string.pointer != string.end)
+// {
+// if (string.start == string.pointer)
+// {
+// if (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, '`')) {
+// flow_indicators = 1;
+// block_indicators = 1;
+// }
+//
+// if (CHECK(string, '?') || CHECK(string, ':')) {
+// flow_indicators = 1;
+// if (followed_by_whitespace) {
+// block_indicators = 1;
+// }
+// }
+//
+// if (CHECK(string, '-') && followed_by_whitespace) {
+// flow_indicators = 1;
+// block_indicators = 1;
+// }
+// }
+// else
+// {
+// if (CHECK(string, ',') || CHECK(string, '?')
+// || CHECK(string, '[') || CHECK(string, ']')
+// || CHECK(string, '{') || CHECK(string, '}')) {
+// flow_indicators = 1;
+// }
+//
+// if (CHECK(string, ':')) {
+// flow_indicators = 1;
+// if (followed_by_whitespace) {
+// block_indicators = 1;
+// }
+// }
+//
+// if (CHECK(string, '#') && preceeded_by_whitespace) {
+// flow_indicators = 1;
+// block_indicators = 1;
+// }
+// }
+//
+// if (!IS_PRINTABLE(string)
+// || (!IS_ASCII(string) && !emitter->unicode)) {
+// special_characters = 1;
+// }
+//
+// if (IS_BREAK(string)) {
+// line_breaks = 1;
+// }
+//
+// if (IS_SPACE(string))
+// {
+// if (string.start == string.pointer) {
+// 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 (string.start == string.pointer) {
+// leading_break = 1;
+// }
+// if (string.pointer+WIDTH(string) == string.end) {
+// trailing_break = 1;
+// }
+// if (previous_space) {
+// space_break = 1;
+// }
+// previous_space = 0;
+// previous_break = 1;
+// }
+// else
+// {
+// previous_space = 0;
+// previous_break = 0;
+// }
+//
+// preceeded_by_whitespace = IS_BLANKZ(string);
+// MOVE(string);
+// if (string.pointer != string.end) {
+// followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
+// }
+// }
+//
+// emitter->scalar_data.multiline = line_breaks;
+//
+// emitter->scalar_data.flow_plain_allowed = 1;
+// emitter->scalar_data.block_plain_allowed = 1;
+// emitter->scalar_data.single_quoted_allowed = 1;
+// emitter->scalar_data.block_allowed = 1;
+//
+// if (leading_space || leading_break || trailing_space || trailing_break) {
+// emitter->scalar_data.flow_plain_allowed = 0;
+// emitter->scalar_data.block_plain_allowed = 0;
+// }
+//
+// if (trailing_space) {
+// emitter->scalar_data.block_allowed = 0;
+// }
+//
+// 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 (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;
+// emitter->scalar_data.block_allowed = 0;
+// }
+//
+// if (line_breaks) {
+// emitter->scalar_data.flow_plain_allowed = 0;
+// emitter->scalar_data.block_plain_allowed = 0;
+// }
+//
+// if (flow_indicators) {
+// emitter->scalar_data.flow_plain_allowed = 0;
+// }
+//
+// if (block_indicators) {
+// emitter->scalar_data.block_plain_allowed = 0;
+// }
+//
+// return 1;
+//}
+//
+///*
+// * Check if the event data is valid.
+// */
+//
+//static int
+//yaml_emitter_analyze_event(yaml_emitter_t *emitter,
+// yaml_event_t *event)
+//{
+// emitter->anchor_data.anchor = NULL;
+// emitter->anchor_data.anchor_length = 0;
+// emitter->tag_data.handle = NULL;
+// emitter->tag_data.handle_length = 0;
+// emitter->tag_data.suffix = NULL;
+// emitter->tag_data.suffix_length = 0;
+// emitter->scalar_data.value = NULL;
+// emitter->scalar_data.length = 0;
+//
+// switch (event->type)
+// {
+// case YAML_ALIAS_EVENT:
+// if (!yaml_emitter_analyze_anchor(emitter,
+// event->data.alias.anchor, 1))
+// return 0;
+// return 1;
+//
+// case YAML_SCALAR_EVENT:
+// if (event->data.scalar.anchor) {
+// if (!yaml_emitter_analyze_anchor(emitter,
+// event->data.scalar.anchor, 0))
+// return 0;
+// }
+// if (event->data.scalar.tag && (emitter->canonical ||
+// (!event->data.scalar.plain_implicit
+// && !event->data.scalar.quoted_implicit))) {
+// if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag))
+// return 0;
+// }
+// if (!yaml_emitter_analyze_scalar(emitter,
+// event->data.scalar.value, event->data.scalar.length))
+// return 0;
+// return 1;
+//
+// case YAML_SEQUENCE_START_EVENT:
+// if (event->data.sequence_start.anchor) {
+// if (!yaml_emitter_analyze_anchor(emitter,
+// event->data.sequence_start.anchor, 0))
+// return 0;
+// }
+// if (event->data.sequence_start.tag && (emitter->canonical ||
+// !event->data.sequence_start.implicit)) {
+// if (!yaml_emitter_analyze_tag(emitter,
+// event->data.sequence_start.tag))
+// return 0;
+// }
+// return 1;
+//
+// case YAML_MAPPING_START_EVENT:
+// if (event->data.mapping_start.anchor) {
+// if (!yaml_emitter_analyze_anchor(emitter,
+// event->data.mapping_start.anchor, 0))
+// return 0;
+// }
+// if (event->data.mapping_start.tag && (emitter->canonical ||
+// !event->data.mapping_start.implicit)) {
+// if (!yaml_emitter_analyze_tag(emitter,
+// event->data.mapping_start.tag))
+// return 0;
+// }
+// return 1;
+//
+// default:
+// return 1;
+// }
+//}
+//
+///*
+// * Write the BOM character.
+// */
+//
+//static int
+//yaml_emitter_write_bom(yaml_emitter_t *emitter)
+//{
+// if (!FLUSH(emitter)) return 0;
+//
+// *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF';
+// *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB';
+// *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF';
+//
+// return 1;
+//}
+//
+//static int
+//yaml_emitter_write_indent(yaml_emitter_t *emitter)
+//{
+// int indent = (emitter->indent >= 0) ? emitter->indent : 0;
+//
+// if (!emitter->indention || emitter->column > indent
+// || (emitter->column == indent && !emitter->whitespace)) {
+// if (!PUT_BREAK(emitter)) return 0;
+// }
+//
+// while (emitter->column < indent) {
+// if (!PUT(emitter, ' ')) return 0;
+// }
+//
+// emitter->whitespace = 1;
+// emitter->indention = 1;
+//
+// return 1;
+//}
+//
+//static int
+//yaml_emitter_write_indicator(yaml_emitter_t *emitter,
+// char *indicator, int need_whitespace,
+// int is_whitespace, int is_indention)
+//{
+// 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;
+// }
+//
+// while (string.pointer != string.end) {
+// if (!WRITE(emitter, string)) return 0;
+// }
+//
+// emitter->whitespace = is_whitespace;
+// emitter->indention = (emitter->indention && is_indention);
+// emitter->open_ended = 0;
+//
+// return 1;
+//}
+//
+//static int
+//yaml_emitter_write_anchor(yaml_emitter_t *emitter,
+// yaml_char_t *value, size_t length)
+//{
+// yaml_string_t string;
+// STRING_ASSIGN(string, value, length);
+//
+// while (string.pointer != string.end) {
+// if (!WRITE(emitter, string)) return 0;
+// }
+//
+// emitter->whitespace = 0;
+// emitter->indention = 0;
+//
+// return 1;
+//}
+//
+//static int
+//yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
+// yaml_char_t *value, size_t 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;
+// }
+//
+// emitter->whitespace = 0;
+// emitter->indention = 0;
+//
+// return 1;
+//}
+//
+//static int
+//yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
+// yaml_char_t *value, size_t length,
+// int need_whitespace)
+//{
+// 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)
+//{
+// 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)
+//{
+// 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 (!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)
+//{
+// 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];
+// 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)
+//{
+// 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)
+//{
+// 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;
+//}
+//
diff --git a/writer_c.go b/writer_c.go
new file mode 100644
index 0000000..5d1afaa
--- /dev/null
+++ b/writer_c.go
@@ -0,0 +1,89 @@
+package goyaml
+
+// Set the writer error and return false.
+func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {
+ emitter.error = yaml_WRITER_ERROR
+ emitter.problem = problem
+ return false
+}
+
+// Flush the output buffer.
+func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
+ if emitter.write_handler == nil {
+ panic("write handler not set")
+ }
+
+ // Check if the buffer is empty.
+ if len(emitter.buffer) == 0 {
+ return true
+ }
+
+ // If the output encoding is UTF-8, we don't need to recode the buffer.
+ if emitter.encoding == yaml_UTF8_ENCODING {
+ if err := emitter.write_handler(emitter, emitter.buffer); err != nil {
+ return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
+ }
+ emitter.buffer = emitter.buffer[:0]
+ return true
+ }
+
+ // Recode the buffer into the raw buffer.
+ var low, high int
+ if emitter.encoding == yaml_UTF16LE_ENCODING {
+ low, high = 0, 1
+ } else {
+ high, low = 1, 0
+ }
+
+ pos := 0
+ for pos < len(emitter.buffer) {
+ // See the "reader.c" code for more details on UTF-8 encoding. Note
+ // that we assume that the buffer contains a valid UTF-8 sequence.
+
+ // Read the next UTF-8 character.
+ octet := emitter.buffer[pos]
+
+ var w int
+ var value rune
+ switch {
+ case octet&0x80 == 0x00:
+ w, value = 1, rune(octet&0x7F)
+ case octet&0xE0 == 0xC0:
+ w, value = 2, rune(octet&0x1F)
+ case octet&0xF0 == 0xE0:
+ w, value = 3, rune(octet&0x0F)
+ case octet&0xF8 == 0xF0:
+ w, value = 4, rune(octet&0x07)
+ }
+ for k := 1; k < w; k++ {
+ octet = emitter.buffer[pos+k]
+ value = (value << 6) + (rune(octet) & 0x3F)
+ }
+ pos += w
+
+ // Write the character.
+ if value < 0x10000 {
+ var b [2]byte
+ b[high] = byte(value >> 8)
+ b[low] = byte(value & 0xFF)
+ emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1])
+ } else {
+ // Write the character using a surrogate pair (check "reader.c").
+ var b [4]byte
+ value -= 0x10000
+ b[high] = byte(0xD8 + (value >> 18))
+ b[low] = byte((value >> 10) & 0xFF)
+ b[high+2] = byte(0xDC + ((value >> 8) & 0xFF))
+ b[low+2] = byte(value & 0xFF)
+ emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3])
+ }
+ }
+
+ // Write the raw buffer.
+ if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil {
+ return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
+ }
+ emitter.buffer = emitter.buffer[:0]
+ emitter.raw_buffer = emitter.raw_buffer[:0]
+ return true
+}
diff --git a/yaml_h.go b/yaml_h.go
index 0c1df00..1e95b96 100644
--- a/yaml_h.go
+++ b/yaml_h.go
@@ -326,188 +326,6 @@
}
-///**
-// * Create the STREAM-START event.
-// *
-// * @param[out] event An empty event object.
-// * @param[in] encoding The stream encoding.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_stream_start_event_initialize(yaml_event_t *event,
-// yaml_encoding_t encoding);
-//
-///**
-// * Create the STREAM-END event.
-// *
-// * @param[out] event An empty event object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_stream_end_event_initialize(yaml_event_t *event);
-//
-///**
-// * Create the DOCUMENT-START event.
-// *
-// * The @a implicit argument is considered as a stylistic parameter and may be
-// * ignored by the emitter.
-// *
-// * @param[out] event An empty event object.
-// * @param[in] version_directive The %YAML directive value or
-// * @c NULL.
-// * @param[in] tag_directives_start The beginning of the %TAG
-// * directives list.
-// * @param[in] tag_directives_end The end of the %TAG directives
-// * list.
-// * @param[in] implicit If the document start indicator is
-// * implicit.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_start_event_initialize(yaml_event_t *event,
-// yaml_version_directive_t *version_directive,
-// yaml_tag_directive_t *tag_directives_start,
-// yaml_tag_directive_t *tag_directives_end,
-// int implicit);
-//
-///**
-// * Create the DOCUMENT-END event.
-// *
-// * The @a implicit argument is considered as a stylistic parameter and may be
-// * ignored by the emitter.
-// *
-// * @param[out] event An empty event object.
-// * @param[in] implicit If the document end indicator is implicit.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_end_event_initialize(yaml_event_t *event, int implicit);
-//
-///**
-// * Create an ALIAS event.
-// *
-// * @param[out] event An empty event object.
-// * @param[in] anchor The anchor value.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor);
-//
-///**
-// * Create a SCALAR event.
-// *
-// * The @a style argument may be ignored by the emitter.
-// *
-// * Either the @a tag attribute or one of the @a plain_implicit and
-// * @a quoted_implicit flags must be set.
-// *
-// * @param[out] event An empty event object.
-// * @param[in] anchor The scalar anchor or @c NULL.
-// * @param[in] tag The scalar tag or @c NULL.
-// * @param[in] value The scalar value.
-// * @param[in] length The length of the scalar value.
-// * @param[in] plain_implicit If the tag may be omitted for the plain
-// * style.
-// * @param[in] quoted_implicit If the tag may be omitted for any
-// * non-plain style.
-// * @param[in] style The scalar style.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_scalar_event_initialize(yaml_event_t *event,
-// yaml_char_t *anchor, yaml_char_t *tag,
-// yaml_char_t *value, int length,
-// int plain_implicit, int quoted_implicit,
-// yaml_scalar_style_t style);
-//
-///**
-// * Create a SEQUENCE-START event.
-// *
-// * The @a style argument may be ignored by the emitter.
-// *
-// * Either the @a tag attribute or the @a implicit flag must be set.
-// *
-// * @param[out] event An empty event object.
-// * @param[in] anchor The sequence anchor or @c NULL.
-// * @param[in] tag The sequence tag or @c NULL.
-// * @param[in] implicit If the tag may be omitted.
-// * @param[in] style The sequence style.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_sequence_start_event_initialize(yaml_event_t *event,
-// yaml_char_t *anchor, yaml_char_t *tag, int implicit,
-// yaml_sequence_style_t style);
-//
-///**
-// * Create a SEQUENCE-END event.
-// *
-// * @param[out] event An empty event object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_sequence_end_event_initialize(yaml_event_t *event);
-//
-///**
-// * Create a MAPPING-START event.
-// *
-// * The @a style argument may be ignored by the emitter.
-// *
-// * Either the @a tag attribute or the @a implicit flag must be set.
-// *
-// * @param[out] event An empty event object.
-// * @param[in] anchor The mapping anchor or @c NULL.
-// * @param[in] tag The mapping tag or @c NULL.
-// * @param[in] implicit If the tag may be omitted.
-// * @param[in] style The mapping style.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_mapping_start_event_initialize(yaml_event_t *event,
-// yaml_char_t *anchor, yaml_char_t *tag, int implicit,
-// yaml_mapping_style_t style);
-//
-///**
-// * Create a MAPPING-END event.
-// *
-// * @param[out] event An empty event object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_mapping_end_event_initialize(yaml_event_t *event);
-//
-///**
-// * Free any memory allocated for an event object.
-// *
-// * @param[in,out] event An event object.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_event_delete(yaml_event_t *event);
-//
-//// @}
-//
-
// Nodes
const (
@@ -796,520 +614,145 @@
document *yaml_document_t // The currently parsed document.
}
-///**
-// * @defgroup emitter Emitter Definitions
-// * @{
-// */
+// Emitter Definitions
+
+// The prototype of a write handler.
//
-///**
-// * The prototype of a write handler.
-// *
-// * The write handler is called when the emitter needs to flush the accumulated
-// * characters to the output. The handler should write @a size bytes of the
-// * @a buffer to the output.
-// *
-// * @param[in,out] data A pointer to an application data specified by
-// * yaml_emitter_set_output().
-// * @param[in] buffer The buffer with bytes to be written.
-// * @param[in] size The size of the buffer.
-// *
-// * @returns On success, the handler should return @c 1. If the handler failed,
-// * the returned value should be @c 0.
-// */
+// The write handler is called when the emitter needs to flush the accumulated
+// characters to the output. The handler should write @a size bytes of the
+// @a buffer to the output.
//
-//typedef int yaml_write_handler_t(void *data, unsigned char *buffer, int size);
+// @param[in,out] data A pointer to an application data specified by
+// yaml_emitter_set_output().
+// @param[in] buffer The buffer with bytes to be written.
+// @param[in] size The size of the buffer.
//
-//// The emitter states.
-//typedef enum yaml_emitter_state_e {
-// // Expect STREAM-START.
-// YAML_EMIT_STREAM_START_STATE,
-// // Expect the first DOCUMENT-START or STREAM-END.
-// YAML_EMIT_FIRST_DOCUMENT_START_STATE,
-// // Expect DOCUMENT-START or STREAM-END.
-// YAML_EMIT_DOCUMENT_START_STATE,
-// // Expect the content of a document.
-// YAML_EMIT_DOCUMENT_CONTENT_STATE,
-// // Expect DOCUMENT-END.
-// YAML_EMIT_DOCUMENT_END_STATE,
-// // Expect the first item of a flow sequence.
-// YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE,
-// // Expect an item of a flow sequence.
-// YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE,
-// // Expect the first key of a flow mapping.
-// YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE,
-// // Expect a key of a flow mapping.
-// YAML_EMIT_FLOW_MAPPING_KEY_STATE,
-// // Expect a value for a simple key of a flow mapping.
-// YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE,
-// // Expect a value of a flow mapping.
-// YAML_EMIT_FLOW_MAPPING_VALUE_STATE,
-// // Expect the first item of a block sequence.
-// YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE,
-// // Expect an item of a block sequence.
-// YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE,
-// // Expect the first key of a block mapping.
-// YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE,
-// // Expect the key of a block mapping.
-// YAML_EMIT_BLOCK_MAPPING_KEY_STATE,
-// // Expect a value for a simple key of a block mapping.
-// YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE,
-// // Expect a value of a block mapping.
-// YAML_EMIT_BLOCK_MAPPING_VALUE_STATE,
-// // Expect nothing.
-// YAML_EMIT_END_STATE
-//} yaml_emitter_state_t;
+// @returns On success, the handler should return @c 1. If the handler failed,
+// the returned value should be @c 0.
//
-///**
-// * The emitter structure.
-// *
-// * All members are internal. Manage the structure using the @c yaml_emitter_
-// * family of functions.
-// */
+type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error
+
+type yaml_emitter_state_t int
+
+// The emitter states.
+const (
+ // Expect STREAM-START.
+ yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota
+
+ yaml_EMIT_FIRST_DOCUMENT_START_STATE // Expect the first DOCUMENT-START or STREAM-END.
+ yaml_EMIT_DOCUMENT_START_STATE // Expect DOCUMENT-START or STREAM-END.
+ yaml_EMIT_DOCUMENT_CONTENT_STATE // Expect the content of a document.
+ yaml_EMIT_DOCUMENT_END_STATE // Expect DOCUMENT-END.
+ yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a flow sequence.
+ yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE // Expect an item of a flow sequence.
+ yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping.
+ yaml_EMIT_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping.
+ yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a flow mapping.
+ yaml_EMIT_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping.
+ yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a block sequence.
+ yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE // Expect an item of a block sequence.
+ yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping.
+ yaml_EMIT_BLOCK_MAPPING_KEY_STATE // Expect the key of a block mapping.
+ yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping.
+ yaml_EMIT_BLOCK_MAPPING_VALUE_STATE // Expect a value of a block mapping.
+ yaml_EMIT_END_STATE // Expect nothing.
+)
+
+// The emitter structure.
//
-//typedef struct yaml_emitter_s {
-//
-// /**
-// * @name Error handling
-// * @{
-// */
-//
-// // Error type.
-// yaml_error_type_t error;
-// // Error description.
-// char *problem;
-//
-// /**
-// * @}
-// */
-//
-// /**
-// * @name Writer stuff
-// * @{
-// */
-//
-// // Write handler.
-// yaml_write_handler_t *write_handler;
-//
-// // A pointer for passing to the white handler.
-// void *write_handler_data;
-//
-// // Standard (string or file) output data.
-// union {
-// // String output data.
-// struct {
-// // The buffer pointer.
-// unsigned char *buffer;
-// // The buffer size.
-// int size;
-// // The number of written bytes.
-// int *size_written;
-// } string;
-//
-// // File output data.
-// FILE *file;
-// } output;
-//
-// // The working buffer.
-// struct {
-// // The beginning of the buffer.
-// yaml_char_t *start;
-// // The end of the buffer.
-// yaml_char_t *end;
-// // The current position of the buffer.
-// yaml_char_t *pointer;
-// // The last filled position of the buffer.
-// yaml_char_t *last;
-// } buffer;
-//
-// // The raw buffer.
-// struct {
-// // The beginning of the buffer.
-// unsigned char *start;
-// // The end of the buffer.
-// unsigned char *end;
-// // The current position of the buffer.
-// unsigned char *pointer;
-// // The last filled position of the buffer.
-// unsigned char *last;
-// } raw_buffer;
-//
-// // The stream encoding.
-// yaml_encoding_t encoding;
-//
-// /**
-// * @}
-// */
-//
-// /**
-// * @name Emitter stuff
-// * @{
-// */
-//
-// // If the output is in the canonical style?
-// int canonical;
-// // The number of indentation spaces.
-// int best_indent;
-// // The preferred width of the output lines.
-// int best_width;
-// // Allow unescaped non-ASCII characters?
-// int unicode;
-// // The preferred line break.
-// yaml_break_t line_break;
-//
-// // The stack of states.
-// struct {
-// // The beginning of the stack.
-// yaml_emitter_state_t *start;
-// // The end of the stack.
-// yaml_emitter_state_t *end;
-// // The top of the stack.
-// yaml_emitter_state_t *top;
-// } states;
-//
-// // The current emitter state.
-// yaml_emitter_state_t state;
-//
-// // The event queue.
-// struct {
-// // The beginning of the event queue.
-// yaml_event_t *start;
-// // The end of the event queue.
-// yaml_event_t *end;
-// // The head of the event queue.
-// yaml_event_t *head;
-// // The tail of the event queue.
-// yaml_event_t *tail;
-// } events;
-//
-// // The stack of indentation levels.
-// struct {
-// // The beginning of the stack.
-// int *start;
-// // The end of the stack.
-// int *end;
-// // The top of the stack.
-// int *top;
-// } indents;
-//
-// // The list of tag directives.
-// struct {
-// // The beginning of the list.
-// yaml_tag_directive_t *start;
-// // The end of the list.
-// yaml_tag_directive_t *end;
-// // The top of the list.
-// yaml_tag_directive_t *top;
-// } tag_directives;
-//
-// // The current indentation level.
-// int indent;
-//
-// // The current flow level.
-// int flow_level;
-//
-// // Is it the document root context?
-// int root_context;
-// // Is it a sequence context?
-// int sequence_context;
-// // Is it a mapping context?
-// int mapping_context;
-// // Is it a simple mapping key context?
-// int simple_key_context;
-//
-// // The current line.
-// int line;
-// // The current column.
-// int column;
-// // If the last character was a whitespace?
-// int whitespace;
-// // If the last character was an indentation character (' ', '-', '?', ':')?
-// int indention;
-// // If an explicit document end is required?
-// int open_ended;
-//
-// // Anchor analysis.
-// struct {
-// // The anchor value.
-// yaml_char_t *anchor;
-// // The anchor length.
-// int anchor_length;
-// // Is it an alias?
-// int alias;
-// } anchor_data;
-//
-// // Tag analysis.
-// struct {
-// // The tag handle.
-// yaml_char_t *handle;
-// // The tag handle length.
-// int handle_length;
-// // The tag suffix.
-// yaml_char_t *suffix;
-// // The tag suffix length.
-// int suffix_length;
-// } tag_data;
-//
-// // Scalar analysis.
-// struct {
-// // The scalar value.
-// yaml_char_t *value;
-// // The scalar length.
-// int length;
-// // Does the scalar contain line breaks?
-// int multiline;
-// // Can the scalar be expessed in the flow plain style?
-// int flow_plain_allowed;
-// // Can the scalar be expressed in the block plain style?
-// int block_plain_allowed;
-// // Can the scalar be expressed in the single quoted style?
-// int single_quoted_allowed;
-// // Can the scalar be expressed in the literal or folded styles?
-// int block_allowed;
-// // The output style.
-// yaml_scalar_style_t style;
-// } scalar_data;
-//
-// /**
-// * @}
-// */
-//
-// /**
-// * @name Dumper stuff
-// * @{
-// */
-//
-// // If the stream was already opened?
-// int opened;
-// // If the stream was already closed?
-// int closed;
-//
-// // The information associated with the document nodes.
-// struct {
-// // The number of references.
-// int references;
-// // The anchor id.
-// int anchor;
-// // If the node has been emitted?
-// int serialized;
-// } *anchors;
-//
-// // The last assigned anchor id.
-// int last_anchor_id;
-//
-// // The currently emitted document.
-// yaml_document_t *document;
-//
-// /**
-// * @}
-// */
-//
-//} yaml_emitter_t;
-//
-///**
-// * Initialize an emitter.
-// *
-// * This function creates a new emitter object. An application is responsible
-// * for destroying the object using the yaml_emitter_delete() function.
-// *
-// * @param[out] emitter An empty parser object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_initialize(yaml_emitter_t *emitter);
-//
-///**
-// * Destroy an emitter.
-// *
-// * @param[in,out] emitter An emitter object.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_delete(yaml_emitter_t *emitter);
-//
-///**
-// * Set a string output.
-// *
-// * The emitter will write the output characters to the @a output buffer of the
-// * size @a size. The emitter will set @a size_written to the number of written
-// * bytes. If the buffer is smaller than required, the emitter produces the
-// * YAML_WRITE_ERROR error.
-// *
-// * @param[in,out] emitter An emitter object.
-// * @param[in] output An output buffer.
-// * @param[in] size The buffer size.
-// * @param[in] size_written The pointer to save the number of written
-// * bytes.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_output_string(yaml_emitter_t *emitter,
-// unsigned char *output, int size, size_t *size_written);
-//
-///**
-// * Set a file output.
-// *
-// * @a file should be a file object open for writing. The application is
-// * responsible for closing the @a file.
-// *
-// * @param[in,out] emitter An emitter object.
-// * @param[in] file An open file.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file);
-//
-///**
-// * Set a generic output handler.
-// *
-// * @param[in,out] emitter An emitter object.
-// * @param[in] handler A write handler.
-// * @param[in] data Any application data for passing to the write
-// * handler.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_output(yaml_emitter_t *emitter,
-// yaml_write_handler_t *handler, void *data);
-//
-///**
-// * Set the output encoding.
-// *
-// * @param[in,out] emitter An emitter object.
-// * @param[in] encoding The output encoding.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding);
-//
-///**
-// * Set if the output should be in the "canonical" format as in the YAML
-// * specification.
-// *
-// * @param[in,out] emitter An emitter object.
-// * @param[in] canonical If the output is canonical.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical);
-//
-///**
-// * Set the intendation increment.
-// *
-// * @param[in,out] emitter An emitter object.
-// * @param[in] indent The indentation increment (1 < . < 10).
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent);
-//
-///**
-// * Set the preferred line width. @c -1 means unlimited.
-// *
-// * @param[in,out] emitter An emitter object.
-// * @param[in] width The preferred line width.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_width(yaml_emitter_t *emitter, int width);
-//
-///**
-// * Set if unescaped non-ASCII characters are allowed.
-// *
-// * @param[in,out] emitter An emitter object.
-// * @param[in] unicode If unescaped Unicode characters are allowed.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode);
-//
-///**
-// * Set the preferred line break.
-// *
-// * @param[in,out] emitter An emitter object.
-// * @param[in] line_break The preferred line break.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break);
-//
-///**
-// * Emit an event.
-// *
-// * The event object may be generated using the yaml_parser_parse() function.
-// * The emitter takes the responsibility for the event object and destroys its
-// * content after it is emitted. The event object is destroyed even if the
-// * function fails.
-// *
-// * @param[in,out] emitter An emitter object.
-// * @param[in,out] event An event object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
-//
-///**
-// * Start a YAML stream.
-// *
-// * This function should be used before yaml_emitter_dump() is called.
-// *
-// * @param[in,out] emitter An emitter object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_open(yaml_emitter_t *emitter);
-//
-///**
-// * Finish a YAML stream.
-// *
-// * This function should be used after yaml_emitter_dump() is called.
-// *
-// * @param[in,out] emitter An emitter object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_close(yaml_emitter_t *emitter);
-//
-///**
-// * Emit a YAML document.
-// *
-// * The documen object may be generated using the yaml_parser_load() function
-// * or the yaml_document_initialize() function. The emitter takes the
-// * responsibility for the document object and destoys its content after
-// * it is emitted. The document object is destroyedeven if the function fails.
-// *
-// * @param[in,out] emitter An emitter object.
-// * @param[in,out] document A document object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
-//
-///**
-// * Flush the accumulated characters to the output.
-// *
-// * @param[in,out] emitter An emitter object.
-// *
-// * @returns @c 1 if the function succeeded, @c 0 on error.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_emitter_flush(yaml_emitter_t *emitter);
-//
-//// @}
-//
-//#ifdef __cplusplus
-//}
-//#endif
-//
-//#endif /* #ifndef YAML_H */
-//
+// All members are internal. Manage the structure using the @c yaml_emitter_
+// family of functions.
+type yaml_emitter_t struct {
+
+ // Error handling
+
+ error yaml_error_type_t // Error type.
+ problem string // Error description.
+
+ // Writer stuff
+
+ write_handler yaml_write_handler_t // Write handler.
+
+ output_buffer *[]byte // String output data.
+ output_file io.Writer // File output data.
+
+ buffer []byte // The working buffer.
+ buffer_pos int // The current position of the buffer.
+
+ raw_buffer []byte // The raw buffer.
+ raw_buffer_pos int // The current position of the buffer.
+
+ encoding yaml_encoding_t // The stream encoding.
+
+ // Emitter stuff
+
+ canonical bool // If the output is in the canonical style?
+ best_indent int // The number of indentation spaces.
+ best_width int // The preferred width of the output lines.
+ unicode bool // Allow unescaped non-ASCII characters?
+ line_break yaml_break_t // The preferred line break.
+
+ state yaml_emitter_state_t // The current emitter state.
+ states []yaml_emitter_state_t // The stack of states.
+
+ events []yaml_event_t // The event queue.
+ events_head int // The head of the event queue.
+
+ indents []int // The stack of indentation levels.
+
+ tag_directives []yaml_tag_directive_t // The list of tag directives.
+
+ indent int // The current indentation level.
+
+ flow_level int // The current flow level.
+
+ root_context bool // Is it the document root context?
+ sequence_context bool // Is it a sequence context?
+ mapping_context bool // Is it a mapping context?
+ simple_key_context bool // Is it a simple mapping key context?
+
+ line int // The current line.
+ column int // The current column.
+ whitespace bool // If the last character was a whitespace?
+ indention bool // If the last character was an indentation character (' ', '-', '?', ':')?
+ open_ended bool // If an explicit document end is required?
+
+ // Anchor analysis.
+ anchor_data struct {
+ anchor []byte // The anchor value.
+ alias bool // Is it an alias?
+ }
+
+ // Tag analysis.
+ tag_data struct {
+ handle []byte // The tag handle.
+ suffix []byte // The tag suffix.
+ }
+
+ // Scalar analysis.
+ scalar_data struct {
+ value []byte // The scalar value.
+ multiline bool // Does the scalar contain line breaks?
+ flow_plain_allowed bool // Can the scalar be expessed in the flow plain style?
+ block_plain_allowed bool // Can the scalar be expressed in the block plain style?
+ single_quoted_allowed bool // Can the scalar be expressed in the single quoted style?
+ block_allowed bool // Can the scalar be expressed in the literal or folded styles?
+ style yaml_scalar_style_t // The output style.
+ }
+
+ // Dumper stuff
+
+ opened bool // If the stream was already opened?
+ closed bool // If the stream was already closed?
+
+ // The information associated with the document nodes.
+ anchors *struct {
+ references int // The number of references.
+ anchor int // The anchor id.
+ serialized bool // If the node has been emitted?
+ }
+
+ last_anchor_id int // The last assigned anchor id.
+
+ document *yaml_document_t // The currently emitted document.
+}