diff --git a/src/libCom/test/Makefile b/src/libCom/test/Makefile
index 04438854c..e07360ac9 100755
--- a/src/libCom/test/Makefile
+++ b/src/libCom/test/Makefile
@@ -215,6 +215,10 @@ ipAddrToAsciiTest_SRCS += ipAddrToAsciiTest.cpp
testHarness_SRCS += ipAddrToAsciiTest.cpp
TESTS += ipAddrToAsciiTest
+TESTPROD_HOST += yajl_test
+yajl_test_SRCS += yajl_test.c
+TESTS += yajlTest
+
# The testHarness runs all the test programs in a known working order.
testHarness_SRCS += epicsRunLibComTests.c
diff --git a/src/libCom/test/yajlTest.plt b/src/libCom/test/yajlTest.plt
new file mode 100644
index 000000000..5c9052032
--- /dev/null
+++ b/src/libCom/test/yajlTest.plt
@@ -0,0 +1,51 @@
+#!/usr/bin/perl
+#
+# This is a test director for running yajl JSON parser tests.
+# The tests are actually defined in the yajlTestCases.pm module,
+# which is generated from the yajl cases by yajlTestConverter.pl
+
+use strict;
+use Test::More;
+use IO::Handle;
+use IPC::Open3;
+
+# Load test cases
+use lib "..";
+use yajlTestCases;
+
+my @cases = cases();
+plan tests => scalar @cases;
+
+# The yajl_test program reads JSON from stdin and sends a description
+# of what it got to stdout, with errors going to stderr. We merge the
+# two output streams for the purpose of checking the test results.
+my $prog = './yajl_test';
+$prog .= '.exe' if ($^O eq 'MSWin32') || ($^O eq 'cygwin');
+
+foreach my $case (@cases) {
+ my $name = $case->{name};
+ my @opts = @{$case->{opts}};
+ my @input = @{$case->{input}};
+ my @gives = @{$case->{gives}};
+
+ my ($rx, $tx);
+ my $pid = open3($tx, $rx, 0, $prog, @opts);
+
+ # Send the test case, then EOF
+ print $tx join "\n", @input;
+ close $tx;
+
+ # Receive the result
+ my @result;
+ while (!$rx->eof) {
+ chomp(my $line = <$rx>);
+ push @result, $line;
+ }
+ close $rx;
+
+ # Clean up the child process
+ waitpid $pid, 0;
+
+ # Report the result of this test case
+ is_deeply(\@result, \@gives, $name);
+}
diff --git a/src/libCom/test/yajlTestCases.pm b/src/libCom/test/yajlTestCases.pm
new file mode 100644
index 000000000..9064df043
--- /dev/null
+++ b/src/libCom/test/yajlTestCases.pm
@@ -0,0 +1,3046 @@
+# Parser test cases from https://github.com/lloyd/yajl
+#
+# This file is generated, DO NOT EDIT!
+#
+# See comments in yajlTestConverter.pl for instructions on
+# how to regenerate this file from the original yajl sources.
+
+sub cases {
+ my $VAR1 = [
+ {
+ name => "difficult_json_c_test_case_with_comments",
+ opts => [
+ "-c"
+ ],
+ input => [
+ "{ \"glossary\": { /* you */ \"title\": /**/ \"example glossary\", /*should*/\"GlossDiv\": { \"title\": /*never*/\"S\", /*ever*/\"GlossList\": [ { \"ID\": \"SGML\", \"SortAs\": \"SGML\", \"GlossTerm\": \"Standard Generalized Markup Language\", \"Acronym\": \"SGML\", \"Abbrev\": \"ISO 8879:1986\", \"GlossDef\": \"A meta-markup language, used to create markup languages such as DocBook.\", /*see*/\"GlossSeeAlso\"/*this*/:/*coming*/[/*out*/\"GML\"/*of*/,/*the*/\"XML\"/*parser!*/, \"markup\"] /*hey*/}/*ho*/]/*hey*/}/*ho*/} } // and the parser won't even get this far, so chill. /* hah!",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "key: 'glossary'",
+ "map open '{'",
+ "key: 'title'",
+ "string: 'example glossary'",
+ "key: 'GlossDiv'",
+ "map open '{'",
+ "key: 'title'",
+ "string: 'S'",
+ "key: 'GlossList'",
+ "array open '['",
+ "map open '{'",
+ "key: 'ID'",
+ "string: 'SGML'",
+ "key: 'SortAs'",
+ "string: 'SGML'",
+ "key: 'GlossTerm'",
+ "string: 'Standard Generalized Markup Language'",
+ "key: 'Acronym'",
+ "string: 'SGML'",
+ "key: 'Abbrev'",
+ "string: 'ISO 8879:1986'",
+ "key: 'GlossDef'",
+ "string: 'A meta-markup language, used to create markup languages such as DocBook.'",
+ "key: 'GlossSeeAlso'",
+ "array open '['",
+ "string: 'GML'",
+ "string: 'XML'",
+ "string: 'markup'",
+ "array close ']'",
+ "map close '}'",
+ "array close ']'",
+ "map close '}'",
+ "map close '}'",
+ "map close '}'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "simple_with_comments",
+ opts => [
+ "-c"
+ ],
+ input => [
+ "{",
+ " \"this\": \"is\", // ignore this",
+ " \"really\": \"simple\",",
+ " /* ignore",
+ "this",
+ "too * / ",
+ "** //",
+ "(/",
+ "******/",
+ " \"json\": \"right?\"",
+ "}",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "key: 'this'",
+ "string: 'is'",
+ "key: 'really'",
+ "string: 'simple'",
+ "key: 'json'",
+ "string: 'right?'",
+ "map close '}'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "false_then_garbage",
+ opts => [
+ "-g"
+ ],
+ input => [
+ "falsex"
+ ],
+ gives => [
+ "bool: false",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "null_then_garbage",
+ opts => [
+ "-g"
+ ],
+ input => [
+ "nullx",
+ ""
+ ],
+ gives => [
+ "null",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "true_then_garbage",
+ opts => [
+ "-g"
+ ],
+ input => [
+ "truex"
+ ],
+ gives => [
+ "bool: true",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "eof",
+ opts => [
+ "-m"
+ ],
+ input => [
+ "{ \"123\":",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "key: '123'",
+ "parse error: premature EOF",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "integers",
+ opts => [
+ "-m"
+ ],
+ input => [
+ "1221 21",
+ ""
+ ],
+ gives => [
+ "integer: 1221",
+ "integer: 21",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "multiple",
+ opts => [
+ "-m"
+ ],
+ input => [
+ "",
+ "{}",
+ "{}",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "map close '}'",
+ "map open '{'",
+ "map close '}'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "stuff",
+ opts => [
+ "-m"
+ ],
+ input => [
+ "{}",
+ "[]",
+ "[]",
+ "\"sdfasd\"",
+ 123,
+ "{ \"123\" : 123 }",
+ "3.1e124",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "map close '}'",
+ "array open '['",
+ "array close ']'",
+ "array open '['",
+ "array close ']'",
+ "string: 'sdfasd'",
+ "integer: 123",
+ "map open '{'",
+ "key: '123'",
+ "integer: 123",
+ "map close '}'",
+ "double: 3.1e+124",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "array_open",
+ opts => [
+ "-p"
+ ],
+ input => [
+ "[",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "eof_str",
+ opts => [
+ "-p"
+ ],
+ input => [
+ "\"abc"
+ ],
+ gives => [
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "map_open",
+ opts => [
+ "-p"
+ ],
+ input => [
+ "{",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "partial_ok",
+ opts => [
+ "-p"
+ ],
+ input => [
+ "[ \"foo\", \"bar\"",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "string: 'foo'",
+ "string: 'bar'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "array",
+ opts => [],
+ input => [
+ "[\"foo\",",
+ " \"bar\", \"baz\",",
+ " true,false,null,{\"key\":\"value\"},",
+ " [null,null,null,[]],",
+ " \"\\n\\r\\\\\"",
+ "]",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "string: 'foo'",
+ "string: 'bar'",
+ "string: 'baz'",
+ "bool: true",
+ "bool: false",
+ "null",
+ "map open '{'",
+ "key: 'key'",
+ "string: 'value'",
+ "map close '}'",
+ "array open '['",
+ "null",
+ "null",
+ "null",
+ "array open '['",
+ "array close ']'",
+ "array close ']'",
+ "string: '",
+ "\r\\'",
+ "array close ']'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "array_close",
+ opts => [],
+ input => [
+ "]",
+ ""
+ ],
+ gives => [
+ "parse error: unallowed token at this point in JSON text",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "bignums",
+ opts => [],
+ input => [
+ "[ 9223372036854775807, -9223372036854775807 ]",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "integer: 9223372036854775807",
+ "integer: -9223372036854775807",
+ "array close ']'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "bogus_char",
+ opts => [],
+ input => [
+ "[\"this\",\"is\",\"what\",\"should\",\"be\",",
+ " \"a happy bit of json\",",
+ " \"but someone, misspelled \\\"true\\\"\", ture,",
+ " \"who says JSON is easy for humans to generate?\"]",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "string: 'this'",
+ "string: 'is'",
+ "string: 'what'",
+ "string: 'should'",
+ "string: 'be'",
+ "string: 'a happy bit of json'",
+ "string: 'but someone, misspelled \"true\"'",
+ "lexical error: invalid string in json text.",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "codepoints_from_unicode_org",
+ opts => [],
+ input => [
+ "\"\\u004d\\u0430\\u4e8c\\ud800\\udf02\"",
+ ""
+ ],
+ gives => [
+ "string: 'M\320\260\344\272\214\360\220\214\202'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "deep_arrays",
+ opts => [],
+ input => [
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
+ ],
+ gives => [
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array open '['",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "array close ']'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "difficult_json_c_test_case",
+ opts => [],
+ input => [
+ "{ \"glossary\": { \"title\": \"example glossary\", \"GlossDiv\": { \"title\": \"S\", \"GlossList\": [ { \"ID\": \"SGML\", \"SortAs\": \"SGML\", \"GlossTerm\": \"Standard Generalized Markup Language\", \"Acronym\": \"SGML\", \"Abbrev\": \"ISO 8879:1986\", \"GlossDef\": \"A meta-markup language, used to create markup languages such as DocBook.\", \"GlossSeeAlso\": [\"GML\", \"XML\", \"markup\"] } ] } } }",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "key: 'glossary'",
+ "map open '{'",
+ "key: 'title'",
+ "string: 'example glossary'",
+ "key: 'GlossDiv'",
+ "map open '{'",
+ "key: 'title'",
+ "string: 'S'",
+ "key: 'GlossList'",
+ "array open '['",
+ "map open '{'",
+ "key: 'ID'",
+ "string: 'SGML'",
+ "key: 'SortAs'",
+ "string: 'SGML'",
+ "key: 'GlossTerm'",
+ "string: 'Standard Generalized Markup Language'",
+ "key: 'Acronym'",
+ "string: 'SGML'",
+ "key: 'Abbrev'",
+ "string: 'ISO 8879:1986'",
+ "key: 'GlossDef'",
+ "string: 'A meta-markup language, used to create markup languages such as DocBook.'",
+ "key: 'GlossSeeAlso'",
+ "array open '['",
+ "string: 'GML'",
+ "string: 'XML'",
+ "string: 'markup'",
+ "array close ']'",
+ "map close '}'",
+ "array close ']'",
+ "map close '}'",
+ "map close '}'",
+ "map close '}'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "doubles",
+ opts => [],
+ input => [
+ "[ 0.1e2, 1e1, 3.141569, 10000000000000e-10]",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "double: 10",
+ "double: 10",
+ "double: 3.14157",
+ "double: 1000",
+ "array close ']'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "doubles_in_array",
+ opts => [],
+ input => [
+ "[0.00011999999999999999, 6E-06, 6E-06, 1E-06, 1E-06]",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "double: 0.00012",
+ "double: 6e-06",
+ "double: 6e-06",
+ "double: 1e-06",
+ "double: 1e-06",
+ "array close ']'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "empty_array",
+ opts => [],
+ input => [
+ "[]"
+ ],
+ gives => [
+ "array open '['",
+ "array close ']'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "empty_string",
+ opts => [],
+ input => [
+ "\"\"",
+ ""
+ ],
+ gives => [
+ "string: ''",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "escaped_bulgarian",
+ opts => [],
+ input => [
+ "[\"\\u0414\\u0430\",",
+ " \"\\u041c\\u0443\",",
+ " \"\\u0415\\u0431\\u0430\",",
+ " \"\\u041c\\u0430\\u0439\\u043a\\u0430\\u0442\\u0430\"]",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "string: '\320\224\320\260'",
+ "string: '\320\234\321\203'",
+ "string: '\320\225\320\261\320\260'",
+ "string: '\320\234\320\260\320\271\320\272\320\260\321\202\320\260'",
+ "array close ']'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "escaped_foobar",
+ opts => [],
+ input => [
+ "\"\\u0066\\u006f\\u006f\\u0062\\u0061\\u0072\"",
+ ""
+ ],
+ gives => [
+ "string: 'foobar'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "false",
+ opts => [],
+ input => [
+ "false",
+ ""
+ ],
+ gives => [
+ "bool: false",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "false_then_garbage",
+ opts => [],
+ input => [
+ "falsex"
+ ],
+ gives => [
+ "bool: false",
+ "parse error: trailing garbage",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "issue_7",
+ opts => [],
+ input => [
+ "2009-10-20\@20:38:21.539575",
+ ""
+ ],
+ gives => [
+ "integer: 2009",
+ "parse error: trailing garbage",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "null_then_garbage",
+ opts => [],
+ input => [
+ "nullx",
+ ""
+ ],
+ gives => [
+ "null",
+ "parse error: trailing garbage",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "true_then_garbage",
+ opts => [],
+ input => [
+ "truex",
+ ""
+ ],
+ gives => [
+ "bool: true",
+ "parse error: trailing garbage",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "four_byte_utf8",
+ opts => [],
+ input => [
+ "{ \"U+10ABCD\": \"\364\212\257\215\" }",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "key: 'U+10ABCD'",
+ "string: '\364\212\257\215'",
+ "map close '}'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "high_overflow",
+ opts => [],
+ input => [
+ "9223372036854775808"
+ ],
+ gives => [
+ "parse error: integer overflow",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "integers",
+ opts => [],
+ input => [
+ "[ 1,2,3,4,5,6,7,",
+ " 123456789 , -123456789,",
+ " 2147483647, -2147483647 ]",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "integer: 1",
+ "integer: 2",
+ "integer: 3",
+ "integer: 4",
+ "integer: 5",
+ "integer: 6",
+ "integer: 7",
+ "integer: 123456789",
+ "integer: -123456789",
+ "integer: 2147483647",
+ "integer: -2147483647",
+ "array close ']'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "invalid_utf8",
+ opts => [],
+ input => [
+ "[\"\320\224\320\260 \320\234\321 \320\225\320\261\320\260 \320\234\320\260\320\271\320\272\320\260\321\202\320\260\"]",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "lexical error: invalid bytes in UTF8 string.",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "isolated_surrogate_marker",
+ opts => [],
+ input => [
+ "\"\\ud800\"",
+ ""
+ ],
+ gives => [
+ "string: '?'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "leading_zero_in_number",
+ opts => [],
+ input => [
+ "{ \"bad thing\": 01 }",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "key: 'bad thing'",
+ "integer: 0",
+ "parse error: after key and value, inside map, I expect ',' or '}'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "lonely_minus_sign",
+ opts => [],
+ input => [
+ "[",
+ "\t\t\"foo\", true,",
+ "\t\ttrue, \"blue\",",
+ "\t\t\"baby where are you?\", \"oh boo hoo!\",",
+ " - ",
+ "]",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "string: 'foo'",
+ "bool: true",
+ "bool: true",
+ "string: 'blue'",
+ "string: 'baby where are you?'",
+ "string: 'oh boo hoo!'",
+ "lexical error: malformed number, a digit is required after the minus sign.",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "lonely_number",
+ opts => [],
+ input => [
+ 123456789
+ ],
+ gives => [
+ "integer: 123456789",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "low_overflow",
+ opts => [],
+ input => [
+ "-9223372036854775808"
+ ],
+ gives => [
+ "parse error: integer overflow",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "map_close",
+ opts => [],
+ input => [
+ "}",
+ ""
+ ],
+ gives => [
+ "parse error: unallowed token at this point in JSON text",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "missing_integer_after_decimal_point",
+ opts => [],
+ input => [
+ "10.e2",
+ ""
+ ],
+ gives => [
+ "lexical error: malformed number, a digit is required after the decimal point.",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "missing_integer_after_exponent",
+ opts => [],
+ input => [
+ "10e",
+ ""
+ ],
+ gives => [
+ "lexical error: malformed number, a digit is required after the exponent.",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "multiple",
+ opts => [],
+ input => [
+ "",
+ "{}",
+ "{}",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "map close '}'",
+ "parse error: trailing garbage",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "non_utf8_char_in_string",
+ opts => [],
+ input => [
+ "{\"CoreletAPIVersion\":2,\"CoreletType\":\"standalone\",\"documentation\":\"A corelet that provides the capability to upload a folder\222s contents into a user\222s locker.\",\"functions\":[{\"documentation\":\"Displays a dialog box that allows user to select a folder on the local system.\",\"name\":\"ShowBrowseDialog\",\"parameters\":[{\"documentation\":\"The callback function for results.\",\"name\":\"callback\",\"required\":true,\"type\":\"callback\"}]},{\"documentation\":\"Uploads all mp3 files in the folder provided.\",\"name\":\"UploadFolder\",\"parameters\":[{\"documentation\":\"The path to upload mp3 files from.\",\"name\":\"path\",\"required\":true,\"type\":\"string\"},{\"documentation\":\"The callback function for progress.\",\"name\":\"callback\",\"required\":true,\"type\":\"callback\"}]},{\"documentation\":\"Returns the server name to the current locker service.\",\"name\":\"GetLockerService\",\"parameters\":[]},{\"documentation\":\"Changes the name of the locker service.\",\"name\":\"SetLockerService\",\"parameters\":[{\"documentation\":\"The value of the locker service to set active.\",\"name\":\"LockerService\",\"required\":true,\"type\":\"string\"}]},{\"documentation\":\"Downloads locker files to the suggested folder.\",\"name\":\"DownloadFile\",\"parameters\":[{\"documentation\":\"The origin path of the locker file.\",\"name\":\"path\",\"required\":true,\"type\":\"string\"},{\"documentation\":\"The Window destination path of the locker file.\",\"name\":\"destination\",\"required\":true,\"type\":\"integer\"},{\"documentation\":\"The callback function for progress.\",\"name\":\"callback\",\"required\":true,\"type\":\"callback\"}]}],\"name\":\"LockerUploader\",\"version\":{\"major\":0,\"micro\":1,\"minor\":0},\"versionString\":\"0.0.1\"}"
+ ],
+ gives => [
+ "map open '{'",
+ "key: 'CoreletAPIVersion'",
+ "integer: 2",
+ "key: 'CoreletType'",
+ "string: 'standalone'",
+ "key: 'documentation'",
+ "lexical error: invalid bytes in UTF8 string.",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "partial_bad",
+ opts => [],
+ input => [
+ "[ \"foo\", \"bar\"",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "string: 'foo'",
+ "string: 'bar'",
+ "parse error: premature EOF",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "null",
+ opts => [],
+ input => [
+ "null",
+ ""
+ ],
+ gives => [
+ "null",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "nulls_and_bools",
+ opts => [],
+ input => [
+ "{",
+ "\t\"boolean, true\": true,",
+ "\t\"boolean, false\": false,",
+ "\t\"null\": null",
+ "}",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "key: 'boolean, true'",
+ "bool: true",
+ "key: 'boolean, false'",
+ "bool: false",
+ "key: 'null'",
+ "null",
+ "map close '}'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "simple",
+ opts => [],
+ input => [
+ "{",
+ " \"this\": \"is\",",
+ " \"really\": \"simple\",",
+ " \"json\": \"right?\"",
+ "}",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "key: 'this'",
+ "string: 'is'",
+ "key: 'really'",
+ "string: 'simple'",
+ "key: 'json'",
+ "string: 'right?'",
+ "map close '}'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "simple_with_comments",
+ opts => [],
+ input => [
+ "{",
+ " \"this\": \"is\", // ignore this",
+ " \"really\": \"simple\",",
+ " /* ignore",
+ "this",
+ "too * / ",
+ "** //",
+ "(/",
+ "******/",
+ " \"json\": \"right?\"",
+ "}",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "key: 'this'",
+ "string: 'is'",
+ "lexical error: probable comment found in input text, comments are not enabled.",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "string_invalid_escape",
+ opts => [],
+ input => [
+ "[\"\\n foo \\/ bar \\r\\f\\\\\\uffff\\t\\b\\\"\\\\ and you can't escape thi\\s\"]",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "lexical error: inside a string, '\\' occurs before a character which it may not.",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "string_invalid_hex_char",
+ opts => [],
+ input => [
+ "\"foo foo, blah blah \\u0123 \\u4567 \\u89ab \\uc/ef \\uABCD \\uEFFE bar baz bing\"",
+ ""
+ ],
+ gives => [
+ "lexical error: invalid (non-hex) character occurs after '\\u' inside string.",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "string_with_escapes",
+ opts => [],
+ input => [
+ "[\"\\n foo \\/ bar \\r\\f\\\\\\uffff\\t\\b\\\"\\\\\",",
+ " \"\\\"and this string has an escape at the beginning\",",
+ " \"and this string has no escapes\" ]",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "string: '",
+ " foo / bar \r\f\\\357\277\277\t\b\"\\'",
+ "string: '\"and this string has an escape at the beginning'",
+ "string: 'and this string has no escapes'",
+ "array close ']'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "string_with_invalid_newline",
+ opts => [],
+ input => [
+ "\"la di dah. this is a string, and I can do this, \\n, but not this",
+ "\"",
+ ""
+ ],
+ gives => [
+ "lexical error: invalid character inside string.",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "three_byte_utf8",
+ opts => [],
+ input => [
+ "{\"matzue\": \"\346\235\276\346\261\237\", \"asakusa\": \"\346\265\205\350\215\211\"}",
+ ""
+ ],
+ gives => [
+ "map open '{'",
+ "key: 'matzue'",
+ "string: '\346\235\276\346\261\237'",
+ "key: 'asakusa'",
+ "string: '\346\265\205\350\215\211'",
+ "map close '}'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "true",
+ opts => [],
+ input => [
+ "true",
+ ""
+ ],
+ gives => [
+ "bool: true",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "unescaped_bulgarian",
+ opts => [],
+ input => [
+ "[\"\320\224\320\260 \320\234\321\203 \320\225\320\261\320\260 \320\234\320\260\320\271\320\272\320\260\321\202\320\260\"]",
+ ""
+ ],
+ gives => [
+ "array open '['",
+ "string: '\320\224\320\260 \320\234\321\203 \320\225\320\261\320\260 \320\234\320\260\320\271\320\272\320\260\321\202\320\260'",
+ "array close ']'",
+ "memory leaks:\t0"
+ ]
+ },
+ {
+ name => "zerobyte",
+ opts => [],
+ input => [
+ "\"\\u0000\"",
+ ""
+ ],
+ gives => [
+ "string: '\0'",
+ "memory leaks:\t0"
+ ]
+ }
+ ];
+
+ return @{$VAR1};
+}
+
+1;
diff --git a/src/libCom/test/yajlTestConverter.pl b/src/libCom/test/yajlTestConverter.pl
new file mode 100755
index 000000000..c3d2b54b6
--- /dev/null
+++ b/src/libCom/test/yajlTestConverter.pl
@@ -0,0 +1,98 @@
+#!/usr/bin/perl
+#
+# This script converts the parsing test cases from the yajl release tree
+# into the yajlTestCases module as used by libCom/test/yajlTest.plt
+#
+# Re-do this conversion and commit after checking out a new version of yajl
+# from https://github.com/lloyd/yajl as follows:
+# $ cd /src/libCom/test
+# $ perl yajlTestConverter.pl /path/to/yajl
+# The tests are saved into the file yajlTestCases.pm in the src/libCom/test
+# directory which will be read by the yajlTest.t test script.
+
+use Data::Dumper;
+
+my $yajl = shift @ARGV
+ or die "Usage: $0 /path/to/yajl\n";
+
+my @files = glob "$yajl/test/parsing/cases/*.json";
+
+my $caseFile = 'yajlTestCases.pm';
+
+my @cases;
+
+for my $file (@files) {
+ $file =~ m|/([afn][cgmp]_)?([^/]*)\.json$|;
+ my $allow = $1;
+ my $name = $2;
+ next if $name eq '';
+
+ my $case = { name => $name };
+
+ if ($allow eq 'ac_') {
+ $case->{opts} = ['-c'];
+ }
+ elsif ($allow eq 'ag_') {
+ $case->{opts} = ['-g'];
+ }
+ elsif ($allow eq 'am_') {
+ $case->{opts} = ['-m'];
+ }
+ elsif ($allow eq 'ap_') {
+ $case->{opts} = ['-p'];
+ }
+ else {
+ $case->{opts} = [];
+ }
+
+ my $input = slurp($file);
+ my @input = split "\n", $input;
+ push @input, '' if $input =~ m/\n$/;
+ $case->{input} = \@input;
+
+ my @gives = split "\n", slurp("$file.gold");
+ $case->{gives} = \@gives;
+
+ push @cases, $case;
+}
+
+# Configure Dumper() output
+$Data::Dumper::Pad = ' ';
+$Data::Dumper::Indent = 1;
+$Data::Dumper::Useqq = 1;
+$Data::Dumper::Quotekeys = 0;
+$Data::Dumper::Sortkeys = sub { return ['name', 'opts', 'input', 'gives'] };
+
+my $data = Dumper(\@cases);
+
+open my $out, '>', $caseFile
+ or die "Can't open/create $caseFile: $@\n";
+print $out <<"EOF";
+# Parser test cases from https://github.com/lloyd/yajl
+#
+# This file is generated, DO NOT EDIT!
+#
+# See comments in yajlTestConverter.pl for instructions on
+# how to regenerate this file from the original yajl sources.
+
+sub cases {
+ my$data
+ return \@{\$VAR1};
+}
+
+1;
+EOF
+
+close $out
+ or die "Problem writing $caseFile: $@\n";
+
+exit 0;
+
+
+sub slurp {
+ my ($file) = @_;
+ open my $in, '<', $file
+ or die "Can't open file $file: $!\n";
+ my $contents = do { local $/; <$in> };
+ return $contents;
+}
diff --git a/src/libCom/test/yajl_test.c b/src/libCom/test/yajl_test.c
new file mode 100644
index 000000000..c07210ac2
--- /dev/null
+++ b/src/libCom/test/yajl_test.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2007-2014, Lloyd Hilaiel
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+/* memory debugging routines */
+typedef struct
+{
+ unsigned int numFrees;
+ unsigned int numMallocs;
+ /* XXX: we really need a hash table here with per-allocation
+ * information */
+} yajlTestMemoryContext;
+
+/* cast void * into context */
+#define TEST_CTX(vptr) ((yajlTestMemoryContext *) (vptr))
+
+static void yajlTestFree(void * ctx, void * ptr)
+{
+ assert(ptr != NULL);
+ TEST_CTX(ctx)->numFrees++;
+ free(ptr);
+}
+
+static void * yajlTestMalloc(void * ctx, size_t sz)
+{
+ assert(sz != 0);
+ TEST_CTX(ctx)->numMallocs++;
+ return malloc(sz);
+}
+
+static void * yajlTestRealloc(void * ctx, void * ptr, size_t sz)
+{
+ if (ptr == NULL) {
+ assert(sz != 0);
+ TEST_CTX(ctx)->numMallocs++;
+ } else if (sz == 0) {
+ TEST_CTX(ctx)->numFrees++;
+ }
+
+ return realloc(ptr, sz);
+}
+
+
+/* begin parsing callback routines */
+#define BUF_SIZE 2048
+
+static int test_yajl_null(void *ctx)
+{
+ printf("null\n");
+ return 1;
+}
+
+static int test_yajl_boolean(void * ctx, int boolVal)
+{
+ printf("bool: %s\n", boolVal ? "true" : "false");
+ return 1;
+}
+
+static int test_yajl_integer(void *ctx, long long integerVal)
+{
+ printf("integer: %lld\n", integerVal);
+ return 1;
+}
+
+static int test_yajl_double(void *ctx, double doubleVal)
+{
+ printf("double: %g\n", doubleVal);
+ return 1;
+}
+
+static int test_yajl_string(void *ctx, const unsigned char * stringVal,
+ size_t stringLen)
+{
+ printf("string: '");
+ fwrite(stringVal, 1, stringLen, stdout);
+ printf("'\n");
+ return 1;
+}
+
+static int test_yajl_map_key(void *ctx, const unsigned char * stringVal,
+ size_t stringLen)
+{
+ char * str = (char *) malloc(stringLen + 1);
+ str[stringLen] = 0;
+ memcpy(str, stringVal, stringLen);
+ printf("key: '%s'\n", str);
+ free(str);
+ return 1;
+}
+
+static int test_yajl_start_map(void *ctx)
+{
+ printf("map open '{'\n");
+ return 1;
+}
+
+
+static int test_yajl_end_map(void *ctx)
+{
+ printf("map close '}'\n");
+ return 1;
+}
+
+static int test_yajl_start_array(void *ctx)
+{
+ printf("array open '['\n");
+ return 1;
+}
+
+static int test_yajl_end_array(void *ctx)
+{
+ printf("array close ']'\n");
+ return 1;
+}
+
+static yajl_callbacks callbacks = {
+ test_yajl_null,
+ test_yajl_boolean,
+ test_yajl_integer,
+ test_yajl_double,
+ NULL,
+ test_yajl_string,
+ test_yajl_start_map,
+ test_yajl_map_key,
+ test_yajl_end_map,
+ test_yajl_start_array,
+ test_yajl_end_array
+};
+
+static void usage(const char * progname)
+{
+ fprintf(stderr,
+ "usage: %s [options]\n"
+ "Parse input from stdin as JSON and ouput parsing details "
+ "to stdout\n"
+ " -b set the read buffer size\n"
+ " -c allow comments\n"
+ " -g allow *g*arbage after valid JSON text\n"
+ " -h print this help message\n"
+ " -m allows the parser to consume multiple JSON values\n"
+ " from a single string separated by whitespace\n"
+ " -p partial JSON documents should not cause errors\n",
+ progname);
+ exit(1);
+}
+
+int
+main(int argc, char ** argv)
+{
+ yajl_handle hand;
+ const char * fileName = NULL;
+ static unsigned char * fileData = NULL;
+ FILE *file;
+ size_t bufSize = BUF_SIZE;
+ yajl_status stat;
+ size_t rd;
+ int i, j;
+
+ /* memory allocation debugging: allocate a structure which collects
+ * statistics */
+ yajlTestMemoryContext memCtx = { 0,0 };
+
+ /* memory allocation debugging: allocate a structure which holds
+ * allocation routines */
+ yajl_alloc_funcs allocFuncs = {
+ yajlTestMalloc,
+ yajlTestRealloc,
+ yajlTestFree,
+ (void *) NULL
+ };
+
+ allocFuncs.ctx = (void *) &memCtx;
+
+ /* allocate the parser */
+ hand = yajl_alloc(&callbacks, &allocFuncs, NULL);
+
+ /* check arguments. We expect exactly one! */
+ for (i=1;i= argc) usage(argv[0]);
+
+ /* validate integer */
+ for (j=0;j<(int)strlen(argv[i]);j++) {
+ if (argv[i][j] <= '9' && argv[i][j] >= '0') continue;
+ fprintf(stderr, "-b requires an integer argument. '%s' "
+ "is invalid\n", argv[i]);
+ usage(argv[0]);
+ }
+
+ bufSize = atoi(argv[i]);
+ if (!bufSize) {
+ fprintf(stderr, "%zu is an invalid buffer size\n",
+ bufSize);
+ }
+ } else if (!strcmp("-g", argv[i])) {
+ yajl_config(hand, yajl_allow_trailing_garbage, 1);
+ } else if (!strcmp("-h", argv[i])) {
+ usage(argv[0]);
+ } else if (!strcmp("-m", argv[i])) {
+ yajl_config(hand, yajl_allow_multiple_values, 1);
+ } else if (!strcmp("-p", argv[i])) {
+ yajl_config(hand, yajl_allow_partial_values, 1);
+ } else {
+ fileName = argv[i];
+ break;
+ }
+ }
+
+ fileData = (unsigned char *) malloc(bufSize);
+
+ if (fileData == NULL) {
+ fprintf(stderr,
+ "failed to allocate read buffer of %zu bytes, exiting.",
+ bufSize);
+ yajl_free(hand);
+ exit(2);
+ }
+
+ if (fileName)
+ {
+ file = fopen(fileName, "r");
+ }
+ else
+ {
+ file = stdin;
+ }
+ for (;;) {
+ rd = fread((void *) fileData, 1, bufSize, file);
+
+ if (rd == 0) {
+ if (!feof(stdin)) {
+ fprintf(stderr, "error reading from '%s'\n", fileName);
+ }
+ break;
+ }
+ /* read file data, now pass to parser */
+ stat = yajl_parse(hand, fileData, rd);
+
+ if (stat != yajl_status_ok) break;
+ }
+
+ stat = yajl_complete_parse(hand);
+ if (stat != yajl_status_ok)
+ {
+ unsigned char * str = yajl_get_error(hand, 0, fileData, rd);
+ fflush(stdout);
+ fprintf(stderr, "%s", (char *) str);
+ yajl_free_error(hand, str);
+ }
+
+ yajl_free(hand);
+ free(fileData);
+
+ if (fileName)
+ {
+ fclose(file);
+ }
+ /* finally, print out some memory statistics */
+
+/* (lth) only print leaks here, as allocations and frees may vary depending
+ * on read buffer size, causing false failures.
+ *
+ * printf("allocations:\t%u\n", memCtx.numMallocs);
+ * printf("frees:\t\t%u\n", memCtx.numFrees);
+*/
+ fflush(stderr);
+ fflush(stdout);
+ printf("memory leaks:\t%u\n", memCtx.numMallocs - memCtx.numFrees);
+
+ return 0;
+}