Kirill Simonov avatar Kirill Simonov committed f5defcc

Another round of API update.

Comments (0)

Files changed (10)

 
 # Define the package version numbers and the bug reporting link.
 m4_define([YAML_MAJOR], 0)
-m4_define([YAML_MINOR], 0)
-m4_define([YAML_PATCH], 1)
+m4_define([YAML_MINOR], 2)
+m4_define([YAML_PATCH], 0)
 m4_define([YAML_BUGS], [http://pyyaml.org/newticket?component=libyaml])
 
 # Define the libtool version numbers; check the Autobook, Section 11.4.
 #       else:
 #           YAML_AGE = 0
 m4_define([YAML_RELEASE], 0)
-m4_define([YAML_CURRENT], 1)
+m4_define([YAML_CURRENT], 2)
 m4_define([YAML_REVISION], 0)
 m4_define([YAML_AGE], 0)
 
 AC_CONFIG_HEADERS([config.h])
 AM_INIT_AUTOMAKE([1.9 foreign])
 
-# Define macro variables for the package version numbers.
-AC_DEFINE(YAML_VERSION_MAJOR, YAML_MAJOR, [Define the major version number.])
-AC_DEFINE(YAML_VERSION_MINOR, YAML_MINOR, [Define the minor version number.])
-AC_DEFINE(YAML_VERSION_PATCH, YAML_PATCH, [Define the patch version number.])
-AC_DEFINE(YAML_VERSION_STRING, "YAML_MAJOR.YAML_MINOR.YAML_PATCH", [Define the version string.])
-
 # Define substitutions for the libtool version numbers.
 YAML_LT_RELEASE=YAML_RELEASE
 YAML_LT_CURRENT=YAML_CURRENT
  * @{
  */
 
-/**
- * Get the library version as a string.
- *
- * @returns The function returns the pointer to a static string of the form
- * @c "X.Y.Z", where @c X is the major version number, @c Y is a minor version
- * number, and @c Z is the patch version number.
- */
+/** The major version number. */
+#define YAML_VERSION_MAJOR  0
 
-YAML_DECLARE(const char *)
-yaml_get_version_string(void);
+/** The minor version number. */
+#define YAML_VERSION_MINOR  2
+
+/** The patch version number. */
+#define YAML_VERSION_PATCH  0
+
+/** The version string generator macro. */
+#define YAML_VERSION_STRING_GENERATOR(major,minor,patch)                        \
+    (#major "." #minor "." #patch)
+
+/** The version string. */
+#define YAML_VERSION_STRING                                                     \
+    YAML_VERSION_STRING_GENERATOR(YAML_VERSION_MAJOR,YAML_VERSION_MINOR,YAML_VERSION_PATCH)
 
 /**
- * Get the library version numbers.
+ * Get the library version numbers at runtime.
  *
  * @param[out]      major   Major version number.
  * @param[out]      minor   Minor version number.
 YAML_DECLARE(void)
 yaml_get_version(int *major, int *minor, int *patch);
 
+/**
+ * Get the library version as a string at runtime.
+ *
+ * @returns The function returns the pointer to a static string of the form
+ * @c "X.Y.Z", where @c X is the major version number, @c Y is the minor version
+ * number, and @c Z is the patch version number.
+ */
+
+YAML_DECLARE(const char *)
+yaml_get_version_string(void);
+
 /** @} */
 
 /**
     YAML_READER_ERROR,
     /** Cannot decode the input stream. */
     YAML_DECODER_ERROR,
-
     /** Cannot scan a YAML token. */
     YAML_SCANNER_ERROR,
     /** Cannot parse a YAML production. */
 
     /** Cannot write into the output stream. */
     YAML_WRITER_ERROR,
-
     /** Cannot emit a YAML event. */
     YAML_EMITTER_ERROR,
     /** Cannot serialize a YAML document. */
-    YAML_SERIALIZER_ERROR
+    YAML_SERIALIZER_ERROR,
+
+    /** Cannot resolve an implicit tag. */
+    YAML_RESOLVER_ERROR
 } yaml_error_type_t;
 
 /** The pointer position. */
          * @c YAML_PARSER_ERROR, or @c YAML_COMPOSER_ERROR).
          */
         struct {
-            /** The problem description. */
-            const char *problem;
-            /** The problem mark. */
-            yaml_mark_t problem_mark;
             /** The context in which the problem occured
              * (@c NULL if not applicable).
              */
             const char *context;
             /** The context mark (if @c problem_mark is not @c NULL). **/
             yaml_mark_t context_mark;
+            /** The problem description. */
+            const char *problem;
+            /** The problem mark. */
+            yaml_mark_t problem_mark;
         } loading;
 
         /** A problem while writing into the stream (@c YAML_WRITER_ERROR). */
             const char *problem;
         } dumping;
 
+        /** A problem while resolving an implicit tag (@c YAML_RESOLVER_ERROR). */
+        struct {
+            /** The problem description. */
+            const char *problem;
+        } resolving;
+
     } data;
 
 } yaml_error_t;
 
+/**
+ * Create an error message.
+ *
+ * @param[in]   error   An error object.
+ * @param[out]  buffer         model   A token to copy.
+ *
+ * @returns @c 1 if the function succeeded, @c 0 on error.  The function may
+ * fail if the buffer is not large enough to contain the whole message.
+ */
+
+YAML_DECLARE(int)
+yaml_error_message(yaml_error_t *error, char *buffer, size_t capacity);
 
 /** @} */
 
  */
 
 YAML_DECLARE(int)
-yaml_token_duplicate(yaml_token_t *token, yaml_token_t *model);
+yaml_token_duplicate(yaml_token_t *token, const yaml_token_t *model);
 
 /**
  * Free any memory allocated for a token object.
  */
 
 YAML_DECLARE(int)
-yaml_event_duplicate(yaml_event_t *event, yaml_event_t *model);
+yaml_event_duplicate(yaml_event_t *event, const yaml_event_t *model);
 
 /**
  * Create a STREAM-START event.
  */
 
 /** The tag @c !!null with the only possible value: @c null. */
-#define YAML_NULL_TAG       "tag:yaml.org,2002:null"
+#define YAML_NULL_TAG       ((const yaml_char_t *) "tag:yaml.org,2002:null")
 /** The tag @c !!bool with the values: @c true and @c falce. */
-#define YAML_BOOL_TAG       "tag:yaml.org,2002:bool"
+#define YAML_BOOL_TAG       ((const yaml_char_t *) "tag:yaml.org,2002:bool")
 /** The tag @c !!str for string values. */
-#define YAML_STR_TAG        "tag:yaml.org,2002:str"
+#define YAML_STR_TAG        ((const yaml_char_t *) "tag:yaml.org,2002:str")
 /** The tag @c !!int for integer values. */
-#define YAML_INT_TAG        "tag:yaml.org,2002:int"
+#define YAML_INT_TAG        ((const yaml_char_t *) "tag:yaml.org,2002:int")
 /** The tag @c !!float for float values. */
-#define YAML_FLOAT_TAG      "tag:yaml.org,2002:float"
+#define YAML_FLOAT_TAG      ((const yaml_char_t *) "tag:yaml.org,2002:float")
 
 /** The tag @c !!seq is used to denote sequences. */
-#define YAML_SEQ_TAG        "tag:yaml.org,2002:seq"
+#define YAML_SEQ_TAG        ((const yaml_char_t *) "tag:yaml.org,2002:seq")
 /** The tag @c !!map is used to denote mapping. */
-#define YAML_MAP_TAG        "tag:yaml.org,2002:map"
+#define YAML_MAP_TAG        ((const yaml_char_t *) "tag:yaml.org,2002:map")
 
 /** The default scalar tag is @c !!str. */
 #define YAML_DEFAULT_SCALAR_TAG     YAML_STR_TAG
  * it should return @c 0.
  */
 
-typedef int yaml_writer_t(void *data, unsigned char *buffer, size_t length);
+typedef int yaml_writer_t(void *data, const unsigned char *buffer,
+        size_t length);
 
 /**
  * The prototype of a tag resolver.
  */
 
 YAML_DECLARE(int)
-yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token);
+yaml_parser_parse_token(yaml_parser_t *parser, yaml_token_t *token);
 
 /**
  * Parse the input stream and produce the next parsing event.
  */
 
 YAML_DECLARE(int)
-yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
+yaml_parser_parse_event(yaml_parser_t *parser, yaml_event_t *event);
 
 #if 0
 
  */
 
 YAML_DECLARE(int)
-yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
+yaml_parser_parse_document(yaml_parser_t *parser, yaml_document_t *document);
 
 #endif
 
  */
 
 YAML_DECLARE(int)
-yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
+yaml_emitter_emit_event(yaml_emitter_t *emitter, yaml_event_t *event);
 
 #if 0
 
  */
 
 YAML_DECLARE(int)
-yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
+yaml_emitter_emit_document(yaml_emitter_t *emitter, yaml_document_t *document);
 
 #endif
 
 }
 
 /*
+ * Format an error message.
+ */
+
+YAML_DECLARE(int)
+yaml_error_message(yaml_error_t *error, char *buffer, size_t capacity)
+{
+    char *prefixes[] = {
+        "No error",
+        "Memory error",
+        "Reader error",
+        "Decoder error",
+        "Scanner error",
+        "Parser error",
+        "Composer error",
+        "Writer error",
+        "Emitter error",
+        "Serializer error",
+        "Resolver error",
+    };
+    int length;
+
+    assert(error);  /* Non-NULL error is expected. */
+    assert(buffer); /* Non-NULL buffer is expected. */
+
+    switch (error->type)
+    {
+        case YAML_NO_ERROR:
+        case YAML_MEMORY_ERROR:
+            length = snprintf(buffer, capacity, "%s",
+                    prefixes[error->type]);
+            break;
+
+        case YAML_READER_ERROR:
+        case YAML_DECODER_ERROR:
+            if (error->data.reading.value == -1) {
+                length = snprintf(buffer, capacity,
+                        "%s: %s at position %d",
+                        prefixes[error->type],
+                        error->data.reading.problem,
+                        error->data.reading.offset);
+            }
+            else {
+                length = snprintf(buffer, capacity,
+                        "%s: %s (#%X) at position %d",
+                        prefixes[error->type],
+                        error->data.reading.problem,
+                        error->data.reading.value,
+                        error->data.reading.offset);
+            }
+            break;
+
+        case YAML_SCANNER_ERROR:
+        case YAML_PARSER_ERROR:
+        case YAML_COMPOSER_ERROR:
+            if (!error->data.loading.context) {
+                length = snprintf(buffer, capacity,
+                        "%s: %s at line %d, column %d",
+                        prefixes[error->type],
+                        error->data.loading.problem,
+                        error->data.loading.problem_mark.line+1,
+                        error->data.loading.problem_mark.column+1);
+            }
+            else {
+                length = snprintf(buffer, capacity,
+                        "%s: %s at line %d, column %d, %s at line %d, column %d",
+                        prefixes[error->type],
+                        error->data.loading.context,
+                        error->data.loading.context_mark.line+1,
+                        error->data.loading.context_mark.column+1,
+                        error->data.loading.problem,
+                        error->data.loading.problem_mark.line+1,
+                        error->data.loading.problem_mark.column+1);
+            }
+            break;
+
+        case YAML_WRITER_ERROR:
+            length = snprintf(buffer, capacity,
+                    "%s: %s at position %d",
+                    prefixes[error->type],
+                    error->data.writing.problem,
+                    error->data.writing.offset);
+            break;
+
+        case YAML_EMITTER_ERROR:
+        case YAML_SERIALIZER_ERROR:
+            length = snprintf(buffer, capacity, "%s: %s",
+                    prefixes[error->type],
+                    error->data.dumping.problem);
+            break;
+
+        case YAML_RESOLVER_ERROR:
+            length = snprintf(buffer, capacity, "%s: %s",
+                    prefixes[error->type],
+                    error->data.resolving.problem);
+            break;
+
+        default:
+            assert(0);  /* Should never happen. */
+    }
+
+    return (length >= 0 && length < capacity);
+}
+
+
+/*
  * Extend a string.
  */
 
 YAML_DECLARE(int)
