Refactor decoder input stream
authorPetri Lehtinen <petri@digip.org>
Tue, 22 Feb 2011 08:47:02 +0000 (10:47 +0200)
committerPetri Lehtinen <petri@digip.org>
Tue, 22 Feb 2011 10:07:37 +0000 (12:07 +0200)
- Add a new field position to the json_error_t structure. This is the
  position in bytes from the beginning of the input.

- Keep track of line, column and input position in the stream level.
  Previously, only line was tracked, and it was in the lexer level, so
  this info was not available for UTF-8 decoding errors.

- While at it, refactor tests so that no separate "stripped" tests are
  required. json_process is now able to strip whitespace from its
  input, and the "valid" and "invalid" test suites now use this to
  test both non-stripped and stripped input.

Closes GH-9.

245 files changed:
doc/apiref.rst
src/error.c
src/jansson.h
src/jansson_private.h
src/load.c
src/pack_unpack.c
test/bin/json_process.c
test/suites/api/test_pack.c
test/suites/invalid-strip/apostrophe/error [deleted file]
test/suites/invalid-strip/apostrophe/input [deleted file]
test/suites/invalid-strip/ascii-unicode-identifier/error [deleted file]
test/suites/invalid-strip/ascii-unicode-identifier/input [deleted file]
test/suites/invalid-strip/brace-comma/error [deleted file]
test/suites/invalid-strip/brace-comma/input [deleted file]
test/suites/invalid-strip/bracket-comma/error [deleted file]
test/suites/invalid-strip/bracket-comma/input [deleted file]
test/suites/invalid-strip/bracket-one-comma/input [deleted file]
test/suites/invalid-strip/empty/error [deleted file]
test/suites/invalid-strip/empty/input [deleted file]
test/suites/invalid-strip/escaped-null-byte-in-string/error [deleted file]
test/suites/invalid-strip/escaped-null-byte-in-string/input [deleted file]
test/suites/invalid-strip/extra-comma-in-array/input [deleted file]
test/suites/invalid-strip/extra-command-in-multiline-array/error [deleted file]
test/suites/invalid-strip/extra-command-in-multiline-array/input [deleted file]
test/suites/invalid-strip/garbage-after-newline/error [deleted file]
test/suites/invalid-strip/garbage-after-newline/input [deleted file]
test/suites/invalid-strip/garbage-at-the-end/error [deleted file]
test/suites/invalid-strip/garbage-at-the-end/input [deleted file]
test/suites/invalid-strip/integer-starting-with-zero/error [deleted file]
test/suites/invalid-strip/integer-starting-with-zero/input [deleted file]
test/suites/invalid-strip/invalid-escape/error [deleted file]
test/suites/invalid-strip/invalid-escape/input [deleted file]
test/suites/invalid-strip/invalid-identifier/error [deleted file]
test/suites/invalid-strip/invalid-identifier/input [deleted file]
test/suites/invalid-strip/invalid-negative-integerr/input [deleted file]
test/suites/invalid-strip/invalid-negative-real/error [deleted file]
test/suites/invalid-strip/invalid-negative-real/input [deleted file]
test/suites/invalid-strip/invalid-second-surrogate/error [deleted file]
test/suites/invalid-strip/invalid-second-surrogate/input [deleted file]
test/suites/invalid-strip/lone-open-brace/input [deleted file]
test/suites/invalid-strip/lone-open-bracket/input [deleted file]
test/suites/invalid-strip/lone-second-surrogate/error [deleted file]
test/suites/invalid-strip/lone-second-surrogate/input [deleted file]
test/suites/invalid-strip/minus-sign-without-number/error [deleted file]
test/suites/invalid-strip/minus-sign-without-number/input [deleted file]
test/suites/invalid-strip/negative-integer-starting-with-zero/error [deleted file]
test/suites/invalid-strip/negative-integer-starting-with-zero/input [deleted file]
test/suites/invalid-strip/null-byte-in-string/error [deleted file]
test/suites/invalid-strip/null-byte-in-string/input [deleted file]
test/suites/invalid-strip/null-byte-outside-string/error [deleted file]
test/suites/invalid-strip/null-byte-outside-string/input [deleted file]
test/suites/invalid-strip/null/error [deleted file]
test/suites/invalid-strip/null/input [deleted file]
test/suites/invalid-strip/object-apostrophes/error [deleted file]
test/suites/invalid-strip/object-apostrophes/input [deleted file]
test/suites/invalid-strip/object-garbage-at-end/error [deleted file]
test/suites/invalid-strip/object-garbage-at-end/input [deleted file]
test/suites/invalid-strip/object-in-unterminated-array/input [deleted file]
test/suites/invalid-strip/object-no-colon/input [deleted file]
test/suites/invalid-strip/object-no-value/input [deleted file]
test/suites/invalid-strip/object-unterminated-value/input [deleted file]
test/suites/invalid-strip/real-garbage-after-e/error [deleted file]
test/suites/invalid-strip/real-garbage-after-e/input [deleted file]
test/suites/invalid-strip/real-negative-overflow/error [deleted file]
test/suites/invalid-strip/real-negative-overflow/input [deleted file]
test/suites/invalid-strip/real-positive-overflow/error [deleted file]
test/suites/invalid-strip/real-positive-overflow/input [deleted file]
test/suites/invalid-strip/real-truncated-at-e/error [deleted file]
test/suites/invalid-strip/real-truncated-at-e/input [deleted file]
test/suites/invalid-strip/real-truncated-at-point/error [deleted file]
test/suites/invalid-strip/real-truncated-at-point/input [deleted file]
test/suites/invalid-strip/run [deleted file]
test/suites/invalid-strip/tab-character-in-string/error [deleted file]
test/suites/invalid-strip/tab-character-in-string/input [deleted file]
test/suites/invalid-strip/too-big-negative-integer/error [deleted file]
test/suites/invalid-strip/too-big-negative-integer/input [deleted file]
test/suites/invalid-strip/too-big-positive-integer/error [deleted file]
test/suites/invalid-strip/too-big-positive-integer/input [deleted file]
test/suites/invalid-strip/truncated-unicode-surrogate/error [deleted file]
test/suites/invalid-strip/truncated-unicode-surrogate/input [deleted file]
test/suites/invalid-strip/unicode-identifier/error [deleted file]
test/suites/invalid-strip/unicode-identifier/input [deleted file]
test/suites/invalid-strip/unterminated-array-and-object/input [deleted file]
test/suites/invalid-strip/unterminated-array/input [deleted file]
test/suites/invalid-strip/unterminated-empty-key/input [deleted file]
test/suites/invalid-strip/unterminated-key/input [deleted file]
test/suites/invalid-strip/unterminated-object-and-array/error [deleted file]
test/suites/invalid-strip/unterminated-object-and-array/input [deleted file]
test/suites/invalid-strip/unterminated-string/input [deleted file]
test/suites/invalid-unicode/encoded-surrogate-half/error
test/suites/invalid-unicode/invalid-utf-8-after-backslash/error
test/suites/invalid-unicode/invalid-utf-8-in-array/error
test/suites/invalid-unicode/invalid-utf-8-in-bigger-int/error
test/suites/invalid-unicode/invalid-utf-8-in-escape/error
test/suites/invalid-unicode/invalid-utf-8-in-exponent/error
test/suites/invalid-unicode/invalid-utf-8-in-identifier/error
test/suites/invalid-unicode/invalid-utf-8-in-int/error
test/suites/invalid-unicode/invalid-utf-8-in-real-after-e/error
test/suites/invalid-unicode/invalid-utf-8-in-string/error
test/suites/invalid-unicode/lone-invalid-utf-8/error
test/suites/invalid-unicode/lone-utf-8-continuation-byte/error
test/suites/invalid-unicode/not-in-unicode-range/error
test/suites/invalid-unicode/overlong-3-byte-encoding/error
test/suites/invalid-unicode/overlong-4-byte-encoding/error
test/suites/invalid-unicode/overlong-ascii-encoding/error
test/suites/invalid-unicode/restricted-utf-8/error
test/suites/invalid-unicode/truncated-utf-8/error
test/suites/invalid/apostrophe/error
test/suites/invalid/ascii-unicode-identifier/error
test/suites/invalid/brace-comma/error
test/suites/invalid/bracket-comma/error
test/suites/invalid/bracket-one-comma/error [deleted file]
test/suites/invalid/bracket-one-comma/error.normal [moved from test/suites/invalid-strip/bracket-one-comma/error with 83% similarity]
test/suites/invalid/bracket-one-comma/error.strip [moved from test/suites/invalid-strip/lone-open-bracket/error with 83% similarity]
test/suites/invalid/empty/error
test/suites/invalid/escaped-null-byte-in-string/error
test/suites/invalid/extra-comma-in-array/error
test/suites/invalid/extra-comma-in-multiline-array/error [moved from test/suites/invalid-strip/extra-comma-in-array/error with 78% similarity]
test/suites/invalid/extra-comma-in-multiline-array/input [moved from test/suites/invalid/extra-command-in-multiline-array/input with 100% similarity]
test/suites/invalid/extra-command-in-multiline-array/error [deleted file]
test/suites/invalid/garbage-after-newline/error
test/suites/invalid/garbage-at-the-end/error
test/suites/invalid/integer-starting-with-zero/error
test/suites/invalid/invalid-escape/error
test/suites/invalid/invalid-identifier/error
test/suites/invalid/invalid-negative-integer/error [moved from test/suites/invalid-strip/invalid-negative-integerr/error with 80% similarity]
test/suites/invalid/invalid-negative-integer/input [moved from test/suites/invalid/invalid-negative-integerr/input with 100% similarity]
test/suites/invalid/invalid-negative-integerr/error [deleted file]
test/suites/invalid/invalid-negative-real/error
test/suites/invalid/invalid-second-surrogate/error
test/suites/invalid/lone-open-brace/error.normal [moved from test/suites/invalid-strip/lone-open-brace/error with 86% similarity]
test/suites/invalid/lone-open-brace/error.strip [moved from test/suites/invalid-strip/unterminated-array-and-object/error with 86% similarity]
test/suites/invalid/lone-open-bracket/error [deleted file]
test/suites/invalid/lone-open-bracket/error.normal [moved from test/suites/invalid-strip/object-in-unterminated-array/error with 83% similarity]
test/suites/invalid/lone-open-bracket/error.strip [moved from test/suites/invalid-strip/unterminated-array/error with 83% similarity]
test/suites/invalid/lone-second-surrogate/error
test/suites/invalid/minus-sign-without-number/error
test/suites/invalid/negative-integer-starting-with-zero/error
test/suites/invalid/null-byte-in-string/error
test/suites/invalid/null-byte-in-string/nostrip [new file with mode: 0644]
test/suites/invalid/null-byte-outside-string/error
test/suites/invalid/null-byte-outside-string/nostrip [new file with mode: 0644]
test/suites/invalid/null/error
test/suites/invalid/object-apostrophes/error
test/suites/invalid/object-garbage-at-end/error
test/suites/invalid/object-in-unterminated-array/error [deleted file]
test/suites/invalid/object-in-unterminated-array/error.normal [new file with mode: 0644]
test/suites/invalid/object-in-unterminated-array/error.strip [new file with mode: 0644]
test/suites/invalid/object-no-colon/error.normal [moved from test/suites/invalid-strip/object-no-colon/error with 83% similarity]
test/suites/invalid/object-no-colon/error.strip [moved from test/suites/invalid/object-no-colon/error with 83% similarity]
test/suites/invalid/object-no-value/error.normal [moved from test/suites/invalid-strip/object-no-value/error with 85% similarity]
test/suites/invalid/object-no-value/error.strip [moved from test/suites/invalid/object-no-value/error with 85% similarity]
test/suites/invalid/object-unterminated-value/error.normal [moved from test/suites/invalid/object-unterminated-value/error with 82% similarity]
test/suites/invalid/object-unterminated-value/error.strip [moved from test/suites/invalid-strip/object-unterminated-value/error with 84% similarity]
test/suites/invalid/real-garbage-after-e/error
test/suites/invalid/real-negative-overflow/error
test/suites/invalid/real-positive-overflow/error
test/suites/invalid/real-truncated-at-e/error
test/suites/invalid/real-truncated-at-point/error
test/suites/invalid/run
test/suites/invalid/tab-character-in-string/error
test/suites/invalid/too-big-negative-integer/error
test/suites/invalid/too-big-positive-integer/error
test/suites/invalid/truncated-unicode-surrogate/error
test/suites/invalid/unicode-identifier/error
test/suites/invalid/unterminated-array-and-object/error.normal [moved from test/suites/invalid/lone-open-brace/error with 86% similarity]
test/suites/invalid/unterminated-array-and-object/error.strip [moved from test/suites/invalid/unterminated-array-and-object/error with 86% similarity]
test/suites/invalid/unterminated-array/error [deleted file]
test/suites/invalid/unterminated-array/error.normal [new file with mode: 0644]
test/suites/invalid/unterminated-array/error.strip [new file with mode: 0644]
test/suites/invalid/unterminated-empty-key/error.normal [moved from test/suites/invalid/unterminated-empty-key/error with 82% similarity]
test/suites/invalid/unterminated-empty-key/error.strip [moved from test/suites/invalid-strip/unterminated-empty-key/error with 84% similarity]
test/suites/invalid/unterminated-key/error.normal [moved from test/suites/invalid/unterminated-key/error with 82% similarity]
test/suites/invalid/unterminated-key/error.strip [moved from test/suites/invalid-strip/unterminated-key/error with 84% similarity]
test/suites/invalid/unterminated-object-and-array/error
test/suites/invalid/unterminated-string/error.normal [moved from test/suites/invalid/unterminated-string/error with 82% similarity]
test/suites/invalid/unterminated-string/error.strip [moved from test/suites/invalid-strip/unterminated-string/error with 84% similarity]
test/suites/valid-strip/complex-array/input [deleted file]
test/suites/valid-strip/complex-array/output [deleted file]
test/suites/valid-strip/empty-array/input [deleted file]
test/suites/valid-strip/empty-array/output [deleted file]
test/suites/valid-strip/empty-object-in-array/input [deleted file]
test/suites/valid-strip/empty-object-in-array/output [deleted file]
test/suites/valid-strip/empty-object/input [deleted file]
test/suites/valid-strip/empty-object/output [deleted file]
test/suites/valid-strip/empty-string/input [deleted file]
test/suites/valid-strip/empty-string/output [deleted file]
test/suites/valid-strip/escaped-utf-control-char/input [deleted file]
test/suites/valid-strip/escaped-utf-control-char/output [deleted file]
test/suites/valid-strip/false/input [deleted file]
test/suites/valid-strip/false/output [deleted file]
test/suites/valid-strip/negative-int/input [deleted file]
test/suites/valid-strip/negative-int/output [deleted file]
test/suites/valid-strip/negative-one/input [deleted file]
test/suites/valid-strip/negative-one/output [deleted file]
test/suites/valid-strip/negative-zero/input [deleted file]
test/suites/valid-strip/negative-zero/output [deleted file]
test/suites/valid-strip/null/input [deleted file]
test/suites/valid-strip/null/output [deleted file]
test/suites/valid-strip/one-byte-utf-8/input [deleted file]
test/suites/valid-strip/one-byte-utf-8/output [deleted file]
test/suites/valid-strip/real-capital-e-negative-exponent/input [deleted file]
test/suites/valid-strip/real-capital-e-negative-exponent/output [deleted file]
test/suites/valid-strip/real-capital-e-positive-exponent/input [deleted file]
test/suites/valid-strip/real-capital-e-positive-exponent/output [deleted file]
test/suites/valid-strip/real-capital-e/input [deleted file]
test/suites/valid-strip/real-capital-e/output [deleted file]
test/suites/valid-strip/real-exponent/input [deleted file]
test/suites/valid-strip/real-exponent/output [deleted file]
test/suites/valid-strip/real-fraction-exponent/input [deleted file]
test/suites/valid-strip/real-fraction-exponent/output [deleted file]
test/suites/valid-strip/real-negative-exponent/input [deleted file]
test/suites/valid-strip/real-negative-exponent/output [deleted file]
test/suites/valid-strip/real-positive-exponent/input [deleted file]
test/suites/valid-strip/real-positive-exponent/output [deleted file]
test/suites/valid-strip/real-underflow/input [deleted file]
test/suites/valid-strip/real-underflow/output [deleted file]
test/suites/valid-strip/run [deleted file]
test/suites/valid-strip/short-string/input [deleted file]
test/suites/valid-strip/short-string/output [deleted file]
test/suites/valid-strip/simple-ascii-string/input [deleted file]
test/suites/valid-strip/simple-ascii-string/output [deleted file]
test/suites/valid-strip/simple-int-0/input [deleted file]
test/suites/valid-strip/simple-int-0/output [deleted file]
test/suites/valid-strip/simple-int-1/input [deleted file]
test/suites/valid-strip/simple-int-1/output [deleted file]
test/suites/valid-strip/simple-int-123/input [deleted file]
test/suites/valid-strip/simple-int-123/output [deleted file]
test/suites/valid-strip/simple-object/input [deleted file]
test/suites/valid-strip/simple-object/output [deleted file]
test/suites/valid-strip/simple-real/input [deleted file]
test/suites/valid-strip/simple-real/output [deleted file]
test/suites/valid-strip/string-escapes/input [deleted file]
test/suites/valid-strip/string-escapes/output [deleted file]
test/suites/valid-strip/three-byte-utf-8/input [deleted file]
test/suites/valid-strip/three-byte-utf-8/output [deleted file]
test/suites/valid-strip/true/input [deleted file]
test/suites/valid-strip/true/output [deleted file]
test/suites/valid-strip/two-byte-utf-8/input [deleted file]
test/suites/valid-strip/two-byte-utf-8/output [deleted file]
test/suites/valid-strip/utf-8-string/input [deleted file]
test/suites/valid-strip/utf-8-string/output [deleted file]
test/suites/valid-strip/utf-surrogate-four-byte-encoding/input [deleted file]
test/suites/valid-strip/utf-surrogate-four-byte-encoding/output [deleted file]
test/suites/valid/run

