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. +}