Index: libyaml/trunk/src/scanner.c
===================================================================
--- libyaml/trunk/src/scanner.c	(revision 190)
+++ libyaml/trunk/src/scanner.c	(revision 194)
@@ -1012,8 +1012,10 @@
 
     parser->tokens[parser->tokens_head++] = NULL;
-    if (parser->tokens_head == parser->tokens_size)
-        parser->tokens_head = 0;
 
     parser->tokens_parsed++;
+
+    if (token->type == YAML_STREAM_END_TOKEN) {
+        parser->stream_end_produced = 1;
+    }
 
     return token;
@@ -1081,5 +1083,5 @@
     memset(new_buffer+string->size, 0, string->size);
 
-    string->pointer = new_buffer + (string->buffer-string->pointer);
+    string->pointer = new_buffer + (string->pointer-string->buffer);
     string->buffer = new_buffer;
     string->size *= 2;
@@ -1104,4 +1106,5 @@
 
     memcpy(string1->pointer, string2->buffer, string2->pointer-string2->buffer);
+    string1->pointer += string2->pointer-string2->buffer;
 
     return 1;
@@ -1139,5 +1142,5 @@
     }
 
-    memset(new_buffer+(*size), 0, item_size*(*size));
+    memset(new_buffer+item_size*(*size), 0, item_size*(*size));
 
     *buffer = new_buffer;
@@ -1160,4 +1163,6 @@
     parser->problem = problem;
     parser->problem_mark = yaml_parser_get_mark(parser);
+
+    return 0;
 }
 
@@ -1205,4 +1210,7 @@
         {
             /* Check if any potential simple key may occupy the head position. */
+
+            if (!yaml_parser_stale_simple_keys(parser))
+                return 0;
 
             for (k = 0; k <= parser->flow_level; k++) {
@@ -1252,4 +1260,9 @@
         return 0;
 
+    /* Remove obsolete potential simple keys. */
+
+    if (!yaml_parser_stale_simple_keys(parser))
+        return 0;
+
     /* Check the indentation level against the current column. */
 
@@ -1331,10 +1344,10 @@
     /* Is it the key indicator? */
 
-    if (CHECK(parser, '?') && (!parser->flow_level || IS_BLANKZ_AT(parser, 1)))
+    if (CHECK(parser, '?') && (parser->flow_level || IS_BLANKZ_AT(parser, 1)))
         return yaml_parser_fetch_key(parser);
 
     /* Is it the value indicator? */
 
-    if (CHECK(parser, ':') && (!parser->flow_level || IS_BLANKZ_AT(parser, 1)))
+    if (CHECK(parser, ':') && (parser->flow_level || IS_BLANKZ_AT(parser, 1)))
         return yaml_parser_fetch_value(parser);
 
@@ -1383,5 +1396,6 @@
      *      '%', '@', '`'.
      *
-     * In the block context, it may also start with the characters
+     * In the block context (and, for the '-' indicator, in the flow context
+     * too), it may also start with the characters
      *
      *      '-', '?', ':'
@@ -1399,7 +1413,7 @@
                 || CHECK(parser, '\'') || CHECK(parser, '"') || CHECK(parser, '%')
                 || CHECK(parser, '@') || CHECK(parser, '`')) ||
+            (CHECK(parser, '-') && !IS_BLANK_AT(parser, 1)) ||
             (!parser->flow_level &&
-             (CHECK(parser, '-') || CHECK(parser, '?') || CHECK(parser, ':')) &&
-             IS_BLANKZ_AT(parser, 1)))
+             (CHECK(parser, '?') || CHECK(parser, ':')) && !IS_BLANKZ_AT(parser, 1)))
         return yaml_parser_fetch_plain_scalar(parser);
 