index b1d5c07..17af036 100644 (file)
@@ -739,26 +739,31 @@ affect especially the behavior of the decoder.
    This data structure is used to return information on decoding
    errors from the decoding functions.
 
-   .. member:: const char *text
+   .. member:: char text[]
 
       The error message (in UTF-8), or an empty string if a message is
       not available.
 
+   .. member:: char source[]
+
+      Source of the error. This is (a part of) the file name when
+      using :func:`json_load_file()`, or a special identifier in angle
+      brackets otherwise (e.g. ``<string>``).
+
    .. member:: int line
 
-      The line number on which the error occurred, or -1 if this
-      information is not available.
+      The line number on which the error occurred.
 
    .. member:: int column
 
-      The character column on which the error occurred, or -1 if this
-      information is not available.
+      The character column on which the error occurred. Note that this
+      is the *character column*, not the byte column, i.e. a non-ASCII
+      UTF-8 character counts as one column.
 
-   .. member:: const char *source
+   .. member:: size_t position
 
-      Source of the error. This is (a part of) the file name when
-      using :func:`json_load_file()`, or a special identifier in angle
-      brackets otherwise (e.g. ``<string>``).
+      The position in bytes from the start of the input. This is
+      useful for debugging Unicode encoding problems.
 
    The normal use of :type:`json_error_t` is to allocate it on the
    stack, and pass a pointer to a decoding function. Example::