-yaml_string_extend(yaml_char_t **buffer, size_t *capacity)
+yaml_ostring_extend(yaml_char_t **buffer, size_t *capacity)
 {
     yaml_char_t *new_buffer = yaml_realloc(*buffer, (*capacity)*2);
 
  */
 
 YAML_DECLARE(int)
-yaml_string_join(
+yaml_ostring_join(
         yaml_char_t **base_buffer, size_t *base_pointer, size_t *base_capacity,
-        yaml_char_t *adj_buffer, size_t adj_pointer, size_t adj_capacity)
+        yaml_char_t *adj_buffer, size_t adj_pointer)
 {
     if (!adj_pointer)
         return 1;
 
     while (*base_capacity - *base_pointer <= adj_pointer) {
-        if (!yaml_string_extend(base_buffer, base_capacity))
+        if (!yaml_ostring_extend(base_buffer, base_capacity))
             return 0;
     }
 
         return NULL;
 
     memset(parser, 0, sizeof(yaml_parser_t));
-    if (!STRING_INIT(parser, parser->raw_input, RAW_INPUT_BUFFER_CAPACITY))
+    if (!IOSTRING_INIT(parser, parser->raw_input, RAW_INPUT_BUFFER_CAPACITY))
         goto error;
-    if (!STRING_INIT(parser, parser->input, INPUT_BUFFER_CAPACITY))
+    if (!IOSTRING_INIT(parser, parser->input, INPUT_BUFFER_CAPACITY))
         goto error;
     if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_CAPACITY))
         goto error;
 {
     assert(parser); /* Non-NULL parser object expected. */
 
-    STRING_DEL(parser, parser->raw_input);
-    STRING_DEL(parser, parser->input);
+    IOSTRING_DEL(parser, parser->raw_input);
+    IOSTRING_DEL(parser, parser->input);
     while (!QUEUE_EMPTY(parser, parser->tokens)) {
         yaml_token_destroy(&DEQUEUE(parser, parser->tokens));
     }
 {
     yaml_standard_reader_data_t *data = untyped_data;
 
-    if (data->string.pointer == data->string.capacity) {
+    if (data->string.pointer == data->string.length) {
         *length = 0;
         return 1;
     }
 
-    if (capacity > (size_t)(data->string.capacity - data->string.pointer)) {
-        capacity = data->string.capacity - data->string.pointer;
+    if (capacity > (size_t)(data->string.length - data->string.pointer)) {
+        capacity = data->string.length - data->string.pointer;
     }
 
     memcpy(buffer, data->string.buffer + data->string.pointer, capacity);
     parser->reader = yaml_string_reader;
     parser->reader_data = &(parser->standard_reader_data);
 
-    parser->standard_reader_data.string.buffer = (unsigned char *)buffer;
+    parser->standard_reader_data.string.buffer = buffer;
     parser->standard_reader_data.string.pointer = 0;
-    parser->standard_reader_data.string.capacity = length;
+    parser->standard_reader_data.string.length = length;
 }
 
 /*
         return NULL;
 
     memset(emitter, 0, sizeof(yaml_emitter_t));
-    if (!STRING_INIT(emitter, emitter->output, OUTPUT_BUFFER_CAPACITY))
+    if (!IOSTRING_INIT(emitter, emitter->output, OUTPUT_BUFFER_CAPACITY))
         goto error;
-    if (!STRING_INIT(emitter, emitter->raw_output, RAW_OUTPUT_BUFFER_CAPACITY))
+    if (!IOSTRING_INIT(emitter, emitter->raw_output, RAW_OUTPUT_BUFFER_CAPACITY))
         goto error;
     if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_CAPACITY))
         goto error;
 {
     assert(emitter);    /* Non-NULL emitter object expected. */
 
-    STRING_DEL(emitter, emitter->output);
-    STRING_DEL(emitter, emitter->raw_output);
+    IOSTRING_DEL(emitter, emitter->output);
+    IOSTRING_DEL(emitter, emitter->raw_output);
     STACK_DEL(emitter, emitter->states);
     while (!QUEUE_EMPTY(emitter, emitter->events)) {
         yaml_event_delete(&DEQUEUE(emitter, emitter->events));
  */
 
 static int
-yaml_string_writer(void *untyped_data, unsigned char *buffer, size_t length)
+yaml_string_writer(void *untyped_data, const unsigned char *buffer, size_t length)
 {
     yaml_standard_writer_data_t *data = untyped_data;
     int result = 1;
  */
 
 static int
-yaml_file_writer(void *untyped_data, unsigned char *buffer, size_t length)
+yaml_file_writer(void *untyped_data, const unsigned char *buffer, size_t length)
 {
     yaml_standard_writer_data_t *data = untyped_data;
 
  */
 
 YAML_DECLARE(int)
-yaml_token_duplicate(yaml_token_t *token, yaml_token_t *model)
+yaml_token_duplicate(yaml_token_t *token, const yaml_token_t *model)
 {
     assert(token);  /* Non-NULL token object is expected. */
     assert(model);  /* Non-NULL model token object is expected. */
  */
 
 YAML_DECLARE(int)
-yaml_event_duplicate(yaml_event_t *event, yaml_event_t *model)
+yaml_event_duplicate(yaml_event_t *event, const yaml_event_t *model)
 {
     struct {
         yaml_error_t error;
  * Put a character to the output buffer.
  */
 
-#define PUT(emitter,value)                                                      \
+#define PUT(emitter, value)                                                     \
     (FLUSH(emitter)                                                             \
-     && (JOIN_OCTET(emitter->output,(yaml_char_t)(value)),                      \
+     && (JOIN_OCTET(emitter->output, (yaml_char_t)(value)),                     \
          emitter->column ++,                                                    \
          1))
 
  * Copy a character from a string into buffer.
  */
 
-#define WRITE(emitter,string)                                                   \
+#define WRITE(emitter, string)                                                  \
     (FLUSH(emitter)                                                             \
-     && (COPY(emitter->output,string),                                          \
+     && (COPY(emitter->output, string),                                         \
          emitter->column ++,                                                    \
          1))
 
  * Copy a line break character from a string into buffer.
  */
 
-#define WRITE_BREAK(emitter,string)                                             \
+#define WRITE_BREAK(emitter, string)                                            \
     (FLUSH(emitter)                                                             \
-     && (CHECK(string,'\n') ?                                                   \
+     && (CHECK(string, '\n') ?                                                  \
          (PUT_BREAK(emitter),                                                   \
           string.pointer ++,                                                    \
           1) :                                                                  \
-         (COPY(emitter->output,string),                                         \
+         (COPY(emitter->output, string),                                        \
           emitter->column = 0,                                                  \
           emitter->line ++,                                                     \
           1)))
  */
 
 YAML_DECLARE(int)
-yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
+yaml_emitter_emit_event(yaml_emitter_t *emitter, yaml_event_t *event);
 
 /*
  * Utility functions.
 
 static int
 yaml_emitter_write_indicator(yaml_emitter_t *emitter,
-        char *indicator, int need_whitespace,
+        const char *indicator, int need_whitespace,
         int is_whitespace, int is_indention);
 
 static int
 yaml_emitter_write_anchor(yaml_emitter_t *emitter,
-        yaml_char_t *value, size_t length);
+        const 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);
+        const 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);
+        const 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);
+        const 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);
+        const 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);
+        const yaml_char_t *value, size_t length, int allow_breaks);
 
 static int
 yaml_emitter_determine_chomping(yaml_emitter_t *emitter,
-        yaml_string_t string);
+        yaml_istring_t string);
 
 static int
 yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
-        yaml_char_t *value, size_t length);
+        const 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);
+        const yaml_char_t *value, size_t length);
 
 /*
  * Emit an event.
  */
 
 YAML_DECLARE(int)
-yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event)
+yaml_emitter_emit_event(yaml_emitter_t *emitter, yaml_event_t *event)
 {
     if (!ENQUEUE(emitter, emitter->events, *event)) {
         yaml_event_delete(event);
                     "expected nothing after STREAM-END");
 
         default:
-            assert(1);      /* Invalid state. */
+            assert(0);      /* Invalid state. */
     }
 
     return 0;
                     emitter->scalar_data.value, emitter->scalar_data.length);
 
         default:
-            assert(1);      /* Impossible. */
+            assert(0);      /* Impossible. */
     }
 
     return 0;
 yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
         yaml_tag_directive_t tag_directive)
 {
-    yaml_string_t handle = STRING(tag_directive.handle,
+    yaml_istring_t handle = ISTRING(tag_directive.handle,
             strlen((char *)tag_directive.handle));
-    yaml_string_t prefix = STRING(tag_directive.prefix,
+    yaml_istring_t prefix = ISTRING(tag_directive.prefix,
             strlen((char *)tag_directive.prefix));
 
-    if (!handle.capacity) {
+    if (!handle.length) {
         return EMITTER_ERROR_INIT(emitter, "tag handle must not be empty");
     }
 
         return EMITTER_ERROR_INIT(emitter, "tag handle must start with '!'");
     }
 
-    if (handle.buffer[handle.capacity-1] != '!') {
+    if (handle.buffer[handle.length-1] != '!') {
         return EMITTER_ERROR_INIT(emitter, "tag handle must end with '!'");
     }
 
     handle.pointer ++;
 
-    while (handle.pointer < handle.capacity-1) {
+    while (handle.pointer < handle.length-1) {
         if (!IS_ALPHA(handle)) {
             return EMITTER_ERROR_INIT(emitter,
                     "tag handle must contain alphanumerical characters only");
         MOVE(handle);
     }
 
-    if (!prefix.capacity) {
+    if (!prefix.length) {
         return EMITTER_ERROR_INIT(emitter, "tag prefix must not be empty");
     }
 
 yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
         yaml_char_t *anchor, int is_alias)
 {
-    yaml_string_t string = STRING(anchor, strlen((char *)anchor));
+    yaml_istring_t string = ISTRING(anchor, strlen((char *)anchor));
 
-    if (!string.capacity) {
+    if (!string.length) {
         return EMITTER_ERROR_INIT(emitter, is_alias ?
                 "alias value must not be empty" :
                 "anchor value must not be empty");
     }
 
-    while (string.pointer < string.capacity) {
+    while (string.pointer < string.length) {
         if (!IS_ALPHA(string)) {
             return EMITTER_ERROR_INIT(emitter, is_alias ?
                     "alias value must contain alphanumerical characters only" :
     }
 
     emitter->anchor_data.anchor = string.buffer;
-    emitter->anchor_data.anchor_length = string.capacity;
+    emitter->anchor_data.anchor_length = string.length;
     emitter->anchor_data.is_alias = is_alias;
 
     return 1;
 yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
         yaml_char_t *tag)
 {
-    yaml_string_t string = STRING(tag, strlen((char *)tag));
+    yaml_istring_t string = ISTRING(tag, strlen((char *)tag));
     size_t idx;
 
-    if (!string.capacity) {
+    if (!string.length) {
         return EMITTER_ERROR_INIT(emitter, "tag value must not be empty");
     }
 
     for (idx = 0; idx < emitter->tag_directives.length; idx ++) {
-        yaml_tag_directive_t *tag_directive = emitter->tag_directives.list+idx;
+        yaml_tag_directive_t *tag_directive =
+            STACK_ITER(emitter, emitter->tag_directives, idx);
         size_t prefix_length = strlen((char *)tag_directive->prefix);
-        if (prefix_length < string.capacity
+        if (prefix_length < string.length
                 && strncmp((char *)tag_directive->prefix, (char *)string.buffer,
                     prefix_length) == 0)
         {
             emitter->tag_data.handle_length =
                 strlen((char *)tag_directive->handle);
             emitter->tag_data.suffix = string.buffer + prefix_length;
-            emitter->tag_data.suffix_length = string.capacity - prefix_length;
+            emitter->tag_data.suffix_length = string.length - prefix_length;
             return 1;
         }
     }
 
     emitter->tag_data.suffix = string.buffer;
-    emitter->tag_data.suffix_length = string.capacity;
+    emitter->tag_data.suffix_length = string.length;
 
     return 1;
 }
 yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
         yaml_char_t *value, size_t length)
 {
-    yaml_string_t string = STRING(value, length);
+    yaml_istring_t string = ISTRING(value, length);
 
     int block_indicators = 0;
     int flow_indicators = 0;
     emitter->scalar_data.value = value;
     emitter->scalar_data.length = length;
 
-    if (!string.capacity)
+    if (!string.length)
     {
         emitter->scalar_data.is_multiline = 0;
         emitter->scalar_data.is_flow_plain_allowed = 0;
     preceeded_by_space = 1;
     followed_by_space = IS_BLANKZ_AT(string, WIDTH(string));
 
-    while (string.pointer < string.capacity)
+    while (string.pointer < string.length)
     {
         if (!string.pointer)
         {
             spaces = breaks = mixed = leading = 0;
         }
 
-        if ((spaces || breaks) && string.pointer == string.capacity-1)
+        if ((spaces || breaks) && string.pointer == string.length-1)
         {
             if (spaces && breaks) {
                 mixed_breaks_spaces = 1;
 
         preceeded_by_space = IS_BLANKZ(string);
         MOVE(string);
-        if (string.pointer < string.capacity) {
+        if (string.pointer < string.length) {
             followed_by_space = IS_BLANKZ_AT(string, WIDTH(string));
         }
     }
 
 static int
 yaml_emitter_write_indicator(yaml_emitter_t *emitter,
-        char *indicator, int need_whitespace,
+        const char *indicator, int need_whitespace,
         int is_whitespace, int is_indention)
 {
-    yaml_string_t string = STRING((yaml_char_t *)indicator, strlen(indicator));
+    yaml_istring_t string = ISTRING((yaml_char_t *)indicator, strlen(indicator));
 
     if (need_whitespace && !emitter->is_whitespace) {
         if (!PUT(emitter, ' ')) return 0;
     }
 
-    while (string.pointer < string.capacity) {
+    while (string.pointer < string.length) {
         if (!WRITE(emitter, string)) return 0;
     }
 
 
 static int
 yaml_emitter_write_anchor(yaml_emitter_t *emitter,
-        yaml_char_t *value, size_t length)
+        const yaml_char_t *value, size_t length)
 {
-    yaml_string_t string = STRING(value, length);
+    yaml_istring_t string = ISTRING(value, length);
 
-    while (string.pointer < string.capacity) {
+    while (string.pointer < string.length) {
         if (!WRITE(emitter, string)) return 0;
     }
 
 
 static int
 yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
-        yaml_char_t *value, size_t length)
+        const yaml_char_t *value, size_t length)
 {
-    yaml_string_t string = STRING(value, length);
+    yaml_istring_t string = ISTRING(value, length);
 
     if (!emitter->is_whitespace) {
         if (!PUT(emitter, ' ')) return 0;
     }
 
-    while (string.pointer < string.capacity) {
+    while (string.pointer < string.length) {
         if (!WRITE(emitter, string)) return 0;
     }
 
 
 static int
 yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
-        yaml_char_t *value, size_t length,
+        const yaml_char_t *value, size_t length,
         int need_whitespace)
 {
-    yaml_string_t string = STRING(value, length);
+    yaml_istring_t string = ISTRING(value, length);
 
     if (need_whitespace && !emitter->is_whitespace) {
         if (!PUT(emitter, ' ')) return 0;
     }
 
-    while (string.pointer < string.capacity) {
+    while (string.pointer < string.length) {
         if (IS_ALPHA(string)
                 || CHECK(string, ';') || CHECK(string, '/')
                 || CHECK(string, '?') || CHECK(string, ':')
 
 static int
 yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
-        yaml_char_t *value, size_t length, int allow_breaks)
+        const yaml_char_t *value, size_t length, int allow_breaks)
 {
-    yaml_string_t string = STRING(value, length);
+    yaml_istring_t string = ISTRING(value, length);
     int spaces = 0;
     int breaks = 0;
 
         if (!PUT(emitter, ' ')) return 0;
     }
 
-    while (string.pointer < string.capacity)
+    while (string.pointer < string.length)
     {
         if (IS_SPACE(string))
         {
 
 static int
 yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
-        yaml_char_t *value, size_t length, int allow_breaks)
+        const yaml_char_t *value, size_t length, int allow_breaks)
 {
-    yaml_string_t string = STRING(value, length);
+    yaml_istring_t string = ISTRING(value, length);
     int spaces = 0;
     int breaks = 0;
 
     if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0))
         return 0;
 
-    while (string.pointer < string.capacity)
+    while (string.pointer < string.length)
     {
         if (IS_SPACE(string))
         {
             if (allow_breaks && !spaces
                     && emitter->column > emitter->best_width
-                    && string.pointer != 0
-                    && string.pointer != string.capacity - 1
+                    && string.pointer > 0 && string.pointer < string.length
                     && !IS_SPACE_AT(string, 1)) {
                 if (!yaml_emitter_write_indent(emitter)) return 0;
                 MOVE(string);
 
 static int
 yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
-        yaml_char_t *value, size_t length, int allow_breaks)
+        const yaml_char_t *value, size_t length, int allow_breaks)
 {
-    yaml_string_t string = STRING(value, length);
+    yaml_istring_t string = ISTRING(value, length);
     int spaces = 0;
 
     if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0))
         return 0;
 
-    while (string.pointer < string.capacity)
+    while (string.pointer < string.length)
     {
         if (!IS_PRINTABLE(string) || (!emitter->is_unicode && !IS_ASCII(string))
                 || IS_BOM(string) || IS_BREAK(string)
         {
             if (allow_breaks && !spaces
                     && emitter->column > emitter->best_width
-                    && string.pointer != 0
-                    && string.pointer != string.capacity - 1) {
+                    && string.pointer > 0
+                    && string.pointer < string.length) {
                 if (!yaml_emitter_write_indent(emitter)) return 0;
                 if (IS_SPACE_AT(string, 1)) {
                     if (!PUT(emitter, '\\')) return 0;
 
 static int
 yaml_emitter_determine_chomping(yaml_emitter_t *emitter,
-        yaml_string_t string)
+        yaml_istring_t string)
 {
-    string.pointer = string.capacity;
+    string.pointer = string.length;
     if (!string.pointer)
         return -1;
     do {
 
 static int
 yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
-        yaml_char_t *value, size_t length)
+        const yaml_char_t *value, size_t length)
 {
-    yaml_string_t string = STRING(value, length);
+    yaml_istring_t string = ISTRING(value, length);
     int chomp = yaml_emitter_determine_chomping(emitter, string);
     int breaks = 0;
 
     if (!yaml_emitter_write_indent(emitter))
         return 0;
 
-    while (string.pointer < string.capacity)
+    while (string.pointer < string.length)
     {
         if (IS_BREAK(string))
         {
 
 static int
 yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
-        yaml_char_t *value, size_t length)
+        const yaml_char_t *value, size_t length)
 {
-    yaml_string_t string = STRING(value, length);
+    yaml_istring_t string = ISTRING(value, length);
     int chomp = yaml_emitter_determine_chomping(emitter, string);
     int breaks = 1;
     int leading_spaces = 0;
     if (!yaml_emitter_write_indent(emitter))
         return 0;
 
-    while (string.pointer < string.capacity)
+    while (string.pointer < string.length)
     {
         if (IS_BREAK(string))
         {
 
 #define PEEK_TOKEN(parser)                                                      \
     ((parser->is_token_available || yaml_parser_fetch_more_tokens(parser)) ?    \
-        parser->tokens.list + parser->tokens.head : NULL)
+        QUEUE_ITER(parser, parser->tokens, 0) : NULL)
 
 /*
  * Remove the next token from the queue (must be called after PEEK_TOKEN).
     (parser->is_token_available = 0,                                            \
      parser->tokens_parsed ++,                                                  \
      parser->is_stream_end_produced =                                           \
-        (parser->tokens.list[parser->tokens.head].type == YAML_STREAM_END_TOKEN),   \
+        (QUEUE_ITER(parser, parser->tokens, 0)->type == YAML_STREAM_END_TOKEN), \
      parser->tokens.head ++)
 
 /*
  */
 
 YAML_DECLARE(int)
-yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
+yaml_parser_parse_event(yaml_parser_t *parser, yaml_event_t *event);
 
 /*
  * State functions.
  */
 
 YAML_DECLARE(int)
-yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
+yaml_parser_parse_event(yaml_parser_t *parser, yaml_event_t *event)
 {
     assert(parser);     /* Non-NULL parser object is expected. */
     assert(event);      /* Non-NULL event object is expected. */
             return yaml_parser_parse_flow_mapping_value(parser, event, 1);
 
         default:
-            assert(1);      /* Invalid state. */
+            assert(0);      /* Invalid state. */
     }
 
     return 0;
             else {
                 int idx;
                 for (idx = 0; idx < parser->tag_directives.length; idx++) {
-                    yaml_tag_directive_t *tag_directive = parser->tag_directives.list + idx;
+                    yaml_tag_directive_t *tag_directive =
+                        STACK_ITER(parser, parser->tag_directives, idx);
                     if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
                         size_t prefix_len = strlen((char *)tag_directive->prefix);
                         size_t suffix_len = strlen((char *)tag_suffix);
     int idx;
 
     for (idx = 0; idx < parser->tag_directives.length; idx++) {
-        yaml_tag_directive_t *tag_directive = parser->tag_directives.list + idx;
+        yaml_tag_directive_t *tag_directive =
+            STACK_ITER(parser, parser->tag_directives, idx);
         if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
             if (allow_duplicates)
                 return 1;
 {
     /* Ensure that we had enough bytes in the raw buffer. */
 
-    while (!parser->is_eof && parser->raw_input.capacity < 3) {
+    while (!parser->is_eof && parser->raw_input.length < 3) {
         if (!yaml_parser_update_raw_buffer(parser)) {
             return 0;
         }
 
     /* Determine the encoding. */
 
-    if (parser->raw_input.capacity >= 2
+    if (parser->raw_input.length >= 2
             && !memcmp(parser->raw_input.buffer, BOM_UTF16LE, 2)) {
         parser->encoding = YAML_UTF16LE_ENCODING;
         parser->raw_input.pointer = 2;
         parser->offset = 2;
     }
-    else if (parser->raw_input.capacity >= 2
+    else if (parser->raw_input.length >= 2
             && !memcmp(parser->raw_input.buffer, BOM_UTF16BE, 2)) {
         parser->encoding = YAML_UTF16BE_ENCODING;
         parser->raw_input.pointer = 2;
         parser->offset = 2;
     }
-    else if (parser->raw_input.capacity >= 3
+    else if (parser->raw_input.length >= 3
             && !memcmp(parser->raw_input.buffer, BOM_UTF8, 3)) {
         parser->encoding = YAML_UTF8_ENCODING;
         parser->raw_input.pointer = 3;
     /* Return if the raw buffer is full. */
 
     if (parser->raw_input.pointer == 0 &&
-            parser->raw_input.capacity == RAW_INPUT_BUFFER_CAPACITY)
+            parser->raw_input.length == parser->raw_input.capacity)
         return 1;
 
     /* Return on EOF. */
     /* Move the remaining bytes in the raw buffer to the beginning. */
 
     if (parser->raw_input.pointer > 0 &&
-            parser->raw_input.pointer < parser->raw_input.capacity) {
+            parser->raw_input.pointer < parser->raw_input.length) {
         memmove(parser->raw_input.buffer,
                 parser->raw_input.buffer + parser->raw_input.pointer,
-                parser->raw_input.capacity - parser->raw_input.pointer);
+                parser->raw_input.length - parser->raw_input.pointer);
     }
-    parser->raw_input.capacity -= parser->raw_input.pointer;
+    parser->raw_input.length -= parser->raw_input.pointer;
     parser->raw_input.pointer = 0;
 
     /* Call the read handler to fill the buffer. */
 
     if (!parser->reader(parser->reader_data,
-                parser->raw_input.buffer + parser->raw_input.capacity,
-                RAW_INPUT_BUFFER_CAPACITY - parser->raw_input.capacity,
+                parser->raw_input.buffer + parser->raw_input.length,
+                parser->raw_input.capacity - parser->raw_input.length,
                 &length)) {
-        return READER_ERROR_INIT(parser, "Input error", parser->offset);
+        return READER_ERROR_INIT(parser, "read handler error", parser->offset);
     }
-    parser->raw_input.capacity += length;
+    parser->raw_input.length += length;
     if (!length) {
         parser->is_eof = 1;
     }
 YAML_DECLARE(int)
 yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
 {
-    size_t old_capacity;
-
     assert(parser->reader); /* Read handler must be set. */
 
     /* If the EOF flag is set and the raw buffer is empty, do nothing. */
 
-    if (parser->is_eof && parser->raw_input.pointer == parser->raw_input.capacity)
+    if (parser->is_eof && parser->raw_input.pointer == parser->raw_input.length)
         return 1;
 
     /* Return if the buffer contains enough characters. */
     /* Move the unread characters to the beginning of the buffer. */
 
     if (parser->input.pointer > 0 &&
-            parser->input.pointer < parser->input.capacity) {
+            parser->input.pointer < parser->input.length) {
         memmove(parser->input.buffer,
                 parser->input.buffer + parser->input.pointer,
-                parser->input.capacity - parser->input.pointer);
-        parser->input.capacity -= parser->input.pointer;
+                parser->input.length - parser->input.pointer);
+        parser->input.length -= parser->input.pointer;
     }
-    else if (parser->input.pointer == parser->input.capacity) {
-        parser->input.capacity = 0;
+    else if (parser->input.pointer == parser->input.length) {
+        parser->input.length = 0;
     }
 
-    /* Set the pointer to the end of the buffer. */
+    /* Switch the buffer to the output mode. */
 
-    parser->input.pointer = parser->input.capacity;
+    parser->input.pointer = parser->input.length;
 
     /* Fill the buffer until it has enough characters. */
 
 
         /* Decode the raw buffer. */
 
-        while (parser->raw_input.pointer != parser->raw_input.capacity)
+        while (parser->raw_input.pointer < parser->raw_input.length)
         {
             size_t raw_unread =
-                parser->raw_input.capacity - parser->raw_input.pointer;
+                parser->raw_input.length - parser->raw_input.pointer;
             unsigned int value = 0, value2 = 0;
             int is_incomplete = 0;
             unsigned char octet;
 
                     if (!width)
                         return DECODER_ERROR_INIT(parser,
-                                "Invalid leading UTF-8 octet",
+                                "invalid leading UTF-8 octet",
                                 parser->offset, octet);
 
                     /* Check if the raw buffer contains an incomplete character. */
                     if (width > raw_unread) {
                         if (parser->is_eof) {
                             return DECODER_ERROR_INIT(parser,
-                                    "Incomplete UTF-8 octet sequence",
+                                    "incomplete UTF-8 octet sequence",
                                     parser->offset, -1);
                         }
                         is_incomplete = 1;
 
                         if ((octet & 0xC0) != 0x80)
                             return DECODER_ERROR_INIT(parser,
-                                    "Invalid trailing UTF-8 octet",
+                                    "invalid trailing UTF-8 octet",
                                     parser->offset+idx, octet);
 
                         /* Decode the octet. */
                             (width == 3 && value >= 0x800) ||
                             (width == 4 && value >= 0x10000)))
                         return DECODER_ERROR_INIT(parser,
-                                "Invalid length of a UTF-8 sequence",
+                                "invalid length of a UTF-8 sequence",
                                 parser->offset, -1);
 
                     /* Check the range of the value. */
 
                     if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF)
                         return DECODER_ERROR_INIT(parser,
-                                "Invalid Unicode character",
+                                "invalid Unicode character",
                                 parser->offset, value);
 
                     break;
                     if (raw_unread < 2) {
                         if (parser->is_eof) {
                             return DECODER_ERROR_INIT(parser,
-                                    "Incomplete UTF-16 character",
+                                    "incomplete UTF-16 character",
                                     parser->offset, -1);
                         }
                         is_incomplete = 1;
 
                     if ((value & 0xFC00) == 0xDC00)
                         return DECODER_ERROR_INIT(parser,
-                                "Unexpected low surrogate area",
+                                "unexpected low surrogate area",
                                 parser->offset, value);
 
                     /* Check for a high surrogate area. */
                         if (raw_unread < 4) {
                             if (parser->is_eof) {
                                 return DECODER_ERROR_INIT(parser,
-                                        "Incomplete UTF-16 surrogate pair",
+                                        "incomplete UTF-16 surrogate pair",
                                         parser->offset, -1);
                             }
                             is_incomplete = 1;
 
                         if ((value2 & 0xFC00) != 0xDC00)
                             return DECODER_ERROR_INIT(parser,
-                                    "Expected low surrogate area",
+                                    "expected low surrogate area",
                                     parser->offset+2, value2);
 
                         /* Generate the value of the surrogate pair. */
                     break;
 
                 default:
-                    assert(1);      /* Impossible. */
+                    assert(0);      /* Impossible. */
             }
 
             /* Check if the raw buffer contains enough bytes to form a character. */
                         || (value >= 0xE000 && value <= 0xFFFD)
                         || (value >= 0x10000 && value <= 0x10FFFF)))
                 return DECODER_ERROR_INIT(parser,
-                        "Control characters are not allowed",
+                        "control characters are not allowed",
                         parser->offset, value);
 
             /* Move the raw pointers. */
         }
 
     }
-    /* Swap the pointer with the end of the buffer. */
 
-    old_capacity = parser->input.capacity;
-    parser->input.capacity = parser->input.pointer;
-    parser->input.pointer = old_capacity;
+    /* Switch the the buffer back to the input mode. */
+
+    parser->input.length = parser->input.pointer;
+    parser->input.pointer = 0;
 
     return 1;
 }
  * Copy a character to a string buffer and advance pointers.
  */
 
-#define READ(parser,string)                                                     \
-     (STRING_EXTEND(parser,string) ?                                            \
-         (COPY(string,parser->input),                                           \
+#define READ(parser, string)                                                    \
+     (OSTRING_EXTEND(parser, string) ?                                          \
+         (COPY(string, parser->input),                                          \
           parser->mark.index ++,                                                \
           parser->mark.column ++,                                               \
           parser->unread --,                                                    \
  * Copy a line break character to a string buffer and advance pointers.
  */
 
-#define READ_LINE(parser,string)                                                \
-    (STRING_EXTEND(parser,string) ?                                             \
-    (((CHECK_AT(parser->input,'\r',0)                                           \
-       && CHECK_AT(parser->input,'\n',1)) ?         /* CR LF -> LF */           \
+#define READ_LINE(parser, string)                                               \
+    (OSTRING_EXTEND(parser, string) ?                                           \
+    (((CHECK_AT(parser->input, '\r', 0)                                         \
+       && CHECK_AT(parser->input, '\n', 1)) ?       /* CR LF -> LF */           \
      (JOIN_OCTET(string, (yaml_char_t) '\n'),                                   \
       parser->input.pointer += 2,                                               \
       parser->mark.index += 2,                                                  \
       parser->mark.column = 0,                                                  \
       parser->mark.line ++,                                                     \
       parser->unread -= 2) :                                                    \
-     (CHECK_AT(parser->input,'\r',0)                                            \
-      || CHECK_AT(parser->input,'\n',0)) ?          /* CR|LF -> LF */           \
-     (JOIN_OCTET(string,(yaml_char_t) '\n'),                                    \
+     (CHECK_AT(parser->input, '\r', 0)                                          \
+      || CHECK_AT(parser->input, '\n', 0)) ?        /* CR|LF -> LF */           \
+     (JOIN_OCTET(string, (yaml_char_t) '\n'),                                   \
       parser->input.pointer ++,                                                 \
       parser->mark.index ++,                                                    \
       parser->mark.column = 0,                                                  \
       parser->mark.line ++,                                                     \
       parser->unread --) :                                                      \
-     (CHECK_AT(parser->input,'\xC2',0)                                          \
-      && CHECK_AT(parser->input,'\x85',1)) ?        /* NEL -> LF */             \
-     (JOIN_OCTET(string,(yaml_char_t) '\n'),                                    \
+     (CHECK_AT(parser->input, '\xC2', 0)                                        \
+      && CHECK_AT(parser->input, '\x85', 1)) ?      /* NEL -> LF */             \
+     (JOIN_OCTET(string, (yaml_char_t) '\n'),                                   \
       parser->input.pointer += 2,                                               \
       parser->mark.index ++,                                                    \
       parser->mark.column = 0,                                                  \
       parser->mark.line ++,                                                     \
       parser->unread --) :                                                      \
-     (CHECK_AT(parser->input,'\xE2',0) &&                                       \
-      CHECK_AT(parser->input,'\x80',1) &&                                       \
-      (CHECK_AT(parser->input,'\xA8',2) ||                                      \
-       CHECK_AT(parser->input,'\xA9',2))) ?         /* LS|PS -> LS|PS */        \
-     (COPY_OCTET(string,parser->input),                                         \
-      COPY_OCTET(string,parser->input),                                         \
-      COPY_OCTET(string,parser->input),                                         \
+     (CHECK_AT(parser->input, '\xE2', 0) &&                                     \
+      CHECK_AT(parser->input, '\x80', 1) &&                                     \
+      (CHECK_AT(parser->input, '\xA8', 2) ||                                    \
+       CHECK_AT(parser->input, '\xA9', 2))) ?       /* LS|PS -> LS|PS */        \
+     (COPY_OCTET(string, parser->input),                                        \
+      COPY_OCTET(string, parser->input),                                        \
+      COPY_OCTET(string, parser->input),                                        \
       parser->mark.index ++,                                                    \
       parser->mark.column = 0,                                                  \
       parser->mark.line ++,                                                     \
  */
 
 YAML_DECLARE(int)
-yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token);
+yaml_parser_parse_token(yaml_parser_t *parser, yaml_token_t *token);
 
 /*
  * High-level token API.
 
 static int
 yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
-        yaml_mark_t start_mark, yaml_string_t *string);
+        yaml_mark_t start_mark, yaml_ostring_t *string);
 
 static int
 yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
 
 static int
 yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
-        int *indent, yaml_string_t *breaks,
+        int *indent, yaml_ostring_t *breaks,
         yaml_mark_t start_mark, yaml_mark_t *end_mark);
 
 static int
  */
 
 YAML_DECLARE(int)
-yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token)
+yaml_parser_parse_token(yaml_parser_t *parser, yaml_token_t *token)
 {
     assert(parser); /* Non-NULL parser object is expected. */
     assert(token);  /* Non-NULL token object is expected. */
 yaml_parser_scan_directive_name(yaml_parser_t *parser,
         yaml_mark_t start_mark, yaml_char_t **name)
 {
-    yaml_string_t string = NULL_STRING;
-
-    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+    yaml_ostring_t string = NULL_OSTRING;
+
+    if (!OSTRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
         goto error;
 
     /* Consume the directive name. */
     return 1;
 
 error:
-    STRING_DEL(parser, string);
+    OSTRING_DEL(parser, string);
     return 0;
 }
 
 {
     int length = 0;
     yaml_mark_t start_mark, end_mark;
-    yaml_string_t string = NULL_STRING;
-
-    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+    yaml_ostring_t string = NULL_OSTRING;
+
+    if (!OSTRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
         goto error;
 
     /* Eat the indicator character. */
     return 1;
 
 error:
-    STRING_DEL(parser, string);
+    OSTRING_DEL(parser, string);
     return 0;
 }
 
 yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
         yaml_mark_t start_mark, yaml_char_t **handle)
 {
-    yaml_string_t string = NULL_STRING;
-
-    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+    yaml_ostring_t string = NULL_OSTRING;
+
+    if (!OSTRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
         goto error;
 
     /* Check the initial '!' character. */
     return 1;
 
 error:
-    STRING_DEL(parser, string);
+    OSTRING_DEL(parser, string);
     return 0;
 }
 
         yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri)
 {
     size_t length = head ? strlen((char *)head) : 0;
-    yaml_string_t string = NULL_STRING;
-
-    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+    yaml_ostring_t string = NULL_OSTRING;
+
+    if (!OSTRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
         goto error;
 
     /* Resize the string to include the head. */
 
     while (string.capacity <= length) {
-        if (!yaml_string_extend(&string.buffer, &string.capacity)) {
+        if (!yaml_ostring_extend(&string.buffer, &string.capacity)) {
             MEMORY_ERROR_INIT(parser);
             goto error;
         }
     /* Check if the tag is non-empty. */
 
     if (!length) {
-        if (!STRING_EXTEND(parser, string))
+        if (!OSTRING_EXTEND(parser, string))
             goto error;
 
         SCANNER_ERROR_WITH_CONTEXT_INIT(parser, directive ?
     return 1;
 
 error:
-    STRING_DEL(parser, string);
+    OSTRING_DEL(parser, string);
     return 0;
 }
 
 
 static int
 yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
-        yaml_mark_t start_mark, yaml_string_t *string)
+        yaml_mark_t start_mark, yaml_ostring_t *string)
 {
     int width = 0;
 
 {
     yaml_mark_t start_mark;
     yaml_mark_t end_mark;
-    yaml_string_t string = NULL_STRING;
-    yaml_string_t leading_break = NULL_STRING;
-    yaml_string_t trailing_breaks = NULL_STRING;
+    yaml_ostring_t string = NULL_OSTRING;
+    yaml_ostring_t leading_break = NULL_OSTRING;
+    yaml_ostring_t trailing_breaks = NULL_OSTRING;
     int chomping = 0;
     int increment = 0;
     int indent = 0;
     int leading_blank = 0;
     int trailing_blank = 0;
 
-    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+    if (!OSTRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
         goto error;
-    if (!STRING_INIT(parser, leading_break, INITIAL_STRING_CAPACITY))
+    if (!OSTRING_INIT(parser, leading_break, INITIAL_STRING_CAPACITY))
         goto error;
-    if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_CAPACITY))
+    if (!OSTRING_INIT(parser, trailing_breaks, INITIAL_STRING_CAPACITY))
         goto error;
 
     /* Eat the indicator '|' or '>'. */
             /* Do we need to join the lines by space? */
 
             if (*trailing_breaks.buffer == '\0') {
-                if (!STRING_EXTEND(parser, string)) goto error;
+                if (!OSTRING_EXTEND(parser, string)) goto error;
                 JOIN_OCTET(string, ' ');
             }
 
             literal ? YAML_LITERAL_SCALAR_STYLE : YAML_FOLDED_SCALAR_STYLE,
             start_mark, end_mark);
 
-    STRING_DEL(parser, leading_break);
-    STRING_DEL(parser, trailing_breaks);
+    OSTRING_DEL(parser, leading_break);
+    OSTRING_DEL(parser, trailing_breaks);
 
     return 1;
 
 error:
-    STRING_DEL(parser, string);
-    STRING_DEL(parser, leading_break);
-    STRING_DEL(parser, trailing_breaks);
+    OSTRING_DEL(parser, string);
+    OSTRING_DEL(parser, leading_break);
+    OSTRING_DEL(parser, trailing_breaks);
 
     return 0;
 }
 
 static int
 yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
-        int *indent, yaml_string_t *breaks,
+        int *indent, yaml_ostring_t *breaks,
         yaml_mark_t start_mark, yaml_mark_t *end_mark)
 {
     int max_indent = 0;
 {
     yaml_mark_t start_mark;
     yaml_mark_t end_mark;
-    yaml_string_t string = NULL_STRING;
-    yaml_string_t leading_break = NULL_STRING;
-    yaml_string_t trailing_breaks = NULL_STRING;
-    yaml_string_t whitespaces = NULL_STRING;
+    yaml_ostring_t string = NULL_OSTRING;
+    yaml_ostring_t leading_break = NULL_OSTRING;
+    yaml_ostring_t trailing_breaks = NULL_OSTRING;
+    yaml_ostring_t whitespaces = NULL_OSTRING;
     int leading_blanks;
 
-    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+    if (!OSTRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
         goto error;
-    if (!STRING_INIT(parser, leading_break, INITIAL_STRING_CAPACITY))
+    if (!OSTRING_INIT(parser, leading_break, INITIAL_STRING_CAPACITY))
         goto error;
-    if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_CAPACITY))
+    if (!OSTRING_INIT(parser, trailing_breaks, INITIAL_STRING_CAPACITY))
         goto error;
-    if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_CAPACITY))
+    if (!OSTRING_INIT(parser, whitespaces, INITIAL_STRING_CAPACITY))
         goto error;
 
     /* Eat the left quote. */
             if (single && CHECK_AT(parser->input, '\'', 0)
                     && CHECK_AT(parser->input, '\'', 1))
             {
-                if (!STRING_EXTEND(parser, string)) goto error;
+                if (!OSTRING_EXTEND(parser, string)) goto error;
                 JOIN_OCTET(string, '\'');
                 SKIP(parser);
                 SKIP(parser);
             {
                 size_t code_length = 0;
 
-                if (!STRING_EXTEND(parser, string)) goto error;
+                if (!OSTRING_EXTEND(parser, string)) goto error;
 
                 /* Check the escape character. */
 
 
             if (leading_break.buffer[0] == '\n') {
                 if (trailing_breaks.buffer[0] == '\0') {
-                    if (!STRING_EXTEND(parser, string)) goto error;
+                    if (!OSTRING_EXTEND(parser, string)) goto error;
                     JOIN_OCTET(string, ' ');
                 }
                 else {
             single ? YAML_SINGLE_QUOTED_SCALAR_STYLE : YAML_DOUBLE_QUOTED_SCALAR_STYLE,
             start_mark, end_mark);
 
-    STRING_DEL(parser, leading_break);
-    STRING_DEL(parser, trailing_breaks);
-    STRING_DEL(parser, whitespaces);
+    OSTRING_DEL(parser, leading_break);
+    OSTRING_DEL(parser, trailing_breaks);
+    OSTRING_DEL(parser, whitespaces);
 
     return 1;
 
 error:
-    STRING_DEL(parser, string);
-    STRING_DEL(parser, leading_break);
-    STRING_DEL(parser, trailing_breaks);
-    STRING_DEL(parser, whitespaces);
+    OSTRING_DEL(parser, string);
+    OSTRING_DEL(parser, leading_break);
+    OSTRING_DEL(parser, trailing_breaks);
+    OSTRING_DEL(parser, whitespaces);
 
     return 0;
 }
 {
     yaml_mark_t start_mark;
     yaml_mark_t end_mark;
-    yaml_string_t string = NULL_STRING;
-    yaml_string_t leading_break = NULL_STRING;
-    yaml_string_t trailing_breaks = NULL_STRING;
-    yaml_string_t whitespaces = NULL_STRING;
+    yaml_ostring_t string = NULL_OSTRING;
+    yaml_ostring_t leading_break = NULL_OSTRING;
+    yaml_ostring_t trailing_breaks = NULL_OSTRING;
+    yaml_ostring_t whitespaces = NULL_OSTRING;
     int leading_blanks = 0;
     int indent = parser->indent+1;
 
-    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+    if (!OSTRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
         goto error;
-    if (!STRING_INIT(parser, leading_break, INITIAL_STRING_CAPACITY))
+    if (!OSTRING_INIT(parser, leading_break, INITIAL_STRING_CAPACITY))
         goto error;
-    if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_CAPACITY))
+    if (!OSTRING_INIT(parser, trailing_breaks, INITIAL_STRING_CAPACITY))
         goto error;
-    if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_CAPACITY))
+    if (!OSTRING_INIT(parser, whitespaces, INITIAL_STRING_CAPACITY))
         goto error;
 
     start_mark = end_mark = parser->mark;
 
                     if (leading_break.buffer[0] == '\n') {
                         if (trailing_breaks.buffer[0] == '\0') {
-                            if (!STRING_EXTEND(parser, string)) goto error;
+                            if (!OSTRING_EXTEND(parser, string)) goto error;
                             JOIN_OCTET(string, ' ');
                         }
                         else {
         parser->is_simple_key_allowed = 1;
     }
 
-    STRING_DEL(parser, leading_break);
-    STRING_DEL(parser, trailing_breaks);
-    STRING_DEL(parser, whitespaces);
+    OSTRING_DEL(parser, leading_break);
+    OSTRING_DEL(parser, trailing_breaks);
+    OSTRING_DEL(parser, whitespaces);
 
     return 1;
 
 error:
-    STRING_DEL(parser, string);
-    STRING_DEL(parser, leading_break);
-    STRING_DEL(parser, trailing_breaks);
-    STRING_DEL(parser, whitespaces);
+    OSTRING_DEL(parser, string);
+    OSTRING_DEL(parser, leading_break);
+    OSTRING_DEL(parser, trailing_breaks);
+    OSTRING_DEL(parser, whitespaces);
 
     return 0;
 }
         return 1;
     }
 
-    /* Switch the pointer to the beginning of the buffer. */
+    /* Switch the buffer into the input mode. */
 
-    emitter->output.capacity = emitter->output.pointer;
+    emitter->output.length = emitter->output.pointer;
     emitter->output.pointer = 0;
 
     /* If the output encoding is UTF-8, we don't need to recode the buffer. */
     if (emitter->encoding == YAML_UTF8_ENCODING)
     {
         if (emitter->writer(emitter->writer_data,
-                    emitter->output.buffer, emitter->output.capacity)) {
-            emitter->offset += emitter->output.capacity;
-            emitter->output.capacity = OUTPUT_BUFFER_CAPACITY;
+                    emitter->output.buffer, emitter->output.length)) {
+            emitter->offset += emitter->output.length;
+            emitter->output.length = 0;
             return 1;
         }
         else {
-            return WRITER_ERROR_INIT(emitter, "Write error", emitter->offset);
+            return WRITER_ERROR_INIT(emitter,
+                    "write handler error", emitter->offset);
         }
     }
 
     low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
     high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
 
-    while (emitter->output.pointer != emitter->output.capacity)
+    while (emitter->output.pointer < emitter->output.length)
     {
         unsigned char octet;
         unsigned int width;
     if (emitter->writer(emitter->writer_data,
                 emitter->raw_output.buffer, emitter->raw_output.pointer)) {
         emitter->output.pointer = 0;
-        emitter->output.capacity = OUTPUT_BUFFER_CAPACITY;
+        emitter->output.length = 0;
         emitter->offset += emitter->raw_output.pointer;
         emitter->raw_output.pointer = 0;
         return 1;
     }
     else {
-        return WRITER_ERROR_INIT(emitter, "Write error", emitter->offset);
+        return WRITER_ERROR_INIT(emitter,
+                "write handler error", emitter->offset);
     }
 }
 

src/yaml_private.h

  * Error management.
  */
 
-#define ERROR_INIT(error,error_type)                                            \
-    (memset(&(error), 0, sizeof(error)),                                        \
-     (error).type = (error_type),                                               \
+/*
+ * Generic error initializers; not to be used directly.
+ */
+
+#define ERROR_INIT(error, _type)                                                \
+    (memset(&(error), 0, sizeof(yaml_error_t)),                                 \
+     (error).type = (_type),                                                    \
      0)
 
-#define READING_ERROR_INIT(error,error_type,error_problem,error_offset,error_value) \
-    (memset(&(error), 0, sizeof(error)),                                        \
-     (error).type = (error_type),                                               \
-     (error).data.reading.problem = (error_problem),                            \
-     (error).data.reading.offset = (error_offset),                              \
-     (error).data.reading.value = (error_value),                                \
+#define READING_ERROR_INIT(error, _type, _problem, _offset, _value)             \
+    (ERROR_INIT(error, _type),                                                  \
+     (error).data.reading.problem = (_problem),                                 \
+     (error).data.reading.offset = (_offset),                                   \
+     (error).data.reading.value = (_value),                                     \
      0)
 
-#define LOADING_ERROR_INIT(error,error_type,error_problem,error_problem_mark)   \
-    (memset(&(error), 0, sizeof(error)),                                        \
-     (error).type = (error_type),                                               \
+#define LOADING_ERROR_INIT(error, _type, _problem, _problem_mark)               \
+    (ERROR_INIT(error, _type),                                                  \
      (error).data.loading.context = NULL,                                       \
      (error).data.loading.context_mark.index = 0,                               \
      (error).data.loading.context_mark.line = 0,                                \
      (error).data.loading.context_mark.column = 0,                              \
-     (error).data.loading.problem = (error_problem),                            \
-     (error).data.loading.problem_mark = (error_problem_mark),                  \
+     (error).data.loading.problem = (_problem),                                 \
+     (error).data.loading.problem_mark = (_problem_mark),                       \
      0)
 
-#define LOADING_ERROR_WITH_CONTEXT_INIT(error,error_type,error_context,error_context_mark,error_problem,error_problem_mark) \
-    (memset(&(error), 0, sizeof(error)),                                        \
-     (error).type = (error_type),                                               \
-     (error).data.loading.context = (error_context),                            \
-     (error).data.loading.context_mark = (error_context_mark),                  \
-     (error).data.loading.problem = (error_problem),                            \
-     (error).data.loading.problem_mark = (error_problem_mark),                  \
+#define LOADING_ERROR_WITH_CONTEXT_INIT(error, _type, _context, _context_mark,  \
+        _problem, _problem_mark)                                                \
+    (ERROR_INIT(error, _type),                                                  \
+     (error).data.loading.context = (_context),                                 \
+     (error).data.loading.context_mark = (_context_mark),                       \
+     (error).data.loading.problem = (_problem),                                 \
+     (error).data.loading.problem_mark = (_problem_mark),                       \
      0)
 
-#define WRITING_ERROR_INIT(error,error_type,error_problem,error_offset)         \
-    (memset(&(error), 0, sizeof(error)),                                        \
-     (error).type = (error_type),                                               \
-     (error).data.writing.problem = (error_problem),                            \
-     (error).data.writing.offset = (error_offset),                              \
+#define WRITING_ERROR_INIT(error, _type, _problem, _offset)                     \
+    (ERROR_INIT(error, _type),                                                  \
+     (error).data.writing.problem = (_problem),                                 \
+     (error).data.writing.offset = (_offset),                                   \
      0)
 
-#define DUMPING_ERROR_INIT(error,error_type,error_problem)                      \
-    (memset(&(error), 0, sizeof(error)),                                        \
-     (error).type = (error_type),                                               \
-     (error).data.dumping.problem = (error_problem),                            \
+#define DUMPING_ERROR_INIT(error, _type, _problem)                              \
+    (ERROR_INIT(error, _type),                                                  \
+     (error).data.dumping.problem = (_problem),                                 \
      0)
 
+#define RESOLVING_ERROR_INIT(error, _type, _problem)                            \
+    (ERROR_INIT(error, _type),                                                  \
+     (error).data.resolving.problem = (_problem),                               \
+     0)
+
+/*
+ * Specific error initializers.
+ */
+
 #define MEMORY_ERROR_INIT(self)                                                 \
-    ERROR_INIT((self)->error,YAML_MEMORY_ERROR)
+    ERROR_INIT((self)->error, YAML_MEMORY_ERROR)
 
-#define READER_ERROR_INIT(self,problem,offset)                                  \
-    READING_ERROR_INIT((self)->error,YAML_READER_ERROR,problem,offset,-1)
+#define READER_ERROR_INIT(self, _problem, _offset)                              \
+    READING_ERROR_INIT((self)->error, YAML_READER_ERROR, _problem, _offset, -1)
 
-#define DECODER_ERROR_INIT(self,problem,offset,value)                           \
-    READING_ERROR_INIT((self)->error,YAML_DECODER_ERROR,problem,offset,value)
+#define DECODER_ERROR_INIT(self, _problem, _offset, _value)                     \
+    READING_ERROR_INIT((self)->error, YAML_DECODER_ERROR, _problem, _offset, _value)
 
-#define SCANNER_ERROR_INIT(self,problem,problem_mark)                           \
-    LOADING_ERROR_INIT((self)->error,YAML_SCANNER_ERROR,problem,problem_mark)
+#define SCANNER_ERROR_INIT(self, _problem, _problem_mark)                       \
+    LOADING_ERROR_INIT((self)->error, YAML_SCANNER_ERROR, _problem, _problem_mark)
 
-#define SCANNER_ERROR_WITH_CONTEXT_INIT(self,context,context_mark,problem,problem_mark) \
-    LOADING_ERROR_WITH_CONTEXT_INIT((self)->error,YAML_SCANNER_ERROR,context,context_mark,problem,problem_mark)
+#define SCANNER_ERROR_WITH_CONTEXT_INIT(self, _context, _context_mark,          \
+        _problem, _problem_mark)                                                \
+    LOADING_ERROR_WITH_CONTEXT_INIT((self)->error, YAML_SCANNER_ERROR,          \
+            _context, _context_mark, _problem, _problem_mark)
 
-#define PARSER_ERROR_INIT(self,problem,problem_mark)                            \
-    LOADING_ERROR_INIT((self)->error,YAML_PARSER_ERROR,problem,problem_mark)
+#define PARSER_ERROR_INIT(self, _problem, _problem_mark)                        \
+    LOADING_ERROR_INIT((self)->error, YAML_PARSER_ERROR, _problem, _problem_mark)
 
-#define PARSER_ERROR_WITH_CONTEXT_INIT(self,context,context_mark,problem,problem_mark)  \
-    LOADING_ERROR_WITH_CONTEXT_INIT((self)->error,YAML_PARSER_ERROR,context,context_mark,problem,problem_mark)
+#define PARSER_ERROR_WITH_CONTEXT_INIT(self, _context, _context_mark,           \
+        _problem, _problem_mark)                                                \
+    LOADING_ERROR_WITH_CONTEXT_INIT((self)->error, YAML_PARSER_ERROR,           \
+            _context, _context_mark, _problem, _problem_mark)
 
-#define COMPOSER_ERROR_INIT(self,problem,problem_mark)                          \
-    LOADING_ERROR_INIT((self)->error,YAML_COMPOSER_ERROR,problem,problem_mark)
+#define COMPOSER_ERROR_INIT(self, _problem, _problem_mark)                      \
+    LOADING_ERROR_INIT((self)->error, YAML_COMPOSER_ERROR, _problem, _problem_mark)
 
-#define COMPOSER_ERROR_WITH_CONTEXT_INIT(self,context,context_mark,problem,problem_mark)    \
-    LOADING_ERROR_WITH_CONTEXT_INIT((self)->error,YAML_COMPOSER_ERROR,context,context_mark,problem,problem_mark)
+#define COMPOSER_ERROR_WITH_CONTEXT_INIT(self, _context, _context_mark,         \
+        _problem, _problem_mark)                                                \
+    LOADING_ERROR_WITH_CONTEXT_INIT((self)->error, YAML_COMPOSER_ERROR,         \
+            _context, _context_mark, _problem, _problem_mark)
 
-#define WRITER_ERROR_INIT(self,problem,offset)                                  \
-    WRITING_ERROR_INIT((self)->error,YAML_WRITER_ERROR,problem,offset)
+#define WRITER_ERROR_INIT(self, _problem, _offset)                              \
+    WRITING_ERROR_INIT((self)->error, YAML_WRITER_ERROR, _problem, _offset)
 
-#define EMITTER_ERROR_INIT(self,problem)                                        \
-    DUMPING_ERROR_INIT((self)->error,YAML_EMITTER_ERROR,problem)
+#define EMITTER_ERROR_INIT(self, _problem)                                      \
+    DUMPING_ERROR_INIT((self)->error, YAML_EMITTER_ERROR, _problem)
 
-#define SERIALIZER_ERROR_INIT(self,context)                                     \
-    DUMPING_ERROR_INIT((self)->error,YAML_SERIALIZER_ERROR,problem)
+#define SERIALIZER_ERROR_INIT(self, _problem)                                   \
+    DUMPING_ERROR_INIT((self)->error, YAML_SERIALIZER_ERROR, _problem)
+
+#define RESOLVER_ERROR_INIT(self, _problem)                                     \
+    RESOLVER_ERROR_INIT((self)->error, YAML_RESOLVER_ERROR, _problem)
 
 /*
  * The size of the input raw buffer.
  * String management.
  */
 
-typedef struct yaml_string_s {
+/*
+ * An immutable string used as an input buffer.
+ */
+
+typedef struct yaml_istring_s {
+    const yaml_char_t *buffer;
+    size_t pointer;
+    size_t length;
+} yaml_istring_t;
+
+/*
+ * A string that is used as an output buffer.
+ */
+
+typedef struct yaml_ostring_s {
     yaml_char_t *buffer;
     size_t pointer;
     size_t capacity;
-} yaml_string_t;
+} yaml_ostring_t;
+
+/*
+ * A string that could be used both as an input and an output buffer.
+ */
+
+typedef struct yaml_iostring_s {
+    yaml_char_t *buffer;
+    size_t pointer;
+    size_t length;
+    size_t capacity;
+} yaml_iostring_t;
+
+/*
+ * Separate type for non-UTF-8 i/o strings.
+ */
+
+typedef struct yaml_raw_iostring_s {
+    unsigned char *buffer;
+    size_t pointer;
+    size_t length;
+    size_t capacity;
+} yaml_raw_iostring_t;
 
 YAML_DECLARE(int)
-yaml_string_extend(yaml_char_t **buffer, size_t *capacity);
+yaml_ostring_extend(yaml_char_t **buffer, size_t *capacity);
 
 YAML_DECLARE(int)
-yaml_string_join(
+yaml_ostring_join(
         yaml_char_t **base_buffer, size_t *base_pointer, size_t *base_capacity,
-        yaml_char_t *adj_buffer, size_t adj_pointer, size_t adj_capacity);
+        yaml_char_t *adj_buffer, size_t adj_pointer);
 
-#define NULL_STRING { NULL, 0, 0 }
+#define ISTRING(buffer, length) { (buffer), 0, (length) }
 
-#define STRING(string,capacity)   { (string), 0, (capacity) }
+#define NULL_OSTRING { NULL, 0, 0 }
 
-#define STRING_INIT(self,string,string_capacity)                                \
-    (((string).buffer = yaml_malloc(string_capacity)) ?                         \
-        ((string).pointer = 0,                                                  \
-         (string).capacity = (string_capacity),                                 \
-         memset((string).buffer, 0, (string_capacity)),                         \
+#define IOSTRING_INIT(self, string, _capacity)                                  \
+    (((string).buffer = yaml_malloc(_capacity)) ?                               \
+        ((string).pointer = (string).length = 0,                                \
+         (string).capacity = (_capacity),                                       \
+         memset((string).buffer, 0, (_capacity)),                               \
          1) :                                                                   \
         ((self)->error.type = YAML_MEMORY_ERROR,                                \
          0))
 
-#define STRING_DEL(self,string)                                                 \
+#define IOSTRING_DEL(self, string)                                              \
+    (yaml_free((string).buffer),                                                \
+     (string).buffer = NULL,                                                    \
+     ((string).pointer = (string).length = (string).capacity = 0))
+
+#define OSTRING_INIT(self, string, _capacity)                                   \
+    (((string).buffer = yaml_malloc(_capacity)) ?                               \
+        ((string).pointer = 0,                                                  \
+         (string).capacity = (_capacity),                                       \
+         memset((string).buffer, 0, (_capacity)),                               \
+         1) :                                                                   \
+        ((self)->error.type = YAML_MEMORY_ERROR,                                \
+         0))
+
+#define OSTRING_DEL(self, string)                                               \
     (yaml_free((string).buffer),                                                \
      (string).buffer = NULL,                                                    \
      ((string).pointer = (string).capacity = 0))
 
-#define STRING_EXTEND(self,string)                                              \
+#define OSTRING_EXTEND(self, string)                                            \
     ((((string).pointer+5 < (string).capacity)                                  \
-        || yaml_string_extend(&(string).buffer, &(string).capacity)) ?          \
+        || yaml_ostring_extend(&(string).buffer, &(string).capacity)) ?         \
      1 :                                                                        \
      ((self)->error.type = YAML_MEMORY_ERROR,                                   \
       0))
 
-#define CLEAR(self,string)                                                      \
+#define CLEAR(self, string)                                                     \
     ((string).pointer = 0,                                                      \
      memset((string).buffer, 0, (string).capacity))
 
-#define JOIN(self,base_string,adj_string)                                       \
-    ((yaml_string_join(&(base_string).buffer, &(base_string).pointer,           \
-                       &(base_string).capacity, (adj_string).buffer,            \
-                       (adj_string).pointer, (adj_string).capacity)) ?          \
+#define JOIN(self, base_string, adj_string)                                     \
+    ((yaml_ostring_join(&(base_string).buffer, &(base_string).pointer,          \
+                       &(base_string).capacity,                                 \
+                       (adj_string).buffer, (adj_string).pointer)) ?            \
         ((adj_string).pointer = 0,                                              \
          1) :                                                                   \
         ((self)->error.type = YAML_MEMORY_ERROR,                                \
  * Get the octet at the specified position.
  */
 
-#define OCTET_AT(string,offset)                                                 \
+#define OCTET_AT(string, offset)                                                \
     ((string).buffer[(string).pointer+(offset)])
 
 /*
  * Get the current offset.
  */
 
-#define OCTET(string)   OCTET_AT((string),0)
+#define OCTET(string)   OCTET_AT((string), 0)
 
 /*
  * Check the octet at the specified position.
  */
 
-#define CHECK_AT(string,octet,offset)                                           \
-    (OCTET_AT((string),(offset)) == (yaml_char_t)(octet))
+#define CHECK_AT(string, octet, offset)                                         \
+    (OCTET_AT((string), (offset)) == (yaml_char_t)(octet))
 
 /*
  * Check the current octet in the buffer.
  */
 
-#define CHECK(string,octet) CHECK_AT((string),(octet),0)
+#define CHECK(string, octet)    CHECK_AT((string), (octet), 0)
 
 /*
  * Check if the character at the specified position is an alphabetical
  * character, a digit, '_', or '-'.
  */
 
-#define IS_ALPHA_AT(string,offset)                                              \
-     ((OCTET_AT((string),(offset)) >= (yaml_char_t) '0' &&                      \
-       OCTET_AT((string),(offset)) <= (yaml_char_t) '9') ||                     \
-      (OCTET_AT((string),(offset)) >= (yaml_char_t) 'A' &&                      \
-       OCTET_AT((string),(offset)) <= (yaml_char_t) 'Z') ||                     \
-      (OCTET_AT((string),(offset)) >= (yaml_char_t) 'a' &&                      \
-       OCTET_AT((string),(offset)) <= (yaml_char_t) 'z') ||                     \
-      OCTET_AT((string),(offset)) == '_' ||                                     \
-      OCTET_AT((string),(offset)) == '-')
+#define IS_ALPHA_AT(string, offset)                                             \
+     ((OCTET_AT((string), (offset)) >= (yaml_char_t) '0' &&                     \
+       OCTET_AT((string), (offset)) <= (yaml_char_t) '9') ||                    \
+      (OCTET_AT((string), (offset)) >= (yaml_char_t) 'A' &&                     \
+       OCTET_AT((string), (offset)) <= (yaml_char_t) 'Z') ||                    \
+      (OCTET_AT((string), (offset)) >= (yaml_char_t) 'a' &&                     \
+       OCTET_AT((string), (offset)) <= (yaml_char_t) 'z') ||                    \
+      OCTET_AT((string), (offset)) == '_' ||                                    \
+      OCTET_AT((string), (offset)) == '-')
 
-#define IS_ALPHA(string)    IS_ALPHA_AT((string),0)
+#define IS_ALPHA(string)    IS_ALPHA_AT((string), 0)
 
 /*
  * Check if the character at the specified position is a digit.
  */
 
-#define IS_DIGIT_AT(string,offset)                                              \
-     ((OCTET_AT((string),(offset)) >= (yaml_char_t) '0' &&                      \
-       OCTET_AT((string),(offset)) <= (yaml_char_t) '9'))
+#define IS_DIGIT_AT(string, offset)                                             \
+     ((OCTET_AT((string), (offset)) >= (yaml_char_t) '0' &&                     \
+       OCTET_AT((string), (offset)) <= (yaml_char_t) '9'))
 
-#define IS_DIGIT(string)    IS_DIGIT_AT((string),0)
+#define IS_DIGIT(string)    IS_DIGIT_AT((string), 0)
 
 /*
  * Get the value of a digit.
  */
 
-#define AS_DIGIT_AT(string,offset)                                              \
-     (OCTET_AT((string),(offset)) - (yaml_char_t) '0')
+#define AS_DIGIT_AT(string, offset)                                             \
+     (OCTET_AT((string), (offset)) - (yaml_char_t) '0')
 
-#define AS_DIGIT(string)    AS_DIGIT_AT((string),0)
+#define AS_DIGIT(string)    AS_DIGIT_AT((string), 0)
 
 /*
  * Check if the character at the specified position is a hex-digit.
  */
 
-#define IS_HEX_AT(string,offset)                                                \
-     ((OCTET_AT((string),(offset)) >= (yaml_char_t) '0' &&                      \
-       OCTET_AT((string),(offset)) <= (yaml_char_t) '9') ||                     \
-      (OCTET_AT((string),(offset)) >= (yaml_char_t) 'A' &&                      \
-       OCTET_AT((string),(offset)) <= (yaml_char_t) 'F') ||                     \
-      (OCTET_AT((string),(offset)) >= (yaml_char_t) 'a' &&                      \
-       OCTET_AT((string),(offset)) <= (yaml_char_t) 'f'))
+#define IS_HEX_AT(string, offset)                                               \
+     ((OCTET_AT((string), (offset)) >= (yaml_char_t) '0' &&                     \
+       OCTET_AT((string), (offset)) <= (yaml_char_t) '9') ||                    \
+      (OCTET_AT((string), (offset)) >= (yaml_char_t) 'A' &&                     \
+       OCTET_AT((string), (offset)) <= (yaml_char_t) 'F') ||                    \
+      (OCTET_AT((string), (offset)) >= (yaml_char_t) 'a' &&                     \
+       OCTET_AT((string), (offset)) <= (yaml_char_t) 'f'))
 
-#define IS_HEX(string)    IS_HEX_AT((string),0)
+#define IS_HEX(string)    IS_HEX_AT((string), 0)
 
 /*
  * Get the value of a hex-digit.
  */
 
-#define AS_HEX_AT(string,offset)                                                \
-      ((OCTET_AT((string),(offset)) >= (yaml_char_t) 'A' &&                     \
-        OCTET_AT((string),(offset)) <= (yaml_char_t) 'F') ?                     \
-       (OCTET_AT((string),(offset)) - (yaml_char_t) 'A' + 10) :                 \
-       (OCTET_AT((string),(offset)) >= (yaml_char_t) 'a' &&                     \
-        OCTET_AT((string),(offset)) <= (yaml_char_t) 'f') ?                     \
-       (OCTET_AT((string),(offset)) - (yaml_char_t) 'a' + 10) :                 \
-       (OCTET_AT((string),(offset)) - (yaml_char_t) '0'))
+#define AS_HEX_AT(string, offset)                                               \
+      ((OCTET_AT((string), (offset)) >= (yaml_char_t) 'A' &&                    \
+        OCTET_AT((string), (offset)) <= (yaml_char_t) 'F') ?                    \
+       (OCTET_AT((string), (offset)) - (yaml_char_t) 'A' + 10) :                \
+       (OCTET_AT((string), (offset)) >= (yaml_char_t) 'a' &&                    \
+        OCTET_AT((string), (offset)) <= (yaml_char_t) 'f') ?                    \
+       (OCTET_AT((string), (offset)) - (yaml_char_t) 'a' + 10) :                \
+       (OCTET_AT((string), (offset)) - (yaml_char_t) '0'))
  
-#define AS_HEX(string)  AS_HEX_AT((string),0)
+#define AS_HEX(string)  AS_HEX_AT((string), 0)
  
 /*
  * Check if the character is ASCII.
  */
 
-#define IS_ASCII_AT(string,offset)                                              \
-    (OCTET_AT((string),(offset)) <= (yaml_char_t) '\x7F')
+#define IS_ASCII_AT(string, offset)                                             \
+    (OCTET_AT((string), (offset)) <= (yaml_char_t) '\x7F')
 
-#define IS_ASCII(string)    IS_ASCII_AT((string),0)
+#define IS_ASCII(string)    IS_ASCII_AT((string), 0)
 
 /*
  * Check if the character can be printed unescaped.
  */
 
-#define IS_PRINTABLE_AT(string,offset)                                          \
-    ((OCTET_AT((string),(offset)) == 0x0A)          /* . == #x0A */             \
-     || (OCTET_AT((string),(offset)) >= 0x20        /* #x20 <= . <= #x7E */     \
-         && OCTET_AT((string),(offset)) <= 0x7E)                                \
-     || (OCTET_AT((string),(offset)) == 0xC2        /* #0xA0 <= . <= #xD7FF */  \
-         && OCTET_AT((string),(offset)+1) >= 0xA0)                              \
-     || (OCTET_AT((string),(offset)) > 0xC2                                     \
-         && OCTET_AT((string),(offset)) < 0xED)                                 \
-     || (OCTET_AT((string),(offset)) == 0xED                                    \
-         && OCTET_AT((string),(offset)+1) < 0xA0)                               \
-     || (OCTET_AT((string),(offset)) == 0xEE)                                   \
-     || (OCTET_AT((string),(offset)) == 0xEF        /* #xE000 <= . <= #xFFFD */ \
-         && !(OCTET_AT((string),(offset)+1) == 0xBB        /* && . != #xFEFF */ \
-             && OCTET_AT((string),(offset)+2) == 0xBF)                          \
-         && !(OCTET_AT((string),(offset)+1) == 0xBF                             \
-             && (OCTET_AT((string),(offset)+2) == 0xBE                          \
-                 || OCTET_AT((string),(offset)+2) == 0xBF))))
+#define IS_PRINTABLE_AT(string, offset)                                         \
+    ((OCTET_AT((string), (offset)) == 0x0A)         /* . == #x0A */             \
+     || (OCTET_AT((string), (offset)) >= 0x20       /* #x20 <= . <= #x7E */     \
+         && OCTET_AT((string), (offset)) <= 0x7E)                               \
+     || (OCTET_AT((string), (offset)) == 0xC2       /* #0xA0 <= . <= #xD7FF */  \
+         && OCTET_AT((string), (offset)+1) >= 0xA0)                             \
+     || (OCTET_AT((string), (offset)) > 0xC2                                    \
+         && OCTET_AT((string), (offset)) < 0xED)                                \