@@ -1436,5 +1450,5 @@
 
         if (simple_key && (simple_key->line < parser->line ||
-                    simple_key->index < parser->index+1024)) {
+                    simple_key->index+1024 < parser->index)) {
 
             /* Check if the potential simple key to be removed is required. */
@@ -1790,7 +1804,10 @@
         return 0;
 
-    /* We have finished. */
-
-    parser->stream_end_produced = 1;
+    /* Reset simple keys. */
+
+    if (!yaml_parser_remove_simple_key(parser))
+        return 0;
+
+    parser->simple_key_allowed = 0;
 
     /* Create the STREAM-END token. */
@@ -2205,5 +2222,5 @@
         /* In the block context, we may need to add the BLOCK-MAPPING-START token. */
 
-        if (!yaml_parser_roll_indent(parser, parser->column,
+        if (!yaml_parser_roll_indent(parser, simple_key->column,
                     simple_key->token_number,
                     YAML_BLOCK_MAPPING_START_TOKEN, simple_key->mark))
@@ -2990,4 +3007,14 @@
             handle[0] = '!';
             handle[1] = '\0';
+
+            /*
+             * A special case: the '!' tag.
+             */
+
+            if (suffix[0] == '\0') {
+                yaml_char_t *tmp = handle;
+                handle = suffix;
+                suffix = tmp;
+            }
         }
     }
@@ -3069,10 +3096,11 @@
     {
         /*
-         * It's not really a tag handle.  If it's a %TAG directive, it's an
-         * error.  If it's a tag token, it must be a part of URI.
+         * It's either the '!' tag or not really a tag handle.  If it's a %TAG
+         * directive, it's an error.  If it's a tag token, it must be a part of
+         * URI.
          */
 
-        if (directive) {
-            yaml_parser_set_scanner_error(parser, "while parsing a directive",
+        if (directive && !(string.buffer[0] == '!' && string.buffer[1] == '\0')) {
+            yaml_parser_set_scanner_error(parser, "while parsing a tag directive",
                     start_mark, "did not find expected '!'");
             goto error;
@@ -3108,9 +3136,13 @@
     }
 
-    /* Copy the head if needed. */
-
-    if (length) {
-        memcpy(string.buffer, head, length);
-        string.pointer += length;
+    /*
+     * Copy the head if needed.
+     *
+     * Note that we don't copy the leading '!' character.
+     */
+
+    if (length > 1) {
+        memcpy(string.buffer, head+1, length-1);
+        string.pointer += length-1;
     }
 
@@ -3673,4 +3705,8 @@
                         break;
 
+                    case '\\':
+                        *(string.pointer++) = '\\';
+                        break;
+
                     case 'N':   /* NEL (#x85) */
                         *(string.pointer++) = '\xC2';
@@ -3692,5 +3728,5 @@
                         *(string.pointer++) = '\xE2';
                         *(string.pointer++) = '\x80';
-                        *(string.pointer++) = '\xA8';
+                        *(string.pointer++) = '\xA9';
                         break;
 
@@ -3801,4 +3837,7 @@
                     COPY(parser, whitespaces);
                 }
+                else {
+                    FORWARD(parser);
+                }
             }
             else
@@ -3932,5 +3971,5 @@
         while (!IS_BLANKZ(parser))
         {
-            /* Check for 'x:x' in the flow context. */
+            /* Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". */
 
             if (parser->flow_level && CHECK(parser, ':') && !IS_BLANKZ_AT(parser, 1)) {
@@ -4011,5 +4050,5 @@
                     yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
                             start_mark, "found a tab character that violate intendation");
-                    break;
+                    goto error;
                 }
 
@@ -4019,4 +4058,7 @@
                     if (!RESIZE(parser, whitespaces)) goto error;
                     COPY(parser, whitespaces);
+                }
+                else {
+                    FORWARD(parser);
                 }
             }
@@ -4044,5 +4086,5 @@
         /* Check intendation level. */
 
-        if (parser->column < indent)
+        if (!parser->flow_level && parser->column < indent)
             break;
     }