index cd80756..b950c2c 100644 (file)
@@ -8,6 +8,7 @@ void jsonp_error_init(json_error_t *error, const char *source)
         error->text[0] = '\0';
         error->line = -1;
         error->column = -1;
+        error->position = 0;
 
         strncpy(error->source, source, JSON_ERROR_SOURCE_LENGTH);
         error->source[JSON_ERROR_SOURCE_LENGTH - 1] = '\0';
@@ -15,17 +16,17 @@ void jsonp_error_init(json_error_t *error, const char *source)
 }
 
 void jsonp_error_set(json_error_t *error, int line, int column,
-                     const char *msg, ...)
+                     size_t position, const char *msg, ...)
 {
     va_list ap;
 
     va_start(ap, msg);
-    jsonp_error_vset(error, line, column, msg, ap);
+    jsonp_error_vset(error, line, column, position, msg, ap);
     va_end(ap);
 }
 
 void jsonp_error_vset(json_error_t *error, int line, int column,
-                      const char *msg, va_list ap)
+                      size_t position, const char *msg, va_list ap)
 {
     if(!error)
         return;
@@ -37,6 +38,7 @@ void jsonp_error_vset(json_error_t *error, int line, int column,
 
     error->line = line;
     error->column = column;
+    error->position = position;
 
     vsnprintf(error->text, JSON_ERROR_TEXT_LENGTH, msg, ap);
 }
index 6e6e77a..8306e21 100644 (file)
@@ -109,10 +109,11 @@ void json_decref(json_t *json)
 #define JSON_ERROR_SOURCE_LENGTH   80
 
 typedef struct {
-    char text[JSON_ERROR_TEXT_LENGTH];
     int line;
     int column;
+    int position;
     char source[JSON_ERROR_SOURCE_LENGTH];
+    char text[JSON_ERROR_TEXT_LENGTH];
 } json_error_t;
 
 
index 66caad7..b4743f3 100644 (file)
@@ -69,9 +69,9 @@ const object_key_t *jsonp_object_iter_fullkey(void *iter);
 
 void jsonp_error_init(json_error_t *error, const char *source);
 void jsonp_error_set(json_error_t *error, int line, int column,
-                     const char *msg, ...);
+                     size_t position, const char *msg, ...);
 void jsonp_error_vset(json_error_t *error, int line, int column,
-                      const char *msg, va_list ap);
+                      size_t position, const char *msg, va_list ap);
 
 /* Wrappers for custom memory functions */
 void* jsonp_malloc(size_t size);
index f4fb3b7..74e33fc 100644 (file)
 #include "strbuffer.h"
 #include "utf.h"
 
+#define STREAM_STATE_OK        0
+#define STREAM_STATE_EOF      -1
+#define STREAM_STATE_ERROR    -2
+
 #define TOKEN_INVALID         -1
 #define TOKEN_EOF              0
 #define TOKEN_STRING         256
 #define TOKEN_FALSE          260
 #define TOKEN_NULL           261
 
-/* read one byte from stream, return EOF on end of file */
+/* Read one byte from stream, convert to unsigned char, then int, and
+   return. return EOF on end of file. This corresponds to the
+   behaviour of fgetc(). */
 typedef int (*get_func)(void *data);
 
-/* return non-zero if end of file has been reached */
-typedef int (*eof_func)(void *data);
-
 typedef struct {
     get_func get;
-    eof_func eof;
     void *data;
-    int stream_pos;
     char buffer[5];
     int buffer_pos;
+    int state;
+    int line;
+    int column, last_column;
+    size_t position;
 } stream_t;
 
-
 typedef struct {
     stream_t stream;
     strbuffer_t saved_text;
     int token;
-    int line, column;
     union {
         char *string;
         json_int_t integer;
@@ -57,6 +60,8 @@ typedef struct {
     } value;
 } lex_t;
 
+#define stream_to_lex(stream) container_of(stream, lex_t, stream)
+
 
 /*** error reporting ***/
 
@@ -67,6 +72,7 @@ static void error_set(json_error_t *error, const lex_t *lex,
     char msg_text[JSON_ERROR_TEXT_LENGTH];
 
     int line = -1, col = -1;
+    size_t pos = 0;
     const char *result = msg_text;
 
     if(!error)
@@ -81,7 +87,9 @@ static void error_set(json_error_t *error, const lex_t *lex,
         const char *saved_text = strbuffer_value(&lex->saved_text);
         char msg_with_context[JSON_ERROR_TEXT_LENGTH];
 
-        line = lex->line;
+        line = lex->stream.line;
+        col = lex->stream.column;
+        pos = lex->stream.position;
 
         if(saved_text && saved_text[0])
         {
@@ -93,41 +101,57 @@ static void error_set(json_error_t *error, const lex_t *lex,
         }
         else
         {
-            snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,
-                     "%s near end of file", msg_text);
-            result = msg_with_context;
+            if(lex->stream.state == STREAM_STATE_ERROR) {
+                /* No context for UTF-8 decoding errors */
+                result = msg_text;
+            }
+            else {
+                snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,
+                         "%s near end of file", msg_text);
+                result = msg_with_context;
+            }
         }
     }
 
-    jsonp_error_set(error, line, col, "%s", result);
+    jsonp_error_set(error, line, col, pos, "%s", result);
 }
 
 
 /*** lexical analyzer ***/
 
 static void
-stream_init(stream_t *stream, get_func get, eof_func eof, void *data)
+stream_init(stream_t *stream, get_func get, void *data)
 {
     stream->get = get;
-    stream->eof = eof;
     stream->data = data;
-    stream->stream_pos = 0;
     stream->buffer[0] = '\0';
     stream->buffer_pos = 0;
+
+    stream->state = STREAM_STATE_OK;
+    stream->line = 1;
+    stream->column = 0;
+    stream->position = 0;
 }
 
-static char stream_get(stream_t *stream, json_error_t *error)
+static int stream_get(stream_t *stream, json_error_t *error)
 {
-    char c;
+    int c;
+
+    if(stream->state != STREAM_STATE_OK)
+        return stream->state;
 
     if(!stream->buffer[stream->buffer_pos])
     {
-        stream->buffer[0] = stream->get(stream->data);
-        stream->buffer_pos = 0;
+        c = stream->get(stream->data);
+        if(c == EOF) {
+            stream->state = STREAM_STATE_EOF;
+            return STREAM_STATE_EOF;
+        }
 
-        c = stream->buffer[0];
+        stream->buffer[0] = c;
+        stream->buffer_pos = 0;
 
-        if((unsigned char)c >= 0x80 && c != (char)EOF)
+        if(0x80 <= c && c <= 0xFF)
         {
             /* multi-byte UTF-8 sequence */
             int i, count;
@@ -144,30 +168,47 @@ static char stream_get(stream_t *stream, json_error_t *error)
             if(!utf8_check_full(stream->buffer, count, NULL))
                 goto out;
 
-            stream->stream_pos += count;
             stream->buffer[count] = '\0';
         }
-        else {
+        else
             stream->buffer[1] = '\0';
-            stream->stream_pos++;
-        }
     }
 
-    return stream->buffer[stream->buffer_pos++];
+    c = stream->buffer[stream->buffer_pos++];
 
-out:
-    error_set(error, NULL, "unable to decode byte 0x%x at position %d",
-              (unsigned char)c, stream->stream_pos);
+    stream->position++;
+    if(c == '\n') {
+        stream->line++;
+        stream->last_column = stream->column;
+        stream->column = 0;
+    }
+    else if(utf8_check_first(c)) {
+        /* track the Unicode character column, so increment only if
+           this is the first character of a UTF-8 sequence */
+        stream->column++;
+    }
 
-    stream->buffer[0] = EOF;
-    stream->buffer[1] = '\0';
-    stream->buffer_pos = 1;
+    return c;
 
-    return EOF;
+out:
+    stream->state = STREAM_STATE_ERROR;
+    error_set(error, stream_to_lex(stream), "unable to decode byte 0x%x", c);
+    return STREAM_STATE_ERROR;
 }
 
-static void stream_unget(stream_t *stream, char c)
+static void stream_unget(stream_t *stream, int c)
 {
+    if(c == STREAM_STATE_EOF || c == STREAM_STATE_ERROR)
+        return;
+
+    stream->position--;
+    if(c == '\n') {
+        stream->line--;
+        stream->column = stream->last_column;
+    }
+    else if(utf8_check_first(c))
+        stream->column--;
+
     assert(stream->buffer_pos > 0);
     stream->buffer_pos--;
     assert(stream->buffer[stream->buffer_pos] == c);
@@ -179,29 +220,32 @@ static int lex_get(lex_t *lex, json_error_t *error)
     return stream_get(&lex->stream, error);
 }
 
-static int lex_eof(lex_t *lex)
-{
-    return lex->stream.eof(lex->stream.data);
-}
-
-static void lex_save(lex_t *lex, char c)
+static void lex_save(lex_t *lex, int c)
 {
     strbuffer_append_byte(&lex->saved_text, c);
 }
 
 static int lex_get_save(lex_t *lex, json_error_t *error)
 {
-    char c = stream_get(&lex->stream, error);
-    lex_save(lex, c);
+    int c = stream_get(&lex->stream, error);
+    if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR)
+        lex_save(lex, c);
     return c;
 }
 
-static void lex_unget_unsave(lex_t *lex, char c)
+static void lex_unget(lex_t *lex, int c)
 {
-    char d;
     stream_unget(&lex->stream, c);
-    d = strbuffer_pop(&lex->saved_text);
-    assert(c == d);
+}
+
+static void lex_unget_unsave(lex_t *lex, int c)
+{
+    if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) {
+        char d;
+        stream_unget(&lex->stream, c);
+        d = strbuffer_pop(&lex->saved_text);
+        assert(c == d);
+    }
 }
 
 static void lex_save_cached(lex_t *lex)
