json: Improve error reporting.
authorBen Pfaff <blp@nicira.com>
Fri, 4 Dec 2009 00:08:34 +0000 (16:08 -0800)
committerBen Pfaff <blp@nicira.com>
Fri, 4 Dec 2009 00:08:34 +0000 (16:08 -0800)
lib/json.c
tests/json.at
tests/ovsdb-log.at

index cdcfba5..c31f418 100644 (file)
@@ -99,6 +99,9 @@ struct json_parser {
     /* Lexical analysis. */
     enum json_lex_state lex_state;
     struct ds buffer;           /* Buffer for accumulating token text. */
+    int line_number;
+    int column_number;
+    int byte_number;
 
     /* Parsing. */
     enum json_parse_state parse_state;
@@ -869,10 +872,18 @@ exit:
 }
 
 static bool
-json_lex_input(struct json_parser *p, int c)
+json_lex_input(struct json_parser *p, unsigned char c)
 {
     struct json_token token;
 
+    p->byte_number++;
+    if (c == '\n') {
+        p->column_number = 0;
+        p->line_number++;
+    } else {
+        p->column_number++;
+    }
+
     switch (p->lex_state) {
     case JSON_LEX_START:
         switch (c) {
@@ -1340,12 +1351,18 @@ static void
 json_error(struct json_parser *p, const char *format, ...)
 {
     if (!p->error) {
+        struct ds msg;
         va_list args;
 
+        ds_init(&msg);
+        ds_put_format(&msg, "line %d, column %d, byte %d: ",
+                      p->line_number, p->column_number, p->byte_number);
         va_start(args, format);
-        p->error = xvasprintf(format, args);
+        ds_put_format_valist(&msg, format, args);
         va_end(args);
 
+        p->error = ds_steal_cstr(&msg);
+
         p->done = true;
     }
 }
index 54d4f8c..3096b26 100644 (file)
@@ -2,15 +2,19 @@ m4_define([JSON_CHECK_POSITIVE],
   [AT_SETUP([$1])
    AT_KEYWORDS([json positive])
    AT_CHECK([printf %s "AS_ESCAPE([$2])" > input])
-   OVS_CHECK_LCOV([test-json $4 input], [0], [$3
-], [])
+   AT_CAPTURE_FILE([input])
+   OVS_CHECK_LCOV([test-json $4 input], [0], [stdout], [])
+   AT_CHECK([cat stdout], [0], [$3
+])
    AT_CLEANUP])
 
 m4_define([JSON_CHECK_NEGATIVE], 
   [AT_SETUP([$1])
    AT_KEYWORDS([json negative])
    AT_CHECK([printf %s "AS_ESCAPE([$2])" > input])
-   OVS_CHECK_LCOV([test-json $4 input], [1], [$3
+   AT_CAPTURE_FILE([input])
+   OVS_CHECK_LCOV([test-json $4 input], [1], [stdout], [])
+   AT_CHECK([[sed 's/^error: [^:]*:/error:/' < stdout]], [0], [$3
 ])
    AT_CLEANUP])
 
@@ -72,7 +76,7 @@ JSON_CHECK_NEGATIVE([null bytes not allowed],
 AT_SETUP([end of input in quoted string])
 AT_KEYWORDS([json negative])
 AT_CHECK([printf '\"xxx' | test-json -], [1],
-  [error: unexpected end of input in quoted string
+  [error: line 0, column 4, byte 4: unexpected end of input in quoted string
 ])
 AT_CLEANUP
 
@@ -259,7 +263,7 @@ JSON_CHECK_NEGATIVE([objects nesting too deep],
 
 AT_SETUP([input may not be empty])
 AT_KEYWORDS([json negative])
-AT_CHECK([test-json /dev/null], [1], [error: empty input stream
+AT_CHECK([test-json /dev/null], [1], [error: line 0, column 0, byte 0: empty input stream
 ])
 AT_CLEANUP
 
index b0c1c97..5a4846c 100644 (file)
@@ -266,7 +266,7 @@ OVS_CHECK_LCOV(
 file: read: [0]
 file: read: [1]
 file: read: [2]
-file: read failed: syntax error: file: 5 bytes starting at offset 228 are not valid JSON (syntax error at beginning of input)
+file: read failed: syntax error: file: 5 bytes starting at offset 228 are not valid JSON (line 1, column 0, byte 5: syntax error at beginning of input)
 file: write:["replacement data"] successful
 ]], [ignore])
 OVS_CHECK_LCOV(