]> mj.ucw.cz Git - libucw.git/blobdiff - ucw-json/parse.c
Released as 6.5.16.
[libucw.git] / ucw-json / parse.c
index f0010788404e830f0667466bf464510d47b97c64..df99ea405196efad68538da24d28ad15073170cc 100644 (file)
@@ -21,17 +21,15 @@ void json_set_input(struct json_context *js, struct fastbuf *in)
 {
   js->in_fb = in;
   js->in_line = 1;
+  js->in_column = 0;
   js->next_char = -1;
   js->next_token = NULL;
   js->in_eof = 0;
-  if (!js->trivial_token)
-    js->trivial_token = json_new_node(js, JSON_INVALID);
 }
 
-// FIXME: Report column as well as line?
 static void NONRET json_parse_error(struct json_context *js, const char *msg)
 {
-  trans_throw("ucw.js.parse", js, "%s at line %u", msg, js->in_line);
+  trans_throw("ucw.json.parse", js, "%s at line %u:%u", msg, js->in_line, js->in_column);
 }
 
 static int json_get_char(struct json_context *js)
@@ -42,9 +40,9 @@ static int json_get_char(struct json_context *js)
       if (c == -2)
        json_parse_error(js, "Malformed UTF-8 character");
       js->in_eof = 1;
-      // FIXME: Reject alternative sequences
       return c;
     }
+  js->in_column++;
   return c;
 }
 
@@ -138,28 +136,30 @@ static struct json_node *json_parse_number(struct json_context *js, int c)
 
 static struct json_node *json_parse_name(struct json_context *js, int c)
 {
-  mp_push(js->pool);
-  char *p = mp_start_noalign(js->pool, 0);
+  char name[16];
+  uint i = 0;
 
   while (c >= 'a' && c <= 'z')
     {
-      p = mp_append_char(js->pool, p, c);
+      if (i < sizeof(name) - 1)
+       name[i++] = c;
       c = json_get_char(js);
     }
+  if (i >= sizeof(name) - 1)
+    json_parse_error(js, "Invalid literal name");
+  name[i] = 0;
   json_unget_char(js, c);
 
-  p = mp_end_string(js->pool, p);
   struct json_node *n;
-  if (!strcmp(p, "null"))
+  if (!strcmp(name, "null"))
     n = json_new_null(js);
-  else if (!strcmp(p, "false"))
+  else if (!strcmp(name, "false"))
     n = json_new_bool(js, 0);
-  else if (!strcmp(p, "true"))
+  else if (!strcmp(name, "true"))
     n = json_new_bool(js, 1);
   else
     json_parse_error(js, "Invalid literal name");
 
-  mp_pop(js->pool);
   return n;
 }
 
@@ -203,7 +203,7 @@ static struct json_node *json_parse_string(struct json_context *js, int c)
          else
            json_parse_error(js, "Invalid private-use character in string");
        }
-      if (unlikely(c > 0xf0000))
+      if (unlikely(c >= 0xf0000))
        {
          if (c > 0x10ffff)
            json_parse_error(js, "Invalid non-Unicode character in string");
@@ -291,7 +291,10 @@ static struct json_node *json_read_token(struct json_context *js)
   while (c == 0x20 || c == 0x09 || c == 0x0a || c == 0x0d)
     {
       if (c == 0x0a)
-       js->in_line++;
+       {
+         js->in_line++;
+         js->in_column = 0;
+       }
       c = json_get_char(js);
     }
   if (c < 0)
@@ -320,6 +323,10 @@ static struct json_node *json_read_token(struct json_context *js)
       return json_triv_token(js, JSON_NAME_SEP);
     case ',':
       return json_triv_token(js, JSON_VALUE_SEP);
+    case '.':
+      json_parse_error(js, "Numbers must start with a digit");
+    case 0xfeff:
+      json_parse_error(js, "Misplaced byte-order mark, complain in Redmond");
     default:
       json_parse_error(js, "Invalid character");
     }
@@ -376,7 +383,7 @@ struct json_node *json_next_value(struct json_context *js)
            if (t->type == JSON_END_ARRAY)
              break;
            if (t->type != JSON_VALUE_SEP)
-             json_parse_error(js, "Comma expected");
+             json_parse_error(js, "Comma or right bracket expected");
          }
        return a;
       }