@@ -210,6 +254,7 @@ static void lex_save_cached(lex_t *lex)
     {
         lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]);
         lex->stream.buffer_pos++;
+        lex->stream.position++;
     }
 }
 
@@ -239,7 +284,7 @@ static int32_t decode_unicode_escape(const char *str)
 
 static void lex_scan_string(lex_t *lex, json_error_t *error)
 {
-    char c;
+    int c;
     const char *p;
     char *t;
     int i;
@@ -250,14 +295,15 @@ static void lex_scan_string(lex_t *lex, json_error_t *error)
     c = lex_get_save(lex, error);
 
     while(c != '"') {
-        if(c == (char)EOF) {
-            lex_unget_unsave(lex, c);
-            if(lex_eof(lex))
-                error_set(error, lex, "premature end of input");
+        if(c == STREAM_STATE_ERROR)
+            goto out;
+
+        else if(c == STREAM_STATE_EOF) {
+            error_set(error, lex, "premature end of input");
             goto out;
         }
 
-        else if((unsigned char)c <= 0x1F) {
+        else if(0 <= c && c <= 0x1F) {
             /* control character */
             lex_unget_unsave(lex, c);
             if(c == '\n')
@@ -273,7 +319,6 @@ static void lex_scan_string(lex_t *lex, json_error_t *error)
                 c = lex_get_save(lex, error);
                 for(i = 0; i < 4; i++) {
                     if(!isxdigit(c)) {
-                        lex_unget_unsave(lex, c);
                         error_set(error, lex, "invalid escape");
                         goto out;
                     }
@@ -284,7 +329,6 @@ static void lex_scan_string(lex_t *lex, json_error_t *error)
                     c == 'f' || c == 'n' || c == 'r' || c == 't')
                 c = lex_get_save(lex, error);
             else {
-                lex_unget_unsave(lex, c);
                 error_set(error, lex, "invalid escape");
                 goto out;
             }
@@ -399,7 +443,7 @@ out:
 #define json_strtoint     strtol
 #endif
 
-static int lex_scan_number(lex_t *lex, char c, json_error_t *error)
+static int lex_scan_number(lex_t *lex, int c, json_error_t *error)
 {
     const char *saved_text;
     char *end;
@@ -423,8 +467,8 @@ static int lex_scan_number(lex_t *lex, char c, json_error_t *error)
             c = lex_get_save(lex, error);
     }
     else {
-      lex_unget_unsave(lex, c);
-      goto out;
+        lex_unget_unsave(lex, c);
+        goto out;
     }
 
     if(c != '.' && c != 'E' && c != 'e') {
@@ -453,8 +497,10 @@ static int lex_scan_number(lex_t *lex, char c, json_error_t *error)
 
     if(c == '.') {
         c = lex_get(lex, error);
-        if(!isdigit(c))
+        if(!isdigit(c)) {
+            lex_unget(lex, c);
             goto out;
+        }
         lex_save(lex, c);
 
         c = lex_get_save(lex, error);
@@ -498,7 +544,7 @@ out:
 
 static int lex_scan(lex_t *lex, json_error_t *error)
 {
-    char c;
+    int c;
 
     strbuffer_clear(&lex->saved_text);
 
@@ -509,18 +555,15 @@ static int lex_scan(lex_t *lex, json_error_t *error)
 
     c = lex_get(lex, error);
     while(c == ' ' || c == '\t' || c == '\n' || c == '\r')
-    {
-        if(c == '\n')
-            lex->line++;
-
         c = lex_get(lex, error);
+
+    if(c == STREAM_STATE_EOF) {
+        lex->token = TOKEN_EOF;
+        goto out;
     }
 
-    if(c == (char)EOF) {
-        if(lex_eof(lex))
-            lex->token = TOKEN_EOF;
-        else
-            lex->token = TOKEN_INVALID;
+    if(c == STREAM_STATE_ERROR) {
+        lex->token = TOKEN_INVALID;
         goto out;
     }
 
@@ -580,15 +623,13 @@ static char *lex_steal_string(lex_t *lex)
     return result;
 }
 
-static int lex_init(lex_t *lex, get_func get, eof_func eof, void *data)
+static int lex_init(lex_t *lex, get_func get, void *data)
 {
-    stream_init(&lex->stream, get, eof, data);
+    stream_init(&lex->stream, get, data);
     if(strbuffer_init(&lex->saved_text))
         return -1;
 
     lex->token = TOKEN_INVALID;
-    lex->line = 1;
-
     return 0;
 }
 
@@ -791,16 +832,10 @@ static int string_get(void *data)
     else
     {
         stream->pos++;
-        return c;
+        return (unsigned char)c;
     }
 }
 
-static int string_eof(void *data)
-{
-    string_data_t *stream = (string_data_t *)data;
-    return (stream->data[stream->pos] == '\0');
-}
-
 json_t *json_loads(const char *string, size_t flags, json_error_t *error)
 {
     lex_t lex;
@@ -809,7 +844,7 @@ json_t *json_loads(const char *string, size_t flags, json_error_t *error)
 
     (void)flags; /* unused */
 
-    if(lex_init(&lex, string_get, string_eof, (void *)&stream_data))
+    if(lex_init(&lex, string_get, (void *)&stream_data))
         return NULL;
 
     jsonp_error_init(error, "<string>");
@@ -837,7 +872,7 @@ json_t *json_loadf(FILE *input, size_t flags, json_error_t *error)
     json_t *result;
     (void)flags; /* unused */
 
-    if(lex_init(&lex, (get_func)fgetc, (eof_func)feof, input))
+    if(lex_init(&lex, (get_func)fgetc, input))
         return NULL;
 
     if(input == stdin)
index e00660d..4fb8c1b 100644 (file)
@@ -10,6 +10,7 @@
 #include "jansson_private.h"
 
 typedef struct {
+    const char *start;
     const char *fmt;
     char token;
     json_error_t *error;
@@ -57,8 +58,12 @@ static void next_token(scanner_t *s)
 static void set_error(scanner_t *s, const char *fmt, ...)
 {
     va_list ap;
+    size_t pos;
     va_start(ap, fmt);
-    jsonp_error_vset(s->error, s->line, s->column, fmt, ap);
+
+    pos = (size_t)(s->fmt - s->start);
+    jsonp_error_vset(s->error, s->line, s->column, pos, fmt, ap);
+
     va_end(ap);
 }
 
@@ -447,13 +452,13 @@ json_t *json_vpack_ex(json_error_t *error, size_t flags,
     jsonp_error_init(error, "");
 
     if(!fmt || !*fmt) {
-        jsonp_error_set(error, 1, 1, "Null or empty format string");
+        jsonp_error_set(error, -1, -1, 0, "Null or empty format string");
         return NULL;
     }
 
     s.error = error;
     s.flags = flags;
-    s.fmt = fmt;
+    s.fmt = s.start = fmt;
     s.line = 1;
     s.column = 0;
 
@@ -505,13 +510,13 @@ int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags,
     jsonp_error_init(error, "");
 
     if(!fmt || !*fmt) {
-        jsonp_error_set(error, 1, 1, "Null or empty format string");
+        jsonp_error_set(error, -1, -1, 0, "Null or empty format string");
         return -1;
     }
 
     s.error = error;
     s.flags = flags;
-    s.fmt = fmt;
+    s.fmt = s.start = fmt;
     s.line = 1;
     s.column = 0;
 
index a2475b7..1ed0c57 100644 (file)
@@ -7,6 +7,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
 #include <jansson.h>
 
 static int getenv_int(const char *name)
@@ -25,6 +27,26 @@ static int getenv_int(const char *name)
     return (int)result;
 }
 
+/* Return a pointer to the first non-whitespace character of str.
+   Modifies str so that all trailing whitespace characters are
+   replaced by '\0'. */
+static const char *strip(char *str)
+{
+    size_t length;
+    char *result = str;
+    while(*result && isspace(*result))
+        result++;
+
+    length = strlen(result);
+    if(length == 0)
+        return result;
+
+    while(isspace(result[length - 1]))
+        result[--length] = '\0';
+
+    return result;
+}
+
 int main(int argc, char *argv[])
 {
     int indent = 0;
@@ -59,9 +81,39 @@ int main(int argc, char *argv[])
     if(getenv_int("JSON_SORT_KEYS"))
         flags |= JSON_SORT_KEYS;
 
-    json = json_loadf(stdin, 0, &error);
+    if(getenv_int("STRIP")) {
+        /* Load to memory, strip leading and trailing whitespace */
+        size_t size = 0, used = 0;
+        char *buffer = NULL;
+
+        while(1) {
+            int count;
+
+            size = (size == 0 ? 128 : size * 2);
+            buffer = realloc(buffer, size);
+            if(!buffer) {
+                fprintf(stderr, "Unable to allocate %d bytes\n", (int)size);
+                return 1;
+            }
+
+            count = fread(buffer + used, 1, size - used, stdin);
+            if(count < size - used) {
+                buffer[used + count] = '\0';
+                break;
+            }
+            used += count;
+        }
+
+        json = json_loads(strip(buffer), 0, &error);
+        free(buffer);
+    }
+    else
+        json = json_loadf(stdin, 0, &error);
+
     if(!json) {
-        fprintf(stderr, "%d\n%s\n", error.line, error.text);
+        fprintf(stderr, "%d %d %d\n%s\n",
+                error.line, error.column, error.position,
+                error.text);
         return 1;
     }
 
index edc6bd6..772afb1 100644 (file)
@@ -180,7 +180,7 @@ int main()
     /* NULL format */
     if(json_pack_ex(&error, 0, NULL))
         fail("json_pack failed to catch NULL format string");
-    if(error.line != 1 || error.column != 1)
+    if(error.line != -1 || error.column != -1)
         fail("json_pack didn't get the error coordinates right!");
 
     /* More complicated checks for row/columns */
diff --git a/test/suites/invalid-strip/apostrophe/error b/test/suites/invalid-strip/apostrophe/error
deleted file mode 100644 (file)
index f30d170..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid token near '''
diff --git a/test/suites/invalid-strip/apostrophe/input b/test/suites/invalid-strip/apostrophe/input
deleted file mode 100644 (file)
index 8bebe3a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-['
\ No newline at end of file
diff --git a/test/suites/invalid-strip/ascii-unicode-identifier/error b/test/suites/invalid-strip/ascii-unicode-identifier/error
deleted file mode 100644 (file)
index 7469919..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-'[' or '{' expected near 'a'
diff --git a/test/suites/invalid-strip/ascii-unicode-identifier/input b/test/suites/invalid-strip/ascii-unicode-identifier/input
deleted file mode 100644 (file)
index ef2ab62..0000000
+++ /dev/null
@@ -1 +0,0 @@
-aå
\ No newline at end of file
diff --git a/test/suites/invalid-strip/brace-comma/error b/test/suites/invalid-strip/brace-comma/error
deleted file mode 100644 (file)
index 394ad5a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-string or '}' expected near ','
diff --git a/test/suites/invalid-strip/brace-comma/input b/test/suites/invalid-strip/brace-comma/input
deleted file mode 100644 (file)
index 47bc910..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{,
\ No newline at end of file
diff --git a/test/suites/invalid-strip/bracket-comma/error b/test/suites/invalid-strip/bracket-comma/error
deleted file mode 100644 (file)
index 54c3924..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-unexpected token near ','
diff --git a/test/suites/invalid-strip/bracket-comma/input b/test/suites/invalid-strip/bracket-comma/input
deleted file mode 100644 (file)
index 6295fdc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[,
\ No newline at end of file
diff --git a/test/suites/invalid-strip/bracket-one-comma/input b/test/suites/invalid-strip/bracket-one-comma/input
deleted file mode 100644 (file)
index 6604698..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1,
\ No newline at end of file
diff --git a/test/suites/invalid-strip/empty/error b/test/suites/invalid-strip/empty/error
deleted file mode 100644 (file)
index ff19200..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-'[' or '{' expected near end of file
diff --git a/test/suites/invalid-strip/empty/input b/test/suites/invalid-strip/empty/input
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/test/suites/invalid-strip/escaped-null-byte-in-string/error b/test/suites/invalid-strip/escaped-null-byte-in-string/error
deleted file mode 100644 (file)
index 0fa36e2..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-\u0000 is not allowed
diff --git a/test/suites/invalid-strip/escaped-null-byte-in-string/input b/test/suites/invalid-strip/escaped-null-byte-in-string/input
deleted file mode 100644 (file)
index 60f7f7b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\u0000 (null byte not allowed)"]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/extra-comma-in-array/input b/test/suites/invalid-strip/extra-comma-in-array/input
deleted file mode 100644 (file)
index 13f6f1d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1,]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/extra-command-in-multiline-array/error b/test/suites/invalid-strip/extra-command-in-multiline-array/error
deleted file mode 100644 (file)
index 26c2152..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-6
-unexpected token near ']'
diff --git a/test/suites/invalid-strip/extra-command-in-multiline-array/input b/test/suites/invalid-strip/extra-command-in-multiline-array/input
deleted file mode 100644 (file)
index e4d4ddd..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[1,
-2,
-3,
-4,
-5,
-]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/garbage-after-newline/error b/test/suites/invalid-strip/garbage-after-newline/error
deleted file mode 100644 (file)
index 90eacdd..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-2
-end of file expected near 'foo'
diff --git a/test/suites/invalid-strip/garbage-after-newline/input b/test/suites/invalid-strip/garbage-after-newline/input
deleted file mode 100644 (file)
index 3614ac7..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[1,2,3]
-foo
diff --git a/test/suites/invalid-strip/garbage-at-the-end/error b/test/suites/invalid-strip/garbage-at-the-end/error
deleted file mode 100644 (file)
index 9076aec..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-end of file expected near 'foo'
diff --git a/test/suites/invalid-strip/garbage-at-the-end/input b/test/suites/invalid-strip/garbage-at-the-end/input
deleted file mode 100644 (file)
index adf1aac..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1,2,3]foo
\ No newline at end of file
diff --git a/test/suites/invalid-strip/integer-starting-with-zero/error b/test/suites/invalid-strip/integer-starting-with-zero/error
deleted file mode 100644 (file)
index e4eee2f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid token near '0'
diff --git a/test/suites/invalid-strip/integer-starting-with-zero/input b/test/suites/invalid-strip/integer-starting-with-zero/input
deleted file mode 100644 (file)
index 7106da1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[012]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/invalid-escape/error b/test/suites/invalid-strip/invalid-escape/error
deleted file mode 100644 (file)
index 9930ca7..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid escape near '"\'
diff --git a/test/suites/invalid-strip/invalid-escape/input b/test/suites/invalid-strip/invalid-escape/input
deleted file mode 100644 (file)
index e305947..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\a <-- invalid escape"]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/invalid-identifier/error b/test/suites/invalid-strip/invalid-identifier/error
deleted file mode 100644 (file)
index 0f88417..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid token near 'troo'
diff --git a/test/suites/invalid-strip/invalid-identifier/input b/test/suites/invalid-strip/invalid-identifier/input
deleted file mode 100644 (file)
index 7c06bd5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[troo
\ No newline at end of file
diff --git a/test/suites/invalid-strip/invalid-negative-integerr/input b/test/suites/invalid-strip/invalid-negative-integerr/input
deleted file mode 100644 (file)
index fe088a3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[-123foo]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/invalid-negative-real/error b/test/suites/invalid-strip/invalid-negative-real/error
deleted file mode 100644 (file)
index f9d930e..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-']' expected near 'foo'
diff --git a/test/suites/invalid-strip/invalid-negative-real/input b/test/suites/invalid-strip/invalid-negative-real/input
deleted file mode 100644 (file)
index 5fc3c1e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[-123.123foo]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/invalid-second-surrogate/error b/test/suites/invalid-strip/invalid-second-surrogate/error
deleted file mode 100644 (file)
index 22d0e1f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid Unicode '\uD888\u3210'
diff --git a/test/suites/invalid-strip/invalid-second-surrogate/input b/test/suites/invalid-strip/invalid-second-surrogate/input
deleted file mode 100644 (file)
index 25a1ca2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\uD888\u3210 (first surrogate and invalid second surrogate)"]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/lone-open-brace/input b/test/suites/invalid-strip/lone-open-brace/input
deleted file mode 100644 (file)
index 81750b9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{
\ No newline at end of file
diff --git a/test/suites/invalid-strip/lone-open-bracket/input b/test/suites/invalid-strip/lone-open-bracket/input
deleted file mode 100644 (file)
index 8e2f0be..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[
\ No newline at end of file
diff --git a/test/suites/invalid-strip/lone-second-surrogate/error b/test/suites/invalid-strip/lone-second-surrogate/error
deleted file mode 100644 (file)
index c96d7f5..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid Unicode '\uDFAA'
diff --git a/test/suites/invalid-strip/lone-second-surrogate/input b/test/suites/invalid-strip/lone-second-surrogate/input
deleted file mode 100644 (file)
index 6882ee4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\uDFAA (second surrogate on it's own)"]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/minus-sign-without-number/error b/test/suites/invalid-strip/minus-sign-without-number/error
deleted file mode 100644 (file)
index e978234..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid token near '-'
diff --git a/test/suites/invalid-strip/minus-sign-without-number/input b/test/suites/invalid-strip/minus-sign-without-number/input
deleted file mode 100644 (file)
index a6d8e78..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[-foo]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/negative-integer-starting-with-zero/error b/test/suites/invalid-strip/negative-integer-starting-with-zero/error
deleted file mode 100644 (file)
index a758d94..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid token near '-0'
diff --git a/test/suites/invalid-strip/negative-integer-starting-with-zero/input b/test/suites/invalid-strip/negative-integer-starting-with-zero/input
deleted file mode 100644 (file)
index 67af096..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[-012]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/null-byte-in-string/error b/test/suites/invalid-strip/null-byte-in-string/error
deleted file mode 100644 (file)
index 273f6d1..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-control character 0x0 near '"null byte '
diff --git a/test/suites/invalid-strip/null-byte-in-string/input b/test/suites/invalid-strip/null-byte-in-string/input
deleted file mode 100644 (file)
index c0d82be..0000000
Binary files a/test/suites/invalid-strip/null-byte-in-string/input and /dev/null differ
diff --git a/test/suites/invalid-strip/null-byte-outside-string/error b/test/suites/invalid-strip/null-byte-outside-string/error
deleted file mode 100644 (file)
index f0e68ec..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid token near end of file
diff --git a/test/suites/invalid-strip/null-byte-outside-string/input b/test/suites/invalid-strip/null-byte-outside-string/input
deleted file mode 100644 (file)
index 75447d8..0000000
Binary files a/test/suites/invalid-strip/null-byte-outside-string/input and /dev/null differ
diff --git a/test/suites/invalid-strip/null/error b/test/suites/invalid-strip/null/error
deleted file mode 100644 (file)
index de9280b..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-'[' or '{' expected near 'null'
diff --git a/test/suites/invalid-strip/null/input b/test/suites/invalid-strip/null/input
deleted file mode 100644 (file)
index ec747fa..0000000
+++ /dev/null
@@ -1 +0,0 @@
-null
\ No newline at end of file
diff --git a/test/suites/invalid-strip/object-apostrophes/error b/test/suites/invalid-strip/object-apostrophes/error
deleted file mode 100644 (file)
index f7b586a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-string or '}' expected near '''
diff --git a/test/suites/invalid-strip/object-apostrophes/input b/test/suites/invalid-strip/object-apostrophes/input
deleted file mode 100644 (file)
index 9dba170..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{'a'
\ No newline at end of file
diff --git a/test/suites/invalid-strip/object-garbage-at-end/error b/test/suites/invalid-strip/object-garbage-at-end/error
deleted file mode 100644 (file)
index a60dc47..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-'}' expected near '123'
diff --git a/test/suites/invalid-strip/object-garbage-at-end/input b/test/suites/invalid-strip/object-garbage-at-end/input
deleted file mode 100644 (file)
index 80c42cb..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"a":"a" 123}
\ No newline at end of file
diff --git a/test/suites/invalid-strip/object-in-unterminated-array/input b/test/suites/invalid-strip/object-in-unterminated-array/input
deleted file mode 100644 (file)
index 043a87e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[{}
\ No newline at end of file
diff --git a/test/suites/invalid-strip/object-no-colon/input b/test/suites/invalid-strip/object-no-colon/input
deleted file mode 100644 (file)
index f3797b3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"a"
\ No newline at end of file
diff --git a/test/suites/invalid-strip/object-no-value/input b/test/suites/invalid-strip/object-no-value/input
deleted file mode 100644 (file)
index 3ef538a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"a":
\ No newline at end of file
diff --git a/test/suites/invalid-strip/object-unterminated-value/input b/test/suites/invalid-strip/object-unterminated-value/input
deleted file mode 100644 (file)
index 7fe699a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"a":"a
\ No newline at end of file
diff --git a/test/suites/invalid-strip/real-garbage-after-e/error b/test/suites/invalid-strip/real-garbage-after-e/error
deleted file mode 100644 (file)
index d9b83e7..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid token near '1e'
diff --git a/test/suites/invalid-strip/real-garbage-after-e/input b/test/suites/invalid-strip/real-garbage-after-e/input
deleted file mode 100644 (file)
index 9213dfc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1ea]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/real-negative-overflow/error b/test/suites/invalid-strip/real-negative-overflow/error
deleted file mode 100644 (file)
index af5a850..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-real number overflow near '-123123e100000'
diff --git a/test/suites/invalid-strip/real-negative-overflow/input b/test/suites/invalid-strip/real-negative-overflow/input
deleted file mode 100644 (file)
index 3d628a9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[-123123e100000]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/real-positive-overflow/error b/test/suites/invalid-strip/real-positive-overflow/error
deleted file mode 100644 (file)
index e9becc3..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-real number overflow near '123123e100000'
diff --git a/test/suites/invalid-strip/real-positive-overflow/input b/test/suites/invalid-strip/real-positive-overflow/input
deleted file mode 100644 (file)
index 54d7d3d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[123123e100000]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/real-truncated-at-e/error b/test/suites/invalid-strip/real-truncated-at-e/error
deleted file mode 100644 (file)
index d9b83e7..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid token near '1e'
diff --git a/test/suites/invalid-strip/real-truncated-at-e/input b/test/suites/invalid-strip/real-truncated-at-e/input
deleted file mode 100644 (file)
index c3ace3a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1e]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/real-truncated-at-point/error b/test/suites/invalid-strip/real-truncated-at-point/error
deleted file mode 100644 (file)
index 7312401..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid token near '1.'
diff --git a/test/suites/invalid-strip/real-truncated-at-point/input b/test/suites/invalid-strip/real-truncated-at-point/input
deleted file mode 100644 (file)
index 1de287c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1.]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/run b/test/suites/invalid-strip/run
deleted file mode 100755 (executable)
index 7cb3243..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2009-2011 Petri Lehtinen <petri@digip.org>
-#
-# Jansson is free software; you can redistribute it and/or modify
-# it under the terms of the MIT license. See LICENSE for details.
-
-is_test() {
-    test -d $test_path
-}
-
-run_test() {
-    $json_process <$test_path/input >$test_log/stdout 2>$test_log/stderr
-    valgrind_check $test_log/stderr || return 1
-    cmp -s $test_path/error $test_log/stderr
-}
-
-show_error() {
-    valgrind_show_error && return
-
-    echo "EXPECTED ERROR:"
-    nl -bn $test_path/error
-    echo "ACTUAL ERROR:"
-    nl -bn $test_log/stderr
-}
-
-. $top_srcdir/test/scripts/run-tests.sh
diff --git a/test/suites/invalid-strip/tab-character-in-string/error b/test/suites/invalid-strip/tab-character-in-string/error
deleted file mode 100644 (file)
index ee81a5f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-control character 0x9 near '"'
diff --git a/test/suites/invalid-strip/tab-character-in-string/input b/test/suites/invalid-strip/tab-character-in-string/input
deleted file mode 100644 (file)
index f3010f5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["      <-- tab character"]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/too-big-negative-integer/error b/test/suites/invalid-strip/too-big-negative-integer/error
deleted file mode 100644 (file)
index 1cfe2d5..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-too big negative integer
diff --git a/test/suites/invalid-strip/too-big-negative-integer/input b/test/suites/invalid-strip/too-big-negative-integer/input
deleted file mode 100644 (file)
index dfa3846..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[-123123123123123123123123123123]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/too-big-positive-integer/error b/test/suites/invalid-strip/too-big-positive-integer/error
deleted file mode 100644 (file)
index 89370e0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-too big integer
diff --git a/test/suites/invalid-strip/too-big-positive-integer/input b/test/suites/invalid-strip/too-big-positive-integer/input
deleted file mode 100644 (file)
index 3156f10..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[123123123123123123123123123123]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/truncated-unicode-surrogate/error b/test/suites/invalid-strip/truncated-unicode-surrogate/error
deleted file mode 100644 (file)
index 17b932d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-invalid Unicode '\uDADA'
diff --git a/test/suites/invalid-strip/truncated-unicode-surrogate/input b/test/suites/invalid-strip/truncated-unicode-surrogate/input
deleted file mode 100644 (file)
index 3937c2c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\uDADA (first surrogate without the second)"]
\ No newline at end of file
diff --git a/test/suites/invalid-strip/unicode-identifier/error b/test/suites/invalid-strip/unicode-identifier/error
deleted file mode 100644 (file)
index e3817fa..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-'[' or '{' expected near 'å'
diff --git a/test/suites/invalid-strip/unicode-identifier/input b/test/suites/invalid-strip/unicode-identifier/input
deleted file mode 100644 (file)
index 7284aea..0000000
+++ /dev/null
@@ -1 +0,0 @@
\ No newline at end of file
diff --git a/test/suites/invalid-strip/unterminated-array-and-object/input b/test/suites/invalid-strip/unterminated-array-and-object/input
deleted file mode 100644 (file)
index 7a63c8c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[{
\ No newline at end of file
diff --git a/test/suites/invalid-strip/unterminated-array/input b/test/suites/invalid-strip/unterminated-array/input
deleted file mode 100644 (file)
index 42a6193..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["a"
\ No newline at end of file
diff --git a/test/suites/invalid-strip/unterminated-empty-key/input b/test/suites/invalid-strip/unterminated-empty-key/input
deleted file mode 100644 (file)
index 20f22da..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"
\ No newline at end of file
diff --git a/test/suites/invalid-strip/unterminated-key/input b/test/suites/invalid-strip/unterminated-key/input
deleted file mode 100644 (file)
index 328c30c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"a
\ No newline at end of file
diff --git a/test/suites/invalid-strip/unterminated-object-and-array/error b/test/suites/invalid-strip/unterminated-object-and-array/error
deleted file mode 100644 (file)
index 5fe61b5..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-string or '}' expected near '['
diff --git a/test/suites/invalid-strip/unterminated-object-and-array/input b/test/suites/invalid-strip/unterminated-object-and-array/input
deleted file mode 100644 (file)
index 381ede5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{[
\ No newline at end of file
diff --git a/test/suites/invalid-strip/unterminated-string/input b/test/suites/invalid-strip/unterminated-string/input
deleted file mode 100644 (file)
index 9822a6b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["a
\ No newline at end of file
index 39763ec..8f08970 100644 (file)
@@ -1,2 +1,2 @@
--1
-unable to decode byte 0xe5 at position 2
+1 2 2
+unable to decode byte 0xe5 near '0'
index 5a00b67..d07ccb3 100644 (file)
@@ -1,2 +1,2 @@
--1
-unable to decode byte 0xf4 at position 2
+1 2 2
+unable to decode byte 0xf4 near '"'
index e71089d..d018f5f 100644 (file)
@@ -1,2 +1,2 @@
--1
-unable to decode byte 0xfd at position 2
+1 2 2
+unable to decode byte 0xfd near '"'
index 48796d1..8a05aba 100644 (file)
@@ -1,2 +1,2 @@
--1
-unable to decode byte 0xe0 at position 2
+1 2 2
+unable to decode byte 0xe0 near '"'
diff --git a/test/suites/invalid/bracket-one-comma/error b/test/suites/invalid/bracket-one-comma/error
deleted file mode 100644 (file)
index 41fd6d6..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-2
-']' expected near end of file
index ff19200..f45da6f 100644 (file)
@@ -1,2 +1,2 @@
-1
+1 0 0
 '[' or '{' expected near end of file
diff --git a/test/suites/invalid/extra-command-in-multiline-array/error b/test/suites/invalid/extra-command-in-multiline-array/error
deleted file mode 100644 (file)
index 26c2152..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-6
-unexpected token near ']'
index 9930ca7..d9863f7 100644 (file)
@@ -1,2 +1,2 @@
-1
-invalid escape near '"\'
+1 4 4
+invalid escape near '"\a'
diff --git a/test/suites/invalid/invalid-negative-integerr/error b/test/suites/invalid/invalid-negative-integerr/error
deleted file mode 100644 (file)
index f9d930e..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-']' expected near 'foo'
diff --git a/test/suites/invalid/lone-open-bracket/error b/test/suites/invalid/lone-open-bracket/error
deleted file mode 100644 (file)
index 41fd6d6..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-2
-']' expected near end of file
diff --git a/test/suites/invalid/null-byte-in-string/nostrip b/test/suites/invalid/null-byte-in-string/nostrip
new file mode 100644 (file)
index 0000000..80f4bf7
--- /dev/null
@@ -0,0 +1,2 @@
+The embedded NULL byte breaks json_loads(), which is used instead of
+json_loadf() in the stripped tests.
diff --git a/test/suites/invalid/null-byte-outside-string/nostrip b/test/suites/invalid/null-byte-outside-string/nostrip
new file mode 100644 (file)
index 0000000..80f4bf7
--- /dev/null
@@ -0,0 +1,2 @@
+The embedded NULL byte breaks json_loads(), which is used instead of
+json_loadf() in the stripped tests.
index de9280b..1f5d464 100644 (file)
@@ -1,2 +1,2 @@
-1
+1 4 4
 '[' or '{' expected near 'null'
diff --git a/test/suites/invalid/object-in-unterminated-array/error b/test/suites/invalid/object-in-unterminated-array/error
deleted file mode 100644 (file)
index 41fd6d6..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-2
-']' expected near end of file
diff --git a/test/suites/invalid/object-in-unterminated-array/error.normal b/test/suites/invalid/object-in-unterminated-array/error.normal
new file mode 100644 (file)
index 0000000..0248b11
--- /dev/null
@@ -0,0 +1,2 @@
+2 0 4
+']' expected near end of file
diff --git a/test/suites/invalid/object-in-unterminated-array/error.strip b/test/suites/invalid/object-in-unterminated-array/error.strip
new file mode 100644 (file)
index 0000000..f89b38f
--- /dev/null
@@ -0,0 +1,2 @@
+1 3 3
+']' expected near end of file
index 7cb3243..f8394d7 100755 (executable)
@@ -9,19 +9,49 @@ is_test() {
     test -d $test_path
 }
 
+do_run() {
+    variant=$1
+    s=".$1"
+
+    strip=0
+    if [ "$variant" = "strip" ]; then
+        # This test should not be stripped
+        [ -f $test_path/nostrip ] && return
+        strip=1
+    fi
+
+    STRIP=$strip $json_process \
+        <$test_path/input >$test_log/stdout$s 2>$test_log/stderr$s
+    valgrind_check $test_log/stderr$s || return 1
+
+    ref=error
+    [ -f $test_path/error$s ] && ref=error$s
+
+    if ! cmp -s $test_path/$ref $test_log/stderr$s; then
+        echo $variant > $test_log/variant
+        return 1
+    fi
+}
+
 run_test() {
-    $json_process <$test_path/input >$test_log/stdout 2>$test_log/stderr
-    valgrind_check $test_log/stderr || return 1
-    cmp -s $test_path/error $test_log/stderr
+    do_run normal && do_run strip
 }
 
 show_error() {
     valgrind_show_error && return
 
+    read variant < $test_log/variant
+    s=".$variant"
+
+    echo "VARIANT: $variant"
+
     echo "EXPECTED ERROR:"
-    nl -bn $test_path/error
+    ref=error
+    [ -f $test_path/error$s ] && ref=error$s
+    nl -bn $test_path/$ref
+
     echo "ACTUAL ERROR:"
-    nl -bn $test_log/stderr
+    nl -bn $test_log/stderr$s
 }
 
 . $top_srcdir/test/scripts/run-tests.sh
diff --git a/test/suites/invalid/unterminated-array/error b/test/suites/invalid/unterminated-array/error
deleted file mode 100644 (file)
index 41fd6d6..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-2
-']' expected near end of file
diff --git a/test/suites/invalid/unterminated-array/error.normal b/test/suites/invalid/unterminated-array/error.normal
new file mode 100644 (file)
index 0000000..8025ed1
--- /dev/null
@@ -0,0 +1,2 @@
+2 0 5
+']' expected near end of file
diff --git a/test/suites/invalid/unterminated-array/error.strip b/test/suites/invalid/unterminated-array/error.strip
new file mode 100644 (file)
index 0000000..495d0f7
--- /dev/null
@@ -0,0 +1,2 @@
+1 4 4
+']' expected near end of file
diff --git a/test/suites/valid-strip/complex-array/input b/test/suites/valid-strip/complex-array/input
deleted file mode 100644 (file)
index 7255532..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-[1,2,3,4,
-"a", "b", "c",
-{"foo": "bar", "core": "dump"},
-true, false, true, true, null, false
-]
\ No newline at end of file
diff --git a/test/suites/valid-strip/complex-array/output b/test/suites/valid-strip/complex-array/output
deleted file mode 100644 (file)
index 7aefe56..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1, 2, 3, 4, "a", "b", "c", {"core": "dump", "foo": "bar"}, true, false, true, true, null, false]
\ No newline at end of file
diff --git a/test/suites/valid-strip/empty-array/input b/test/suites/valid-strip/empty-array/input
deleted file mode 100644 (file)
index 0637a08..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[]
\ No newline at end of file
diff --git a/test/suites/valid-strip/empty-array/output b/test/suites/valid-strip/empty-array/output
deleted file mode 100644 (file)
index 0637a08..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[]
\ No newline at end of file
diff --git a/test/suites/valid-strip/empty-object-in-array/input b/test/suites/valid-strip/empty-object-in-array/input
deleted file mode 100644 (file)
index ee1aac4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[{}]
\ No newline at end of file
diff --git a/test/suites/valid-strip/empty-object-in-array/output b/test/suites/valid-strip/empty-object-in-array/output
deleted file mode 100644 (file)
index ee1aac4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[{}]
\ No newline at end of file
diff --git a/test/suites/valid-strip/empty-object/input b/test/suites/valid-strip/empty-object/input
deleted file mode 100644 (file)
index 9e26dfe..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/test/suites/valid-strip/empty-object/output b/test/suites/valid-strip/empty-object/output
deleted file mode 100644 (file)
index 9e26dfe..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/test/suites/valid-strip/empty-string/input b/test/suites/valid-strip/empty-string/input
deleted file mode 100644 (file)
index 93b6be2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[""]
\ No newline at end of file
diff --git a/test/suites/valid-strip/empty-string/output b/test/suites/valid-strip/empty-string/output
deleted file mode 100644 (file)
index 93b6be2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[""]
\ No newline at end of file
diff --git a/test/suites/valid-strip/escaped-utf-control-char/input b/test/suites/valid-strip/escaped-utf-control-char/input
deleted file mode 100644 (file)
index 07221b7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\u0012 escaped control character"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/escaped-utf-control-char/output b/test/suites/valid-strip/escaped-utf-control-char/output
deleted file mode 100644 (file)
index 07221b7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\u0012 escaped control character"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/false/input b/test/suites/valid-strip/false/input
deleted file mode 100644 (file)
index 67b2f07..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[false]
\ No newline at end of file
diff --git a/test/suites/valid-strip/false/output b/test/suites/valid-strip/false/output
deleted file mode 100644 (file)
index 67b2f07..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[false]
\ No newline at end of file
diff --git a/test/suites/valid-strip/negative-int/input b/test/suites/valid-strip/negative-int/input
deleted file mode 100644 (file)
index 8e30f8b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[-123]
\ No newline at end of file
diff --git a/test/suites/valid-strip/negative-int/output b/test/suites/valid-strip/negative-int/output
deleted file mode 100644 (file)
index 8e30f8b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[-123]
\ No newline at end of file
diff --git a/test/suites/valid-strip/negative-one/input b/test/suites/valid-strip/negative-one/input
deleted file mode 100644 (file)
index 99d21a2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[-1]
\ No newline at end of file
diff --git a/test/suites/valid-strip/negative-one/output b/test/suites/valid-strip/negative-one/output
deleted file mode 100644 (file)
index 99d21a2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[-1]
\ No newline at end of file
diff --git a/test/suites/valid-strip/negative-zero/input b/test/suites/valid-strip/negative-zero/input
deleted file mode 100644 (file)
index 37af131..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[-0]
\ No newline at end of file
diff --git a/test/suites/valid-strip/negative-zero/output b/test/suites/valid-strip/negative-zero/output
deleted file mode 100644 (file)
index 6e7ea63..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[0]
\ No newline at end of file
diff --git a/test/suites/valid-strip/null/input b/test/suites/valid-strip/null/input
deleted file mode 100644 (file)
index 500db4a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[null]
\ No newline at end of file
diff --git a/test/suites/valid-strip/null/output b/test/suites/valid-strip/null/output
deleted file mode 100644 (file)
index 500db4a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[null]
\ No newline at end of file
diff --git a/test/suites/valid-strip/one-byte-utf-8/input b/test/suites/valid-strip/one-byte-utf-8/input
deleted file mode 100644 (file)
index f26edd0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\u002c one-byte UTF-8"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/one-byte-utf-8/output b/test/suites/valid-strip/one-byte-utf-8/output
deleted file mode 100644 (file)
index c33d250..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[", one-byte UTF-8"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-capital-e-negative-exponent/input b/test/suites/valid-strip/real-capital-e-negative-exponent/input
deleted file mode 100644 (file)
index 0a01bd3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1E-2]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-capital-e-negative-exponent/output b/test/suites/valid-strip/real-capital-e-negative-exponent/output
deleted file mode 100644 (file)
index 75b9ef9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[0.01]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-capital-e-positive-exponent/input b/test/suites/valid-strip/real-capital-e-positive-exponent/input
deleted file mode 100644 (file)
index 5a8fc09..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1E+2]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-capital-e-positive-exponent/output b/test/suites/valid-strip/real-capital-e-positive-exponent/output
deleted file mode 100644 (file)
index d8ff702..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[100.0]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-capital-e/input b/test/suites/valid-strip/real-capital-e/input
deleted file mode 100644 (file)
index 6edbdfc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1E22]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-capital-e/output b/test/suites/valid-strip/real-capital-e/output
deleted file mode 100644 (file)
index 88e90ce..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1e+22]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-exponent/input b/test/suites/valid-strip/real-exponent/input
deleted file mode 100644 (file)
index da2522d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[123e45]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-exponent/output b/test/suites/valid-strip/real-exponent/output
deleted file mode 100644 (file)
index ac910d6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1.2299999999999999e+47]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-fraction-exponent/input b/test/suites/valid-strip/real-fraction-exponent/input
deleted file mode 100644 (file)
index 3944a7a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[123.456e78]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-fraction-exponent/output b/test/suites/valid-strip/real-fraction-exponent/output
deleted file mode 100644 (file)
index 4b87bda..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1.23456e+80]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-negative-exponent/input b/test/suites/valid-strip/real-negative-exponent/input
deleted file mode 100644 (file)
index ca40d3c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1e-2]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-negative-exponent/output b/test/suites/valid-strip/real-negative-exponent/output
deleted file mode 100644 (file)
index 75b9ef9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[0.01]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-positive-exponent/input b/test/suites/valid-strip/real-positive-exponent/input
deleted file mode 100644 (file)
index 343601d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1e+2]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-positive-exponent/output b/test/suites/valid-strip/real-positive-exponent/output
deleted file mode 100644 (file)
index d8ff702..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[100.0]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-underflow/input b/test/suites/valid-strip/real-underflow/input
deleted file mode 100644 (file)
index c5236eb..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[123e-10000000]
\ No newline at end of file
diff --git a/test/suites/valid-strip/real-underflow/output b/test/suites/valid-strip/real-underflow/output
deleted file mode 100644 (file)
index 92df1df..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[0.0]
\ No newline at end of file
diff --git a/test/suites/valid-strip/run b/test/suites/valid-strip/run
deleted file mode 100755 (executable)
index cd88a07..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2009-2011 Petri Lehtinen <petri@digip.org>
-#
-# Jansson is free software; you can redistribute it and/or modify
-# it under the terms of the MIT license. See LICENSE for details.
-
-export JSON_SORT_KEYS=1
-
-is_test() {
-    test -d $test_path
-}
-
-run_test() {
-    $json_process <$test_path/input >$test_log/stdout 2>$test_log/stderr
-    valgrind_check $test_log/stderr || return 1
-    cmp -s $test_path/output $test_log/stdout
-}
-
-show_error() {
-    valgrind_show_error && return
-
-    echo "EXPECTED OUTPUT:"
-    nl -bn $test_path/output
-    echo "ACTUAL OUTPUT:"
-    nl -bn $test_log/stdout
-}
-
-. $top_srcdir/test/scripts/run-tests.sh
diff --git a/test/suites/valid-strip/short-string/input b/test/suites/valid-strip/short-string/input
deleted file mode 100644 (file)
index eac5f7b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["a"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/short-string/output b/test/suites/valid-strip/short-string/output
deleted file mode 100644 (file)
index eac5f7b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["a"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/simple-ascii-string/input b/test/suites/valid-strip/simple-ascii-string/input
deleted file mode 100644 (file)
index 90358ab..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["abcdefghijklmnopqrstuvwxyz1234567890 "]
\ No newline at end of file
diff --git a/test/suites/valid-strip/simple-ascii-string/output b/test/suites/valid-strip/simple-ascii-string/output
deleted file mode 100644 (file)
index 90358ab..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["abcdefghijklmnopqrstuvwxyz1234567890 "]
\ No newline at end of file
diff --git a/test/suites/valid-strip/simple-int-0/input b/test/suites/valid-strip/simple-int-0/input
deleted file mode 100644 (file)
index 6e7ea63..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[0]
\ No newline at end of file
diff --git a/test/suites/valid-strip/simple-int-0/output b/test/suites/valid-strip/simple-int-0/output
deleted file mode 100644 (file)
index 6e7ea63..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[0]
\ No newline at end of file
diff --git a/test/suites/valid-strip/simple-int-1/input b/test/suites/valid-strip/simple-int-1/input
deleted file mode 100644 (file)
index bace2a0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1]
\ No newline at end of file
diff --git a/test/suites/valid-strip/simple-int-1/output b/test/suites/valid-strip/simple-int-1/output
deleted file mode 100644 (file)
index bace2a0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[1]
\ No newline at end of file
diff --git a/test/suites/valid-strip/simple-int-123/input b/test/suites/valid-strip/simple-int-123/input
deleted file mode 100644 (file)
index e47f69a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[123]
\ No newline at end of file
diff --git a/test/suites/valid-strip/simple-int-123/output b/test/suites/valid-strip/simple-int-123/output
deleted file mode 100644 (file)
index e47f69a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[123]
\ No newline at end of file
diff --git a/test/suites/valid-strip/simple-object/input b/test/suites/valid-strip/simple-object/input
deleted file mode 100644 (file)
index a34fb49..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"a":[]}
diff --git a/test/suites/valid-strip/simple-object/output b/test/suites/valid-strip/simple-object/output
deleted file mode 100644 (file)
index 982abe8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"a": []}
\ No newline at end of file
diff --git a/test/suites/valid-strip/simple-real/input b/test/suites/valid-strip/simple-real/input
deleted file mode 100644 (file)
index b02878e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[123.456789]
\ No newline at end of file
diff --git a/test/suites/valid-strip/simple-real/output b/test/suites/valid-strip/simple-real/output
deleted file mode 100644 (file)
index b02878e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[123.456789]
\ No newline at end of file
diff --git a/test/suites/valid-strip/string-escapes/input b/test/suites/valid-strip/string-escapes/input
deleted file mode 100644 (file)
index 7f49553..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\"\\\/\b\f\n\r\t"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/string-escapes/output b/test/suites/valid-strip/string-escapes/output
deleted file mode 100644 (file)
index ca5c1c6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\"\\/\b\f\n\r\t"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/three-byte-utf-8/input b/test/suites/valid-strip/three-byte-utf-8/input
deleted file mode 100644 (file)
index 25dcede..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\u0821 three-byte UTF-8"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/three-byte-utf-8/output b/test/suites/valid-strip/three-byte-utf-8/output
deleted file mode 100644 (file)
index c44d124..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["ࠡ three-byte UTF-8"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/true/input b/test/suites/valid-strip/true/input
deleted file mode 100644 (file)
index de601e3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[true]
\ No newline at end of file
diff --git a/test/suites/valid-strip/true/output b/test/suites/valid-strip/true/output
deleted file mode 100644 (file)
index de601e3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[true]
\ No newline at end of file
diff --git a/test/suites/valid-strip/two-byte-utf-8/input b/test/suites/valid-strip/two-byte-utf-8/input
deleted file mode 100644 (file)
index 627046a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\u0123 two-byte UTF-8"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/two-byte-utf-8/output b/test/suites/valid-strip/two-byte-utf-8/output
deleted file mode 100644 (file)
index 1f0988d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["ģ two-byte UTF-8"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/utf-8-string/input b/test/suites/valid-strip/utf-8-string/input
deleted file mode 100644 (file)
index 5372865..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["€þıœəßð some utf-8 ĸʒ×ŋµåäö𝄞"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/utf-8-string/output b/test/suites/valid-strip/utf-8-string/output
deleted file mode 100644 (file)
index 5372865..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["€þıœəßð some utf-8 ĸʒ×ŋµåäö𝄞"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/utf-surrogate-four-byte-encoding/input b/test/suites/valid-strip/utf-surrogate-four-byte-encoding/input
deleted file mode 100644 (file)
index 183855a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["\uD834\uDD1E surrogate, four-byte UTF-8"]
\ No newline at end of file
diff --git a/test/suites/valid-strip/utf-surrogate-four-byte-encoding/output b/test/suites/valid-strip/utf-surrogate-four-byte-encoding/output
deleted file mode 100644 (file)
index fa806d2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-["𝄞 surrogate, four-byte UTF-8"]
\ No newline at end of file
index cd88a07..fa594e6 100755 (executable)
@@ -11,19 +11,45 @@ is_test() {
     test -d $test_path
 }
 
+do_run() {
+    variant=$1
+    s=".$1"
+
+    strip=0
+    [ "$variant" = "strip" ] && strip=1
+
+    STRIP=$strip $json_process \
+        <$test_path/input >$test_log/stdout$s 2>$test_log/stderr$s
+    valgrind_check $test_log/stderr$s || return 1
+
+    ref=output
+    [ -f $test_path/output$s ] && ref=output$s
+
+    if ! cmp -s $test_path/$ref $test_log/stdout$s; then
+        echo $variant > $test_log/variant
+        return 1
+    fi
+}
+
 run_test() {
-    $json_process <$test_path/input >$test_log/stdout 2>$test_log/stderr
-    valgrind_check $test_log/stderr || return 1
-    cmp -s $test_path/output $test_log/stdout
+    do_run normal && do_run strip
 }
 
 show_error() {
     valgrind_show_error && return
 
+    read variant < $test_log/variant
+    s=".$variant"
+
+    echo "VARIANT: $variant"
+
     echo "EXPECTED OUTPUT:"
-    nl -bn $test_path/output
+    ref=output
+    [ -f $test_path/output$s ] && ref=output$s
+    nl -bn $test_path/$ref
+
     echo "ACTUAL OUTPUT:"
-    nl -bn $test_log/stdout
+    nl -bn $test_log/stdout$s
 }
 
 . $top_srcdir/test/scripts/run-tests.sh