Index: /libyaml/trunk/tests/run-scanner.c
===================================================================
--- /libyaml/trunk/tests/run-scanner.c	(revision 242)
+++ /libyaml/trunk/tests/run-scanner.c	(revision 263)
@@ -22,5 +22,5 @@
     {
         FILE *file;
-        yaml_parser_t parser;
+        yaml_parser_t *parser;
         yaml_token_t token;
         int done = 0;
@@ -34,11 +34,11 @@
         assert(file);
 
-        assert(yaml_parser_initialize(&parser));
+        assert((parser = yaml_parser_new()));
 
-        yaml_parser_set_input_file(&parser, file);
+        yaml_parser_set_file_reader(parser, file);
 
         while (!done)
         {
-            if (!yaml_parser_scan(&parser, &token)) {
+            if (!yaml_parser_scan(parser, &token)) {
                 error = 1;
                 break;
@@ -47,10 +47,10 @@
             done = (token.type == YAML_STREAM_END_TOKEN);
 
-            yaml_token_delete(&token);
+            yaml_token_destroy(&token);
 
             count ++;
         }
 
-        yaml_parser_delete(&parser);
+        yaml_parser_delete(parser);
 
         assert(!fclose(file));
Index: /libyaml/trunk/src/loader.c
===================================================================
--- /libyaml/trunk/src/loader.c	(revision 243)
+++ /libyaml/trunk/src/loader.c	(revision 263)
@@ -1,4 +1,6 @@
 
 #include "yaml_private.h"
+
+#if 0
 
 /*
@@ -429,2 +431,4 @@
 }
 
+#endif
+
Index: /libyaml/trunk/src/api.c
===================================================================
--- /libyaml/trunk/src/api.c	(revision 261)
+++ /libyaml/trunk/src/api.c	(revision 263)
@@ -173,7 +173,7 @@
 
     memset(parser, 0, sizeof(yaml_parser_t));
-    if (!BUFFER_INIT(parser, parser->raw_input, RAW_INPUT_BUFFER_CAPACITY))
+    if (!STRING_INIT(parser, parser->raw_input, RAW_INPUT_BUFFER_CAPACITY))
         goto error;
-    if (!BUFFER_INIT(parser, parser->input, INPUT_BUFFER_CAPACITY))
+    if (!STRING_INIT(parser, parser->input, INPUT_BUFFER_CAPACITY))
         goto error;
     if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_CAPACITY))
@@ -207,6 +207,6 @@
     assert(parser); /* Non-NULL parser object expected. */
 
-    BUFFER_DEL(parser, parser->raw_input);
-    BUFFER_DEL(parser, parser->input);
+    STRING_DEL(parser, parser->raw_input);
+    STRING_DEL(parser, parser->input);
     while (!QUEUE_EMPTY(parser, parser->tokens)) {
         yaml_token_destroy(&DEQUEUE(parser, parser->tokens));
@@ -358,7 +358,7 @@
 
     memset(emitter, 0, sizeof(yaml_emitter_t));
-    if (!BUFFER_INIT(emitter, emitter->output, OUTPUT_BUFFER_CAPACITY))
+    if (!STRING_INIT(emitter, emitter->output, OUTPUT_BUFFER_CAPACITY))
         goto error;
-    if (!BUFFER_INIT(emitter, emitter->raw_output, RAW_OUTPUT_BUFFER_CAPACITY))
+    if (!STRING_INIT(emitter, emitter->raw_output, RAW_OUTPUT_BUFFER_CAPACITY))
         goto error;
     if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_CAPACITY))
@@ -388,6 +388,6 @@
     assert(emitter);    /* Non-NULL emitter object expected. */
 
-    BUFFER_DEL(emitter, emitter->output);
-    BUFFER_DEL(emitter, emitter->raw_output);
+    STRING_DEL(emitter, emitter->output);
+    STRING_DEL(emitter, emitter->raw_output);
     STACK_DEL(emitter, emitter->states);
     while (!QUEUE_EMPTY(emitter, emitter->events)) {
Index: /libyaml/trunk/src/emitter.c
===================================================================
--- /libyaml/trunk/src/emitter.c	(revision 241)
+++ /libyaml/trunk/src/emitter.c	(revision 263)
@@ -7,5 +7,5 @@
 
 #define FLUSH(emitter)                                                          \
-    ((emitter->buffer.pointer+5 < emitter->buffer.end)                          \
+    ((emitter->output.pointer+5 < emitter->output.capacity)                     \
      || yaml_emitter_flush(emitter))
 
@@ -16,5 +16,5 @@
 #define PUT(emitter,value)                                                      \
     (FLUSH(emitter)                                                             \
-     && (*(emitter->buffer.pointer++) = (yaml_char_t)(value),                   \
+     && (JOIN_OCTET(emitter->output,(yaml_char_t)(value)),                      \
          emitter->column ++,                                                    \
          1))
@@ -27,10 +27,10 @@
     (FLUSH(emitter)                                                             \
      && ((emitter->line_break == YAML_CR_BREAK ?                                \
-             (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') :              \
+             JOIN_OCTET(emitter->output, (yaml_char_t) '\r') :                  \
           emitter->line_break == YAML_LN_BREAK ?                                \
-             (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') :              \
+             JOIN_OCTET(emitter->output, (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),          \
+             (JOIN_OCTET(emitter->output, (yaml_char_t) '\r'),                  \
+              JOIN_OCTET(emitter->output, (yaml_char_t) '\n')) : 0),            \
          emitter->column = 0,                                                   \
          emitter->line ++,                                                      \
@@ -43,5 +43,5 @@
 #define WRITE(emitter,string)                                                   \
     (FLUSH(emitter)                                                             \
-     && (COPY(emitter->buffer,string),                                          \
+     && (COPY(emitter->output,string),                                          \
          emitter->column ++,                                                    \
          1))
@@ -57,5 +57,5 @@
           string.pointer ++,                                                    \
           1) :                                                                  \
-         (COPY(emitter->buffer,string),                                         \
+         (COPY(emitter->output,string),                                         \
           emitter->column = 0,                                                  \
           emitter->line ++,                                                     \
@@ -74,7 +74,4 @@
 
 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);
 
@@ -136,5 +133,5 @@
 static int
 yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
-        int root, int sequence, int mapping, int simple_key);
+        int is_root, int is_sequence, int is_mapping, int is_simple_key);
 
 static int
@@ -262,17 +259,4 @@
 
 /*
- * 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.
  */
@@ -287,7 +271,9 @@
 
     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))
+        if (!yaml_emitter_analyze_event(emitter,
+                    emitter->events.list + emitter->events.head))
+            return 0;
+        if (!yaml_emitter_state_machine(emitter,
+                    emitter->events.list + emitter->events.head))
             return 0;
         yaml_event_delete(&DEQUEUE(emitter, emitter->events));
@@ -311,10 +297,10 @@
     int level = 0;
     int accumulate = 0;
-    yaml_event_t *event;
+    size_t idx;
 
     if (QUEUE_EMPTY(emitter, emitter->events))
         return 1;
 
-    switch (emitter->events.head->type) {
+    switch (emitter->events.list[emitter->events.head].type) {
         case YAML_DOCUMENT_START_EVENT:
             accumulate = 1;
@@ -333,5 +319,6 @@
         return 0;
 
-    for (event = emitter->events.head; event != emitter->events.tail; event ++) {
+    for (idx = emitter->events.head; idx < emitter->events.tail; idx ++) {
+        yaml_event_t *event = emitter->events.list+idx;
         switch (event->type) {
             case YAML_STREAM_START_EVENT:
@@ -365,14 +352,13 @@
         yaml_tag_directive_t value, int allow_duplicates)
 {
-    yaml_tag_directive_t *tag_directive;
+    int idx;
     yaml_tag_directive_t copy = { NULL, NULL };
 
-    for (tag_directive = emitter->tag_directives.start;
-            tag_directive != emitter->tag_directives.top; tag_directive ++) {
+    for (idx = 0; idx < emitter->tag_directives.length; idx ++) {
+        yaml_tag_directive_t *tag_directive = emitter->tag_directives.list+idx;
         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");
+            return EMITTER_ERROR_INIT(emitter, "duplicate %TAG directive");
         }
     }
@@ -381,5 +367,5 @@
     copy.prefix = yaml_strdup(value.prefix);
     if (!copy.handle || !copy.prefix) {
-        emitter->error = YAML_MEMORY_ERROR;
+        MEMORY_ERROR_INIT(emitter);
         goto error;
     }
@@ -478,5 +464,5 @@
 
         case YAML_EMIT_END_STATE:
-            return yaml_emitter_set_emitter_error(emitter,
+            return EMITTER_ERROR_INIT(emitter,
                     "expected nothing after STREAM-END");
 
@@ -527,6 +513,6 @@
         emitter->line = 0;
         emitter->column = 0;
-        emitter->whitespace = 1;
-        emitter->indention = 1;
+        emitter->is_whitespace = 1;
+        emitter->is_indention = 1;
 
         if (emitter->encoding != YAML_UTF8_ENCODING) {
@@ -540,6 +526,5 @@
     }
 
-    return yaml_emitter_set_emitter_error(emitter,
-            "expected STREAM-START");
+    return EMITTER_ERROR_INIT(emitter, "expected STREAM-START");
 }
 
@@ -560,5 +545,6 @@
         };
         yaml_tag_directive_t *tag_directive;
-        int implicit;
+        int is_implicit;
+        int idx;
 
         if (event->data.document_start.version_directive) {
@@ -568,7 +554,6 @@
         }
 
-        for (tag_directive = event->data.document_start.tag_directives.start;
-                tag_directive != event->data.document_start.tag_directives.end;
-                tag_directive ++) {
+        for (idx = 0; idx < event->data.document_start.tag_directives.length; idx++) {
+            tag_directive = event->data.document_start.tag_directives.list+idx;
             if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive))
                 return 0;
@@ -583,11 +568,11 @@
         }
 
-        implicit = event->data.document_start.implicit;
-        if (!first || emitter->canonical) {
-            implicit = 0;
+        is_implicit = event->data.document_start.is_implicit;
+        if (!first || emitter->is_canonical) {
+            is_implicit = 0;
         }
 
         if (event->data.document_start.version_directive) {
-            implicit = 0;
+            is_implicit = 0;
             if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0))
                 return 0;
@@ -598,10 +583,9 @@
         }
         
-        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 (event->data.document_start.tag_directives.length) {
+            is_implicit = 0;
+            for (idx = 0; idx < event->data.document_start.tag_directives.length;
+                    idx++) {
+                tag_directive = event->data.document_start.tag_directives.list+idx;
                 if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0))
                     return 0;
@@ -618,13 +602,13 @@
 
         if (yaml_emitter_check_empty_document(emitter)) {
-            implicit = 0;
-        }
-
-        if (!implicit) {
+            is_implicit = 0;
+        }
+
+        if (!is_implicit) {
             if (!yaml_emitter_write_indent(emitter))
                 return 0;
             if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0))
                 return 0;
-            if (emitter->canonical) {
+            if (emitter->is_canonical) {
                 if (!yaml_emitter_write_indent(emitter))
                     return 0;
@@ -647,6 +631,5 @@
     }
 
-    return yaml_emitter_set_emitter_error(emitter,
-            "expected DOCUMENT-START or STREAM-END");
+    return EMITTER_ERROR_INIT(emitter, "expected DOCUMENT-START or STREAM-END");
 }
 
@@ -677,5 +660,5 @@
         if (!yaml_emitter_write_indent(emitter))
             return 0;
-        if (!event->data.document_end.implicit) {
+        if (!event->data.document_end.is_implicit) {
             if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
                 return 0;
@@ -698,6 +681,5 @@
     }
 
-    return yaml_emitter_set_emitter_error(emitter,
-            "expected DOCUMENT-END");
+    return EMITTER_ERROR_INIT(emitter, "expected DOCUMENT-END");
 }
 
@@ -724,5 +706,5 @@
         emitter->flow_level --;
         emitter->indent = POP(emitter, emitter->indents);
-        if (emitter->canonical && !first) {
+        if (emitter->is_canonical && !first) {
             if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
                 return 0;
@@ -742,5 +724,5 @@
     }
 
-    if (emitter->canonical || emitter->column > emitter->best_width) {
+    if (emitter->is_canonical || emitter->column > emitter->best_width) {
         if (!yaml_emitter_write_indent(emitter))
             return 0;
@@ -773,5 +755,5 @@
         emitter->flow_level --;
         emitter->indent = POP(emitter, emitter->indents);
-        if (emitter->canonical && !first) {
+        if (emitter->is_canonical && !first) {
             if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
                 return 0;
@@ -790,10 +772,10 @@
             return 0;
     }
-    if (emitter->canonical || emitter->column > emitter->best_width) {
+    if (emitter->is_canonical || emitter->column > emitter->best_width) {
         if (!yaml_emitter_write_indent(emitter))
             return 0;
     }
 
-    if (!emitter->canonical && yaml_emitter_check_simple_key(emitter))
+    if (!emitter->is_canonical && yaml_emitter_check_simple_key(emitter))
     {
         if (!PUSH(emitter, emitter->states,
@@ -828,5 +810,5 @@
     }
     else {
-        if (emitter->canonical || emitter->column > emitter->best_width) {
+        if (emitter->is_canonical || emitter->column > emitter->best_width) {
             if (!yaml_emitter_write_indent(emitter))
                 return 0;
@@ -851,5 +833,5 @@
     {
         if (!yaml_emitter_increase_indent(emitter, 0,
-                    (emitter->mapping_context && !emitter->indention)))
+                    (emitter->is_mapping_context && !emitter->is_indention)))
             return 0;
     }
@@ -950,10 +932,10 @@
 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;
+        int is_root, int is_sequence, int is_mapping, int is_simple_key)
+{
+    emitter->is_root_context = is_root;
+    emitter->is_sequence_context = is_sequence;
+    emitter->is_mapping_context = is_mapping;
+    emitter->is_simple_key_context = is_simple_key;
 
     switch (event->type)
@@ -972,5 +954,5 @@
 
         default:
-            return yaml_emitter_set_emitter_error(emitter,
+            return EMITTER_ERROR_INIT(emitter,
                     "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS");
     }
@@ -1028,5 +1010,5 @@
         return 0;
 
-    if (emitter->flow_level || emitter->canonical
+    if (emitter->flow_level || emitter->is_canonical
             || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE
             || yaml_emitter_check_empty_sequence(emitter)) {
@@ -1052,5 +1034,5 @@
         return 0;
 
-    if (emitter->flow_level || emitter->canonical
+    if (emitter->flow_level || emitter->is_canonical
             || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE
             || yaml_emitter_check_empty_mapping(emitter)) {
@@ -1084,6 +1066,8 @@
         return 0;
 
-    return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT
-            && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT);
+    return (emitter->events.list[emitter->events.head].type
+                            == YAML_SEQUENCE_START_EVENT &&
+            emitter->events.list[emitter->events.head+1].type
+                            == YAML_SEQUENCE_END_EVENT);
 }
 
@@ -1098,6 +1082,8 @@
         return 0;
 
-    return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT
-            && emitter->events.head[1].type == YAML_MAPPING_END_EVENT);
+    return (emitter->events.list[emitter->events.head].type
+                            == YAML_MAPPING_START_EVENT &&
+            emitter->events.list[emitter->events.head+1].type
+                            == YAML_MAPPING_END_EVENT);
 }
 
@@ -1109,5 +1095,5 @@
 yaml_emitter_check_simple_key(yaml_emitter_t *emitter)
 {
-    yaml_event_t *event = emitter->events.head;
+    yaml_event_t *event = emitter->events.list + emitter->events.head;
     size_t length = 0;
 
@@ -1119,5 +1105,5 @@
 
         case YAML_SCALAR_EVENT:
-            if (emitter->scalar_data.multiline)
+            if (emitter->scalar_data.is_multiline)
                 return 0;
             length += emitter->anchor_data.anchor_length
@@ -1163,7 +1149,7 @@
     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,
+    if (no_tag && !event->data.scalar.is_plain_implicit
+            && !event->data.scalar.is_quoted_implicit) {
+        return EMITTER_ERROR_INIT(emitter,
                 "neither tag nor implicit flags are specified");
     }
@@ -1172,19 +1158,19 @@
         style = YAML_PLAIN_SCALAR_STYLE;
 
-    if (emitter->canonical)
+    if (emitter->is_canonical)
         style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
 
-    if (emitter->simple_key_context && emitter->scalar_data.multiline)
+    if (emitter->is_simple_key_context && emitter->scalar_data.is_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))
+        if ((emitter->flow_level && !emitter->scalar_data.is_flow_plain_allowed)
+                || (!emitter->flow_level && !emitter->scalar_data.is_block_plain_allowed))
             style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
         if (!emitter->scalar_data.length
-                && (emitter->flow_level || emitter->simple_key_context))
+                && (emitter->flow_level || emitter->is_simple_key_context))
             style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
-        if (no_tag && !event->data.scalar.plain_implicit)
+        if (no_tag && !event->data.scalar.is_plain_implicit)
             style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
     }
@@ -1192,5 +1178,5 @@
     if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE)
     {
-        if (!emitter->scalar_data.single_quoted_allowed)
+        if (!emitter->scalar_data.is_single_quoted_allowed)
             style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
     }
@@ -1198,10 +1184,10 @@
     if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE)
     {
-        if (!emitter->scalar_data.block_allowed
-                || emitter->flow_level || emitter->simple_key_context)
+        if (!emitter->scalar_data.is_block_allowed
+                || emitter->flow_level || emitter->is_simple_key_context)
             style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
     }
 
-    if (no_tag && !event->data.scalar.quoted_implicit
+    if (no_tag && !event->data.scalar.is_quoted_implicit
             && style != YAML_PLAIN_SCALAR_STYLE)
     {
@@ -1226,5 +1212,5 @@
 
     if (!yaml_emitter_write_indicator(emitter,
-                (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0))
+                (emitter->anchor_data.is_alias ? "*" : "&"), 1, 0, 0))
         return 0;
 
@@ -1280,15 +1266,15 @@
             return yaml_emitter_write_plain_scalar(emitter,
                     emitter->scalar_data.value, emitter->scalar_data.length,
-                    !emitter->simple_key_context);
+                    !emitter->is_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);
+                    !emitter->is_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);
+                    !emitter->is_simple_key_context);
 
         case YAML_LITERAL_SCALAR_STYLE:
@@ -1316,6 +1302,5 @@
 {
     if (version_directive.major != 1 || version_directive.minor != 1) {
-        return yaml_emitter_set_emitter_error(emitter,
-                "incompatible %YAML directive");
+        return EMITTER_ERROR_INIT(emitter, "incompatible %YAML directive");
     }
 
@@ -1336,24 +1321,21 @@
             strlen((char *)tag_directive.prefix));
 
-    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 '!'");
+    if (!handle.capacity) {
+        return EMITTER_ERROR_INIT(emitter, "tag handle must not be empty");
+    }
+
+    if (handle.buffer[0] != '!') {
+        return EMITTER_ERROR_INIT(emitter, "tag handle must start with '!'");
+    }
+
+    if (handle.buffer[handle.capacity-1] != '!') {
+        return EMITTER_ERROR_INIT(emitter, "tag handle must end with '!'");
     }
 
     handle.pointer ++;
 
-    while (handle.pointer < handle.end-1) {
+    while (handle.pointer < handle.capacity-1) {
         if (!IS_ALPHA(handle)) {
-            return yaml_emitter_set_emitter_error(emitter,
+            return EMITTER_ERROR_INIT(emitter,
                     "tag handle must contain alphanumerical characters only");
         }
@@ -1361,7 +1343,6 @@
     }
 
-    if (prefix.start == prefix.end) {
-        return yaml_emitter_set_emitter_error(emitter,
-                "tag prefix must not be empty");
+    if (!prefix.capacity) {
+        return EMITTER_ERROR_INIT(emitter, "tag prefix must not be empty");
     }
 
@@ -1375,17 +1356,17 @@
 static int
 yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
-        yaml_char_t *anchor, int alias)
+        yaml_char_t *anchor, int is_alias)
 {
     yaml_string_t string = STRING(anchor, strlen((char *)anchor));
 
-    if (string.start == string.end) {
-        return yaml_emitter_set_emitter_error(emitter, alias ?
+    if (!string.capacity) {
+        return EMITTER_ERROR_INIT(emitter, is_alias ?
                 "alias value must not be empty" :
                 "anchor value must not be empty");
     }
 
-    while (string.pointer != string.end) {
+    while (string.pointer < string.capacity) {
         if (!IS_ALPHA(string)) {
-            return yaml_emitter_set_emitter_error(emitter, alias ?
+            return EMITTER_ERROR_INIT(emitter, is_alias ?
                     "alias value must contain alphanumerical characters only" :
                     "anchor value must contain alphanumerical characters only");
@@ -1394,7 +1375,7 @@
     }
 
-    emitter->anchor_data.anchor = string.start;
-    emitter->anchor_data.anchor_length = string.end - string.start;
-    emitter->anchor_data.alias = alias;
+    emitter->anchor_data.anchor = string.buffer;
+    emitter->anchor_data.anchor_length = string.capacity;
+    emitter->anchor_data.is_alias = is_alias;
 
     return 1;
@@ -1410,16 +1391,15 @@
 {
     yaml_string_t string = STRING(tag, strlen((char *)tag));
-    yaml_tag_directive_t *tag_directive;
-
-    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 idx;
+
+    if (!string.capacity) {
+        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;
         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,
+        if (prefix_length < string.capacity
+                && strncmp((char *)tag_directive->prefix, (char *)string.buffer,
                     prefix_length) == 0)
         {
@@ -1427,13 +1407,12 @@
             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;
+            emitter->tag_data.suffix = string.buffer + prefix_length;
+            emitter->tag_data.suffix_length = string.capacity - prefix_length;
             return 1;
         }
     }
 
-    emitter->tag_data.suffix = string.start;
-    emitter->tag_data.suffix_length = string.end - string.start;
+    emitter->tag_data.suffix = string.buffer;
+    emitter->tag_data.suffix_length = string.capacity;
 
     return 1;
@@ -1474,11 +1453,11 @@
     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;
+    if (!string.capacity)
+    {
+        emitter->scalar_data.is_multiline = 0;
+        emitter->scalar_data.is_flow_plain_allowed = 0;
+        emitter->scalar_data.is_block_plain_allowed = 1;
+        emitter->scalar_data.is_single_quoted_allowed = 1;
+        emitter->scalar_data.is_block_allowed = 0;
 
         return 1;
@@ -1498,7 +1477,7 @@
     followed_by_space = IS_BLANKZ_AT(string, WIDTH(string));
 
-    while (string.pointer != string.end)
-    {
-        if (string.start == string.pointer)
+    while (string.pointer < string.capacity)
+    {
+        if (!string.pointer)
         {
             if (CHECK(string, '#') || CHECK(string, ',')
@@ -1548,5 +1527,5 @@
 
         if (!IS_PRINTABLE(string)
-                || (!IS_ASCII(string) && !emitter->unicode)) {
+                || (!IS_ASCII(string) && !emitter->is_unicode)) {
             special_characters = 1;
         }
@@ -1559,5 +1538,5 @@
         {
             spaces = 1;
-            if (string.start == string.pointer) {
+            if (!string.pointer) {
                 leading = 1;
             }
@@ -1570,5 +1549,5 @@
             }
             breaks = 1;
-            if (string.start == string.pointer) {
+            if (!string.pointer) {
                 leading = 1;
             }
@@ -1605,5 +1584,5 @@
         }
 
-        if ((spaces || breaks) && string.pointer == string.end-1)
+        if ((spaces || breaks) && string.pointer == string.capacity-1)
         {
             if (spaces && breaks) {
@@ -1626,51 +1605,51 @@
         preceeded_by_space = IS_BLANKZ(string);
         MOVE(string);
-        if (string.pointer != string.end) {
+        if (string.pointer < string.capacity) {
             followed_by_space = 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;
+    emitter->scalar_data.is_multiline = line_breaks;
+
+    emitter->scalar_data.is_flow_plain_allowed = 1;
+    emitter->scalar_data.is_block_plain_allowed = 1;
+    emitter->scalar_data.is_single_quoted_allowed = 1;
+    emitter->scalar_data.is_block_allowed = 1;
 
     if (leading_spaces || leading_breaks || trailing_spaces) {
-        emitter->scalar_data.flow_plain_allowed = 0;
-        emitter->scalar_data.block_plain_allowed = 0;
-        emitter->scalar_data.block_allowed = 0;
+        emitter->scalar_data.is_flow_plain_allowed = 0;
+        emitter->scalar_data.is_block_plain_allowed = 0;
+        emitter->scalar_data.is_block_allowed = 0;
     }
 
     if (trailing_breaks) {
-        emitter->scalar_data.flow_plain_allowed = 0;
-        emitter->scalar_data.block_plain_allowed = 0;
+        emitter->scalar_data.is_flow_plain_allowed = 0;
+        emitter->scalar_data.is_block_plain_allowed = 0;
     }
 
     if (inline_breaks_spaces) {
-        emitter->scalar_data.flow_plain_allowed = 0;
-        emitter->scalar_data.block_plain_allowed = 0;
-        emitter->scalar_data.single_quoted_allowed = 0;
+        emitter->scalar_data.is_flow_plain_allowed = 0;
+        emitter->scalar_data.is_block_plain_allowed = 0;
+        emitter->scalar_data.is_single_quoted_allowed = 0;
     }
 
     if (mixed_breaks_spaces || 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;
+        emitter->scalar_data.is_flow_plain_allowed = 0;
+        emitter->scalar_data.is_block_plain_allowed = 0;
+        emitter->scalar_data.is_single_quoted_allowed = 0;
+        emitter->scalar_data.is_block_allowed = 0;
     }
 
     if (line_breaks) {
-        emitter->scalar_data.flow_plain_allowed = 0;
-        emitter->scalar_data.block_plain_allowed = 0;
+        emitter->scalar_data.is_flow_plain_allowed = 0;
+        emitter->scalar_data.is_block_plain_allowed = 0;
     }
 
     if (flow_indicators) {
-        emitter->scalar_data.flow_plain_allowed = 0;
+        emitter->scalar_data.is_flow_plain_allowed = 0;
     }
 
     if (block_indicators) {
-        emitter->scalar_data.block_plain_allowed = 0;
+        emitter->scalar_data.is_block_plain_allowed = 0;
     }
 
@@ -1709,7 +1688,7 @@
                     return 0;
             }
-            if (event->data.scalar.tag && (emitter->canonical ||
-                        (!event->data.scalar.plain_implicit
-                         && !event->data.scalar.quoted_implicit))) {
+            if (event->data.scalar.tag && (emitter->is_canonical ||
+                        (!event->data.scalar.is_plain_implicit
+                         && !event->data.scalar.is_quoted_implicit))) {
                 if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag))
                     return 0;
@@ -1726,6 +1705,6 @@
                     return 0;
             }
-            if (event->data.sequence_start.tag && (emitter->canonical ||
-                        !event->data.sequence_start.implicit)) {
+            if (event->data.sequence_start.tag && (emitter->is_canonical ||
+                        !event->data.sequence_start.is_implicit)) {
                 if (!yaml_emitter_analyze_tag(emitter,
                             event->data.sequence_start.tag))
@@ -1740,6 +1719,6 @@
                     return 0;
             }
-            if (event->data.mapping_start.tag && (emitter->canonical ||
-                        !event->data.mapping_start.implicit)) {
+            if (event->data.mapping_start.tag && (emitter->is_canonical ||
+                        !event->data.mapping_start.is_implicit)) {
                 if (!yaml_emitter_analyze_tag(emitter,
                             event->data.mapping_start.tag))
@@ -1762,7 +1741,7 @@
     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';
+    JOIN_OCTET(emitter->output, (yaml_char_t) '\xEF');
+    JOIN_OCTET(emitter->output, (yaml_char_t) '\xBB');
+    JOIN_OCTET(emitter->output, (yaml_char_t) '\xBF');
 
     return 1;
@@ -1774,6 +1753,6 @@
     int indent = (emitter->indent >= 0) ? emitter->indent : 0;
 
-    if (!emitter->indention || emitter->column > indent
-            || (emitter->column == indent && !emitter->whitespace)) {
+    if (!emitter->is_indention || emitter->column > indent
+            || (emitter->column == indent && !emitter->is_whitespace)) {
         if (!PUT_BREAK(emitter)) return 0;
     }
@@ -1783,6 +1762,6 @@
     }
 
-    emitter->whitespace = 1;
-    emitter->indention = 1;
+    emitter->is_whitespace = 1;
+    emitter->is_indention = 1;
 
     return 1;
@@ -1796,14 +1775,14 @@
     yaml_string_t string = STRING((yaml_char_t *)indicator, strlen(indicator));
 
-    if (need_whitespace && !emitter->whitespace) {
+    if (need_whitespace && !emitter->is_whitespace) {
         if (!PUT(emitter, ' ')) return 0;
     }
 
-    while (string.pointer != string.end) {
+    while (string.pointer < string.capacity) {
         if (!WRITE(emitter, string)) return 0;
     }
 
-    emitter->whitespace = is_whitespace;
-    emitter->indention = (emitter->indention && is_indention);
+    emitter->is_whitespace = is_whitespace;
+    emitter->is_indention = (emitter->is_indention && is_indention);
 
     return 1;
@@ -1816,10 +1795,10 @@
     yaml_string_t string = STRING(value, length);
 
-    while (string.pointer != string.end) {
+    while (string.pointer < string.capacity) {
         if (!WRITE(emitter, string)) return 0;
     }
 
-    emitter->whitespace = 0;
-    emitter->indention = 0;
+    emitter->is_whitespace = 0;
+    emitter->is_indention = 0;
 
     return 1;
@@ -1832,14 +1811,14 @@
     yaml_string_t string = STRING(value, length);
 
-    if (!emitter->whitespace) {
+    if (!emitter->is_whitespace) {
         if (!PUT(emitter, ' ')) return 0;
     }
 
-    while (string.pointer != string.end) {
+    while (string.pointer < string.capacity) {
         if (!WRITE(emitter, string)) return 0;
     }
 
-    emitter->whitespace = 0;
-    emitter->indention = 0;
+    emitter->is_whitespace = 0;
+    emitter->is_indention = 0;
 
     return 1;
@@ -1853,9 +1832,9 @@
     yaml_string_t string = STRING(value, length);
 
-    if (need_whitespace && !emitter->whitespace) {
+    if (need_whitespace && !emitter->is_whitespace) {
         if (!PUT(emitter, ' ')) return 0;
     }
 
-    while (string.pointer != string.end) {
+    while (string.pointer < string.capacity) {
         if (IS_ALPHA(string)
                 || CHECK(string, ';') || CHECK(string, '/')
@@ -1875,5 +1854,6 @@
             unsigned int value;
             while (width --) {
-                value = *(string.pointer++);
+                value = OCTET(string);
+                string.pointer ++;
                 if (!PUT(emitter, '%')) return 0;
                 if (!PUT(emitter, (value >> 4)
@@ -1887,6 +1867,6 @@
     }
 
-    emitter->whitespace = 0;
-    emitter->indention = 0;
+    emitter->is_whitespace = 0;
+    emitter->is_indention = 0;
 
     return 1;
@@ -1901,9 +1881,9 @@
     int breaks = 0;
 
-    if (!emitter->whitespace) {
+    if (!emitter->is_whitespace) {
         if (!PUT(emitter, ' ')) return 0;
     }
 
-    while (string.pointer != string.end)
+    while (string.pointer < string.capacity)
     {
         if (IS_SPACE(string))
@@ -1926,5 +1906,5 @@
             }
             if (!WRITE_BREAK(emitter, string)) return 0;
-            emitter->indention = 1;
+            emitter->is_indention = 1;
             breaks = 1;
         }
@@ -1935,5 +1915,5 @@
             }
             if (!WRITE(emitter, string)) return 0;
-            emitter->indention = 0;
+            emitter->is_indention = 0;
             spaces = 0;
             breaks = 0;
@@ -1941,6 +1921,6 @@
     }
 
-    emitter->whitespace = 0;
-    emitter->indention = 0;
+    emitter->is_whitespace = 0;
+    emitter->is_indention = 0;
 
     return 1;
@@ -1958,5 +1938,5 @@
         return 0;
 
-    while (string.pointer != string.end)
+    while (string.pointer < string.capacity)
     {
         if (IS_SPACE(string))
@@ -1964,6 +1944,6 @@
             if (allow_breaks && !spaces
                     && emitter->column > emitter->best_width
-                    && string.pointer != string.start
-                    && string.pointer != string.end - 1
+                    && string.pointer != 0
+                    && string.pointer != string.capacity - 1
                     && !IS_SPACE_AT(string, 1)) {
                 if (!yaml_emitter_write_indent(emitter)) return 0;
@@ -1981,5 +1961,5 @@
             }
             if (!WRITE_BREAK(emitter, string)) return 0;
-            emitter->indention = 1;
+            emitter->is_indention = 1;
             breaks = 1;
         }
@@ -1993,5 +1973,5 @@
             }
             if (!WRITE(emitter, string)) return 0;
-            emitter->indention = 0;
+            emitter->is_indention = 0;
             spaces = 0;
             breaks = 0;
@@ -2002,6 +1982,6 @@
         return 0;
 
-    emitter->whitespace = 0;
-    emitter->indention = 0;
+    emitter->is_whitespace = 0;
+    emitter->is_indention = 0;
 
     return 1;
@@ -2018,7 +1998,7 @@
         return 0;
 
-    while (string.pointer != string.end)
-    {
-        if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string))
+    while (string.pointer < string.capacity)
+    {
+        if (!IS_PRINTABLE(string) || (!emitter->is_unicode && !IS_ASCII(string))
                 || IS_BOM(string) || IS_BREAK(string)
                 || CHECK(string, '"') || CHECK(string, '\\'))
@@ -2027,7 +2007,7 @@
             unsigned int width;
             unsigned int value;
-            int k;
-
-            octet = string.pointer[0];
+            int idx;
+
+            octet = OCTET(string);
             width = (octet & 0x80) == 0x00 ? 1 :
                     (octet & 0xE0) == 0xC0 ? 2 :
@@ -2038,6 +2018,6 @@
                     (octet & 0xF0) == 0xE0 ? octet & 0x0F :
                     (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
-            for (k = 1; k < (int)width; k ++) {
-                octet = string.pointer[k];
+            for (idx = 1; idx < width; idx ++) {
+                octet = OCTET_AT(string, idx);
                 value = (value << 6) + (octet & 0x3F);
             }
@@ -2121,6 +2101,6 @@
                         width = 8;
                     }
-                    for (k = (width-1)*4; k >= 0; k -= 4) {
-                        int digit = (value >> k) & 0x0F;
+                    for (idx = (width-1)*4; idx >= 0; idx -= 4) {
+                        int digit = (value >> idx) & 0x0F;
                         if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10)))
                             return 0;
@@ -2133,6 +2113,6 @@
             if (allow_breaks && !spaces
                     && emitter->column > emitter->best_width
-                    && string.pointer != string.start
-                    && string.pointer != string.end - 1) {
+                    && string.pointer != 0
+                    && string.pointer != string.capacity - 1) {
                 if (!yaml_emitter_write_indent(emitter)) return 0;
                 if (IS_SPACE_AT(string, 1)) {
@@ -2156,6 +2136,6 @@
         return 0;
 
-    emitter->whitespace = 0;
-    emitter->indention = 0;
+    emitter->is_whitespace = 0;
+    emitter->is_indention = 0;
 
     return 1;
@@ -2166,17 +2146,17 @@
         yaml_string_t string)
 {
-    string.pointer = string.end;
-    if (string.start == string.pointer)
+    string.pointer = string.capacity;
+    if (!string.pointer)
         return -1;
     do {
         string.pointer --;
-    } while ((*string.pointer & 0xC0) == 0x80);
+    } while ((OCTET(string) & 0xC0) == 0x80);
     if (!IS_BREAK(string))
         return -1;
-    if (string.start == string.pointer)
+    if (!string.pointer)
         return 0;
     do {
         string.pointer --;
-    } while ((*string.pointer & 0xC0) == 0x80);
+    } while ((OCTET(string) & 0xC0) == 0x80);
     if (!IS_BREAK(string))
         return 0;
@@ -2199,10 +2179,10 @@
         return 0;
 
-    while (string.pointer != string.end)
+    while (string.pointer < string.capacity)
     {
         if (IS_BREAK(string))
         {
             if (!WRITE_BREAK(emitter, string)) return 0;
-            emitter->indention = 1;
+            emitter->is_indention = 1;
             breaks = 1;
         }
@@ -2213,5 +2193,5 @@
             }
             if (!WRITE(emitter, string)) return 0;
-            emitter->indention = 0;
+            emitter->is_indention = 0;
             breaks = 0;
         }
@@ -2236,5 +2216,5 @@
         return 0;
 
-    while (string.pointer != string.end)
+    while (string.pointer < string.capacity)
     {
         if (IS_BREAK(string))
@@ -2250,5 +2230,5 @@
             }
             if (!WRITE_BREAK(emitter, string)) return 0;
-            emitter->indention = 1;
+            emitter->is_indention = 1;
             breaks = 1;
         }
@@ -2267,5 +2247,5 @@
                 if (!WRITE(emitter, string)) return 0;
             }
-            emitter->indention = 0;
+            emitter->is_indention = 0;
             breaks = 0;
         }
Index: /libyaml/trunk/src/scanner.c
===================================================================
--- /libyaml/trunk/src/scanner.c	(revision 243)
+++ /libyaml/trunk/src/scanner.c	(revision 263)
@@ -496,19 +496,19 @@
       parser->mark.column ++,                                                   \
       parser->unread --,                                                        \
-      parser->buffer.pointer += WIDTH(parser->buffer))
+      parser->input.pointer += WIDTH(parser->input))
 
 #define SKIP_LINE(parser)                                                       \
-     (IS_CRLF(parser->buffer) ?                                                 \
+     (IS_CRLF(parser->input) ?                                                  \
       (parser->mark.index += 2,                                                 \
        parser->mark.column = 0,                                                 \
        parser->mark.line ++,                                                    \
        parser->unread -= 2,                                                     \
-       parser->buffer.pointer += 2) :                                           \
-      IS_BREAK(parser->buffer) ?                                                \
+       parser->input.pointer += 2) :                                            \
+      IS_BREAK(parser->input) ?                                                 \
       (parser->mark.index ++,                                                   \
        parser->mark.column = 0,                                                 \
        parser->mark.line ++,                                                    \
        parser->unread --,                                                       \
-       parser->buffer.pointer += WIDTH(parser->buffer)) : 0)
+       parser->input.pointer += WIDTH(parser->input)) : 0)
 
 /*
@@ -518,5 +518,5 @@
 #define READ(parser,string)                                                     \
      (STRING_EXTEND(parser,string) ?                                            \
-         (COPY(string,parser->buffer),                                          \
+         (COPY(string,parser->input),                                           \
           parser->mark.index ++,                                                \
           parser->mark.column ++,                                               \
@@ -530,35 +530,35 @@
 #define READ_LINE(parser,string)                                                \
     (STRING_EXTEND(parser,string) ?                                             \
-    (((CHECK_AT(parser->buffer,'\r',0)                                          \
-       && CHECK_AT(parser->buffer,'\n',1)) ?        /* CR LF -> LF */           \
-     (*((string).pointer++) = (yaml_char_t) '\n',                               \
-      parser->buffer.pointer += 2,                                              \
+    (((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->buffer,'\r',0)                                           \
-      || CHECK_AT(parser->buffer,'\n',0)) ?         /* CR|LF -> LF */           \
-     (*((string).pointer++) = (yaml_char_t) '\n',                               \
-      parser->buffer.pointer ++,                                                \
+     (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->buffer,'\xC2',0)                                         \
-      && CHECK_AT(parser->buffer,'\x85',1)) ?       /* NEL -> LF */             \
-     (*((string).pointer++) = (yaml_char_t) '\n',                               \
-      parser->buffer.pointer += 2,                                              \
+     (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->buffer,'\xE2',0) &&                                      \
-      CHECK_AT(parser->buffer,'\x80',1) &&                                      \
-      (CHECK_AT(parser->buffer,'\xA8',2) ||                                     \
-       CHECK_AT(parser->buffer,'\xA9',2))) ?        /* LS|PS -> LS|PS */        \
-     (*((string).pointer++) = *(parser->buffer.pointer++),                      \
-      *((string).pointer++) = *(parser->buffer.pointer++),                      \
-      *((string).pointer++) = *(parser->buffer.pointer++),                      \
+     (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,                                                  \
@@ -575,12 +575,4 @@
 
 /*
- * Error handling.
- */
-
-static int
-yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
-        yaml_mark_t context_mark, const char *problem);
-
-/*
  * High-level token API.
  */
@@ -751,5 +743,5 @@
     /* No tokens after STREAM-END or error. */
 
-    if (parser->stream_end_produced || parser->error) {
+    if (parser->is_stream_end_produced || parser->error.type) {
         return 1;
     }
@@ -757,5 +749,5 @@
     /* Ensure that the tokens queue contains enough tokens. */
 
-    if (!parser->token_available) {
+    if (!parser->is_token_available) {
         if (!yaml_parser_fetch_more_tokens(parser))
             return 0;
@@ -765,29 +757,12 @@
     
     *token = DEQUEUE(parser, parser->tokens);
-    parser->token_available = 0;
+    parser->is_token_available = 0;
     parser->tokens_parsed ++;
 
     if (token->type == YAML_STREAM_END_TOKEN) {
-        parser->stream_end_produced = 1;
-    }
-
-    return 1;
-}
-
-/*
- * Set the scanner error and return 0.
- */
-
-static int
-yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
-        yaml_mark_t context_mark, const char *problem)
-{
-    parser->error = YAML_SCANNER_ERROR;
-    parser->context = context;
-    parser->context_mark = context_mark;
-    parser->problem = problem;
-    parser->problem_mark = parser->mark;
-
-    return 0;
+        parser->is_stream_end_produced = 1;
+    }
+
+    return 1;
 }
 
@@ -820,5 +795,5 @@
         else
         {
-            yaml_simple_key_t *simple_key;
+            size_t idx;
 
             /* Check if any potential simple key may occupy the head position. */
@@ -827,7 +802,7 @@
                 return 0;
 
-            for (simple_key = parser->simple_keys.start;
-                    simple_key != parser->simple_keys.top; simple_key++) {
-                if (simple_key->possible
+            for (idx = 0; idx < parser->simple_keys.length; idx++) {
+                yaml_simple_key_t *simple_key  = parser->simple_keys.list + idx;
+                if (simple_key->is_possible
                         && simple_key->token_number == parser->tokens_parsed) {
                     need_more_tokens = 1;
@@ -848,5 +823,5 @@
     }
 
-    parser->token_available = 1;
+    parser->is_token_available = 1;
 
     return 1;
@@ -860,4 +835,6 @@
 yaml_parser_fetch_next_token(yaml_parser_t *parser)
 {
+    yaml_mark_t start_mark = parser->mark;
+
     /* Ensure that the buffer is initialized. */
 
@@ -867,5 +844,5 @@
     /* Check if we just started scanning.  Fetch STREAM-START then. */
 
-    if (!parser->stream_start_produced)
+    if (!parser->is_stream_start_produced)
         return yaml_parser_fetch_stream_start(parser);
 
@@ -895,10 +872,10 @@
     /* Is it the end of the stream? */
 
-    if (IS_Z(parser->buffer))
+    if (IS_Z(parser->input))
         return yaml_parser_fetch_stream_end(parser);
 
     /* Is it a directive? */
 
-    if (parser->mark.column == 0 && CHECK(parser->buffer, '%'))
+    if (parser->mark.column == 0 && CHECK(parser->input, '%'))
         return yaml_parser_fetch_directive(parser);
 
@@ -906,8 +883,8 @@
 
     if (parser->mark.column == 0
-            && CHECK_AT(parser->buffer, '-', 0)
-            && CHECK_AT(parser->buffer, '-', 1)
-            && CHECK_AT(parser->buffer, '-', 2)
-            && IS_BLANKZ_AT(parser->buffer, 3))
+            && CHECK_AT(parser->input, '-', 0)
+            && CHECK_AT(parser->input, '-', 1)
+            && CHECK_AT(parser->input, '-', 2)
+            && IS_BLANKZ_AT(parser->input, 3))
         return yaml_parser_fetch_document_indicator(parser,
                 YAML_DOCUMENT_START_TOKEN);
@@ -916,8 +893,8 @@
 
     if (parser->mark.column == 0
-            && CHECK_AT(parser->buffer, '.', 0)
-            && CHECK_AT(parser->buffer, '.', 1)
-            && CHECK_AT(parser->buffer, '.', 2)
-            && IS_BLANKZ_AT(parser->buffer, 3))
+            && CHECK_AT(parser->input, '.', 0)
+            && CHECK_AT(parser->input, '.', 1)
+            && CHECK_AT(parser->input, '.', 2)
+            && IS_BLANKZ_AT(parser->input, 3))
         return yaml_parser_fetch_document_indicator(parser,
                 YAML_DOCUMENT_END_TOKEN);
@@ -925,5 +902,5 @@
     /* Is it the flow sequence start indicator? */
 
-    if (CHECK(parser->buffer, '['))
+    if (CHECK(parser->input, '['))
         return yaml_parser_fetch_flow_collection_start(parser,
                 YAML_FLOW_SEQUENCE_START_TOKEN);
@@ -931,5 +908,5 @@
     /* Is it the flow mapping start indicator? */
 
-    if (CHECK(parser->buffer, '{'))
+    if (CHECK(parser->input, '{'))
         return yaml_parser_fetch_flow_collection_start(parser,
                 YAML_FLOW_MAPPING_START_TOKEN);
@@ -937,5 +914,5 @@
     /* Is it the flow sequence end indicator? */
 
-    if (CHECK(parser->buffer, ']'))
+    if (CHECK(parser->input, ']'))
         return yaml_parser_fetch_flow_collection_end(parser,
                 YAML_FLOW_SEQUENCE_END_TOKEN);
@@ -943,5 +920,5 @@
     /* Is it the flow mapping end indicator? */
 
-    if (CHECK(parser->buffer, '}'))
+    if (CHECK(parser->input, '}'))
         return yaml_parser_fetch_flow_collection_end(parser,
                 YAML_FLOW_MAPPING_END_TOKEN);
@@ -949,57 +926,57 @@
     /* Is it the flow entry indicator? */
 
-    if (CHECK(parser->buffer, ','))
+    if (CHECK(parser->input, ','))
         return yaml_parser_fetch_flow_entry(parser);
 
     /* Is it the block entry indicator? */
 
-    if (CHECK(parser->buffer, '-') && IS_BLANKZ_AT(parser->buffer, 1))
+    if (CHECK(parser->input, '-') && IS_BLANKZ_AT(parser->input, 1))
         return yaml_parser_fetch_block_entry(parser);
 
     /* Is it the key indicator? */
 
-    if (CHECK(parser->buffer, '?')
-            && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1)))
+    if (CHECK(parser->input, '?')
+            && (parser->flow_level || IS_BLANKZ_AT(parser->input, 1)))
         return yaml_parser_fetch_key(parser);
 
     /* Is it the value indicator? */
 
-    if (CHECK(parser->buffer, ':')
-            && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1)))
+    if (CHECK(parser->input, ':')
+            && (parser->flow_level || IS_BLANKZ_AT(parser->input, 1)))
         return yaml_parser_fetch_value(parser);
 
     /* Is it an alias? */
 
-    if (CHECK(parser->buffer, '*'))
+    if (CHECK(parser->input, '*'))
         return yaml_parser_fetch_anchor(parser, YAML_ALIAS_TOKEN);
 
     /* Is it an anchor? */
 
-    if (CHECK(parser->buffer, '&'))
+    if (CHECK(parser->input, '&'))
         return yaml_parser_fetch_anchor(parser, YAML_ANCHOR_TOKEN);
 
     /* Is it a tag? */
 
-    if (CHECK(parser->buffer, '!'))
+    if (CHECK(parser->input, '!'))
         return yaml_parser_fetch_tag(parser);
 
     /* Is it a literal scalar? */
 
-    if (CHECK(parser->buffer, '|') && !parser->flow_level)
+    if (CHECK(parser->input, '|') && !parser->flow_level)
         return yaml_parser_fetch_block_scalar(parser, 1);
 
     /* Is it a folded scalar? */
 
-    if (CHECK(parser->buffer, '>') && !parser->flow_level)
+    if (CHECK(parser->input, '>') && !parser->flow_level)
         return yaml_parser_fetch_block_scalar(parser, 0);
 
     /* Is it a single-quoted scalar? */
 
-    if (CHECK(parser->buffer, '\''))
+    if (CHECK(parser->input, '\''))
         return yaml_parser_fetch_flow_scalar(parser, 1);
 
     /* Is it a double-quoted scalar? */
 
-    if (CHECK(parser->buffer, '"'))
+    if (CHECK(parser->input, '"'))
         return yaml_parser_fetch_flow_scalar(parser, 0);
 
@@ -1023,18 +1000,18 @@
      */
 
-    if (!(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '-')
-                || CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':')
-                || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '[')
-                || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
-                || CHECK(parser->buffer, '}') || CHECK(parser->buffer, '#')
-                || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '*')
-                || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '|')
-                || CHECK(parser->buffer, '>') || CHECK(parser->buffer, '\'')
-                || CHECK(parser->buffer, '"') || CHECK(parser->buffer, '%')
-                || CHECK(parser->buffer, '@') || CHECK(parser->buffer, '`')) ||
-            (CHECK(parser->buffer, '-') && !IS_BLANK_AT(parser->buffer, 1)) ||
+    if (!(IS_BLANKZ(parser->input) || CHECK(parser->input, '-')
+                || CHECK(parser->input, '?') || CHECK(parser->input, ':')
+                || CHECK(parser->input, ',') || CHECK(parser->input, '[')
+                || CHECK(parser->input, ']') || CHECK(parser->input, '{')
+                || CHECK(parser->input, '}') || CHECK(parser->input, '#')
+                || CHECK(parser->input, '&') || CHECK(parser->input, '*')
+                || CHECK(parser->input, '!') || CHECK(parser->input, '|')
+                || CHECK(parser->input, '>') || CHECK(parser->input, '\'')
+                || CHECK(parser->input, '"') || CHECK(parser->input, '%')
+                || CHECK(parser->input, '@') || CHECK(parser->input, '`')) ||
+            (CHECK(parser->input, '-') && !IS_BLANK_AT(parser->input, 1)) ||
             (!parser->flow_level &&
-             (CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':'))
-             && !IS_BLANKZ_AT(parser->buffer, 1)))
+             (CHECK(parser->input, '?') || CHECK(parser->input, ':'))
+             && !IS_BLANKZ_AT(parser->input, 1)))
         return yaml_parser_fetch_plain_scalar(parser);
 
@@ -1043,7 +1020,7 @@
      */
 
-    return yaml_parser_set_scanner_error(parser,
-            "while scanning for the next token", parser->mark,
-            "found character that cannot start any token");
+    return SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+            "while scanning for the next token", start_mark,
+            "found character that cannot start any token", parser->mark);
 }
 
@@ -1056,11 +1033,12 @@
 yaml_parser_stale_simple_keys(yaml_parser_t *parser)
 {
-    yaml_simple_key_t *simple_key;
+    size_t idx;
 
     /* Check for a potential simple key for each flow level. */
 
-    for (simple_key = parser->simple_keys.start;
-            simple_key != parser->simple_keys.top; simple_key ++)
+    for (idx = 0; idx < parser->simple_keys.length; idx ++)
     {
+        yaml_simple_key_t *simple_key = parser->simple_keys.list + idx;
+
         /*
          * The specification requires that a simple key
@@ -1070,5 +1048,5 @@
          */
 
-        if (simple_key->possible
+        if (simple_key->is_possible
                 && (simple_key->mark.line < parser->mark.line
                     || simple_key->mark.index+1024 < parser->mark.index)) {
@@ -1076,11 +1054,11 @@
             /* Check if the potential simple key to be removed is required. */
 
-            if (simple_key->required) {
-                return yaml_parser_set_scanner_error(parser,
+            if (simple_key->is_required) {
+                return SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
                         "while scanning a simple key", simple_key->mark,
-                        "could not found expected ':'");
+                        "could not found expected ':'", parser->mark);
             }
 
-            simple_key->possible = 0;
+            simple_key->is_possible = 0;
         }
     }
@@ -1103,5 +1081,5 @@
      */
 
-    int required = (!parser->flow_level
+    int is_required = (!parser->flow_level
             && parser->indent == (int)parser->mark.column);
 
@@ -1111,5 +1089,5 @@
      */
 
-    assert(parser->simple_key_allowed || !required);    /* Impossible. */
+    assert(parser->is_simple_key_allowed || !is_required);  /* Impossible. */
 
     /*
@@ -1117,7 +1095,7 @@
      */
 
-    if (parser->simple_key_allowed)
+    if (parser->is_simple_key_allowed)
     {
-        yaml_simple_key_t simple_key = { 1, required,
+        yaml_simple_key_t simple_key = { 1, is_required,
             parser->tokens_parsed + parser->tokens.tail - parser->tokens.head,
             { 0, 0, 0 } };
@@ -1126,5 +1104,5 @@
         if (!yaml_parser_remove_simple_key(parser)) return 0;
 
-        *(parser->simple_keys.top-1) = simple_key;
+        parser->simple_keys.list[parser->simple_keys.length-1] = simple_key;
     }
 
@@ -1139,14 +1117,15 @@
 yaml_parser_remove_simple_key(yaml_parser_t *parser)
 {
-    yaml_simple_key_t *simple_key = parser->simple_keys.top-1;
-
-    if (simple_key->possible)
+    yaml_simple_key_t *simple_key =
+        parser->simple_keys.list + parser->simple_keys.length - 1;
+
+    if (simple_key->is_possible)
     {
         /* If the key is required, it is an error. */
 
-        if (simple_key->required) {
-            return yaml_parser_set_scanner_error(parser,
+        if (simple_key->is_required) {
+            return SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
                     "while scanning a simple key", simple_key->mark,
-                    "could not found expected ':'");
+                    "could not found expected ':'", parser->mark);
         }
     }
@@ -1154,5 +1133,5 @@
     /* Remove the key from the stack. */
 
-    simple_key->possible = 0;
+    simple_key->is_possible = 0;
 
     return 1;
@@ -1302,9 +1281,9 @@
     /* A simple key is allowed at the beginning of the stream. */
 
-    parser->simple_key_allowed = 1;
+    parser->is_simple_key_allowed = 1;
 
     /* We have started. */
 
-    parser->stream_start_produced = 1;
+    parser->is_stream_start_produced = 1;
 
     /* Create the STREAM-START token and append it to the queue. */
@@ -1345,5 +1324,5 @@
         return 0;
 
-    parser->simple_key_allowed = 0;
+    parser->is_simple_key_allowed = 0;
 
     /* Create the STREAM-END token and append it to the queue. */
@@ -1376,5 +1355,5 @@
         return 0;
 
-    parser->simple_key_allowed = 0;
+    parser->is_simple_key_allowed = 0;
 
     /* Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. */
@@ -1414,5 +1393,5 @@
         return 0;
 
-    parser->simple_key_allowed = 0;
+    parser->is_simple_key_allowed = 0;
 
     /* Consume the token. */
@@ -1461,5 +1440,5 @@
     /* A simple key may follow the indicators '[' and '{'. */
 
-    parser->simple_key_allowed = 1;
+    parser->is_simple_key_allowed = 1;
 
     /* Consume the token. */
@@ -1504,5 +1483,5 @@
     /* No simple keys after the indicators ']' and '}'. */
 
-    parser->simple_key_allowed = 0;
+    parser->is_simple_key_allowed = 0;
 
     /* Consume the token. */
@@ -1541,5 +1520,5 @@
     /* Simple keys are allowed after ','. */
 
-    parser->simple_key_allowed = 1;
+    parser->is_simple_key_allowed = 1;
 
     /* Consume the token. */
@@ -1575,7 +1554,8 @@
         /* Check if we are allowed to start a new entry. */
 
-        if (!parser->simple_key_allowed) {
-            return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
-                    "block sequence entries are not allowed in this context");
+        if (!parser->is_simple_key_allowed) {
+            return SCANNER_ERROR_INIT(parser,
+                    "block sequence entries are not allowed in this context",
+                    parser->mark);
         }
 
@@ -1602,5 +1582,5 @@
     /* Simple keys are allowed after '-'. */
 
-    parser->simple_key_allowed = 1;
+    parser->is_simple_key_allowed = 1;
 
     /* Consume the token. */
@@ -1636,7 +1616,7 @@
         /* Check if we are allowed to start a new key (not nessesary simple). */
 
-        if (!parser->simple_key_allowed) {
-            return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
-                    "mapping keys are not allowed in this context");
+        if (!parser->is_simple_key_allowed) {
+            return SCANNER_ERROR_INIT(parser,
+                    "mapping keys are not allowed in this context", parser->mark);
         }
 
@@ -1655,5 +1635,5 @@
     /* Simple keys are allowed after '?' in the block context. */
 
-    parser->simple_key_allowed = (!parser->flow_level);
+    parser->is_simple_key_allowed = (!parser->flow_level);
 
     /* Consume the token. */
@@ -1682,9 +1662,10 @@
     yaml_mark_t start_mark, end_mark;
     yaml_token_t token;
-    yaml_simple_key_t *simple_key = parser->simple_keys.top-1;
+    yaml_simple_key_t *simple_key =
+        parser->simple_keys.list + parser->simple_keys.length - 1;
 
     /* Have we found a simple key? */
 
-    if (simple_key->possible)
+    if (simple_key->is_possible)
     {
 
@@ -1706,9 +1687,9 @@
         /* Remove the simple key. */
 
-        simple_key->possible = 0;
+        simple_key->is_possible = 0;
 
         /* A simple key cannot follow another simple key. */
 
-        parser->simple_key_allowed = 0;
+        parser->is_simple_key_allowed = 0;
     }
     else
@@ -1722,7 +1703,8 @@
             /* Check if we are allowed to start a complex value. */
 
-            if (!parser->simple_key_allowed) {
-                return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
-                        "mapping values are not allowed in this context");
+            if (!parser->is_simple_key_allowed) {
+                return SCANNER_ERROR_INIT(parser,
+                        "mapping values are not allowed in this context",
+                        parser->mark);
             }
 
@@ -1736,5 +1718,5 @@
         /* Simple keys after ':' are allowed in the block context. */
 
-        parser->simple_key_allowed = (!parser->flow_level);
+        parser->is_simple_key_allowed = (!parser->flow_level);
     }
 
@@ -1771,5 +1753,5 @@
     /* A simple key cannot follow an anchor or an alias. */
 
-    parser->simple_key_allowed = 0;
+    parser->is_simple_key_allowed = 0;
 
     /* Create the ALIAS or ANCHOR token and append it to the queue. */
@@ -1801,5 +1783,5 @@
     /* A simple key cannot follow a tag. */
 
-    parser->simple_key_allowed = 0;
+    parser->is_simple_key_allowed = 0;
 
     /* Create the TAG token and append it to the queue. */
@@ -1832,5 +1814,5 @@
     /* A simple key may follow a block scalar. */
 
-    parser->simple_key_allowed = 1;
+    parser->is_simple_key_allowed = 1;
 
     /* Create the SCALAR token and append it to the queue. */
@@ -1863,5 +1845,5 @@
     /* A simple key cannot follow a flow scalar. */
 
-    parser->simple_key_allowed = 0;
+    parser->is_simple_key_allowed = 0;
 
     /* Create the SCALAR token and append it to the queue. */
@@ -1894,5 +1876,5 @@
     /* A simple key cannot follow a flow scalar. */
 
-    parser->simple_key_allowed = 0;
+    parser->is_simple_key_allowed = 0;
 
     /* Create the SCALAR token and append it to the queue. */
@@ -1924,5 +1906,5 @@
         if (!CACHE(parser, 1)) return 0;
 
-        if (parser->mark.column == 0 && IS_BOM(parser->buffer))
+        if (parser->mark.column == 0 && IS_BOM(parser->input))
             SKIP(parser);
 
@@ -1939,7 +1921,7 @@
         if (!CACHE(parser, 1)) return 0;
 
-        while (CHECK(parser->buffer,' ') ||
-                ((parser->flow_level || !parser->simple_key_allowed) &&
-                 CHECK(parser->buffer, '\t'))) {
+        while (CHECK(parser->input,' ') ||
+                ((parser->flow_level || !parser->is_simple_key_allowed) &&
+                 CHECK(parser->input, '\t'))) {
             SKIP(parser);
             if (!CACHE(parser, 1)) return 0;
@@ -1948,6 +1930,6 @@
         /* Eat a comment until a line break. */
 
-        if (CHECK(parser->buffer, '#')) {
-            while (!IS_BREAKZ(parser->buffer)) {
+        if (CHECK(parser->input, '#')) {
+            while (!IS_BREAKZ(parser->input)) {
                 SKIP(parser);
                 if (!CACHE(parser, 1)) return 0;
@@ -1957,5 +1939,5 @@
         /* If it is a line break, eat it. */
 
-        if (IS_BREAK(parser->buffer))
+        if (IS_BREAK(parser->input))
         {
             if (!CACHE(parser, 2)) return 0;
@@ -1965,5 +1947,5 @@
 
             if (!parser->flow_level) {
-                parser->simple_key_allowed = 1;
+                parser->is_simple_key_allowed = 1;
             }
         }
@@ -2048,6 +2030,7 @@
     else
     {
-        yaml_parser_set_scanner_error(parser, "while scanning a directive",
-                start_mark, "found uknown directive name");
+        SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                "while scanning a directive", start_mark,
+                "found uknown directive name", parser->mark);
         goto error;
     }
@@ -2057,11 +2040,11 @@
     if (!CACHE(parser, 1)) goto error;
 
-    while (IS_BLANK(parser->buffer)) {
+    while (IS_BLANK(parser->input)) {
         SKIP(parser);
         if (!CACHE(parser, 1)) goto error;
     }
 
-    if (CHECK(parser->buffer, '#')) {
-        while (!IS_BREAKZ(parser->buffer)) {
+    if (CHECK(parser->input, '#')) {
+        while (!IS_BREAKZ(parser->input)) {
             SKIP(parser);
             if (!CACHE(parser, 1)) goto error;
@@ -2071,7 +2054,8 @@
     /* Check if we are at the end of the line. */
 
-    if (!IS_BREAKZ(parser->buffer)) {
-        yaml_parser_set_scanner_error(parser, "while scanning a directive",
-                start_mark, "did not found expected comment or line break");
+    if (!IS_BREAKZ(parser->input)) {
+        SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                "while scanning a directive", start_mark,
+                "did not found expected comment or line break", parser->mark);
         goto error;
     }
@@ -2079,5 +2063,5 @@
     /* Eat a line break. */
 
-    if (IS_BREAK(parser->buffer)) {
+    if (IS_BREAK(parser->input)) {
         if (!CACHE(parser, 2)) goto error;
         SKIP_LINE(parser);
@@ -2111,5 +2095,6 @@
     yaml_string_t string = NULL_STRING;
 
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+        goto error;
 
     /* Consume the directive name. */
@@ -2117,5 +2102,5 @@
     if (!CACHE(parser, 1)) goto error;
 
-    while (IS_ALPHA(parser->buffer))
+    while (IS_ALPHA(parser->input))
     {
         if (!READ(parser, string)) goto error;
@@ -2125,7 +2110,8 @@
     /* Check if the name is empty. */
 
-    if (string.start == string.pointer) {
-        yaml_parser_set_scanner_error(parser, "while scanning a directive",
-                start_mark, "cannot found expected directive name");
+    if (!string.pointer) {
+        SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                "while scanning a directive", start_mark,
+                "cannot found expected directive name", parser->mark);
         goto error;
     }
@@ -2133,11 +2119,12 @@
     /* Check for an blank character after the name. */
 
-    if (!IS_BLANKZ(parser->buffer)) {
-        yaml_parser_set_scanner_error(parser, "while scanning a directive",
-                start_mark, "found unexpected non-alphabetical character");
+    if (!IS_BLANKZ(parser->input)) {
+        SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                "while scanning a directive", start_mark,
+                "found unexpected non-alphabetical character", parser->mark);
         goto error;
     }
 
-    *name = string.start;
+    *name = string.buffer;
 
     return 1;
@@ -2164,5 +2151,5 @@
     if (!CACHE(parser, 1)) return 0;
 
-    while (IS_BLANK(parser->buffer)) {
+    while (IS_BLANK(parser->input)) {
         SKIP(parser);
         if (!CACHE(parser, 1)) return 0;
@@ -2176,7 +2163,8 @@
     /* Eat '.'. */
 
-    if (!CHECK(parser->buffer, '.')) {
-        return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
-                start_mark, "did not find expected digit or '.' character");
+    if (!CHECK(parser->input, '.')) {
+        return SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                "while scanning a %YAML directive", start_mark,
+                "did not find expected digit or '.' character", parser->mark);
     }
 
@@ -2214,14 +2202,15 @@
     if (!CACHE(parser, 1)) return 0;
 
-    while (IS_DIGIT(parser->buffer))
+    while (IS_DIGIT(parser->input))
     {
         /* Check if the number is too long. */
 
         if (++length > MAX_NUMBER_LENGTH) {
-            return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
-                    start_mark, "found extremely long version number");
-        }
-
-        value = value*10 + AS_DIGIT(parser->buffer);
+            return SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                    "while scanning a %YAML directive", start_mark,
+                    "found extremely long version number", parser->mark);
+        }
+
+        value = value*10 + AS_DIGIT(parser->input);
 
         SKIP(parser);
@@ -2233,6 +2222,7 @@
 
     if (!length) {
-        return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
-                start_mark, "did not find expected version number");
+        return SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                "while scanning a %YAML directive", start_mark,
+                "did not find expected version number", parser->mark);
     }
 
@@ -2261,5 +2251,5 @@
     if (!CACHE(parser, 1)) goto error;
 
-    while (IS_BLANK(parser->buffer)) {
+    while (IS_BLANK(parser->input)) {
         SKIP(parser);
         if (!CACHE(parser, 1)) goto error;
@@ -2275,7 +2265,8 @@
     if (!CACHE(parser, 1)) goto error;
 
-    if (!IS_BLANK(parser->buffer)) {
-        yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
-                start_mark, "did not find expected whitespace");
+    if (!IS_BLANK(parser->input)) {
+        SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                "while scanning a %TAG directive", start_mark,
+                "did not find expected whitespace", parser->mark);
         goto error;
     }
@@ -2283,5 +2274,5 @@
     /* Eat whitespaces. */
 
-    while (IS_BLANK(parser->buffer)) {
+    while (IS_BLANK(parser->input)) {
         SKIP(parser);
         if (!CACHE(parser, 1)) goto error;
@@ -2297,7 +2288,8 @@
     if (!CACHE(parser, 1)) goto error;
 
-    if (!IS_BLANKZ(parser->buffer)) {
-        yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
-                start_mark, "did not find expected whitespace or line break");
+    if (!IS_BLANKZ(parser->input)) {
+        SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                "while scanning a %TAG directive", start_mark,
+                "did not find expected whitespace or line break", parser->mark);
         goto error;
     }
@@ -2322,5 +2314,6 @@
     yaml_string_t string = NULL_STRING;
 
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+        goto error;
 
     /* Eat the indicator character. */
@@ -2334,5 +2327,5 @@
     if (!CACHE(parser, 1)) goto error;
 
-    while (IS_ALPHA(parser->buffer)) {
+    while (IS_ALPHA(parser->input)) {
         if (!READ(parser, string)) goto error;
         if (!CACHE(parser, 1)) goto error;
@@ -2349,12 +2342,14 @@
      */
 
-    if (!length || !(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '?')
-                || CHECK(parser->buffer, ':') || CHECK(parser->buffer, ',')
-                || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '}')
-                || CHECK(parser->buffer, '%') || CHECK(parser->buffer, '@')
-                || CHECK(parser->buffer, '`'))) {
-        yaml_parser_set_scanner_error(parser, type == YAML_ANCHOR_TOKEN ?
-                "while scanning an anchor" : "while scanning an alias", start_mark,
-                "did not find expected alphabetic or numeric character");
+    if (!length || !(IS_BLANKZ(parser->input) || CHECK(parser->input, '?')
+                || CHECK(parser->input, ':') || CHECK(parser->input, ',')
+                || CHECK(parser->input, ']') || CHECK(parser->input, '}')
+                || CHECK(parser->input, '%') || CHECK(parser->input, '@')
+                || CHECK(parser->input, '`'))) {
+        SCANNER_ERROR_WITH_CONTEXT_INIT(parser, type == YAML_ANCHOR_TOKEN ?
+                "while scanning an anchor" : "while scanning an alias",
+                start_mark,
+                "did not find expected alphabetic or numeric character",
+                parser->mark);
         goto error;
     }
@@ -2363,8 +2358,8 @@
 
     if (type == YAML_ANCHOR_TOKEN) {
-        ANCHOR_TOKEN_INIT(*token, string.start, start_mark, end_mark);
+        ANCHOR_TOKEN_INIT(*token, string.buffer, start_mark, end_mark);
     }
     else {
-        ALIAS_TOKEN_INIT(*token, string.start, start_mark, end_mark);
+        ALIAS_TOKEN_INIT(*token, string.buffer, start_mark, end_mark);
     }
 
@@ -2393,5 +2388,5 @@
     if (!CACHE(parser, 2)) goto error;
 
-    if (CHECK_AT(parser->buffer, '<', 1))
+    if (CHECK_AT(parser->input, '<', 1))
     {
         /* Set the handle to '' */
@@ -2413,7 +2408,8 @@
         /* Check for '>' and eat it. */
 
-        if (!CHECK(parser->buffer, '>')) {
-            yaml_parser_set_scanner_error(parser, "while scanning a tag",
-                    start_mark, "did not find the expected '>'");
+        if (!CHECK(parser->input, '>')) {
+            SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                    "while scanning a tag", start_mark,
+                    "did not find the expected '>'", parser->mark);
             goto error;
         }
@@ -2471,7 +2467,8 @@
     if (!CACHE(parser, 1)) goto error;
 
-    if (!IS_BLANKZ(parser->buffer)) {
-        yaml_parser_set_scanner_error(parser, "while scanning a tag",
-                start_mark, "did not found expected whitespace or line break");
+    if (!IS_BLANKZ(parser->input)) {
+        SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                "while scanning a tag", start_mark,
+                "did not found expected whitespace or line break", parser->mark);
         goto error;
     }
@@ -2501,5 +2498,6 @@
     yaml_string_t string = NULL_STRING;
 
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+        goto error;
 
     /* Check the initial '!' character. */
@@ -2507,8 +2505,8 @@
     if (!CACHE(parser, 1)) goto error;
 
-    if (!CHECK(parser->buffer, '!')) {
-        yaml_parser_set_scanner_error(parser, directive ?
+    if (!CHECK(parser->input, '!')) {
+        SCANNER_ERROR_WITH_CONTEXT_INIT(parser, directive ?
                 "while scanning a tag directive" : "while scanning a tag",
-                start_mark, "did not find expected '!'");
+                start_mark, "did not find expected '!'", parser->mark);
         goto error;
     }
@@ -2522,5 +2520,5 @@
     if (!CACHE(parser, 1)) goto error;
 
-    while (IS_ALPHA(parser->buffer))
+    while (IS_ALPHA(parser->input))
     {
         if (!READ(parser, string)) goto error;
@@ -2530,5 +2528,5 @@
     /* Check if the trailing character is '!' and copy it. */
 
-    if (CHECK(parser->buffer, '!'))
+    if (CHECK(parser->input, '!'))
     {
         if (!READ(parser, string)) goto error;
@@ -2542,12 +2540,14 @@
          */
 
-        if (directive && !(string.start[0] == '!' && string.start[1] == '\0')) {
-            yaml_parser_set_scanner_error(parser, "while parsing a tag directive",
-                    start_mark, "did not find expected '!'");
+        if (directive &&
+                !(string.buffer[0] == '!' && string.buffer[1] == '\0')) {
+            SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                    "while parsing a tag directive", start_mark,
+                    "did not find expected '!'", parser->mark);
             goto error;
         }
     }
 
-    *handle = string.start;
+    *handle = string.buffer;
 
     return 1;
@@ -2569,11 +2569,12 @@
     yaml_string_t string = NULL_STRING;
 
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+        goto error;
 
     /* Resize the string to include the head. */
 
-    while (string.end - string.start <= (int)length) {
-        if (!yaml_string_extend(&string.start, &string.pointer, &string.end)) {
-            parser->error = YAML_MEMORY_ERROR;
+    while (string.capacity <= length) {
+        if (!yaml_string_extend(&string.buffer, &string.capacity)) {
+            MEMORY_ERROR_INIT(parser);
             goto error;
         }
@@ -2587,5 +2588,5 @@
 
     if (length > 1) {
-        memcpy(string.start, head+1, length-1);
+        memcpy(string.buffer, head+1, length-1);
         string.pointer += length-1;
     }
@@ -2603,19 +2604,19 @@
      */
 
-    while (IS_ALPHA(parser->buffer) || CHECK(parser->buffer, ';')
-            || CHECK(parser->buffer, '/') || CHECK(parser->buffer, '?')
-            || CHECK(parser->buffer, ':') || CHECK(parser->buffer, '@')
-            || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '=')
-            || CHECK(parser->buffer, '+') || CHECK(parser->buffer, '$')
-            || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '.')
-            || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '~')
-            || CHECK(parser->buffer, '*') || CHECK(parser->buffer, '\'')
-            || CHECK(parser->buffer, '(') || CHECK(parser->buffer, ')')
-            || CHECK(parser->buffer, '[') || CHECK(parser->buffer, ']')
-            || CHECK(parser->buffer, '%'))
+    while (IS_ALPHA(parser->input) || CHECK(parser->input, ';')
+            || CHECK(parser->input, '/') || CHECK(parser->input, '?')
+            || CHECK(parser->input, ':') || CHECK(parser->input, '@')
+            || CHECK(parser->input, '&') || CHECK(parser->input, '=')
+            || CHECK(parser->input, '+') || CHECK(parser->input, '$')
+            || CHECK(parser->input, ',') || CHECK(parser->input, '.')
+            || CHECK(parser->input, '!') || CHECK(parser->input, '~')
+            || CHECK(parser->input, '*') || CHECK(parser->input, '\'')
+            || CHECK(parser->input, '(') || CHECK(parser->input, ')')
+            || CHECK(parser->input, '[') || CHECK(parser->input, ']')
+            || CHECK(parser->input, '%'))
     {
         /* Check if it is a URI-escape sequence. */
 
-        if (CHECK(parser->buffer, '%')) {
+        if (CHECK(parser->input, '%')) {
             if (!yaml_parser_scan_uri_escapes(parser,
                         directive, start_mark, &string)) goto error;
@@ -2635,11 +2636,11 @@
             goto error;
 
-        yaml_parser_set_scanner_error(parser, directive ?
+        SCANNER_ERROR_WITH_CONTEXT_INIT(parser, directive ?
                 "while parsing a %TAG directive" : "while parsing a tag",
-                start_mark, "did not find expected tag URI");
+                start_mark, "did not find expected tag URI", parser->mark);
         goto error;
     }
 
-    *uri = string.start;
+    *uri = string.buffer;
 
     return 1;
@@ -2663,5 +2664,4 @@
 
     do {
-
         unsigned char octet = 0;
 
@@ -2670,15 +2670,15 @@
         if (!CACHE(parser, 3)) return 0;
 
-        if (!(CHECK(parser->buffer, '%')
-                    && IS_HEX_AT(parser->buffer, 1)
-                    && IS_HEX_AT(parser->buffer, 2))) {
-            return yaml_parser_set_scanner_error(parser, directive ?
+        if (!(CHECK(parser->input, '%')
+                    && IS_HEX_AT(parser->input, 1)
+                    && IS_HEX_AT(parser->input, 2))) {
+            return SCANNER_ERROR_WITH_CONTEXT_INIT(parser, directive ?
                     "while parsing a %TAG directive" : "while parsing a tag",
-                    start_mark, "did not find URI escaped octet");
+                    start_mark, "did not find URI escaped octet", parser->mark);
         }
 
         /* Get the octet. */
 
-        octet = (AS_HEX_AT(parser->buffer, 1) << 4) + AS_HEX_AT(parser->buffer, 2);
+        octet = (AS_HEX_AT(parser->input, 1) << 4) + AS_HEX_AT(parser->input, 2);
 
         /* If it is the leading octet, determine the length of the UTF-8 sequence. */
@@ -2691,7 +2691,8 @@
                     (octet & 0xF8) == 0xF0 ? 4 : 0;
             if (!width) {
-                return yaml_parser_set_scanner_error(parser, directive ?
+                return SCANNER_ERROR_WITH_CONTEXT_INIT(parser, directive ?
                         "while parsing a %TAG directive" : "while parsing a tag",
-                        start_mark, "found an incorrect leading UTF-8 octet");
+                        start_mark, "found an incorrect leading UTF-8 octet",
+                        parser->mark);
             }
         }
@@ -2701,7 +2702,8 @@
 
             if ((octet & 0xC0) != 0x80) {
-                return yaml_parser_set_scanner_error(parser, directive ?
+                return SCANNER_ERROR_WITH_CONTEXT_INIT(parser, directive ?
                         "while parsing a %TAG directive" : "while parsing a tag",
-                        start_mark, "found an incorrect trailing UTF-8 octet");
+                        start_mark, "found an incorrect trailing UTF-8 octet",
+                        parser->mark);
             }
         }
@@ -2709,5 +2711,5 @@
         /* Copy the octet and move the pointers. */
 
-        *(string->pointer++) = octet;
+        JOIN_OCTET(*string, octet);
         SKIP(parser);
         SKIP(parser);
@@ -2738,7 +2740,10 @@
     int trailing_blank = 0;
 
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
+    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+        goto error;
+    if (!STRING_INIT(parser, leading_break, INITIAL_STRING_CAPACITY))
+        goto error;
+    if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_CAPACITY))
+        goto error;
 
     /* Eat the indicator '|' or '>'. */
@@ -2754,9 +2759,9 @@
     /* Check for a chomping indicator. */
 
-    if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-'))
+    if (CHECK(parser->input, '+') || CHECK(parser->input, '-'))
     {
         /* Set the chomping method and eat the indicator. */
 
-        chomping = CHECK(parser->buffer, '+') ? +1 : -1;
+        chomping = CHECK(parser->input, '+') ? +1 : -1;
 
         SKIP(parser);
@@ -2766,11 +2771,12 @@
         if (!CACHE(parser, 1)) goto error;
 
-        if (IS_DIGIT(parser->buffer))
+        if (IS_DIGIT(parser->input))
         {
             /* Check that the intendation is greater than 0. */
 
-            if (CHECK(parser->buffer, '0')) {
-                yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-                        start_mark, "found an intendation indicator equal to 0");
+            if (CHECK(parser->input, '0')) {
+                SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                        "while scanning a block scalar", start_mark,
+                        "found an intendation indicator equal to 0", parser->mark);
                 goto error;
             }
@@ -2778,5 +2784,5 @@
             /* Get the intendation level and eat the indicator. */
 
-            increment = AS_DIGIT(parser->buffer);
+            increment = AS_DIGIT(parser->input);
 
             SKIP(parser);
@@ -2786,13 +2792,14 @@
     /* Do the same as above, but in the opposite order. */
 
-    else if (IS_DIGIT(parser->buffer))
+    else if (IS_DIGIT(parser->input))
     {
-        if (CHECK(parser->buffer, '0')) {
-            yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-                    start_mark, "found an intendation indicator equal to 0");
+        if (CHECK(parser->input, '0')) {
+            SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                    "while scanning a block scalar", start_mark,
+                    "found an intendation indicator equal to 0", parser->mark);
             goto error;
         }
 
-        increment = AS_DIGIT(parser->buffer);
+        increment = AS_DIGIT(parser->input);
 
         SKIP(parser);
@@ -2800,6 +2807,6 @@
         if (!CACHE(parser, 1)) goto error;
 
-        if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-')) {
-            chomping = CHECK(parser->buffer, '+') ? +1 : -1;
+        if (CHECK(parser->input, '+') || CHECK(parser->input, '-')) {
+            chomping = CHECK(parser->input, '+') ? +1 : -1;
 
             SKIP(parser);
@@ -2811,11 +2818,11 @@
     if (!CACHE(parser, 1)) goto error;
 
-    while (IS_BLANK(parser->buffer)) {
+    while (IS_BLANK(parser->input)) {
         SKIP(parser);
         if (!CACHE(parser, 1)) goto error;
     }
 
-    if (CHECK(parser->buffer, '#')) {
-        while (!IS_BREAKZ(parser->buffer)) {
+    if (CHECK(parser->input, '#')) {
+        while (!IS_BREAKZ(parser->input)) {
             SKIP(parser);
             if (!CACHE(parser, 1)) goto error;
@@ -2825,7 +2832,8 @@
     /* Check if we are at the end of the line. */
 
-    if (!IS_BREAKZ(parser->buffer)) {
-        yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-                start_mark, "did not found expected comment or line break");
+    if (!IS_BREAKZ(parser->input)) {
+        SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                "while scanning a block scalar", start_mark,
+                "did not found expected comment or line break", parser->mark);
         goto error;
     }
@@ -2833,5 +2841,5 @@
     /* Eat a line break. */
 
-    if (IS_BREAK(parser->buffer)) {
+    if (IS_BREAK(parser->input)) {
         if (!CACHE(parser, 2)) goto error;
         SKIP_LINE(parser);
@@ -2855,5 +2863,5 @@
     if (!CACHE(parser, 1)) goto error;
 
-    while ((int)parser->mark.column == indent && !IS_Z(parser->buffer))
+    while ((int)parser->mark.column == indent && !IS_Z(parser->input))
     {
         /*
@@ -2863,16 +2871,16 @@
         /* Is it a trailing whitespace? */
 
-        trailing_blank = IS_BLANK(parser->buffer);
+        trailing_blank = IS_BLANK(parser->input);
 
         /* Check if we need to fold the leading line break. */
 
-        if (!literal && (*leading_break.start == '\n')
+        if (!literal && (*leading_break.buffer == '\n')
                 && !leading_blank && !trailing_blank)
         {
             /* Do we need to join the lines by space? */
 
-            if (*trailing_breaks.start == '\0') {
+            if (*trailing_breaks.buffer == '\0') {
                 if (!STRING_EXTEND(parser, string)) goto error;
-                *(string.pointer ++) = ' ';
+                JOIN_OCTET(string, ' ');
             }
 
@@ -2891,9 +2899,9 @@
         /* Is it a leading whitespace? */
 
-        leading_blank = IS_BLANK(parser->buffer);
+        leading_blank = IS_BLANK(parser->input);
 
         /* Consume the current line. */
 
-        while (!IS_BREAKZ(parser->buffer)) {
+        while (!IS_BREAKZ(parser->input)) {
             if (!READ(parser, string)) goto error;
             if (!CACHE(parser, 1)) goto error;
@@ -2923,5 +2931,5 @@
     /* Create a token. */
 
-    SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
+    SCALAR_TOKEN_INIT(*token, string.buffer, string.pointer,
             literal ? YAML_LITERAL_SCALAR_STYLE : YAML_FOLDED_SCALAR_STYLE,
             start_mark, end_mark);
@@ -2963,5 +2971,5 @@
 
         while ((!*indent || (int)parser->mark.column < *indent)
-                && IS_SPACE(parser->buffer)) {
+                && IS_SPACE(parser->input)) {
             SKIP(parser);
             if (!CACHE(parser, 1)) return 0;
@@ -2974,12 +2982,14 @@
 
         if ((!*indent || (int)parser->mark.column < *indent)
-                && IS_TAB(parser->buffer)) {
-            return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-                    start_mark, "found a tab character where an intendation space is expected");
+                && IS_TAB(parser->input)) {
+            return SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                    "while scanning a block scalar", start_mark,
+                    "found a tab character where an intendation space is expected",
+                    parser->mark);
         }
 
         /* Have we found a non-empty line? */
 
-        if (!IS_BREAK(parser->buffer)) break;
+        if (!IS_BREAK(parser->input)) break;
 
         /* Consume the line break. */
@@ -3019,8 +3029,12 @@
     int leading_blanks;
 
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error;
+    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+        goto error;
+    if (!STRING_INIT(parser, leading_break, INITIAL_STRING_CAPACITY))
+        goto error;
+    if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_CAPACITY))
+        goto error;
+    if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_CAPACITY))
+        goto error;
 
     /* Eat the left quote. */
@@ -3039,14 +3053,15 @@
 
         if (parser->mark.column == 0 &&
-            ((CHECK_AT(parser->buffer, '-', 0) &&
-              CHECK_AT(parser->buffer, '-', 1) &&
-              CHECK_AT(parser->buffer, '-', 2)) ||
-             (CHECK_AT(parser->buffer, '.', 0) &&
-              CHECK_AT(parser->buffer, '.', 1) &&
-              CHECK_AT(parser->buffer, '.', 2))) &&
-            IS_BLANKZ_AT(parser->buffer, 3))
+            ((CHECK_AT(parser->input, '-', 0) &&
+              CHECK_AT(parser->input, '-', 1) &&
+              CHECK_AT(parser->input, '-', 2)) ||
+             (CHECK_AT(parser->input, '.', 0) &&
+              CHECK_AT(parser->input, '.', 1) &&
+              CHECK_AT(parser->input, '.', 2))) &&
+            IS_BLANKZ_AT(parser->input, 3))
         {
-            yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
-                    start_mark, "found unexpected document indicator");
+            SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                    "while scanning a quoted scalar", start_mark,
+                    "found unexpected document indicator", parser->mark);
             goto error;
         }
@@ -3054,7 +3069,8 @@
         /* Check for EOF. */
 
-        if (IS_Z(parser->buffer)) {
-            yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
-                    start_mark, "found unexpected end of stream");
+        if (IS_Z(parser->input)) {
+            SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                    "while scanning a quoted scalar", start_mark,
+                    "found unexpected end of stream", parser->mark);
             goto error;
         }
@@ -3066,13 +3082,13 @@
         leading_blanks = 0;
 
-        while (!IS_BLANKZ(parser->buffer))
+        while (!IS_BLANKZ(parser->input))
         {
             /* Check for an escaped single quote. */
 
-            if (single && CHECK_AT(parser->buffer, '\'', 0)
-                    && CHECK_AT(parser->buffer, '\'', 1))
+            if (single && CHECK_AT(parser->input, '\'', 0)
+                    && CHECK_AT(parser->input, '\'', 1))
             {
                 if (!STRING_EXTEND(parser, string)) goto error;
-                *(string.pointer++) = '\'';
+                JOIN_OCTET(string, '\'');
                 SKIP(parser);
                 SKIP(parser);
@@ -3081,5 +3097,5 @@
             /* Check for the right quote. */
 
-            else if (CHECK(parser->buffer, single ? '\'' : '"'))
+            else if (CHECK(parser->input, single ? '\'' : '"'))
             {
                 break;
@@ -3088,6 +3104,6 @@
             /* Check for an escaped line break. */
 
-            else if (!single && CHECK(parser->buffer, '\\')
-                    && IS_BREAK_AT(parser->buffer, 1))
+            else if (!single && CHECK(parser->input, '\\')
+                    && IS_BREAK_AT(parser->input, 1))
             {
                 if (!CACHE(parser, 3)) goto error;
@@ -3100,5 +3116,5 @@
             /* Check for an escape sequence. */
 
-            else if (!single && CHECK(parser->buffer, '\\'))
+            else if (!single && CHECK(parser->input, '\\'))
             {
                 size_t code_length = 0;
@@ -3108,79 +3124,79 @@
                 /* Check the escape character. */
 
-                switch (parser->buffer.pointer[1])
+                switch (OCTET_AT(parser->input, 1))
                 {
                     case '0':
-                        *(string.pointer++) = '\0';
+                        JOIN_OCTET(string, '\0');
                         break;
 
                     case 'a':
-                        *(string.pointer++) = '\x07';
+                        JOIN_OCTET(string, '\x07');
                         break;
 
                     case 'b':
-                        *(string.pointer++) = '\x08';
+                        JOIN_OCTET(string, '\x08');
                         break;
 
                     case 't':
                     case '\t':
-                        *(string.pointer++) = '\x09';
+                        JOIN_OCTET(string, '\x09');
                         break;
 
                     case 'n':
-                        *(string.pointer++) = '\x0A';
+                        JOIN_OCTET(string, '\x0A');
                         break;
 
                     case 'v':
-                        *(string.pointer++) = '\x0B';
+                        JOIN_OCTET(string, '\x0B');
                         break;
 
                     case 'f':
-                        *(string.pointer++) = '\x0C';
+                        JOIN_OCTET(string, '\x0C');
                         break;
 
                     case 'r':
-                        *(string.pointer++) = '\x0D';
+                        JOIN_OCTET(string, '\x0D');
                         break;
 
                     case 'e':
-                        *(string.pointer++) = '\x1B';
+                        JOIN_OCTET(string, '\x1B');
                         break;
 
                     case ' ':
-                        *(string.pointer++) = '\x20';
+                        JOIN_OCTET(string, '\x20');
                         break;
 
                     case '"':
-                        *(string.pointer++) = '"';
+                        JOIN_OCTET(string, '"');
                         break;
 
                     case '\'':
-                        *(string.pointer++) = '\'';
+                        JOIN_OCTET(string, '\'');
                         break;
 
                     case '\\':
-                        *(string.pointer++) = '\\';
+                        JOIN_OCTET(string, '\\');
                         break;
 
                     case 'N':   /* NEL (#x85) */
-                        *(string.pointer++) = '\xC2';
-                        *(string.pointer++) = '\x85';
+                        JOIN_OCTET(string, '\xC2');
+                        JOIN_OCTET(string, '\x85');
                         break;
 
                     case '_':   /* #xA0 */
-                        *(string.pointer++) = '\xC2';
-                        *(string.pointer++) = '\xA0';
+                        JOIN_OCTET(string, '\xC2');
+                        JOIN_OCTET(string, '\xA0');
                         break;
 
                     case 'L':   /* LS (#x2028) */
-                        *(string.pointer++) = '\xE2';
-                        *(string.pointer++) = '\x80';
-                        *(string.pointer++) = '\xA8';
+                        JOIN_OCTET(string, '\xE2');
+                        JOIN_OCTET(string, '\x80');
+                        JOIN_OCTET(string, '\xA8');
                         break;
 
                     case 'P':   /* PS (#x2029) */
-                        *(string.pointer++) = '\xE2';
-                        *(string.pointer++) = '\x80';
-                        *(string.pointer++) = '\xA9';
+                        JOIN_OCTET(string, '\xE2');
+                        JOIN_OCTET(string, '\x80');
+                        JOIN_OCTET(string, '\xA9');
                         break;
 
@@ -3198,6 +3214,7 @@
 
                     default:
-                        yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
-                                start_mark, "found unknown escape character");
+                        SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                                "while parsing a quoted scalar", start_mark,
+                                "found unknown escape character", parser->mark);
                         goto error;
                 }
@@ -3211,5 +3228,5 @@
                 {
                     unsigned int value = 0;
-                    size_t k;
+                    size_t idx;
 
                     /* Scan the character value. */
@@ -3217,11 +3234,13 @@
                     if (!CACHE(parser, code_length)) goto error;
 
-                    for (k = 0; k < code_length; k ++) {
-                        if (!IS_HEX_AT(parser->buffer, k)) {
-                            yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
-                                    start_mark, "did not find expected hexdecimal number");
+                    for (idx = 0; idx < code_length; idx ++) {
+                        if (!IS_HEX_AT(parser->input, idx)) {
+                            SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                                    "while parsing a quoted scalar", start_mark,
+                                    "did not find expected hexdecimal number",
+                                    parser->mark);
                             goto error;
                         }
-                        value = (value << 4) + AS_HEX_AT(parser->buffer, k);
+                        value = (value << 4) + AS_HEX_AT(parser->input, idx);
                     }
 
@@ -3229,31 +3248,33 @@
 
                     if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
-                        yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
-                                start_mark, "found invalid Unicode character escape code");
+                        SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                                "while parsing a quoted scalar", start_mark,
+                                "found invalid Unicode character escape code",
+                                parser->mark);
                         goto error;
                     }
 
                     if (value <= 0x7F) {
-                        *(string.pointer++) = value;
+                        JOIN_OCTET(string, value);
                     }
                     else if (value <= 0x7FF) {
-                        *(string.pointer++) = 0xC0 + (value >> 6);
-                        *(string.pointer++) = 0x80 + (value & 0x3F);
+                        JOIN_OCTET(string, 0xC0 + (value >> 6));
+                        JOIN_OCTET(string, 0x80 + (value & 0x3F));
                     }
                     else if (value <= 0xFFFF) {
-                        *(string.pointer++) = 0xE0 + (value >> 12);
-                        *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F);
-                        *(string.pointer++) = 0x80 + (value & 0x3F);
+                        JOIN_OCTET(string, 0xE0 + (value >> 12));
+                        JOIN_OCTET(string, 0x80 + ((value >> 6) & 0x3F));
+                        JOIN_OCTET(string, 0x80 + (value & 0x3F));
                     }
                     else {
-                        *(string.pointer++) = 0xF0 + (value >> 18);
-                        *(string.pointer++) = 0x80 + ((value >> 12) & 0x3F);
-                        *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F);
-                        *(string.pointer++) = 0x80 + (value & 0x3F);
+                        JOIN_OCTET(string, 0xF0 + (value >> 18));
+                        JOIN_OCTET(string, 0x80 + ((value >> 12) & 0x3F));
+                        JOIN_OCTET(string, 0x80 + ((value >> 6) & 0x3F));
+                        JOIN_OCTET(string, 0x80 + (value & 0x3F));
                     }
 
                     /* Advance the pointer. */
 
-                    for (k = 0; k < code_length; k ++) {
+                    for (idx = 0; idx < code_length; idx ++) {
                         SKIP(parser);
                     }
@@ -3273,5 +3294,5 @@
         /* Check if we are at the end of the scalar. */
 
-        if (CHECK(parser->buffer, single ? '\'' : '"'))
+        if (CHECK(parser->input, single ? '\'' : '"'))
             break;
 
@@ -3280,7 +3301,7 @@
         if (!CACHE(parser, 1)) goto error;
 
-        while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))
+        while (IS_BLANK(parser->input) || IS_BREAK(parser->input))
         {
-            if (IS_BLANK(parser->buffer))
+            if (IS_BLANK(parser->input))
             {
                 /* Consume a space or a tab character. */
@@ -3319,8 +3340,8 @@
             /* Do we need to fold line breaks? */
 
-            if (leading_break.start[0] == '\n') {
-                if (trailing_breaks.start[0] == '\0') {
+            if (leading_break.buffer[0] == '\n') {
+                if (trailing_breaks.buffer[0] == '\0') {
                     if (!STRING_EXTEND(parser, string)) goto error;
-                    *(string.pointer++) = ' ';
+                    JOIN_OCTET(string, ' ');
                 }
                 else {
@@ -3352,5 +3373,5 @@
     /* Create a token. */
 
-    SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
+    SCALAR_TOKEN_INIT(*token, string.buffer, string.pointer,
             single ? YAML_SINGLE_QUOTED_SCALAR_STYLE : YAML_DOUBLE_QUOTED_SCALAR_STYLE,
             start_mark, end_mark);
@@ -3387,8 +3408,12 @@
     int indent = parser->indent+1;
 
-    if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
-    if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error;
+    if (!STRING_INIT(parser, string, INITIAL_STRING_CAPACITY))
+        goto error;
+    if (!STRING_INIT(parser, leading_break, INITIAL_STRING_CAPACITY))
+        goto error;
+    if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_CAPACITY))
+        goto error;
+    if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_CAPACITY))
+        goto error;
 
     start_mark = end_mark = parser->mark;
@@ -3403,28 +3428,29 @@
 
         if (parser->mark.column == 0 &&
-            ((CHECK_AT(parser->buffer, '-', 0) &&
-              CHECK_AT(parser->buffer, '-', 1) &&
-              CHECK_AT(parser->buffer, '-', 2)) ||
-             (CHECK_AT(parser->buffer, '.', 0) &&
-              CHECK_AT(parser->buffer, '.', 1) &&
-              CHECK_AT(parser->buffer, '.', 2))) &&
-            IS_BLANKZ_AT(parser->buffer, 3)) break;
+            ((CHECK_AT(parser->input, '-', 0) &&
+              CHECK_AT(parser->input, '-', 1) &&
+              CHECK_AT(parser->input, '-', 2)) ||
+             (CHECK_AT(parser->input, '.', 0) &&
+              CHECK_AT(parser->input, '.', 1) &&
+              CHECK_AT(parser->input, '.', 2))) &&
+            IS_BLANKZ_AT(parser->input, 3)) break;
 
         /* Check for a comment. */
 
-        if (CHECK(parser->buffer, '#'))
+        if (CHECK(parser->input, '#'))
             break;
 
         /* Consume non-blank characters. */
 
-        while (!IS_BLANKZ(parser->buffer))
+        while (!IS_BLANKZ(parser->input))
         {
             /* Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". */
 
             if (parser->flow_level
-                    && CHECK(parser->buffer, ':')
-                    && !IS_BLANKZ_AT(parser->buffer, 1)) {
-                yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
-                        start_mark, "found unexpected ':'");
+                    && CHECK(parser->input, ':')
+                    && !IS_BLANKZ_AT(parser->input, 1)) {
+                SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                        "while scanning a plain scalar", start_mark,
+                        "found unexpected ':'", parser->mark);
                 goto error;
             }
@@ -3432,15 +3458,15 @@
             /* Check for indicators that may end a plain scalar. */
 
-            if ((CHECK(parser->buffer, ':') && IS_BLANKZ_AT(parser->buffer, 1))
+            if ((CHECK(parser->input, ':') && IS_BLANKZ_AT(parser->input, 1))
                     || (parser->flow_level &&
-                        (CHECK(parser->buffer, ',') || CHECK(parser->buffer, ':')
-                         || CHECK(parser->buffer, '?') || CHECK(parser->buffer, '[')
-                         || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
-                         || CHECK(parser->buffer, '}'))))
+                        (CHECK(parser->input, ',') || CHECK(parser->input, ':')
+                         || CHECK(parser->input, '?') || CHECK(parser->input, '[')
+                         || CHECK(parser->input, ']') || CHECK(parser->input, '{')
+                         || CHECK(parser->input, '}'))))
                 break;
 
             /* Check if we need to join whitespaces and breaks. */
 
-            if (leading_blanks || whitespaces.start != whitespaces.pointer)
+            if (leading_blanks || whitespaces.pointer > 0)
             {
                 if (leading_blanks)
@@ -3448,8 +3474,8 @@
                     /* Do we need to fold line breaks? */
 
-                    if (leading_break.start[0] == '\n') {
-                        if (trailing_breaks.start[0] == '\0') {
+                    if (leading_break.buffer[0] == '\n') {
+                        if (trailing_breaks.buffer[0] == '\0') {
                             if (!STRING_EXTEND(parser, string)) goto error;
-                            *(string.pointer++) = ' ';
+                            JOIN_OCTET(string, ' ');
                         }
                         else {
@@ -3486,5 +3512,5 @@
         /* Is it the end? */
 
-        if (!(IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer)))
+        if (!(IS_BLANK(parser->input) || IS_BREAK(parser->input)))
             break;
 
@@ -3493,14 +3519,16 @@
         if (!CACHE(parser, 1)) goto error;
 
-        while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))
+        while (IS_BLANK(parser->input) || IS_BREAK(parser->input))
         {
-            if (IS_BLANK(parser->buffer))
+            if (IS_BLANK(parser->input))
             {
                 /* Check for tab character that abuse intendation. */
 
                 if (leading_blanks && (int)parser->mark.column < indent
-                        && IS_TAB(parser->buffer)) {
-                    yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
-                            start_mark, "found a tab character that violate intendation");
+                        && IS_TAB(parser->input)) {
+                    SCANNER_ERROR_WITH_CONTEXT_INIT(parser,
+                            "while scanning a plain scalar", start_mark,
+                            "found a tab character that violate intendation",
+                            parser->mark);
                     goto error;
                 }
@@ -3543,11 +3571,11 @@
     /* Create a token. */
 
-    SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
+    SCALAR_TOKEN_INIT(*token, string.buffer, string.pointer,
             YAML_PLAIN_SCALAR_STYLE, start_mark, end_mark);
 
-    /* Note that we change the 'simple_key_allowed' flag. */
+    /* Note that we change the 'is_simple_key_allowed' flag. */
 
     if (leading_blanks) {
-        parser->simple_key_allowed = 1;
+        parser->is_simple_key_allowed = 1;
     }
 
Index: /libyaml/trunk/src/dumper.c
===================================================================
--- /libyaml/trunk/src/dumper.c	(revision 238)
+++ /libyaml/trunk/src/dumper.c	(revision 263)
@@ -1,4 +1,6 @@
 
 #include "yaml_private.h"
+
+#if 0
 
 /*
@@ -393,2 +395,4 @@
 }
 
+#endif
+
Index: /libyaml/trunk/src/parser.c
===================================================================
--- /libyaml/trunk/src/parser.c	(revision 250)
+++ /libyaml/trunk/src/parser.c	(revision 263)
@@ -47,6 +47,6 @@
 
 #define PEEK_TOKEN(parser)                                                      \
-    ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ?       \
-        parser->tokens.head : NULL)
+    ((parser->is_token_available || yaml_parser_fetch_more_tokens(parser)) ?    \
+        parser->tokens.list + parser->tokens.head : NULL)
 
 /*
@@ -55,8 +55,8 @@
 
 #define SKIP_TOKEN(parser)                                                      \
-    (parser->token_available = 0,                                               \
+    (parser->is_token_available = 0,                                            \
      parser->tokens_parsed ++,                                                  \
-     parser->stream_end_produced =                                              \
-        (parser->tokens.head->type == YAML_STREAM_END_TOKEN),                   \
+     parser->is_stream_end_produced =                                           \
+        (parser->tokens.list[parser->tokens.head].type == YAML_STREAM_END_TOKEN),   \
      parser->tokens.head ++)
 
@@ -69,17 +69,4 @@
 
 /*
- * Error handling.
- */
-
-static int
-yaml_parser_set_parser_error(yaml_parser_t *parser,
-        const char *problem, yaml_mark_t problem_mark);
-
-static int
-yaml_parser_set_parser_error_context(yaml_parser_t *parser,
-        const char *context, yaml_mark_t context_mark,
-        const char *problem, yaml_mark_t problem_mark);
-
-/*
  * State functions.
  */
@@ -156,6 +143,7 @@
 yaml_parser_process_directives(yaml_parser_t *parser,
         yaml_version_directive_t **version_directive_ref,
-        yaml_tag_directive_t **tag_directives_start_ref,
-        yaml_tag_directive_t **tag_directives_end_ref);
+        yaml_tag_directive_t **tag_directives_list_ref,
+        size_t *tag_directives_length_ref,
+        size_t *tag_directives_capacity_ref);
 
 static int
@@ -179,6 +167,6 @@
     /* No events after the end of the stream or error. */
 
-    if (parser->stream_end_produced || parser->error ||
-            parser->state == YAML_PARSE_END_STATE) {
+    if (parser->is_stream_end_produced || parser->error.type
+            || parser->state == YAML_PARSE_END_STATE) {
         return 1;
     }
@@ -188,34 +176,4 @@
     return yaml_parser_state_machine(parser, event);
 }
-
-/*
- * Set parser error.
- */
-
-static int
-yaml_parser_set_parser_error(yaml_parser_t *parser,
-        const char *problem, yaml_mark_t problem_mark)
-{
-    parser->error = YAML_PARSER_ERROR;
-    parser->problem = problem;
-    parser->problem_mark = problem_mark;
-
-    return 0;
-}
-
-static int
-yaml_parser_set_parser_error_context(yaml_parser_t *parser,
-        const char *context, yaml_mark_t context_mark,
-        const char *problem, yaml_mark_t problem_mark)
-{
-    parser->error = YAML_PARSER_ERROR;
-    parser->context = context;
-    parser->context_mark = context_mark;
-    parser->problem = problem;
-    parser->problem_mark = problem_mark;
-
-    return 0;
-}
-
 
 /*
@@ -319,5 +277,5 @@
 
     if (token->type != YAML_STREAM_START_TOKEN) {
-        return yaml_parser_set_parser_error(parser,
+        return PARSER_ERROR_INIT(parser,
                 "did not found expected <stream-start>", token->start_mark);
     }
@@ -346,7 +304,8 @@
     yaml_version_directive_t *version_directive = NULL;
     struct {
-        yaml_tag_directive_t *start;
-        yaml_tag_directive_t *end;
-    } tag_directives = { NULL, NULL };
+        yaml_tag_directive_t *list;
+        size_t length;
+        size_t capacity;
+    } tag_directives = { NULL, 0, 0 };
 
     token = PEEK_TOKEN(parser);
@@ -371,10 +330,10 @@
             token->type != YAML_STREAM_END_TOKEN)
     {
-        if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
+        if (!yaml_parser_process_directives(parser, NULL, NULL, NULL, NULL))
             return 0;
         if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
             return 0;
         parser->state = YAML_PARSE_BLOCK_NODE_STATE;
-        DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
+        DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, 0, 0, 1,
                 token->start_mark, token->start_mark);
         return 1;
@@ -388,10 +347,11 @@
         start_mark = token->start_mark;
         if (!yaml_parser_process_directives(parser, &version_directive,
-                    &tag_directives.start, &tag_directives.end))
+                    &tag_directives.list, &tag_directives.length,
+                    &tag_directives.capacity))
             return 0;
         token = PEEK_TOKEN(parser);
         if (!token) goto error;
         if (token->type != YAML_DOCUMENT_START_TOKEN) {
-            yaml_parser_set_parser_error(parser,
+            PARSER_ERROR_INIT(parser,
                     "did not found expected <document start>", token->start_mark);
             goto error;
@@ -402,9 +362,11 @@
         end_mark = token->end_mark;
         DOCUMENT_START_EVENT_INIT(*event, version_directive,
-                tag_directives.start, tag_directives.end, 0,
+                tag_directives.list, tag_directives.length,
+                tag_directives.capacity, 0,
                 start_mark, end_mark);
         SKIP_TOKEN(parser);
         version_directive = NULL;
-        tag_directives.start = tag_directives.end = NULL;
+        tag_directives.list = NULL;
+        tag_directives.length = tag_directives.capacity = 0;
         return 1;
     }
@@ -422,10 +384,10 @@
 error:
     yaml_free(version_directive);
-    while (tag_directives.start != tag_directives.end) {
-        yaml_free(tag_directives.end[-1].handle);
-        yaml_free(tag_directives.end[-1].prefix);
-        tag_directives.end --;
-    }
-    yaml_free(tag_directives.start);
+    while (!STACK_EMPTY(parser, tag_directives)) {
+        yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
+        yaml_free(tag_directive.handle);
+        yaml_free(tag_directive.prefix);
+    }
+    STACK_DEL(parser, tag_directives);
     return 0;
 }
@@ -599,8 +561,7 @@
             }
             else {
-                yaml_tag_directive_t *tag_directive;
-                for (tag_directive = parser->tag_directives.start;
-                        tag_directive != parser->tag_directives.top;
-                        tag_directive ++) {
+                int idx;
+                for (idx = 0; idx < parser->tag_directives.length; idx++) {
+                    yaml_tag_directive_t *tag_directive = parser->tag_directives.list + idx;
                     if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
                         size_t prefix_len = strlen((char *)tag_directive->prefix);
@@ -608,5 +569,5 @@
                         tag = yaml_malloc(prefix_len+suffix_len+1);
                         if (!tag) {
-                            parser->error = YAML_MEMORY_ERROR;
+                            MEMORY_ERROR_INIT(parser);
                             goto error;
                         }
@@ -621,5 +582,5 @@
                 }
                 if (!tag) {
-                    yaml_parser_set_parser_error_context(parser,
+                    PARSER_ERROR_WITH_CONTEXT_INIT(parser,
                             "while parsing a node", start_mark,
                             "found undefined tag handle", tag_mark);
@@ -688,5 +649,5 @@
                 yaml_char_t *value = yaml_malloc(1);
                 if (!value) {
-                    parser->error = YAML_MEMORY_ERROR;
+                    MEMORY_ERROR_INIT(parser);
                     goto error;
                 }
@@ -699,5 +660,5 @@
             }
             else {
-                yaml_parser_set_parser_error_context(parser,
+                PARSER_ERROR_WITH_CONTEXT_INIT(parser,
                         (block ? "while parsing a block node"
                          : "while parsing a flow node"), start_mark,
@@ -770,5 +731,5 @@
     else
     {
-        return yaml_parser_set_parser_error_context(parser,
+        return PARSER_ERROR_WITH_CONTEXT_INIT(parser,
                 "while parsing a block collection", POP(parser, parser->marks),
                 "did not found expected '-' indicator", token->start_mark);
@@ -880,5 +841,5 @@
     else
     {
-        return yaml_parser_set_parser_error_context(parser,
+        return PARSER_ERROR_WITH_CONTEXT_INIT(parser,
                 "while parsing a block mapping", POP(parser, parser->marks),
                 "did not found expected key", token->start_mark);
@@ -974,5 +935,5 @@
             }
             else {
-                return yaml_parser_set_parser_error_context(parser,
+                return PARSER_ERROR_WITH_CONTEXT_INIT(parser,
                         "while parsing a flow sequence", POP(parser, parser->marks),
                         "did not found expected ',' or ']'", token->start_mark);
@@ -1126,5 +1087,5 @@
             }
             else {
-                return yaml_parser_set_parser_error_context(parser,
+                return PARSER_ERROR_WITH_CONTEXT_INIT(parser,
                         "while parsing a flow mapping", POP(parser, parser->marks),
                         "did not found expected ',' or '}'", token->start_mark);
@@ -1215,6 +1176,5 @@
     value = yaml_malloc(1);
     if (!value) {
-        parser->error = YAML_MEMORY_ERROR;
-        return 0;
+        return MEMORY_ERROR_INIT(parser);
     }
     value[0] = '\0';
@@ -1233,6 +1193,7 @@
 yaml_parser_process_directives(yaml_parser_t *parser,
         yaml_version_directive_t **version_directive_ref,
-        yaml_tag_directive_t **tag_directives_start_ref,
-        yaml_tag_directive_t **tag_directives_end_ref)
+        yaml_tag_directive_t **tag_directives_list_ref,
+        size_t *tag_directives_length_ref,
+        size_t *tag_directives_capacity_ref)
 {
     yaml_tag_directive_t default_tag_directives[] = {
@@ -1244,11 +1205,11 @@
     yaml_version_directive_t *version_directive = NULL;
     struct {
-        yaml_tag_directive_t *start;
-        yaml_tag_directive_t *end;
-        yaml_tag_directive_t *top;
-    } tag_directives = { NULL, NULL, NULL };
-    yaml_token_t *token;
-
-    if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
+        yaml_tag_directive_t *list;
+        size_t length;
+        size_t capacity;
+    } tag_directives = { NULL, 0, 0 };
+    yaml_token_t *token;
+
+    if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_CAPACITY))
         goto error;
 
@@ -1261,5 +1222,5 @@
         if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
             if (version_directive) {
-                yaml_parser_set_parser_error(parser,
+                PARSER_ERROR_INIT(parser,
                         "found duplicate %YAML directive", token->start_mark);
                 goto error;
@@ -1267,5 +1228,5 @@
             if (token->data.version_directive.major != 1
                     || token->data.version_directive.minor != 1) {
-                yaml_parser_set_parser_error(parser,
+                PARSER_ERROR_INIT(parser,
                         "found incompatible YAML document", token->start_mark);
                 goto error;
@@ -1273,5 +1234,5 @@
             version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
             if (!version_directive) {
-                parser->error = YAML_MEMORY_ERROR;
+                MEMORY_ERROR_INIT(parser);
                 goto error;
             }
@@ -1307,12 +1268,15 @@
         *version_directive_ref = version_directive;
     }
-    if (tag_directives_start_ref) {
+    if (tag_directives_list_ref) {
         if (STACK_EMPTY(parser, tag_directives)) {
-            *tag_directives_start_ref = *tag_directives_end_ref = NULL;
+            *tag_directives_list_ref = NULL;
+            *tag_directives_length_ref = 0;
+            *tag_directives_capacity_ref = 0;
             STACK_DEL(parser, tag_directives);
         }
         else {
-            *tag_directives_start_ref = tag_directives.start;
-            *tag_directives_end_ref = tag_directives.top;
+            *tag_directives_list_ref = tag_directives.list;
+            *tag_directives_length_ref = tag_directives.length;
+            *tag_directives_capacity_ref = tag_directives.capacity;
         }
     }
@@ -1344,11 +1308,12 @@
     yaml_tag_directive_t *tag_directive;
     yaml_tag_directive_t copy = { NULL, NULL };
-
-    for (tag_directive = parser->tag_directives.start;
-            tag_directive != parser->tag_directives.top; tag_directive ++) {
+    int idx;
+
+    for (idx = 0; idx < parser->tag_directives.length; idx++) {
+        yaml_tag_directive_t *tag_directive = parser->tag_directives.list + idx;
         if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
             if (allow_duplicates)
                 return 1;
-            return yaml_parser_set_parser_error(parser,
+            return PARSER_ERROR_INIT(parser,
                     "found duplicate %TAG directive", mark);
         }
@@ -1358,5 +1323,5 @@
     copy.prefix = yaml_strdup(value.prefix);
     if (!copy.handle || !copy.prefix) {
-        parser->error = YAML_MEMORY_ERROR;
+        MEMORY_ERROR_INIT(parser);
         goto error;
     }
Index: /libyaml/trunk/src/writer.c
===================================================================
--- /libyaml/trunk/src/writer.c	(revision 239)
+++ /libyaml/trunk/src/writer.c	(revision 263)
@@ -6,22 +6,6 @@
  */
 
-static int
-yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem);
-
 YAML_DECLARE(int)
 yaml_emitter_flush(yaml_emitter_t *emitter);
-
-/*
- * Set the writer error and return 0.
- */
-
-static int
-yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem)
-{
-    emitter->error = YAML_WRITER_ERROR;
-    emitter->problem = problem;
-
-    return 0;
-}
 
 /*
@@ -35,15 +19,17 @@
 
     assert(emitter);    /* Non-NULL emitter object is expected. */
-    assert(emitter->write_handler); /* Write handler must be set. */
+    assert(emitter->writer);    /* Write handler must be set. */
     assert(emitter->encoding);  /* Output encoding must be set. */
-
-    emitter->buffer.last = emitter->buffer.pointer;
-    emitter->buffer.pointer = emitter->buffer.start;
 
     /* Check if the buffer is empty. */
 
-    if (emitter->buffer.start == emitter->buffer.last) {
+    if (!emitter->output.pointer) {
         return 1;
     }
+
+    /* Switch the pointer to the beginning of the buffer. */
+
+    emitter->output.capacity = emitter->output.pointer;
+    emitter->output.pointer = 0;
 
     /* If the output encoding is UTF-8, we don't need to recode the buffer. */
@@ -51,13 +37,12 @@
     if (emitter->encoding == YAML_UTF8_ENCODING)
     {
-        if (emitter->write_handler(emitter->write_handler_data,
-                    emitter->buffer.start,
-                    emitter->buffer.last - emitter->buffer.start)) {
-            emitter->buffer.last = emitter->buffer.start;
-            emitter->buffer.pointer = emitter->buffer.start;
+        if (emitter->writer(emitter->writer_data,
+                    emitter->output.buffer, emitter->output.capacity)) {
+            emitter->offset += emitter->output.capacity;
+            emitter->output.capacity = OUTPUT_BUFFER_CAPACITY;
             return 1;
         }
         else {
-            return yaml_emitter_set_writer_error(emitter, "Write error");
+            return WRITER_ERROR_INIT(emitter, "Write error", emitter->offset);
         }
     }
@@ -68,10 +53,10 @@
     high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
 
-    while (emitter->buffer.pointer != emitter->buffer.last)
+    while (emitter->output.pointer != emitter->output.capacity)
     {
         unsigned char octet;
         unsigned int width;
         unsigned int value;
-        size_t k;
+        size_t idx;
 
         /* 
@@ -82,5 +67,5 @@
         /* Read the next UTF-8 character. */
 
-        octet = emitter->buffer.pointer[0];
+        octet = OCTET(emitter->output);
 
         width = (octet & 0x80) == 0x00 ? 1 :
@@ -94,10 +79,10 @@
                 (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
 
-        for (k = 1; k < width; k ++) {
-            octet = emitter->buffer.pointer[k];
+        for (idx = 1; idx < width; idx ++) {
+            octet = OCTET_AT(emitter->output, idx);
             value = (value << 6) + (octet & 0x3F);
         }
 
-        emitter->buffer.pointer += width;
+        emitter->output.pointer += width;
 
         /* Write the character. */
@@ -105,8 +90,8 @@
         if (value < 0x10000)
         {
-            emitter->raw_buffer.last[high] = value >> 8;
-            emitter->raw_buffer.last[low] = value & 0xFF;
+            OCTET_AT(emitter->raw_output, high) = value >> 8;
+            OCTET_AT(emitter->raw_output, low) = value & 0xFF;
 
-            emitter->raw_buffer.last += 2;
+            emitter->raw_output.pointer += 2;
         }
         else
@@ -115,10 +100,10 @@
 
             value -= 0x10000;
-            emitter->raw_buffer.last[high] = 0xD8 + (value >> 18);
-            emitter->raw_buffer.last[low] = (value >> 10) & 0xFF;
-            emitter->raw_buffer.last[high+2] = 0xDC + ((value >> 8) & 0xFF);
-            emitter->raw_buffer.last[low+2] = value & 0xFF;
+            OCTET_AT(emitter->raw_output, high) = 0xD8 + (value >> 18);
+            OCTET_AT(emitter->raw_output, low) = (value >> 10) & 0xFF;
+            OCTET_AT(emitter->raw_output, high+2) = 0xDC + ((value >> 8) & 0xFF);
+            OCTET_AT(emitter->raw_output, low+2) = value & 0xFF;
 
-            emitter->raw_buffer.last += 4;
+            emitter->raw_output.pointer += 4;
         }
     }
@@ -126,15 +111,14 @@
     /* Write the raw buffer. */
 
-    if (emitter->write_handler(emitter->write_handler_data,
-                emitter->raw_buffer.start,
-                emitter->raw_buffer.last - emitter->raw_buffer.start)) {
-        emitter->buffer.last = emitter->buffer.start;
-        emitter->buffer.pointer = emitter->buffer.start;
-        emitter->raw_buffer.last = emitter->raw_buffer.start;
-        emitter->raw_buffer.pointer = emitter->raw_buffer.start;
+    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->offset += emitter->raw_output.pointer;
+        emitter->raw_output.pointer = 0;
         return 1;
     }
     else {
-        return yaml_emitter_set_writer_error(emitter, "Write error");
+        return WRITER_ERROR_INIT(emitter, "Write error", emitter->offset);
     }
 }
Index: /libyaml/trunk/src/yaml_private.h
===================================================================
--- /libyaml/trunk/src/yaml_private.h	(revision 262)
+++ /libyaml/trunk/src/yaml_private.h	(revision 263)
@@ -72,5 +72,5 @@
     (memset(&(error), 0, sizeof(error)),                                        \
      (error).type = (error_type),                                               \
-     (error).type.dumping.problem = (error_problem),                            \
+     (error).data.dumping.problem = (error_problem),                            \
      0)
 
@@ -105,5 +105,5 @@
     WRITING_ERROR_INIT((self)->error,YAML_WRITER_ERROR,problem,offset)
 
-#define EMITTER_ERROR_INIT(self,context,problem)                                \
+#define EMITTER_ERROR_INIT(self,problem)                                        \
     DUMPING_ERROR_INIT((self)->error,YAML_EMITTER_ERROR,problem)
 
@@ -148,20 +148,4 @@
 #define INITIAL_QUEUE_CAPACITY  16
 #define INITIAL_STRING_CAPACITY 16
-
-/*
- * Input/output buffer management.
- */
-
-#define STORAGE_INIT(self,storage,storage_capacity)                             \
-    (((storage).buffer = yaml_malloc(storage_capacity)) ?                       \
-        ((storage).pointer = (storage).length = 0,                              \
-         (buffer).capacity = (storage_capacity)                                 \
-         1) :                                                                   \
-        ((self)->error.type = YAML_MEMORY_ERROR,                                \
-         0))
-
-#define STORAGE_DEL(self,storage)                                               \
-    (yaml_free((storage).buffer),                                               \
-     (storage).pointer = (storage).length = (storage).capacity = 0)
 
 /*
@@ -183,5 +167,5 @@
         yaml_char_t *adj_buffer, size_t adj_pointer, size_t adj_capacity);
 
-#define NULL_STRING { NULL, NULL, NULL }
+#define NULL_STRING { NULL, 0, 0 }
 
 #define STRING(string,capacity)   { (string), 0, (capacity) }
@@ -460,4 +444,11 @@
 
 #define MOVE(string)    ((string).pointer += WIDTH((string)))
+
+/*
+ * Write a single octet and bump the pointer.
+ */
+
+#define JOIN_OCTET(string,octet)                                                \
+    ((string).buffer[(string).pointer++] = (octet))
 
 /*
@@ -864,5 +855,4 @@
         yaml_char_t *buffer;
         size_t pointer;
-        size_t length;
         size_t capacity;
     } input;
@@ -875,5 +865,4 @@
         unsigned char *buffer;
         size_t pointer;
-        size_t length;
         size_t capacity;
     } raw_input;
@@ -1069,5 +1058,4 @@
         yaml_char_t *buffer;
         size_t pointer;
-        size_t length;
         size_t capacity;
     } output;
@@ -1077,7 +1065,9 @@
         yaml_char_t *buffer;
         size_t pointer;
-        size_t length;
         size_t capacity;
     } raw_output;
+
+    /* The offset of the current position (in bytes). */
+    size_t offset;
 
     /* The stream encoding. */
@@ -1151,7 +1141,7 @@
     int column;
     /* If the last character was a whitespace? */
-    int whitespace;
+    int is_whitespace;
     /* If the last character was an indentation character (' ', '-', '?', ':')? */
-    int indention;
+    int is_indention;
 
     /* Anchor analysis. */
Index: /libyaml/trunk/src/reader.c
===================================================================
--- /libyaml/trunk/src/reader.c	(revision 262)
+++ /libyaml/trunk/src/reader.c	(revision 263)
@@ -36,5 +36,5 @@
     /* Ensure that we had enough bytes in the raw buffer. */
 
-    while (!parser->is_eof && parser->raw_input.length < 3) {
+    while (!parser->is_eof && parser->raw_input.capacity < 3) {
         if (!yaml_parser_update_raw_buffer(parser)) {
             return 0;
@@ -44,5 +44,5 @@
     /* Determine the encoding. */
 
-    if (parser->raw_input.length >= 2
+    if (parser->raw_input.capacity >= 2
             && !memcmp(parser->raw_input.buffer, BOM_UTF16LE, 2)) {
         parser->encoding = YAML_UTF16LE_ENCODING;
@@ -50,5 +50,5 @@
         parser->offset = 2;
     }
-    else if (parser->raw_input.length >= 2
+    else if (parser->raw_input.capacity >= 2
             && !memcmp(parser->raw_input.buffer, BOM_UTF16BE, 2)) {
         parser->encoding = YAML_UTF16BE_ENCODING;
@@ -56,5 +56,5 @@
         parser->offset = 2;
     }
-    else if (parser->raw_input.length >= 3
+    else if (parser->raw_input.capacity >= 3
             && !memcmp(parser->raw_input.buffer, BOM_UTF8, 3)) {
         parser->encoding = YAML_UTF8_ENCODING;
@@ -81,5 +81,5 @@
 
     if (parser->raw_input.pointer == 0 &&
-            parser->raw_input.length == parser->raw_input.capacity)
+            parser->raw_input.capacity == RAW_INPUT_BUFFER_CAPACITY)
         return 1;
 
@@ -92,9 +92,10 @@
 
     if (parser->raw_input.pointer > 0 &&
-            parser->raw_input.pointer < parser->raw_input.length) {
+            parser->raw_input.pointer < parser->raw_input.capacity) {
         memmove(parser->raw_input.buffer,
                 parser->raw_input.buffer + parser->raw_input.pointer,
-                parser->raw_input.length - parser->raw_input.pointer);
-    }
+                parser->raw_input.capacity - parser->raw_input.pointer);
+    }
+    parser->raw_input.capacity -= parser->raw_input.pointer;
     parser->raw_input.pointer = 0;
 
@@ -102,10 +103,10 @@
 
     if (!parser->reader(parser->reader_data,
-                parser->raw_input.buffer + parser->raw_input.length,
-                parser->raw_input.capacity - parser->raw_input.length,
+                parser->raw_input.buffer + parser->raw_input.capacity,
+                RAW_INPUT_BUFFER_CAPACITY - parser->raw_input.capacity,
                 &length)) {
         return READER_ERROR_INIT(parser, "Input error", parser->offset);
     }
-    parser->raw_input.length += length;
+    parser->raw_input.capacity += length;
     if (!length) {
         parser->is_eof = 1;
@@ -125,9 +126,11 @@
 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.length)
+    if (parser->is_eof && parser->raw_input.pointer == parser->raw_input.capacity)
         return 1;
 
@@ -147,14 +150,17 @@
 
     if (parser->input.pointer > 0 &&
-            parser->input.pointer < parser->input.length) {
+            parser->input.pointer < parser->input.capacity) {
         memmove(parser->input.buffer,
                 parser->input.buffer + parser->input.pointer,
-                parser->input.length - parser->input.pointer);
-        parser->input.length -= parser->input.pointer;
-        parser->input.pointer = 0;
-    }
-    else if (parser->input.pointer == parser->input.length) {
-        parser->input.pointer = parser->input.length = 0;
-    }
+                parser->input.capacity - parser->input.pointer);
+        parser->input.capacity -= parser->input.pointer;
+    }
+    else if (parser->input.pointer == parser->input.capacity) {
+        parser->input.capacity = 0;
+    }
+
+    /* Set the pointer to the end of the buffer. */
+
+    parser->input.pointer = parser->input.capacity;
 
     /* Fill the buffer until it has enough characters. */
@@ -168,10 +174,8 @@
         /* Decode the raw buffer. */
 
-        while (parser->raw_input.pointer != parser->raw_input.length)
+        while (parser->raw_input.pointer != parser->raw_input.capacity)
         {
-            unsigned char *raw_buffer =
-                parser->raw_input.buffer + parser->raw_input.pointer;
             size_t raw_unread =
-                parser->raw_input.length - parser->raw_input.pointer;
+                parser->raw_input.capacity - parser->raw_input.pointer;
             unsigned int value = 0, value2 = 0;
             int is_incomplete = 0;
@@ -179,5 +183,5 @@
             unsigned int width = 0;
             int low, high;
-            size_t k;
+            size_t idx;
 
             /* Decode the next character. */
@@ -209,5 +213,5 @@
                     /* Determine the length of the UTF-8 sequence. */
 
-                    octet = *raw_buffer;
+                    octet = OCTET(parser->raw_input);
                     width = (octet & 0x80) == 0x00 ? 1 :
                             (octet & 0xE0) == 0xC0 ? 2 :
@@ -243,7 +247,7 @@
                     /* Check and decode the trailing octets. */
 
-                    for (k = 1; k < width; k ++)
+                    for (idx = 1; idx < width; idx ++)
                     {
-                        octet = raw_buffer[k];
+                        octet = OCTET_AT(parser->raw_input, idx);
 
                         /* Check if the octet is valid. */
@@ -252,5 +256,5 @@
                             return DECODER_ERROR_INIT(parser,
                                     "Invalid trailing UTF-8 octet",
-                                    parser->offset+k, octet);
+                                    parser->offset+idx, octet);
 
                         /* Decode the octet. */
@@ -324,5 +328,6 @@
                     /* Get the character. */
 
-                    value = raw_buffer[low] + (raw_buffer[high] << 8);
+                    value = OCTET_AT(parser->raw_input, low)
+                        + (OCTET_AT(parser->raw_input, high) << 8);
 
                     /* Check for unexpected low surrogate area. */
@@ -353,5 +358,6 @@
                         /* Get the next character. */
 
-                        value2 = raw_buffer[low+2] + (raw_buffer[high+2] << 8);
+                        value2 = OCTET_AT(parser->raw_input, low+2)
+                            + (OCTET_AT(parser->raw_input, high+2) << 8);
 
                         /* Check for a low surrogate area. */
@@ -407,23 +413,23 @@
             /* 0000 0000-0000 007F -> 0xxxxxxx */
             if (value <= 0x7F) {
-                parser->input.buffer[parser->input.length++] = value;
+                JOIN_OCTET(parser->input, value);
             }
             /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */
             else if (value <= 0x7FF) {
-                parser->input.buffer[parser->input.length++] = 0xC0 + (value >> 6);
-                parser->input.buffer[parser->input.length++] = 0x80 + (value & 0x3F);
+                JOIN_OCTET(parser->input, 0xC0 + (value >> 6));
+                JOIN_OCTET(parser->input, 0x80 + (value & 0x3F));
             }
             /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
             else if (value <= 0xFFFF) {
-                parser->input.buffer[parser->input.length++] = 0xE0 + (value >> 12);
-                parser->input.buffer[parser->input.length++] = 0x80 + ((value >> 6) & 0x3F);
-                parser->input.buffer[parser->input.length++] = 0x80 + (value & 0x3F);
+                JOIN_OCTET(parser->input, 0xE0 + (value >> 12));
+                JOIN_OCTET(parser->input, 0x80 + ((value >> 6) & 0x3F));
+                JOIN_OCTET(parser->input, 0x80 + (value & 0x3F));
             }
             /* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
             else {
-                parser->input.buffer[parser->input.length++] = 0xF0 + (value >> 18);
-                parser->input.buffer[parser->input.length++] = 0x80 + ((value >> 12) & 0x3F);
-                parser->input.buffer[parser->input.length++] = 0x80 + ((value >> 6) & 0x3F);
-                parser->input.buffer[parser->input.length++] = 0x80 + (value & 0x3F);
+                JOIN_OCTET(parser->input, 0xF0 + (value >> 18));
+                JOIN_OCTET(parser->input, 0x80 + ((value >> 12) & 0x3F));
+                JOIN_OCTET(parser->input, 0x80 + ((value >> 6) & 0x3F));
+                JOIN_OCTET(parser->input, 0x80 + (value & 0x3F));
             }
 
@@ -431,13 +437,18 @@
         }
 
-        /* On EOF, put NUL into the buffer and return. */
+        /* On EOF, put NUL into the buffer and stop. */
 
         if (parser->is_eof) {
-            parser->input.buffer[parser->input.length++] = '\0';
+            JOIN_OCTET(parser->input, '\0');
             parser->unread ++;
-            return 1;
+            break;
         }
 
     }
+    /* 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;
 
     return 1;
