summaryrefslogtreecommitdiff
path: root/json-c
diff options
context:
space:
mode:
Diffstat (limited to 'json-c')
-rw-r--r--json-c/src/Android.configure.mk39
-rw-r--r--json-c/src/README.md63
-rw-r--r--json-c/src/configure.ac114
-rw-r--r--json-c/src/json-c-uninstalled.pc.in11
-rw-r--r--json-c/src/json-c.pc.in12
-rw-r--r--json-c/src/json-c.vcproj185
-rw-r--r--json-c/src/json-c.vcxproj165
-rw-r--r--json-c/src/json-c.vcxproj.filters90
-rw-r--r--json-c/src/json_c_version.c20
-rw-r--r--json-c/src/json_c_version.h22
-rw-r--r--json-c/src/json_config.h.win325
-rw-r--r--json-c/src/libjson.c26
-rw-r--r--json-c/src/math_compat.h31
-rw-r--r--json-c/src/random_seed.c238
-rw-r--r--json-c/src/random_seed.h25
-rw-r--r--json-c/src/tests/Makefile.am41
-rw-r--r--json-c/src/tests/parse_flags.c50
-rw-r--r--json-c/src/tests/parse_flags.h4
-rw-r--r--json-c/src/tests/test-defs.sh128
-rw-r--r--json-c/src/tests/test1.c134
-rw-r--r--json-c/src/tests/test1.expected36
-rw-r--r--json-c/src/tests/test1.test22
-rw-r--r--json-c/src/tests/test1Formatted_plain.expected36
-rw-r--r--json-c/src/tests/test1Formatted_pretty.expected59
-rw-r--r--json-c/src/tests/test1Formatted_spaced.expected36
-rw-r--r--json-c/src/tests/test2.c34
-rw-r--r--json-c/src/tests/test2.expected1
-rw-r--r--json-c/src/tests/test2.test22
-rw-r--r--json-c/src/tests/test2Formatted_plain.expected1
-rw-r--r--json-c/src/tests/test2Formatted_pretty.expected23
-rw-r--r--json-c/src/tests/test2Formatted_spaced.expected1
-rw-r--r--json-c/src/tests/test4.c53
-rw-r--r--json-c/src/tests/test4.expected3
-rw-r--r--json-c/src/tests/test4.test12
-rw-r--r--json-c/src/tests/testReplaceExisting.c78
-rw-r--r--json-c/src/tests/testReplaceExisting.expected15
-rw-r--r--json-c/src/tests/testReplaceExisting.test12
-rw-r--r--json-c/src/tests/test_cast.c111
-rw-r--r--json-c/src/tests/test_cast.expected56
-rw-r--r--json-c/src/tests/test_cast.test12
-rw-r--r--json-c/src/tests/test_charcase.c40
-rw-r--r--json-c/src/tests/test_charcase.expected1
-rw-r--r--json-c/src/tests/test_charcase.test12
-rw-r--r--json-c/src/tests/test_locale.c31
-rw-r--r--json-c/src/tests/test_locale.expected2
-rw-r--r--json-c/src/tests/test_locale.test12
-rw-r--r--json-c/src/tests/test_null.c57
-rw-r--r--json-c/src/tests/test_null.expected3
-rw-r--r--json-c/src/tests/test_null.test12
-rw-r--r--json-c/src/tests/test_parse.c342
-rw-r--r--json-c/src/tests/test_parse.expected70
-rw-r--r--json-c/src/tests/test_parse.test12
-rw-r--r--json-c/src/tests/test_parse_int64.c115
-rw-r--r--json-c/src/tests/test_parse_int64.expected29
-rw-r--r--json-c/src/tests/test_parse_int64.test12
-rw-r--r--json-c/src/tests/test_printbuf.c166
-rw-r--r--json-c/src/tests/test_printbuf.expected32
-rw-r--r--json-c/src/tests/test_printbuf.test12
-rw-r--r--json-c/src/tests/test_set_serializer.c71
-rw-r--r--json-c/src/tests/test_set_serializer.expected10
-rw-r--r--json-c/src/tests/test_set_serializer.test12
61 files changed, 3079 insertions, 0 deletions
diff --git a/json-c/src/Android.configure.mk b/json-c/src/Android.configure.mk
new file mode 100644
index 0000000..c52c220
--- /dev/null
+++ b/json-c/src/Android.configure.mk
@@ -0,0 +1,39 @@
+# This file is the top android makefile for all sub-modules.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+json_c_TOP := $(LOCAL_PATH)
+
+JSON_C_BUILT_SOURCES := Android.mk
+
+JSON_C_BUILT_SOURCES := $(patsubst %, $(abspath $(json_c_TOP))/%, $(JSON_C_BUILT_SOURCES))
+
+.PHONY: json-c-configure json-c-configure-real
+json-c-configure-real:
+ echo $(JSON_C_BUILT_SOURCES)
+ cd $(json_c_TOP) ; \
+ $(abspath $(json_c_TOP))/autogen.sh && \
+ CC="$(CONFIGURE_CC)" \
+ CFLAGS="$(CONFIGURE_CFLAGS)" \
+ LD=$(TARGET_LD) \
+ LDFLAGS="$(CONFIGURE_LDFLAGS)" \
+ CPP=$(CONFIGURE_CPP) \
+ CPPFLAGS="$(CONFIGURE_CPPFLAGS)" \
+ PKG_CONFIG_LIBDIR=$(CONFIGURE_PKG_CONFIG_LIBDIR) \
+ PKG_CONFIG_TOP_BUILD_DIR=/ \
+ ac_cv_func_malloc_0_nonnull=yes \
+ ac_cv_func_realloc_0_nonnull=yes \
+ $(abspath $(json_c_TOP))/$(CONFIGURE) --host=$(CONFIGURE_HOST) \
+ --prefix=/system \
+ && \
+ for file in $(JSON_C_BUILT_SOURCES); do \
+ rm -f $$file && \
+ make -C $$(dirname $$file) $$(basename $$file) ; \
+ done
+
+json-c-configure: json-c-configure-real
+
+PA_CONFIGURE_TARGETS += json-c-configure
+
+-include $(json_c_TOP)/Android.mk
diff --git a/json-c/src/README.md b/json-c/src/README.md
new file mode 100644
index 0000000..3d009b5
--- /dev/null
+++ b/json-c/src/README.md
@@ -0,0 +1,63 @@
+`json-c`
+========
+
+Building on Unix with `git`, `gcc` and `autotools`
+--------------------------------------------------
+
+Home page for json-c: https://github.com/json-c/json-c/wiki
+
+Caution: do **NOT** use sources from svn.metaparadigm.com,
+they are old.
+
+Prerequisites:
+
+ - `gcc`, `clang`, or another C compiler
+ - `libtool`
+
+If you're not using a release tarball, you'll also need:
+
+ - `autoconf` (`autoreconf`)
+ - `automake`
+
+Make sure you have a complete `libtool` install, including `libtoolize`.
+
+`json-c` GitHub repo: https://github.com/json-c/json-c
+
+```bash
+$ git clone https://github.com/json-c/json-c.git
+$ cd json-c
+$ sh autogen.sh
+```
+
+followed by
+
+```bash
+$ ./configure
+$ make
+$ make install
+```
+
+To build and run the test programs:
+
+```bash
+$ make check
+```
+
+Linking to `libjson-c`
+----------------------
+
+If your system has `pkgconfig`,
+then you can just add this to your `makefile`:
+
+```make
+CFLAGS += $(shell pkg-config --cflags json-c)
+LDFLAGS += $(shell pkg-config --libs json-c)
+```
+
+Without `pkgconfig`, you would do something like this:
+
+```make
+JSON_C_DIR=/path/to/json_c/install
+CFLAGS += -I$(JSON_C_DIR)/include/json-c
+LDFLAGS+= -L$(JSON_C_DIR)/lib -ljson-c
+```
diff --git a/json-c/src/configure.ac b/json-c/src/configure.ac
new file mode 100644
index 0000000..94b0d0c
--- /dev/null
+++ b/json-c/src/configure.ac
@@ -0,0 +1,114 @@
+AC_PREREQ(2.52)
+
+# Process this file with autoconf to produce a configure script.
+AC_INIT([json-c], 0.12.99, [json-c@googlegroups.com])
+
+AM_INIT_AUTOMAKE
+
+AC_PROG_MAKE_SET
+
+AC_ARG_ENABLE(rdrand,
+ AS_HELP_STRING([--enable-rdrand],
+ [Enable RDRAND Hardware RNG Hash Seed generation on supported x86/x64 platforms.]),
+[if test x$enableval = xyes; then
+ enable_rdrand=yes
+ AC_DEFINE(ENABLE_RDRAND, 1, [Enable RDRANR Hardware RNG Hash Seed])
+fi])
+
+if test "x$enable_rdrand" = "xyes"; then
+ AC_MSG_RESULT([RDRAND Hardware RNG Hash Seed enabled on supported x86/x64 platforms])
+else
+ AC_MSG_RESULT([RDRAND Hardware RNG Hash Seed disabled. Use --enable-rdrand to enable])
+fi
+
+# enable silent build by default
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+# Checks for programs.
+
+# Checks for libraries.
+
+# Checks for header files.
+AM_PROG_CC_C_O
+AC_CONFIG_HEADER(config.h)
+AC_CONFIG_HEADER(json_config.h)
+AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h limits.h strings.h syslog.h unistd.h [sys/cdefs.h] [sys/param.h] stdarg.h locale.h endian.h)
+AC_CHECK_HEADER(inttypes.h,[AC_DEFINE([JSON_C_HAVE_INTTYPES_H],[1],[Public define for json_inttypes.h])])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+
+# Checks for library functions.
+AC_FUNC_VPRINTF
+AC_FUNC_MEMCMP
+AC_FUNC_MALLOC
+AC_FUNC_REALLOC
+AC_CHECK_FUNCS(strcasecmp strdup strerror snprintf vsnprintf vasprintf open vsyslog strncasecmp setlocale)
+AC_CHECK_DECLS([INFINITY], [], [], [[#include <math.h>]])
+AC_CHECK_DECLS([nan], [], [], [[#include <math.h>]])
+AC_CHECK_DECLS([isnan], [], [], [[#include <math.h>]])
+AC_CHECK_DECLS([isinf], [], [], [[#include <math.h>]])
+AC_CHECK_DECLS([_isnan], [], [], [[#include <float.h>]])
+AC_CHECK_DECLS([_finite], [], [], [[#include <float.h>]])
+
+if test "$ac_cv_have_decl_isnan" = "yes" ; then
+ AC_TRY_LINK([#include <math.h>], [float f = 0.0; return isnan(f)], [], [LIBS="$LIBS -lm"])
+fi
+
+#check if .section.gnu.warning accepts long strings (for __warn_references)
+AC_LANG_PUSH([C])
+
+AC_MSG_CHECKING([if .gnu.warning accepts long strings])
+AC_LINK_IFELSE([AC_LANG_SOURCE([[
+extern void json_object_get();
+__asm__(".section .gnu.json_object_get,\n\t.ascii \"Please link against libjson-c instead of libjson\"\n\t.text");
+
+int main(int c,char* v) {return 0;}
+]])], [
+ AC_DEFINE(HAS_GNU_WARNING_LONG, 1, [Define if .gnu.warning accepts long strings.])
+ AC_MSG_RESULT(yes)
+], [
+ AC_MSG_RESULT(no)
+])
+
+AC_LANG_POP([C])
+
+AM_PROG_LIBTOOL
+
+# Check for the -Bsymbolic-functions linker flag
+AC_ARG_ENABLE([Bsymbolic],
+ [AS_HELP_STRING([--disable-Bsymbolic], [Avoid linking with -Bsymbolic-function])],
+ [],
+ [enable_Bsymbolic=check])
+
+AS_IF([test "x$enable_Bsymbolic" = "xcheck"],
+ [
+ saved_LDFLAGS="${LDFLAGS}"
+ AC_MSG_CHECKING([for -Bsymbolic-functions linker flag])
+ LDFLAGS=-Wl,-Bsymbolic-functions
+ AC_TRY_LINK([], [int main (void) { return 0; }],
+ [
+ AC_MSG_RESULT([yes])
+ enable_Bsymbolic=yes
+ ],
+ [
+ AC_MSG_RESULT([no])
+ enable_Bsymbolic=no
+ ])
+ LDFLAGS="${saved_LDFLAGS}"
+ ])
+
+AS_IF([test "x$enable_Bsymbolic" = "xyes"], [JSON_BSYMBOLIC_LDFLAGS=-Wl[,]-Bsymbolic-functions])
+AC_SUBST(JSON_BSYMBOLIC_LDFLAGS)
+
+AC_CONFIG_FILES([
+Makefile
+json-c.pc
+tests/Makefile
+json-c-uninstalled.pc
+])
+
+AC_OUTPUT
+
diff --git a/json-c/src/json-c-uninstalled.pc.in b/json-c/src/json-c-uninstalled.pc.in
new file mode 100644
index 0000000..288f29c
--- /dev/null
+++ b/json-c/src/json-c-uninstalled.pc.in
@@ -0,0 +1,11 @@
+prefix=
+exec_prefix=
+libdir=@abs_top_builddir@
+includedir=@abs_top_srcdir@
+
+Name: json
+Description: JSON implementation in C
+Version: @VERSION@
+Requires:
+Libs: -L@abs_top_builddir@ -ljson-c
+Cflags: -I@abs_top_srcdir@
diff --git a/json-c/src/json-c.pc.in b/json-c/src/json-c.pc.in
new file mode 100644
index 0000000..54b65e6
--- /dev/null
+++ b/json-c/src/json-c.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: json-c
+Description: JSON implementation in C
+Version: @VERSION@
+Requires:
+Libs.private: @LIBS@
+Libs: -L${libdir} -ljson-c
+Cflags: -I${includedir}/json-c
diff --git a/json-c/src/json-c.vcproj b/json-c/src/json-c.vcproj
new file mode 100644
index 0000000..55a579f
--- /dev/null
+++ b/json-c/src/json-c.vcproj
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="json-c"
+ ProjectGUID="{04D8CDBE-FB3E-4362-87E6-07DC3C0083B2}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/jsonD.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="copy config.h.win32 config.h
+copy json_config.h.win32 json_config.h"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="4"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/json.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="copy config.h.win32 config.h
+copy json_config.h.win32 json_config.h"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\arraylist.c">
+ </File>
+ <File
+ RelativePath=".\debug.c">
+ </File>
+ <File
+ RelativePath=".\json_object.c">
+ </File>
+ <File
+ RelativePath=".\json_tokener.c">
+ </File>
+ <File
+ RelativePath=".\json_util.c">
+ </File>
+ <File
+ RelativePath=".\linkhash.c">
+ </File>
+ <File
+ RelativePath=".\printbuf.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\arraylist.h">
+ </File>
+ <File
+ RelativePath=".\bits.h">
+ </File>
+ <File
+ RelativePath=".\debug.h">
+ </File>
+ <File
+ RelativePath=".\json_object.h">
+ </File>
+ <File
+ RelativePath=".\json_object_private.h">
+ </File>
+ <File
+ RelativePath=".\json_tokener.h">
+ </File>
+ <File
+ RelativePath=".\json_util.h">
+ </File>
+ <File
+ RelativePath=".\linkhash.h">
+ </File>
+ <File
+ RelativePath=".\printbuf.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ <Filter
+ Name="Documentation"
+ Filter="">
+ <File
+ RelativePath=".\Doxyfile">
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\config.h.win32">
+ </File>
+ <File
+ RelativePath=".\json_config.h.win32">
+ </File>
+ <File
+ RelativePath=".\README-WIN32.html">
+ </File>
+ <File
+ RelativePath=".\README.html">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/json-c/src/json-c.vcxproj b/json-c/src/json-c.vcxproj
new file mode 100644
index 0000000..d9ec767
--- /dev/null
+++ b/json-c/src/json-c.vcxproj
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{04D8CDBE-FB3E-4362-87E6-07DC3C0083B2}</ProjectGuid>
+ <RootNamespace>jsonc</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>CompileAsCpp</CompileAs>
+ </ClCompile>
+ <PreBuildEvent>
+ <Command>copy config.h.win32 config.h
+copy json_config.h.win32 json_config.h
+</Command>
+ </PreBuildEvent>
+ <PreBuildEvent>
+ <Message>copy config.h from Windows template instead of calling configure</Message>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>CompileAsCpp</CompileAs>
+ </ClCompile>
+ <PreBuildEvent>
+ <Command>copy config.h.win32 config.h
+copy json_config.h.win32 json_config.h
+</Command>
+ </PreBuildEvent>
+ <PreBuildEvent>
+ <Message>copy config.h from Windows template instead of calling configure</Message>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>CompileAsCpp</CompileAs>
+ </ClCompile>
+ <PreBuildEvent>
+ <Command>copy config.h.win32 config.h
+copy json_config.h.win32 json_config.h
+</Command>
+ </PreBuildEvent>
+ <PreBuildEvent>
+ <Message>copy config.h from Windows template instead of calling configure</Message>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>CompileAsCpp</CompileAs>
+ </ClCompile>
+ <PreBuildEvent>
+ <Command>copy config.h.win32 config.h
+copy json_config.h.win32 json_config.h
+</Command>
+ </PreBuildEvent>
+ <PreBuildEvent>
+ <Message>copy config.h from Windows template instead of calling configure</Message>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="arraylist.c" />
+ <ClCompile Include="debug.c" />
+ <ClCompile Include="json_object.c" />
+ <ClCompile Include="json_tokener.c" />
+ <ClCompile Include="json_util.c" />
+ <ClCompile Include="linkhash.c" />
+ <ClCompile Include="printbuf.c" />
+ <ClCompile Include="random_seed.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="arraylist.h" />
+ <ClInclude Include="debug.h" />
+ <ClInclude Include="json_inttypes.h" />
+ <ClInclude Include="json_object.h" />
+ <ClInclude Include="json_object_private.h" />
+ <ClInclude Include="json_tokener.h" />
+ <ClInclude Include="json_util.h" />
+ <ClInclude Include="linkhash.h" />
+ <ClInclude Include="math_compat.h" />
+ <ClInclude Include="printbuf.h" />
+ <ClInclude Include="random_seed.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="config.h.win32" />
+ <None Include="Doxyfile" />
+ <None Include="json_config.h.win32" />
+ <None Include="README-WIN32.html" />
+ <None Include="README.html" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/json-c/src/json-c.vcxproj.filters b/json-c/src/json-c.vcxproj.filters
new file mode 100644
index 0000000..b199efb
--- /dev/null
+++ b/json-c/src/json-c.vcxproj.filters
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
+ </Filter>
+ <Filter Include="Documentation">
+ <UniqueIdentifier>{8c5a59ed-4639-4361-9b7c-ecdcd09b953c}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="arraylist.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="debug.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="json_object.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="json_tokener.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="json_util.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="linkhash.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="printbuf.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="random_seed.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="arraylist.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="debug.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="json_object.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="json_object_private.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="json_tokener.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="json_util.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="linkhash.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="printbuf.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="json_inttypes.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="math_compat.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="random_seed.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Doxyfile">
+ <Filter>Documentation</Filter>
+ </None>
+ <None Include="config.h.win32" />
+ <None Include="json_config.h.win32" />
+ <None Include="README-WIN32.html" />
+ <None Include="README.html" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/json-c/src/json_c_version.c b/json-c/src/json_c_version.c
new file mode 100644
index 0000000..b6ded48
--- /dev/null
+++ b/json-c/src/json_c_version.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012 Eric Haszlakiewicz
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ */
+#include "config.h"
+
+#include "json_c_version.h"
+
+const char *json_c_version(void)
+{
+ return JSON_C_VERSION;
+}
+
+int json_c_version_num(void)
+{
+ return JSON_C_VERSION_NUM;
+}
+
diff --git a/json-c/src/json_c_version.h b/json-c/src/json_c_version.h
new file mode 100644
index 0000000..617e7f2
--- /dev/null
+++ b/json-c/src/json_c_version.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2012 Eric Haszlakiewicz
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ */
+
+#ifndef _json_c_version_h_
+#define _json_c_version_h_
+
+#define JSON_C_MAJOR_VERSION 0
+#define JSON_C_MINOR_VERSION 12
+#define JSON_C_MICRO_VERSION 99
+#define JSON_C_VERSION_NUM ((JSON_C_MAJOR_VERSION << 16) | \
+ (JSON_C_MINOR_VERSION << 8) | \
+ JSON_C_MICRO_VERSION)
+#define JSON_C_VERSION "0.12.99"
+
+const char *json_c_version(void); /* Returns JSON_C_VERSION */
+int json_c_version_num(void); /* Returns JSON_C_VERSION_NUM */
+
+#endif
diff --git a/json-c/src/json_config.h.win32 b/json-c/src/json_config.h.win32
new file mode 100644
index 0000000..00f55bb
--- /dev/null
+++ b/json-c/src/json_config.h.win32
@@ -0,0 +1,5 @@
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#if defined(_MSC_VER) && _MSC_VER >= 1800
+#define JSON_C_HAVE_INTTYPES_H 1
+#endif
diff --git a/json-c/src/libjson.c b/json-c/src/libjson.c
new file mode 100644
index 0000000..1e2bab5
--- /dev/null
+++ b/json-c/src/libjson.c
@@ -0,0 +1,26 @@
+
+/* dummy source file for compatibility purposes */
+
+#if defined(HAVE_CDEFS_H)
+#include <sys/cdefs.h>
+#endif
+
+#ifndef __warn_references
+
+#if defined(__GNUC__) && defined (HAS_GNU_WARNING_LONG)
+
+#define __warn_references(sym,msg) \
+ __asm__(".section .gnu" #sym ",\n\t.ascii \"" msg "\"\n\t.text");
+
+#else
+#define __warn_references(sym,msg) /* nothing */
+#endif
+
+#endif
+
+#include "json_object.h"
+
+__warn_references(json_object_get, "Warning: please link against libjson-c instead of libjson");
+
+/* __asm__(".section .gnu.warning." __STRING(sym) \
+ " ; .ascii \"" msg "\" ; .text") */
diff --git a/json-c/src/math_compat.h b/json-c/src/math_compat.h
new file mode 100644
index 0000000..6506bd9
--- /dev/null
+++ b/json-c/src/math_compat.h
@@ -0,0 +1,31 @@
+#ifndef __math_compat_h
+#define __math_compat_h
+
+/* Define isnan, isinf, infinity and nan on Windows/MSVC */
+
+#ifndef HAVE_DECL_ISNAN
+# ifdef HAVE_DECL__ISNAN
+#include <float.h>
+#define isnan(x) _isnan(x)
+# endif
+#endif
+
+#ifndef HAVE_DECL_ISINF
+# ifdef HAVE_DECL__FINITE
+#include <float.h>
+#define isinf(x) (!_finite(x))
+# endif
+#endif
+
+#ifndef HAVE_DECL_INFINITY
+#include <float.h>
+#define INFINITY (DBL_MAX + DBL_MAX)
+#define HAVE_DECL_INFINITY
+#endif
+
+#ifndef HAVE_DECL_NAN
+#define NAN (INFINITY - INFINITY)
+#define HAVE_DECL_NAN
+#endif
+
+#endif
diff --git a/json-c/src/random_seed.c b/json-c/src/random_seed.c
new file mode 100644
index 0000000..7fe538d
--- /dev/null
+++ b/json-c/src/random_seed.c
@@ -0,0 +1,238 @@
+/*
+ * random_seed.c
+ *
+ * Copyright (c) 2013 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include <stdio.h>
+#include "config.h"
+#include "random_seed.h"
+
+#define DEBUG_SEED(s)
+
+
+#if defined ENABLE_RDRAND
+
+/* cpuid */
+
+#if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
+#define HAS_X86_CPUID 1
+
+static void do_cpuid(int regs[], int h)
+{
+ __asm__ __volatile__(
+#if defined __x86_64__
+ "pushq %%rbx;\n"
+#else
+ "pushl %%ebx;\n"
+#endif
+ "cpuid;\n"
+#if defined __x86_64__
+ "popq %%rbx;\n"
+#else
+ "popl %%ebx;\n"
+#endif
+ : "=a"(regs[0]), [ebx] "=r"(regs[1]), "=c"(regs[2]), "=d"(regs[3])
+ : "a"(h));
+}
+
+#elif defined _MSC_VER
+
+#define HAS_X86_CPUID 1
+#define do_cpuid __cpuid
+
+#endif
+
+/* has_rdrand */
+
+#if HAS_X86_CPUID
+
+static int has_rdrand()
+{
+ // CPUID.01H:ECX.RDRAND[bit 30] == 1
+ int regs[4];
+ do_cpuid(regs, 1);
+ return (regs[2] & (1 << 30)) != 0;
+}
+
+#endif
+
+/* get_rdrand_seed - GCC x86 and X64 */
+
+#if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
+
+#define HAVE_RDRAND 1
+
+static int get_rdrand_seed()
+{
+ DEBUG_SEED("get_rdrand_seed");
+ int _eax;
+ // rdrand eax
+ __asm__ __volatile__("1: .byte 0x0F\n"
+ " .byte 0xC7\n"
+ " .byte 0xF0\n"
+ " jnc 1b;\n"
+ : "=a" (_eax));
+ return _eax;
+}
+
+#endif
+
+#if defined _MSC_VER
+
+#if _MSC_VER >= 1700
+#define HAVE_RDRAND 1
+
+/* get_rdrand_seed - Visual Studio 2012 and above */
+
+static int get_rdrand_seed()
+{
+ DEBUG_SEED("get_rdrand_seed");
+ int r;
+ while (_rdrand32_step(&r) == 0);
+ return r;
+}
+
+#elif defined _M_IX86
+#define HAVE_RDRAND 1
+
+/* get_rdrand_seed - Visual Studio 2010 and below - x86 only */
+
+static int get_rdrand_seed()
+{
+ DEBUG_SEED("get_rdrand_seed");
+ int _eax;
+retry:
+ // rdrand eax
+ __asm _emit 0x0F __asm _emit 0xC7 __asm _emit 0xF0
+ __asm jnc retry
+ __asm mov _eax, eax
+ return _eax;
+}
+
+#endif
+#endif
+
+#endif /* defined ENABLE_RDRAND */
+
+
+/* has_dev_urandom */
+
+#if defined (__APPLE__) || defined(__unix__) || defined(__linux__)
+
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#define HAVE_DEV_RANDOM 1
+
+static const char *dev_random_file = "/dev/urandom";
+
+static int has_dev_urandom()
+{
+ struct stat buf;
+ if (stat(dev_random_file, &buf)) {
+ return 0;
+ }
+ return ((buf.st_mode & S_IFCHR) != 0);
+}
+
+
+/* get_dev_random_seed */
+
+static int get_dev_random_seed()
+{
+ DEBUG_SEED("get_dev_random_seed");
+
+ int fd = open(dev_random_file, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "error opening %s: %s", dev_random_file, strerror(errno));
+ exit(1);
+ }
+
+ int r;
+ ssize_t nread = read(fd, &r, sizeof(r));
+ if (nread != sizeof(r)) {
+ fprintf(stderr, "error short read %s: %s", dev_random_file, strerror(errno));
+ exit(1);
+ }
+
+ close(fd);
+ return r;
+}
+
+#endif
+
+
+/* get_cryptgenrandom_seed */
+
+#ifdef WIN32
+
+#define HAVE_CRYPTGENRANDOM 1
+
+#include <windows.h>
+#include <wincrypt.h>
+#ifndef __GNUC__
+#pragma comment(lib, "advapi32.lib")
+#endif
+
+static int get_cryptgenrandom_seed()
+{
+ DEBUG_SEED("get_cryptgenrandom_seed");
+
+ HCRYPTPROV hProvider = 0;
+ int r;
+
+ if (!CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+ fprintf(stderr, "error CryptAcquireContextW");
+ exit(1);
+ }
+
+ if (!CryptGenRandom(hProvider, sizeof(r), (BYTE*)&r)) {
+ fprintf(stderr, "error CryptGenRandom");
+ exit(1);
+ }
+
+ CryptReleaseContext(hProvider, 0);
+
+ return r;
+}
+
+#endif
+
+
+/* get_time_seed */
+
+#include <time.h>
+
+static int get_time_seed()
+{
+ DEBUG_SEED("get_time_seed");
+
+ return (int)time(NULL) * 433494437;
+}
+
+
+/* json_c_get_random_seed */
+
+int json_c_get_random_seed()
+{
+#if HAVE_RDRAND
+ if (has_rdrand()) return get_rdrand_seed();
+#endif
+#if HAVE_DEV_RANDOM
+ if (has_dev_urandom()) return get_dev_random_seed();
+#endif
+#if HAVE_CRYPTGENRANDOM
+ return get_cryptgenrandom_seed();
+#endif
+ return get_time_seed();
+}
diff --git a/json-c/src/random_seed.h b/json-c/src/random_seed.h
new file mode 100644
index 0000000..6d1e268
--- /dev/null
+++ b/json-c/src/random_seed.h
@@ -0,0 +1,25 @@
+/*
+ * random_seed.h
+ *
+ * Copyright (c) 2013 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef seed_h
+#define seed_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int json_c_get_random_seed();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/json-c/src/tests/Makefile.am b/json-c/src/tests/Makefile.am
new file mode 100644
index 0000000..ea4b051
--- /dev/null
+++ b/json-c/src/tests/Makefile.am
@@ -0,0 +1,41 @@
+
+include ../Makefile.am.inc
+LDADD= $(LIBJSON_LA)
+
+LIBJSON_LA=$(top_builddir)/libjson-c.la
+
+TESTS=
+TESTS+= test1.test
+TESTS+= test2.test
+TESTS+= test4.test
+TESTS+= testReplaceExisting.test
+TESTS+= test_parse_int64.test
+TESTS+= test_null.test
+TESTS+= test_cast.test
+TESTS+= test_parse.test
+TESTS+= test_locale.test
+TESTS+= test_charcase.test
+TESTS+= test_printbuf.test
+TESTS+= test_set_serializer.test
+
+check_PROGRAMS=
+check_PROGRAMS += $(TESTS:.test=)
+
+# Note: handled by test1.test
+check_PROGRAMS += test1Formatted
+test1Formatted_SOURCES = test1.c parse_flags.c
+test1Formatted_CPPFLAGS = -DTEST_FORMATTED
+
+# Note: handled by test2.test
+check_PROGRAMS += test2Formatted
+test2Formatted_SOURCES = test2.c parse_flags.c
+test2Formatted_CPPFLAGS = -DTEST_FORMATTED
+
+EXTRA_DIST=
+EXTRA_DIST += $(TESTS)
+
+testsubdir=testSubDir
+TESTS_ENVIRONMENT = top_builddir=$(top_builddir)
+
+distclean-local:
+ -rm -rf $(testsubdir)
diff --git a/json-c/src/tests/parse_flags.c b/json-c/src/tests/parse_flags.c
new file mode 100644
index 0000000..06910e6
--- /dev/null
+++ b/json-c/src/tests/parse_flags.c
@@ -0,0 +1,50 @@
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "json.h"
+#include "parse_flags.h"
+
+#if !defined(HAVE_STRCASECMP) && defined(_MSC_VER)
+# define strcasecmp _stricmp
+#elif !defined(HAVE_STRCASECMP)
+# error You do not have strcasecmp on your system.
+#endif /* HAVE_STRNCASECMP */
+
+static struct {
+ const char *arg;
+ int flag;
+} format_args[] = {
+ { "plain", JSON_C_TO_STRING_PLAIN },
+ { "spaced", JSON_C_TO_STRING_SPACED },
+ { "pretty", JSON_C_TO_STRING_PRETTY },
+};
+
+#ifndef NELEM
+#define NELEM(x) (sizeof(x) / sizeof(&x[0]))
+#endif
+
+int parse_flags(int argc, char **argv)
+{
+ int arg_idx;
+ int sflags = 0;
+ for (arg_idx = 1; arg_idx < argc ; arg_idx++)
+ {
+ int jj;
+ for (jj = 0; jj < (int)NELEM(format_args); jj++)
+ {
+ if (strcasecmp(argv[arg_idx], format_args[jj].arg) == 0)
+ {
+ sflags |= format_args[jj].flag;
+ break;
+ }
+ }
+ if (jj == NELEM(format_args))
+ {
+ printf("Unknown arg: %s\n", argv[arg_idx]);
+ exit(1);
+ }
+ }
+ return sflags;
+}
diff --git a/json-c/src/tests/parse_flags.h b/json-c/src/tests/parse_flags.h
new file mode 100644
index 0000000..dd5149d
--- /dev/null
+++ b/json-c/src/tests/parse_flags.h
@@ -0,0 +1,4 @@
+#ifndef __parse_flags_h
+#define __parse_flags_h
+int parse_flags(int argc, char **argv);
+#endif
diff --git a/json-c/src/tests/test-defs.sh b/json-c/src/tests/test-defs.sh
new file mode 100644
index 0000000..062170a
--- /dev/null
+++ b/json-c/src/tests/test-defs.sh
@@ -0,0 +1,128 @@
+#!/bin/sh
+
+# Make sure srcdir is an absolute path. Supply the variable
+# if it does not exist. We want to be able to run the tests
+# stand-alone!!
+#
+srcdir=${srcdir-.}
+if test ! -d $srcdir ; then
+ echo "test-defs.sh: installation error" 1>&2
+ exit 1
+fi
+
+# Use absolute paths
+case "$srcdir" in
+ /* | [A-Za-z]:\\*) ;;
+ *) srcdir=`\cd $srcdir && pwd` ;;
+esac
+
+case "$top_builddir" in
+ /* | [A-Za-z]:\\*) ;;
+ *) top_builddir=`\cd ${top_builddir-..} && pwd` ;;
+esac
+
+top_builddir=${top_builddir}/tests
+
+progname=`echo "$0" | sed 's,^.*/,,'`
+testname=`echo "$progname" | sed 's,-.*$,,'`
+testsubdir=${testsubdir-testSubDir}
+testsubdir=${testsubdir}/${progname}
+
+# User can set VERBOSE to cause output redirection
+case "$VERBOSE" in
+[Nn]|[Nn][Oo]|0|"")
+ VERBOSE=0
+ exec > /dev/null
+ ;;
+[Yy]|[Yy][Ee][Ss])
+ VERBOSE=1
+ ;;
+esac
+
+rm -rf "$testsubdir" > /dev/null 2>&1
+mkdir -p "$testsubdir"
+CURDIR=$(pwd)
+cd "$testsubdir" \
+ || { echo "Cannot make or change into $testsubdir"; exit 1; }
+
+echo "=== Running test $progname"
+
+CMP="${CMP-cmp}"
+
+use_valgrind=${USE_VALGRIND-1}
+valgrind_path=$(which valgrind 2> /dev/null)
+if [ -z "${valgrind_path}" -o ! -x "${valgrind_path}" ] ; then
+ use_valgrind=0
+fi
+
+#
+# This is a common function to check the results of a test program
+# that is intended to generate consistent output across runs.
+#
+# ${top_builddir} must be set to the top level build directory.
+#
+# Output will be written to the current directory.
+#
+# It must be passed the name of the test command to run, which must be present
+# in the ${top_builddir} directory.
+#
+# It will compare the output of running that against <name of command>.expected
+#
+run_output_test()
+{
+ if [ "$1" = "-o" ] ; then
+ TEST_OUTPUT="$2"
+ shift
+ shift
+ fi
+ TEST_COMMAND="$1"
+ shift
+ if [ -z "${TEST_OUTPUT}" ] ; then
+ TEST_OUTPUT=${TEST_COMMAND}
+ fi
+
+ REDIR_OUTPUT="> \"${TEST_OUTPUT}.out\""
+ if [ $VERBOSE -gt 1 ] ; then
+ REDIR_OUTPUT="| tee \"${TEST_OUTPUT}.out\""
+ fi
+
+ if [ $use_valgrind -eq 1 ] ; then
+ eval valgrind --tool=memcheck \
+ --trace-children=yes \
+ --demangle=yes \
+ --log-file="${TEST_OUTPUT}.vg.out" \
+ --leak-check=full \
+ --show-reachable=yes \
+ --run-libc-freeres=yes \
+ "\"${top_builddir}/${TEST_COMMAND}\"" \"\$@\" ${REDIR_OUTPUT}
+ err=$?
+
+ else
+ eval "\"${top_builddir}/${TEST_COMMAND}"\" \"\$@\" ${REDIR_OUTPUT}
+ err=$?
+ fi
+
+ if [ $err -ne 0 ] ; then
+ echo "ERROR: \"${TEST_COMMAND} $@\" exited with non-zero exit status: $err" 1>&2
+ fi
+
+ if [ $use_valgrind -eq 1 ] ; then
+ if ! tail -1 "${TEST_OUTPUT}.vg.out" | grep -q "ERROR SUMMARY: 0 errors" ; then
+ echo "ERROR: valgrind found errors during execution:" 1>&2
+ cat "${TEST_OUTPUT}.vg.out"
+ err=1
+ fi
+ fi
+
+ if ! "$CMP" -s "${top_builddir}/${TEST_OUTPUT}.expected" "${TEST_OUTPUT}.out" ; then
+ echo "ERROR: \"${TEST_COMMAND} $@\" (${TEST_OUTPUT}) failed (set VERBOSE=1 to see full output):" 1>&2
+ (cd "${CURDIR}" ; set -x ; diff "${top_builddir}/${TEST_OUTPUT}.expected" "$testsubdir/${TEST_OUTPUT}.out")
+ echo "cp \"$testsubdir/${TEST_OUTPUT}.out\" \"${top_builddir}/${TEST_OUTPUT}.expected\"" 1>&2
+
+ err=1
+ fi
+
+ return $err
+}
+
+
diff --git a/json-c/src/tests/test1.c b/json-c/src/tests/test1.c
new file mode 100644
index 0000000..8136227
--- /dev/null
+++ b/json-c/src/tests/test1.c
@@ -0,0 +1,134 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+
+#include "json.h"
+#include "parse_flags.h"
+
+static int sort_fn (const void *j1, const void *j2)
+{
+ json_object * const *jso1, * const *jso2;
+ int i1, i2;
+
+ jso1 = (json_object* const*)j1;
+ jso2 = (json_object* const*)j2;
+ if (!*jso1 && !*jso2)
+ return 0;
+ if (!*jso1)
+ return -1;
+ if (!*jso2)
+ return 1;
+
+ i1 = json_object_get_int(*jso1);
+ i2 = json_object_get_int(*jso2);
+
+ return i1 - i2;
+}
+
+#ifdef TEST_FORMATTED
+#define json_object_to_json_string(obj) json_object_to_json_string_ext(obj,sflags)
+#else
+/* no special define */
+#endif
+
+int main(int argc, char **argv)
+{
+ json_object *my_string, *my_int, *my_object, *my_array;
+ int i;
+#ifdef TEST_FORMATTED
+ int sflags = 0;
+#endif
+
+ MC_SET_DEBUG(1);
+
+#ifdef TEST_FORMATTED
+ sflags = parse_flags(argc, argv);
+#endif
+
+ my_string = json_object_new_string("\t");
+ printf("my_string=%s\n", json_object_get_string(my_string));
+ printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string));
+ json_object_put(my_string);
+
+ my_string = json_object_new_string("\\");
+ printf("my_string=%s\n", json_object_get_string(my_string));
+ printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string));
+ json_object_put(my_string);
+
+ my_string = json_object_new_string("foo");
+ printf("my_string=%s\n", json_object_get_string(my_string));
+ printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string));
+
+ my_int = json_object_new_int(9);
+ printf("my_int=%d\n", json_object_get_int(my_int));
+ printf("my_int.to_string()=%s\n", json_object_to_json_string(my_int));
+
+ my_array = json_object_new_array();
+ json_object_array_add(my_array, json_object_new_int(1));
+ json_object_array_add(my_array, json_object_new_int(2));
+ json_object_array_add(my_array, json_object_new_int(3));
+ json_object_array_put_idx(my_array, 4, json_object_new_int(5));
+ printf("my_array=\n");
+ for(i=0; i < json_object_array_length(my_array); i++)
+ {
+ json_object *obj = json_object_array_get_idx(my_array, i);
+ printf("\t[%d]=%s\n", i, json_object_to_json_string(obj));
+ }
+ printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array));
+
+ json_object_put(my_array);
+
+ my_array = json_object_new_array();
+ json_object_array_add(my_array, json_object_new_int(3));
+ json_object_array_add(my_array, json_object_new_int(1));
+ json_object_array_add(my_array, json_object_new_int(2));
+ json_object_array_put_idx(my_array, 4, json_object_new_int(0));
+ printf("my_array=\n");
+ for(i=0; i < json_object_array_length(my_array); i++)
+ {
+ json_object *obj = json_object_array_get_idx(my_array, i);
+ printf("\t[%d]=%s\n", i, json_object_to_json_string(obj));
+ }
+ printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array));
+ json_object_array_sort(my_array, sort_fn);
+ printf("my_array=\n");
+ for(i=0; i < json_object_array_length(my_array); i++)
+ {
+ json_object *obj = json_object_array_get_idx(my_array, i);
+ printf("\t[%d]=%s\n", i, json_object_to_json_string(obj));
+ }
+ printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array));
+
+ my_object = json_object_new_object();
+ json_object_object_add(my_object, "abc", json_object_new_int(12));
+ json_object_object_add(my_object, "foo", json_object_new_string("bar"));
+ json_object_object_add(my_object, "bool0", json_object_new_boolean(0));
+ json_object_object_add(my_object, "bool1", json_object_new_boolean(1));
+ json_object_object_add(my_object, "baz", json_object_new_string("bang"));
+
+ json_object *baz_obj = json_object_new_string("fark");
+ json_object_get(baz_obj);
+ json_object_object_add(my_object, "baz", baz_obj);
+ json_object_object_del(my_object, "baz");
+
+ /* baz_obj should still be valid */
+ printf("baz_obj.to_string()=%s\n", json_object_to_json_string(baz_obj));
+ json_object_put(baz_obj);
+
+ /*json_object_object_add(my_object, "arr", my_array);*/
+ printf("my_object=\n");
+ json_object_object_foreach(my_object, key, val)
+ {
+ printf("\t%s: %s\n", key, json_object_to_json_string(val));
+ }
+ printf("my_object.to_string()=%s\n", json_object_to_json_string(my_object));
+
+ json_object_put(my_string);
+ json_object_put(my_int);
+ json_object_put(my_object);
+ json_object_put(my_array);
+
+ return 0;
+}
diff --git a/json-c/src/tests/test1.expected b/json-c/src/tests/test1.expected
new file mode 100644
index 0000000..4aaf6cc
--- /dev/null
+++ b/json-c/src/tests/test1.expected
@@ -0,0 +1,36 @@
+my_string=
+my_string.to_string()="\t"
+my_string=\
+my_string.to_string()="\\"
+my_string=foo
+my_string.to_string()="foo"
+my_int=9
+my_int.to_string()=9
+my_array=
+ [0]=1
+ [1]=2
+ [2]=3
+ [3]=null
+ [4]=5
+my_array.to_string()=[ 1, 2, 3, null, 5 ]
+my_array=
+ [0]=3
+ [1]=1
+ [2]=2
+ [3]=null
+ [4]=0
+my_array.to_string()=[ 3, 1, 2, null, 0 ]
+my_array=
+ [0]=null
+ [1]=0
+ [2]=1
+ [3]=2
+ [4]=3
+my_array.to_string()=[ null, 0, 1, 2, 3 ]
+baz_obj.to_string()="fark"
+my_object=
+ abc: 12
+ foo: "bar"
+ bool0: false
+ bool1: true
+my_object.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true }
diff --git a/json-c/src/tests/test1.test b/json-c/src/tests/test1.test
new file mode 100644
index 0000000..bf9d75e
--- /dev/null
+++ b/json-c/src/tests/test1.test
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test1
+_err=$?
+
+for flag in plain spaced pretty ; do
+ run_output_test -o test1Formatted_${flag} test1Formatted ${flag}
+ _err2=$?
+ if [ $_err -eq 0 ] ; then
+ _err=$_err2
+ fi
+done
+
+exit $_err
diff --git a/json-c/src/tests/test1Formatted_plain.expected b/json-c/src/tests/test1Formatted_plain.expected
new file mode 100644
index 0000000..843f55a
--- /dev/null
+++ b/json-c/src/tests/test1Formatted_plain.expected
@@ -0,0 +1,36 @@
+my_string=
+my_string.to_string()="\t"
+my_string=\
+my_string.to_string()="\\"
+my_string=foo
+my_string.to_string()="foo"
+my_int=9
+my_int.to_string()=9
+my_array=
+ [0]=1
+ [1]=2
+ [2]=3
+ [3]=null
+ [4]=5
+my_array.to_string()=[1,2,3,null,5]
+my_array=
+ [0]=3
+ [1]=1
+ [2]=2
+ [3]=null
+ [4]=0
+my_array.to_string()=[3,1,2,null,0]
+my_array=
+ [0]=null
+ [1]=0
+ [2]=1
+ [3]=2
+ [4]=3
+my_array.to_string()=[null,0,1,2,3]
+baz_obj.to_string()="fark"
+my_object=
+ abc: 12
+ foo: "bar"
+ bool0: false
+ bool1: true
+my_object.to_string()={"abc":12,"foo":"bar","bool0":false,"bool1":true}
diff --git a/json-c/src/tests/test1Formatted_pretty.expected b/json-c/src/tests/test1Formatted_pretty.expected
new file mode 100644
index 0000000..ca4ff67
--- /dev/null
+++ b/json-c/src/tests/test1Formatted_pretty.expected
@@ -0,0 +1,59 @@
+my_string=
+my_string.to_string()="\t"
+my_string=\
+my_string.to_string()="\\"
+my_string=foo
+my_string.to_string()="foo"
+my_int=9
+my_int.to_string()=9
+my_array=
+ [0]=1
+ [1]=2
+ [2]=3
+ [3]=null
+ [4]=5
+my_array.to_string()=[
+ 1,
+ 2,
+ 3,
+ null,
+ 5
+]
+my_array=
+ [0]=3
+ [1]=1
+ [2]=2
+ [3]=null
+ [4]=0
+my_array.to_string()=[
+ 3,
+ 1,
+ 2,
+ null,
+ 0
+]
+my_array=
+ [0]=null
+ [1]=0
+ [2]=1
+ [3]=2
+ [4]=3
+my_array.to_string()=[
+ null,
+ 0,
+ 1,
+ 2,
+ 3
+]
+baz_obj.to_string()="fark"
+my_object=
+ abc: 12
+ foo: "bar"
+ bool0: false
+ bool1: true
+my_object.to_string()={
+ "abc":12,
+ "foo":"bar",
+ "bool0":false,
+ "bool1":true
+}
diff --git a/json-c/src/tests/test1Formatted_spaced.expected b/json-c/src/tests/test1Formatted_spaced.expected
new file mode 100644
index 0000000..4aaf6cc
--- /dev/null
+++ b/json-c/src/tests/test1Formatted_spaced.expected
@@ -0,0 +1,36 @@
+my_string=
+my_string.to_string()="\t"
+my_string=\
+my_string.to_string()="\\"
+my_string=foo
+my_string.to_string()="foo"
+my_int=9
+my_int.to_string()=9
+my_array=
+ [0]=1
+ [1]=2
+ [2]=3
+ [3]=null
+ [4]=5
+my_array.to_string()=[ 1, 2, 3, null, 5 ]
+my_array=
+ [0]=3
+ [1]=1
+ [2]=2
+ [3]=null
+ [4]=0
+my_array.to_string()=[ 3, 1, 2, null, 0 ]
+my_array=
+ [0]=null
+ [1]=0
+ [2]=1
+ [3]=2
+ [4]=3
+my_array.to_string()=[ null, 0, 1, 2, 3 ]
+baz_obj.to_string()="fark"
+my_object=
+ abc: 12
+ foo: "bar"
+ bool0: false
+ bool1: true
+my_object.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true }
diff --git a/json-c/src/tests/test2.c b/json-c/src/tests/test2.c
new file mode 100644
index 0000000..9b30c62
--- /dev/null
+++ b/json-c/src/tests/test2.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "json.h"
+#include "parse_flags.h"
+
+#ifdef TEST_FORMATTED
+#define json_object_to_json_string(obj) json_object_to_json_string_ext(obj,sflags)
+#else
+/* no special define */
+#endif
+
+
+int main(int argc, char **argv)
+{
+ json_object *new_obj;
+#ifdef TEST_FORMATTED
+ int sflags = 0;
+#endif
+
+ MC_SET_DEBUG(1);
+
+#ifdef TEST_FORMATTED
+ sflags = parse_flags(argc, argv);
+#endif
+
+ new_obj = json_tokener_parse("/* more difficult test case */ { \"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\"] } ] } } }");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ return 0;
+}
diff --git a/json-c/src/tests/test2.expected b/json-c/src/tests/test2.expected
new file mode 100644
index 0000000..ac404e0
--- /dev/null
+++ b/json-c/src/tests/test2.expected
@@ -0,0 +1 @@
+new_obj.to_string()={ "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" ] } ] } } }
diff --git a/json-c/src/tests/test2.test b/json-c/src/tests/test2.test
new file mode 100644
index 0000000..0b5fc87
--- /dev/null
+++ b/json-c/src/tests/test2.test
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test2
+_err=$?
+
+for flag in plain spaced pretty ; do
+ run_output_test -o test2Formatted_${flag} test2Formatted ${flag}
+ _err2=$?
+ if [ $_err -eq 0 ] ; then
+ _err=$_err2
+ fi
+done
+
+exit $_err
diff --git a/json-c/src/tests/test2Formatted_plain.expected b/json-c/src/tests/test2Formatted_plain.expected
new file mode 100644
index 0000000..8b2053d
--- /dev/null
+++ b/json-c/src/tests/test2Formatted_plain.expected
@@ -0,0 +1 @@
+new_obj.to_string()={"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"]}]}}}
diff --git a/json-c/src/tests/test2Formatted_pretty.expected b/json-c/src/tests/test2Formatted_pretty.expected
new file mode 100644
index 0000000..c311691
--- /dev/null
+++ b/json-c/src/tests/test2Formatted_pretty.expected
@@ -0,0 +1,23 @@
+new_obj.to_string()={
+ "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"
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/json-c/src/tests/test2Formatted_spaced.expected b/json-c/src/tests/test2Formatted_spaced.expected
new file mode 100644
index 0000000..ac404e0
--- /dev/null
+++ b/json-c/src/tests/test2Formatted_spaced.expected
@@ -0,0 +1 @@
+new_obj.to_string()={ "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" ] } ] } } }
diff --git a/json-c/src/tests/test4.c b/json-c/src/tests/test4.c
new file mode 100644
index 0000000..99331bb
--- /dev/null
+++ b/json-c/src/tests/test4.c
@@ -0,0 +1,53 @@
+/*
+ * gcc -o utf8 utf8.c -I/home/y/include -L./.libs -ljson
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "config.h"
+
+#include "json_inttypes.h"
+#include "json_object.h"
+#include "json_tokener.h"
+
+void print_hex( const char* s)
+{
+ const char *iter = s;
+ unsigned char ch;
+ while ((ch = *iter++) != 0)
+ {
+ if( ',' != ch)
+ printf("%x ", ch);
+ else
+ printf( ",");
+ }
+ printf("\n");
+}
+
+int main()
+{
+ const char *input = "\"\\ud840\\udd26,\\ud840\\udd27,\\ud800\\udd26,\\ud800\\udd27\"";
+ const char *expected = "\xF0\xA0\x84\xA6,\xF0\xA0\x84\xA7,\xF0\x90\x84\xA6,\xF0\x90\x84\xA7";
+ struct json_object *parse_result = json_tokener_parse((char*)input);
+ const char *unjson = json_object_get_string(parse_result);
+
+ printf("input: %s\n", input);
+
+ int strings_match = !strcmp( expected, unjson);
+ int retval = 0;
+ if (strings_match)
+ {
+ printf("JSON parse result is correct: %s\n", unjson);
+ printf("PASS\n");
+ } else {
+ printf("JSON parse result doesn't match expected string\n");
+ printf("expected string bytes: ");
+ print_hex( expected);
+ printf("parsed string bytes: ");
+ print_hex( unjson);
+ printf("FAIL\n");
+ retval = 1;
+ }
+ json_object_put(parse_result);
+ return retval;
+}
diff --git a/json-c/src/tests/test4.expected b/json-c/src/tests/test4.expected
new file mode 100644
index 0000000..932761d
--- /dev/null
+++ b/json-c/src/tests/test4.expected
@@ -0,0 +1,3 @@
+input: "\ud840\udd26,\ud840\udd27,\ud800\udd26,\ud800\udd27"
+JSON parse result is correct: 𠄦,𠄧,𐄦,𐄧
+PASS
diff --git a/json-c/src/tests/test4.test b/json-c/src/tests/test4.test
new file mode 100644
index 0000000..4e8147e
--- /dev/null
+++ b/json-c/src/tests/test4.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test4
+exit $?
diff --git a/json-c/src/tests/testReplaceExisting.c b/json-c/src/tests/testReplaceExisting.c
new file mode 100644
index 0000000..0534cf9
--- /dev/null
+++ b/json-c/src/tests/testReplaceExisting.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "json.h"
+
+int main(int argc, char **argv)
+{
+ MC_SET_DEBUG(1);
+
+ /*
+ * Check that replacing an existing object keeps the key valid,
+ * and that it keeps the order the same.
+ */
+ json_object *my_object = json_object_new_object();
+ json_object_object_add(my_object, "foo1", json_object_new_string("bar1"));
+ json_object_object_add(my_object, "foo2", json_object_new_string("bar2"));
+ json_object_object_add(my_object, "deleteme", json_object_new_string("bar2"));
+ json_object_object_add(my_object, "foo3", json_object_new_string("bar3"));
+
+ printf("==== delete-in-loop test starting ====\n");
+
+ int orig_count = 0;
+ json_object_object_foreach(my_object, key0, val0)
+ {
+ printf("Key at index %d is [%s]", orig_count, key0);
+ if (strcmp(key0, "deleteme") == 0)
+ {
+ json_object_object_del(my_object, key0);
+ printf(" (deleted)\n");
+ }
+ else
+ printf(" (kept)\n");
+ orig_count++;
+ }
+
+ printf("==== replace-value first loop starting ====\n");
+
+ const char *original_key = NULL;
+ orig_count = 0;
+ json_object_object_foreach(my_object, key, val)
+ {
+ printf("Key at index %d is [%s]\n", orig_count, key);
+ orig_count++;
+ if (strcmp(key, "foo2") != 0)
+ continue;
+ printf("replacing value for key [%s]\n", key);
+ original_key = key;
+ json_object_object_add(my_object, key, json_object_new_string("zzz"));
+ }
+
+ printf("==== second loop starting ====\n");
+
+ int new_count = 0;
+ int retval = 0;
+ json_object_object_foreach(my_object, key2, val2)
+ {
+ printf("Key at index %d is [%s]\n", new_count, key2);
+ new_count++;
+ if (strcmp(key2, "foo2") != 0)
+ continue;
+ printf("pointer for key [%s] does %smatch\n", key2,
+ (key2 == original_key) ? "" : "NOT ");
+ if (key2 != original_key)
+ retval = 1;
+ }
+ if (new_count != orig_count)
+ {
+ printf("mismatch between original count (%d) and new count (%d)\n",
+ orig_count, new_count);
+ retval = 1;
+ }
+
+ json_object_put( my_object );
+
+ return retval;
+}
diff --git a/json-c/src/tests/testReplaceExisting.expected b/json-c/src/tests/testReplaceExisting.expected
new file mode 100644
index 0000000..2b6e532
--- /dev/null
+++ b/json-c/src/tests/testReplaceExisting.expected
@@ -0,0 +1,15 @@
+==== delete-in-loop test starting ====
+Key at index 0 is [foo1] (kept)
+Key at index 1 is [foo2] (kept)
+Key at index 2 is [deleteme] (deleted)
+Key at index 3 is [foo3] (kept)
+==== replace-value first loop starting ====
+Key at index 0 is [foo1]
+Key at index 1 is [foo2]
+replacing value for key [foo2]
+Key at index 2 is [foo3]
+==== second loop starting ====
+Key at index 0 is [foo1]
+Key at index 1 is [foo2]
+pointer for key [foo2] does match
+Key at index 2 is [foo3]
diff --git a/json-c/src/tests/testReplaceExisting.test b/json-c/src/tests/testReplaceExisting.test
new file mode 100644
index 0000000..8ac7674
--- /dev/null
+++ b/json-c/src/tests/testReplaceExisting.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test testReplaceExisting
+exit $?
diff --git a/json-c/src/tests/test_cast.c b/json-c/src/tests/test_cast.c
new file mode 100644
index 0000000..edbb348
--- /dev/null
+++ b/json-c/src/tests/test_cast.c
@@ -0,0 +1,111 @@
+/*
+ * Tests if casting within the json_object_get_* functions work correctly.
+ * Also checks the json_object_get_type and json_object_is_type functions.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "config.h"
+
+#include "json_inttypes.h"
+#include "json_object.h"
+#include "json_tokener.h"
+#include "json_util.h"
+
+static void getit(struct json_object *new_obj, const char *field);
+static void checktype_header(void);
+static void checktype(struct json_object *new_obj, const char *field);
+
+int main(int argc, char **argv)
+{
+ const char *input = "{\n\
+ \"string_of_digits\": \"123\",\n\
+ \"regular_number\": 222,\n\
+ \"decimal_number\": 99.55,\n\
+ \"boolean_true\": true,\n\
+ \"boolean_false\": false,\n\
+ \"big_number\": 2147483649,\n\
+ \"a_null\": null,\n\
+ }";
+ /* Note: 2147483649 = INT_MAX + 2 */
+
+ struct json_object *new_obj;
+
+ new_obj = json_tokener_parse(input);
+ printf("Parsed input: %s\n", input);
+ printf("Result is %s\n", (new_obj == NULL) ? "NULL (error!)" : "not NULL");
+ if (!new_obj)
+ return 1; // oops, we failed.
+
+ getit(new_obj, "string_of_digits");
+ getit(new_obj, "regular_number");
+ getit(new_obj, "decimal_number");
+ getit(new_obj, "boolean_true");
+ getit(new_obj, "boolean_false");
+ getit(new_obj, "big_number");
+ getit(new_obj, "a_null");
+
+ // Now check the behaviour of the json_object_is_type() function.
+ printf("\n================================\n");
+ checktype_header();
+ checktype(new_obj, NULL);
+ checktype(new_obj, "string_of_digits");
+ checktype(new_obj, "regular_number");
+ checktype(new_obj, "decimal_number");
+ checktype(new_obj, "boolean_true");
+ checktype(new_obj, "boolean_false");
+ checktype(new_obj, "big_number");
+ checktype(new_obj, "a_null");
+
+ json_object_put(new_obj);
+
+ return 0;
+}
+
+static void getit(struct json_object *new_obj, const char *field)
+{
+ struct json_object *o = NULL;
+ if (!json_object_object_get_ex(new_obj, field, &o))
+ printf("Field %s does not exist\n", field);
+
+ enum json_type o_type = json_object_get_type(o);
+ printf("new_obj.%s json_object_get_type()=%s\n", field,
+ json_type_to_name(o_type));
+ printf("new_obj.%s json_object_get_int()=%d\n", field,
+ json_object_get_int(o));
+ printf("new_obj.%s json_object_get_int64()=%" PRId64 "\n", field,
+ json_object_get_int64(o));
+ printf("new_obj.%s json_object_get_boolean()=%d\n", field,
+ json_object_get_boolean(o));
+ printf("new_obj.%s json_object_get_double()=%f\n", field,
+ json_object_get_double(o));
+}
+
+static void checktype_header()
+{
+ printf("json_object_is_type: %s,%s,%s,%s,%s,%s,%s\n",
+ json_type_to_name(json_type_null),
+ json_type_to_name(json_type_boolean),
+ json_type_to_name(json_type_double),
+ json_type_to_name(json_type_int),
+ json_type_to_name(json_type_object),
+ json_type_to_name(json_type_array),
+ json_type_to_name(json_type_string));
+}
+static void checktype(struct json_object *new_obj, const char *field)
+{
+ struct json_object *o = new_obj;
+ if (field && !json_object_object_get_ex(new_obj, field, &o))
+ printf("Field %s does not exist\n", field);
+
+ printf("new_obj%s%-18s: %d,%d,%d,%d,%d,%d,%d\n",
+ field ? "." : " ", field ? field : "",
+ json_object_is_type(o, json_type_null),
+ json_object_is_type(o, json_type_boolean),
+ json_object_is_type(o, json_type_double),
+ json_object_is_type(o, json_type_int),
+ json_object_is_type(o, json_type_object),
+ json_object_is_type(o, json_type_array),
+ json_object_is_type(o, json_type_string));
+}
diff --git a/json-c/src/tests/test_cast.expected b/json-c/src/tests/test_cast.expected
new file mode 100644
index 0000000..abf8924
--- /dev/null
+++ b/json-c/src/tests/test_cast.expected
@@ -0,0 +1,56 @@
+Parsed input: {
+ "string_of_digits": "123",
+ "regular_number": 222,
+ "decimal_number": 99.55,
+ "boolean_true": true,
+ "boolean_false": false,
+ "big_number": 2147483649,
+ "a_null": null,
+ }
+Result is not NULL
+new_obj.string_of_digits json_object_get_type()=string
+new_obj.string_of_digits json_object_get_int()=123
+new_obj.string_of_digits json_object_get_int64()=123
+new_obj.string_of_digits json_object_get_boolean()=1
+new_obj.string_of_digits json_object_get_double()=123.000000
+new_obj.regular_number json_object_get_type()=int
+new_obj.regular_number json_object_get_int()=222
+new_obj.regular_number json_object_get_int64()=222
+new_obj.regular_number json_object_get_boolean()=1
+new_obj.regular_number json_object_get_double()=222.000000
+new_obj.decimal_number json_object_get_type()=double
+new_obj.decimal_number json_object_get_int()=99
+new_obj.decimal_number json_object_get_int64()=99
+new_obj.decimal_number json_object_get_boolean()=1
+new_obj.decimal_number json_object_get_double()=99.550000
+new_obj.boolean_true json_object_get_type()=boolean
+new_obj.boolean_true json_object_get_int()=1
+new_obj.boolean_true json_object_get_int64()=1
+new_obj.boolean_true json_object_get_boolean()=1
+new_obj.boolean_true json_object_get_double()=1.000000
+new_obj.boolean_false json_object_get_type()=boolean
+new_obj.boolean_false json_object_get_int()=0
+new_obj.boolean_false json_object_get_int64()=0
+new_obj.boolean_false json_object_get_boolean()=0
+new_obj.boolean_false json_object_get_double()=0.000000
+new_obj.big_number json_object_get_type()=int
+new_obj.big_number json_object_get_int()=2147483647
+new_obj.big_number json_object_get_int64()=2147483649
+new_obj.big_number json_object_get_boolean()=1
+new_obj.big_number json_object_get_double()=2147483649.000000
+new_obj.a_null json_object_get_type()=null
+new_obj.a_null json_object_get_int()=0
+new_obj.a_null json_object_get_int64()=0
+new_obj.a_null json_object_get_boolean()=0
+new_obj.a_null json_object_get_double()=0.000000
+
+================================
+json_object_is_type: null,boolean,double,int,object,array,string
+new_obj : 0,0,0,0,1,0,0
+new_obj.string_of_digits : 0,0,0,0,0,0,1
+new_obj.regular_number : 0,0,0,1,0,0,0
+new_obj.decimal_number : 0,0,1,0,0,0,0
+new_obj.boolean_true : 0,1,0,0,0,0,0
+new_obj.boolean_false : 0,1,0,0,0,0,0
+new_obj.big_number : 0,0,0,1,0,0,0
+new_obj.a_null : 1,0,0,0,0,0,0
diff --git a/json-c/src/tests/test_cast.test b/json-c/src/tests/test_cast.test
new file mode 100644
index 0000000..df165f8
--- /dev/null
+++ b/json-c/src/tests/test_cast.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test_cast
+exit $?
diff --git a/json-c/src/tests/test_charcase.c b/json-c/src/tests/test_charcase.c
new file mode 100644
index 0000000..9179467
--- /dev/null
+++ b/json-c/src/tests/test_charcase.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+
+#include "json.h"
+#include "json_tokener.h"
+
+static void test_case_parse(void);
+
+int main(int argc, char **argv)
+{
+ MC_SET_DEBUG(1);
+
+ test_case_parse();
+}
+
+/* make sure only lowercase forms are parsed in strict mode */
+static void test_case_parse()
+{
+ struct json_tokener *tok;
+ json_object *new_obj;
+
+ tok = json_tokener_new();
+ json_tokener_set_flags(tok, JSON_TOKENER_STRICT);
+
+ new_obj = json_tokener_parse_ex(tok, "True", 4);
+ assert (new_obj == NULL);
+
+ new_obj = json_tokener_parse_ex(tok, "False", 5);
+ assert (new_obj == NULL);
+
+ new_obj = json_tokener_parse_ex(tok, "Null", 4);
+ assert (new_obj == NULL);
+
+ printf("OK\n");
+
+ json_tokener_free(tok);
+}
diff --git a/json-c/src/tests/test_charcase.expected b/json-c/src/tests/test_charcase.expected
new file mode 100644
index 0000000..e178f82
--- /dev/null
+++ b/json-c/src/tests/test_charcase.expected
@@ -0,0 +1 @@
+OK
diff --git a/json-c/src/tests/test_charcase.test b/json-c/src/tests/test_charcase.test
new file mode 100644
index 0000000..40edbf4
--- /dev/null
+++ b/json-c/src/tests/test_charcase.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test_charcase
+exit $?
diff --git a/json-c/src/tests/test_locale.c b/json-c/src/tests/test_locale.c
new file mode 100644
index 0000000..7924bca
--- /dev/null
+++ b/json-c/src/tests/test_locale.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+
+#include "config.h"
+#include "json.h"
+#include "json_tokener.h"
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif /* HAVE_LOCALE_H */
+
+int main(int argc, char **argv)
+{
+ json_object *new_obj;
+#ifdef HAVE_SETLOCALE
+ setlocale(LC_NUMERIC, "de_DE");
+#else
+ printf("No locale\n");
+#endif
+
+ MC_SET_DEBUG(1);
+
+ new_obj = json_tokener_parse("[1.2,3.4,123456.78,5.0,2.3e10]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string_ext(new_obj,JSON_C_TO_STRING_NOZERO));
+ json_object_put(new_obj);
+}
+
diff --git a/json-c/src/tests/test_locale.expected b/json-c/src/tests/test_locale.expected
new file mode 100644
index 0000000..4415692
--- /dev/null
+++ b/json-c/src/tests/test_locale.expected
@@ -0,0 +1,2 @@
+new_obj.to_string()=[ 1.2, 3.4, 123456.78, 5.0, 2.3e10 ]
+new_obj.to_string()=[1.2,3.4,123456.78,5.0,2.3e10]
diff --git a/json-c/src/tests/test_locale.test b/json-c/src/tests/test_locale.test
new file mode 100644
index 0000000..436587f
--- /dev/null
+++ b/json-c/src/tests/test_locale.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test_locale
+exit $?
diff --git a/json-c/src/tests/test_null.c b/json-c/src/tests/test_null.c
new file mode 100644
index 0000000..da86fb6
--- /dev/null
+++ b/json-c/src/tests/test_null.c
@@ -0,0 +1,57 @@
+/*
+* Tests if binary strings are supported.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "config.h"
+
+#include "json_inttypes.h"
+#include "json_object.h"
+#include "json_tokener.h"
+
+int main()
+{
+ // this test has a space after the null character. check that it's still included
+ const char *input = " \0 ";
+ const char *expected = "\" \\u0000 \"";
+ struct json_object *string = json_object_new_string_len(input, 3);
+ const char *json = json_object_to_json_string(string);
+
+ int strings_match = !strcmp( expected, json);
+ int retval = 0;
+ if (strings_match)
+ {
+ printf("JSON write result is correct: %s\n", json);
+ printf("PASS\n");
+ } else {
+ printf("JSON write result doesn't match expected string\n");
+ printf("expected string: ");
+ printf("%s\n", expected);
+ printf("parsed string: ");
+ printf("%s\n", json);
+ printf("FAIL\n");
+ retval=1;
+ }
+ json_object_put(string);
+
+ struct json_object *parsed_str = json_tokener_parse(expected);
+ if (parsed_str)
+ {
+ int parsed_len = json_object_get_string_len(parsed_str);
+ const char *parsed_cstr = json_object_get_string(parsed_str);
+ int ii;
+ printf("Re-parsed object string len=%d, chars=[", parsed_len);
+ for (ii = 0; ii < parsed_len ; ii++)
+ {
+ printf("%s%d", (ii ? ", " : ""), (int)parsed_cstr[ii]);
+ }
+ printf("]\n");
+ json_object_put(parsed_str);
+ }
+ else
+ {
+ printf("ERROR: failed to parse\n");
+ }
+ return retval;
+}
diff --git a/json-c/src/tests/test_null.expected b/json-c/src/tests/test_null.expected
new file mode 100644
index 0000000..be1c9d1
--- /dev/null
+++ b/json-c/src/tests/test_null.expected
@@ -0,0 +1,3 @@
+JSON write result is correct: " \u0000 "
+PASS
+Re-parsed object string len=3, chars=[32, 0, 32]
diff --git a/json-c/src/tests/test_null.test b/json-c/src/tests/test_null.test
new file mode 100644
index 0000000..7c4365c
--- /dev/null
+++ b/json-c/src/tests/test_null.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test_null
+exit $?
diff --git a/json-c/src/tests/test_parse.c b/json-c/src/tests/test_parse.c
new file mode 100644
index 0000000..2e5996e
--- /dev/null
+++ b/json-c/src/tests/test_parse.c
@@ -0,0 +1,342 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+
+#include "json.h"
+#include "json_tokener.h"
+
+static void test_basic_parse(void);
+static void test_verbose_parse(void);
+static void test_incremental_parse(void);
+
+int main(int argc, char **argv)
+{
+ MC_SET_DEBUG(1);
+
+ test_basic_parse();
+ printf("==================================\n");
+ test_verbose_parse();
+ printf("==================================\n");
+ test_incremental_parse();
+ printf("==================================\n");
+}
+
+static void test_basic_parse()
+{
+ json_object *new_obj;
+
+ new_obj = json_tokener_parse("\"\003\"");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("/* hello */\"foo\"");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("// hello\n\"foo\"");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("\"\\u0041\\u0042\\u0043\"");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("null");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("NaN");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("-NaN"); /* non-sensical, returns null */
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("Inf"); /* must use full string, returns null */
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("inf"); /* must use full string, returns null */
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("Infinity");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("infinity");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("-Infinity");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("-infinity");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("True");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("12");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("12.3");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("12.3.4"); /* non-sensical, returns null */
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ /* was returning (int)2015 before patch, should return null */
+ new_obj = json_tokener_parse("2015-01-15");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("{\"FoO\" : -12.3E512}");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("{\"FoO\" : -12.3E51.2}"); /* non-sensical, returns null */
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("[\"\\n\"]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("[\"\\nabc\\n\"]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("[null]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("[]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("[false]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("[\"abc\",null,\"def\",12]");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("{}");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("{ \"foo\": \"bar\" }");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("{ \"foo\": [null, \"foo\"] }");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+
+ new_obj = json_tokener_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }");
+ printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
+ json_object_put(new_obj);
+}
+
+static void test_verbose_parse()
+{
+ json_object *new_obj;
+ enum json_tokener_error error = json_tokener_success;
+
+ new_obj = json_tokener_parse_verbose("{ foo }", &error);
+ assert (error == json_tokener_error_parse_object_key_name);
+ assert (new_obj == NULL);
+
+ new_obj = json_tokener_parse("{ foo }");
+ assert (new_obj == NULL);
+
+ new_obj = json_tokener_parse("foo");
+ assert (new_obj == NULL);
+ new_obj = json_tokener_parse_verbose("foo", &error);
+ assert (new_obj == NULL);
+
+ /* b/c the string starts with 'f' parsing return a boolean error */
+ assert (error == json_tokener_error_parse_boolean);
+
+ printf("json_tokener_parse_versbose() OK\n");
+}
+
+struct incremental_step {
+ const char *string_to_parse;
+ int length;
+ int char_offset;
+ enum json_tokener_error expected_error;
+ int reset_tokener;
+} incremental_steps[] = {
+
+ /* Check that full json messages can be parsed, both w/ and w/o a reset */
+ { "{ \"foo\": 123 }", -1, -1, json_tokener_success, 0 },
+ { "{ \"foo\": 456 }", -1, -1, json_tokener_success, 1 },
+ { "{ \"foo\": 789 }", -1, -1, json_tokener_success, 1 },
+
+ /* Check a basic incremental parse */
+ { "{ \"foo", -1, -1, json_tokener_continue, 0 },
+ { "\": {\"bar", -1, -1, json_tokener_continue, 0 },
+ { "\":13}}", -1, -1, json_tokener_success, 1 },
+
+ /* Check that json_tokener_reset actually resets */
+ { "{ \"foo", -1, -1, json_tokener_continue, 1 },
+ { ": \"bar\"}", -1, 0, json_tokener_error_parse_unexpected, 1 },
+
+ /* Check incremental parsing with trailing characters */
+ { "{ \"foo", -1, -1, json_tokener_continue, 0 },
+ { "\": {\"bar", -1, -1, json_tokener_continue, 0 },
+ { "\":13}}XXXX", 10, 6, json_tokener_success, 0 },
+ { "XXXX", 4, 0, json_tokener_error_parse_unexpected, 1 },
+
+ /* Check that trailing characters can change w/o a reset */
+ { "{\"x\": 123 }\"X\"", -1, 11, json_tokener_success, 0 },
+ { "\"Y\"", -1, -1, json_tokener_success, 1 },
+
+ /* To stop parsing a number we need to reach a non-digit, e.g. a \0 */
+ { "1", 1, 1, json_tokener_continue, 0 },
+ { "2", 2, 1, json_tokener_success, 0 },
+
+ /* Some bad formatting. Check we get the correct error status */
+ { "2015-01-15", 10, 4, json_tokener_error_parse_number, 1 },
+
+ /* Strings have a well defined end point, so we can stop at the quote */
+ { "\"blue\"", -1, -1, json_tokener_success, 0 },
+
+ /* Check each of the escape sequences defined by the spec */
+ { "\"\\\"\"", -1, -1, json_tokener_success, 0 },
+ { "\"\\\\\"", -1, -1, json_tokener_success, 0 },
+ { "\"\\b\"", -1, -1, json_tokener_success, 0 },
+ { "\"\\f\"", -1, -1, json_tokener_success, 0 },
+ { "\"\\n\"", -1, -1, json_tokener_success, 0 },
+ { "\"\\r\"", -1, -1, json_tokener_success, 0 },
+ { "\"\\t\"", -1, -1, json_tokener_success, 0 },
+
+ { "[1,2,3]", -1, -1, json_tokener_success, 0 },
+
+ /* This behaviour doesn't entirely follow the json spec, but until we have
+ a way to specify how strict to be we follow Postel's Law and be liberal
+ in what we accept (up to a point). */
+ { "[1,2,3,]", -1, -1, json_tokener_success, 0 },
+ { "[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0 },
+
+ { "[1,2,3,]", -1, 7, json_tokener_error_parse_unexpected, 3 },
+ { "{\"a\":1,}", -1, 7, json_tokener_error_parse_unexpected, 3 },
+
+ { NULL, -1, -1, json_tokener_success, 0 },
+};
+
+static void test_incremental_parse()
+{
+ json_object *new_obj;
+ enum json_tokener_error jerr;
+ json_tokener *tok;
+ const char *string_to_parse;
+ int ii;
+ int num_ok, num_error;
+
+ num_ok = 0;
+ num_error = 0;
+
+ printf("Starting incremental tests.\n");
+ printf("Note: quotes and backslashes seen in the output here are literal values passed\n");
+ printf(" to the parse functions. e.g. this is 4 characters: \"\\f\"\n");
+
+ string_to_parse = "{ \"foo"; /* } */
+ printf("json_tokener_parse(%s) ... ", string_to_parse);
+ new_obj = json_tokener_parse(string_to_parse);
+ if (new_obj == NULL) printf("got error as expected\n");
+
+ /* test incremental parsing in various forms */
+ tok = json_tokener_new();
+ for (ii = 0; incremental_steps[ii].string_to_parse != NULL; ii++)
+ {
+ int this_step_ok = 0;
+ struct incremental_step *step = &incremental_steps[ii];
+ int length = step->length;
+ int expected_char_offset = step->char_offset;
+
+ if (step->reset_tokener & 2)
+ json_tokener_set_flags(tok, JSON_TOKENER_STRICT);
+ else
+ json_tokener_set_flags(tok, 0);
+
+ if (length == -1)
+ length = strlen(step->string_to_parse);
+ if (expected_char_offset == -1)
+ expected_char_offset = length;
+
+ printf("json_tokener_parse_ex(tok, %-12s, %3d) ... ",
+ step->string_to_parse, length);
+ new_obj = json_tokener_parse_ex(tok, step->string_to_parse, length);
+
+ jerr = json_tokener_get_error(tok);
+ if (step->expected_error != json_tokener_success)
+ {
+ if (new_obj != NULL)
+ printf("ERROR: invalid object returned: %s\n",
+ json_object_to_json_string(new_obj));
+ else if (jerr != step->expected_error)
+ printf("ERROR: got wrong error: %s\n",
+ json_tokener_error_desc(jerr));
+ else if (tok->char_offset != expected_char_offset)
+ printf("ERROR: wrong char_offset %d != expected %d\n",
+ tok->char_offset,
+ expected_char_offset);
+ else
+ {
+ printf("OK: got correct error: %s\n", json_tokener_error_desc(jerr));
+ this_step_ok = 1;
+ }
+ }
+ else
+ {
+ if (new_obj == NULL)
+ printf("ERROR: expected valid object, instead: %s\n",
+ json_tokener_error_desc(jerr));
+ else if (tok->char_offset != expected_char_offset)
+ printf("ERROR: wrong char_offset %d != expected %d\n",
+ tok->char_offset,
+ expected_char_offset);
+ else
+ {
+ printf("OK: got object of type [%s]: %s\n",
+ json_type_to_name(json_object_get_type(new_obj)),
+ json_object_to_json_string(new_obj));
+ this_step_ok = 1;
+ }
+ }
+
+ if (new_obj)
+ json_object_put(new_obj);
+
+ if (step->reset_tokener & 1)
+ json_tokener_reset(tok);
+
+ if (this_step_ok)
+ num_ok++;
+ else
+ num_error++;
+ }
+
+ json_tokener_free(tok);
+
+ printf("End Incremental Tests OK=%d ERROR=%d\n", num_ok, num_error);
+
+ return;
+}
diff --git a/json-c/src/tests/test_parse.expected b/json-c/src/tests/test_parse.expected
new file mode 100644
index 0000000..bb76db2
--- /dev/null
+++ b/json-c/src/tests/test_parse.expected
@@ -0,0 +1,70 @@
+new_obj.to_string()="\u0003"
+new_obj.to_string()="foo"
+new_obj.to_string()="foo"
+new_obj.to_string()="ABC"
+new_obj.to_string()=null
+new_obj.to_string()=NaN
+new_obj.to_string()=null
+new_obj.to_string()=null
+new_obj.to_string()=null
+new_obj.to_string()=Infinity
+new_obj.to_string()=Infinity
+new_obj.to_string()=-Infinity
+new_obj.to_string()=-Infinity
+new_obj.to_string()=true
+new_obj.to_string()=12
+new_obj.to_string()=12.3
+new_obj.to_string()=null
+new_obj.to_string()=null
+new_obj.to_string()={ "FoO": -12.3E512 }
+new_obj.to_string()=null
+new_obj.to_string()=[ "\n" ]
+new_obj.to_string()=[ "\nabc\n" ]
+new_obj.to_string()=[ null ]
+new_obj.to_string()=[ ]
+new_obj.to_string()=[ false ]
+new_obj.to_string()=[ "abc", null, "def", 12 ]
+new_obj.to_string()={ }
+new_obj.to_string()={ "foo": "bar" }
+new_obj.to_string()={ "foo": "bar", "baz": null, "bool0": true }
+new_obj.to_string()={ "foo": [ null, "foo" ] }
+new_obj.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "arr": [ 1, 2, 3, null, 5 ] }
+==================================
+json_tokener_parse_versbose() OK
+==================================
+Starting incremental tests.
+Note: quotes and backslashes seen in the output here are literal values passed
+ to the parse functions. e.g. this is 4 characters: "\f"
+json_tokener_parse({ "foo) ... got error as expected
+json_tokener_parse_ex(tok, { "foo": 123 }, 14) ... OK: got object of type [object]: { "foo": 123 }
+json_tokener_parse_ex(tok, { "foo": 456 }, 14) ... OK: got object of type [object]: { "foo": 456 }
+json_tokener_parse_ex(tok, { "foo": 789 }, 14) ... OK: got object of type [object]: { "foo": 789 }
+json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue
+json_tokener_parse_ex(tok, ": {"bar , 8) ... OK: got correct error: continue
+json_tokener_parse_ex(tok, ":13}} , 6) ... OK: got object of type [object]: { "foo": { "bar": 13 } }
+json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue
+json_tokener_parse_ex(tok, : "bar"} , 8) ... OK: got correct error: unexpected character
+json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue
+json_tokener_parse_ex(tok, ": {"bar , 8) ... OK: got correct error: continue
+json_tokener_parse_ex(tok, ":13}}XXXX , 10) ... OK: got object of type [object]: { "foo": { "bar": 13 } }
+json_tokener_parse_ex(tok, XXXX , 4) ... OK: got correct error: unexpected character
+json_tokener_parse_ex(tok, {"x": 123 }"X", 14) ... OK: got object of type [object]: { "x": 123 }
+json_tokener_parse_ex(tok, "Y" , 3) ... OK: got object of type [string]: "Y"
+json_tokener_parse_ex(tok, 1 , 1) ... OK: got correct error: continue
+json_tokener_parse_ex(tok, 2 , 2) ... OK: got object of type [int]: 12
+json_tokener_parse_ex(tok, 2015-01-15 , 10) ... OK: got correct error: number expected
+json_tokener_parse_ex(tok, "blue" , 6) ... OK: got object of type [string]: "blue"
+json_tokener_parse_ex(tok, "\"" , 4) ... OK: got object of type [string]: "\""
+json_tokener_parse_ex(tok, "\\" , 4) ... OK: got object of type [string]: "\\"
+json_tokener_parse_ex(tok, "\b" , 4) ... OK: got object of type [string]: "\b"
+json_tokener_parse_ex(tok, "\f" , 4) ... OK: got object of type [string]: "\f"
+json_tokener_parse_ex(tok, "\n" , 4) ... OK: got object of type [string]: "\n"
+json_tokener_parse_ex(tok, "\r" , 4) ... OK: got object of type [string]: "\r"
+json_tokener_parse_ex(tok, "\t" , 4) ... OK: got object of type [string]: "\t"
+json_tokener_parse_ex(tok, [1,2,3] , 7) ... OK: got object of type [array]: [ 1, 2, 3 ]
+json_tokener_parse_ex(tok, [1,2,3,] , 8) ... OK: got object of type [array]: [ 1, 2, 3 ]
+json_tokener_parse_ex(tok, [1,2,,3,] , 9) ... OK: got correct error: unexpected character
+json_tokener_parse_ex(tok, [1,2,3,] , 8) ... OK: got correct error: unexpected character
+json_tokener_parse_ex(tok, {"a":1,} , 8) ... OK: got correct error: unexpected character
+End Incremental Tests OK=30 ERROR=0
+==================================
diff --git a/json-c/src/tests/test_parse.test b/json-c/src/tests/test_parse.test
new file mode 100644
index 0000000..719a3ad
--- /dev/null
+++ b/json-c/src/tests/test_parse.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test_parse
+exit $?
diff --git a/json-c/src/tests/test_parse_int64.c b/json-c/src/tests/test_parse_int64.c
new file mode 100644
index 0000000..dfcdae0
--- /dev/null
+++ b/json-c/src/tests/test_parse_int64.c
@@ -0,0 +1,115 @@
+
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+
+#include "json_inttypes.h"
+#include "json_util.h"
+
+void checkit(const char *buf)
+{
+ int64_t cint64 = -666;
+
+ int retval = json_parse_int64(buf, &cint64);
+ printf("buf=%s parseit=%d, value=%" PRId64 " \n", buf, retval, cint64);
+}
+
+/**
+ * This test calls json_parse_int64 with a variety of different strings.
+ * It's purpose is to ensure that the results are consistent across all
+ * different environments that it might be executed in.
+ *
+ * This always exits with a 0 exit value. The output should be compared
+ * against previously saved expected output.
+ */
+int main()
+{
+ char buf[100];
+
+ checkit("x");
+
+ checkit("0");
+ checkit("-0");
+
+ checkit("00000000");
+ checkit("-00000000");
+
+ checkit("1");
+
+ strcpy(buf, "2147483647"); // aka INT32_MAX
+ checkit(buf);
+
+ strcpy(buf, "-1");
+ checkit(buf);
+
+ strcpy(buf, " -1");
+ checkit(buf);
+
+ strcpy(buf, "00001234");
+ checkit(buf);
+
+ strcpy(buf, "0001234x");
+ checkit(buf);
+
+ strcpy(buf, "-00001234");
+ checkit(buf);
+
+ strcpy(buf, "-00001234x");
+ checkit(buf);
+
+ strcpy(buf, "4294967295"); // aka UINT32_MAX
+
+ sprintf(buf, "4294967296"); // aka UINT32_MAX + 1
+
+ strcpy(buf, "21474836470"); // INT32_MAX * 10
+ checkit(buf);
+
+ strcpy(buf, "31474836470"); // INT32_MAX * 10 + a bunch
+ checkit(buf);
+
+ strcpy(buf, "-2147483647"); // INT32_MIN + 1
+ checkit(buf);
+
+ strcpy(buf, "-2147483648"); // INT32_MIN
+ checkit(buf);
+
+ strcpy(buf, "-2147483649"); // INT32_MIN - 1
+ checkit(buf);
+
+ strcpy(buf, "-21474836480"); // INT32_MIN * 10
+ checkit(buf);
+
+ strcpy(buf, "9223372036854775806"); // INT64_MAX - 1
+ checkit(buf);
+
+ strcpy(buf, "9223372036854775807"); // INT64_MAX
+ checkit(buf);
+
+ strcpy(buf, "9223372036854775808"); // INT64_MAX + 1
+ checkit(buf);
+
+ strcpy(buf, "-9223372036854775808"); // INT64_MIN
+ checkit(buf);
+
+ strcpy(buf, "-9223372036854775809"); // INT64_MIN - 1
+ checkit(buf);
+
+ strcpy(buf, "18446744073709551614"); // UINT64_MAX - 1
+ checkit(buf);
+
+ strcpy(buf, "18446744073709551615"); // UINT64_MAX
+ checkit(buf);
+
+ strcpy(buf, "18446744073709551616"); // UINT64_MAX + 1
+ checkit(buf);
+
+ strcpy(buf, "-18446744073709551616"); // -UINT64_MAX
+ checkit(buf);
+
+ // Ensure we can still parse valid numbers after parsing out of range ones.
+ strcpy(buf, "123");
+ checkit(buf);
+
+ return 0;
+}
diff --git a/json-c/src/tests/test_parse_int64.expected b/json-c/src/tests/test_parse_int64.expected
new file mode 100644
index 0000000..1ed8f02
--- /dev/null
+++ b/json-c/src/tests/test_parse_int64.expected
@@ -0,0 +1,29 @@
+buf=x parseit=1, value=-666
+buf=0 parseit=0, value=0
+buf=-0 parseit=0, value=0
+buf=00000000 parseit=0, value=0
+buf=-00000000 parseit=0, value=0
+buf=1 parseit=0, value=1
+buf=2147483647 parseit=0, value=2147483647
+buf=-1 parseit=0, value=-1
+buf= -1 parseit=0, value=-1
+buf=00001234 parseit=0, value=1234
+buf=0001234x parseit=0, value=1234
+buf=-00001234 parseit=0, value=-1234
+buf=-00001234x parseit=0, value=-1234
+buf=21474836470 parseit=0, value=21474836470
+buf=31474836470 parseit=0, value=31474836470
+buf=-2147483647 parseit=0, value=-2147483647
+buf=-2147483648 parseit=0, value=-2147483648
+buf=-2147483649 parseit=0, value=-2147483649
+buf=-21474836480 parseit=0, value=-21474836480
+buf=9223372036854775806 parseit=0, value=9223372036854775806
+buf=9223372036854775807 parseit=0, value=9223372036854775807
+buf=9223372036854775808 parseit=0, value=9223372036854775807
+buf=-9223372036854775808 parseit=0, value=-9223372036854775808
+buf=-9223372036854775809 parseit=0, value=-9223372036854775808
+buf=18446744073709551614 parseit=0, value=9223372036854775807
+buf=18446744073709551615 parseit=0, value=9223372036854775807
+buf=18446744073709551616 parseit=0, value=9223372036854775807
+buf=-18446744073709551616 parseit=0, value=-9223372036854775808
+buf=123 parseit=0, value=123
diff --git a/json-c/src/tests/test_parse_int64.test b/json-c/src/tests/test_parse_int64.test
new file mode 100644
index 0000000..556681f
--- /dev/null
+++ b/json-c/src/tests/test_parse_int64.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test_parse_int64
+exit $?
diff --git a/json-c/src/tests/test_printbuf.c b/json-c/src/tests/test_printbuf.c
new file mode 100644
index 0000000..b363296
--- /dev/null
+++ b/json-c/src/tests/test_printbuf.c
@@ -0,0 +1,166 @@
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include "debug.h"
+#include "printbuf.h"
+
+static void test_basic_printbuf_memset(void);
+static void test_printbuf_memset_length(void);
+
+static void test_basic_printbuf_memset()
+{
+ struct printbuf *pb;
+
+ printf("%s: starting test\n", __func__);
+ pb = printbuf_new();
+ sprintbuf(pb, "blue:%d", 1);
+ printbuf_memset(pb, -1, 'x', 52);
+ printf("Buffer contents:%.*s\n", printbuf_length(pb), pb->buf);
+ printbuf_free(pb);
+ printf("%s: end test\n", __func__);
+}
+
+static void test_printbuf_memset_length()
+{
+ struct printbuf *pb;
+
+ printf("%s: starting test\n", __func__);
+ pb = printbuf_new();
+ printbuf_memset(pb, -1, ' ', 0);
+ printbuf_memset(pb, -1, ' ', 0);
+ printbuf_memset(pb, -1, ' ', 0);
+ printbuf_memset(pb, -1, ' ', 0);
+ printbuf_memset(pb, -1, ' ', 0);
+ printf("Buffer length: %d\n", printbuf_length(pb));
+ printbuf_memset(pb, -1, ' ', 2);
+ printbuf_memset(pb, -1, ' ', 4);
+ printbuf_memset(pb, -1, ' ', 6);
+ printf("Buffer length: %d\n", printbuf_length(pb));
+ printbuf_memset(pb, -1, ' ', 6);
+ printf("Buffer length: %d\n", printbuf_length(pb));
+ printbuf_memset(pb, -1, ' ', 8);
+ printbuf_memset(pb, -1, ' ', 10);
+ printbuf_memset(pb, -1, ' ', 10);
+ printbuf_memset(pb, -1, ' ', 10);
+ printbuf_memset(pb, -1, ' ', 20);
+ printf("Buffer length: %d\n", printbuf_length(pb));
+
+ // No length change should occur
+ printbuf_memset(pb, 0, 'x', 30);
+ printf("Buffer length: %d\n", printbuf_length(pb));
+
+ // This should extend it by one.
+ printbuf_memset(pb, 0, 'x', printbuf_length(pb) + 1);
+ printf("Buffer length: %d\n", printbuf_length(pb));
+
+ printbuf_free(pb);
+ printf("%s: end test\n", __func__);
+}
+
+static void test_printbuf_memappend(int *before_resize);
+static void test_printbuf_memappend(int *before_resize)
+{
+ struct printbuf *pb;
+ int initial_size;
+
+ printf("%s: starting test\n", __func__);
+ pb = printbuf_new();
+ printf("Buffer length: %d\n", printbuf_length(pb));
+
+ initial_size = pb->size;
+
+ while(pb->size == initial_size)
+ {
+ printbuf_memappend_fast(pb, "x", 1);
+ }
+ *before_resize = printbuf_length(pb) - 1;
+ printf("Appended %d bytes for resize: [%s]\n", *before_resize + 1, pb->buf);
+
+ printbuf_reset(pb);
+ printbuf_memappend_fast(pb, "bluexyz123", 3);
+ printf("Partial append: %d, [%s]\n", printbuf_length(pb), pb->buf);
+
+ char with_nulls[] = { 'a', 'b', '\0', 'c' };
+ printbuf_reset(pb);
+ printbuf_memappend_fast(pb, with_nulls, (int)sizeof(with_nulls));
+ printf("With embedded \\0 character: %d, [%s]\n", printbuf_length(pb), pb->buf);
+
+ printbuf_free(pb);
+ pb = printbuf_new();
+ char *data = malloc(*before_resize);
+ memset(data, 'X', *before_resize);
+ printbuf_memappend_fast(pb, data, *before_resize);
+ printf("Append to just before resize: %d, [%s]\n", printbuf_length(pb), pb->buf);
+
+ free(data);
+ printbuf_free(pb);
+
+ pb = printbuf_new();
+ data = malloc(*before_resize + 1);
+ memset(data, 'X', *before_resize + 1);
+ printbuf_memappend_fast(pb, data, *before_resize + 1);
+ printf("Append to just after resize: %d, [%s]\n", printbuf_length(pb), pb->buf);
+
+ free(data);
+
+ printbuf_free(pb);
+ printf("%s: end test\n", __func__);
+}
+
+static void test_sprintbuf(int before_resize);
+static void test_sprintbuf(int before_resize)
+{
+ struct printbuf *pb;
+
+ printf("%s: starting test\n", __func__);
+ pb = printbuf_new();
+ printf("Buffer length: %d\n", printbuf_length(pb));
+
+ char *data = malloc(before_resize + 1 + 1);
+ memset(data, 'X', before_resize + 1 + 1);
+ data[before_resize + 1] = '\0';
+ sprintbuf(pb, "%s", data);
+ free(data);
+ printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize, printbuf_length(pb), pb->buf, (int)strlen(pb->buf));
+
+ printbuf_reset(pb);
+ sprintbuf(pb, "plain");
+ printf("%d, [%s]\n", printbuf_length(pb), pb->buf);
+
+ sprintbuf(pb, "%d", 1);
+ printf("%d, [%s]\n", printbuf_length(pb), pb->buf);
+
+ sprintbuf(pb, "%d", INT_MAX);
+ printf("%d, [%s]\n", printbuf_length(pb), pb->buf);
+
+ sprintbuf(pb, "%d", INT_MIN);
+ printf("%d, [%s]\n", printbuf_length(pb), pb->buf);
+
+ sprintbuf(pb, "%s", "%s");
+ printf("%d, [%s]\n", printbuf_length(pb), pb->buf);
+
+ printbuf_free(pb);
+ printf("%s: end test\n", __func__);
+}
+
+int main(int argc, char **argv)
+{
+ int before_resize = 0;
+
+ mc_set_debug(1);
+
+ test_basic_printbuf_memset();
+ printf("========================================\n");
+ test_printbuf_memset_length();
+ printf("========================================\n");
+ test_printbuf_memappend(&before_resize);
+ printf("========================================\n");
+ test_sprintbuf(before_resize);
+ printf("========================================\n");
+
+ return 0;
+}
diff --git a/json-c/src/tests/test_printbuf.expected b/json-c/src/tests/test_printbuf.expected
new file mode 100644
index 0000000..ec69095
--- /dev/null
+++ b/json-c/src/tests/test_printbuf.expected
@@ -0,0 +1,32 @@
+test_basic_printbuf_memset: starting test
+Buffer contents:blue:1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+test_basic_printbuf_memset: end test
+========================================
+test_printbuf_memset_length: starting test
+Buffer length: 0
+Buffer length: 12
+Buffer length: 18
+Buffer length: 76
+Buffer length: 76
+Buffer length: 77
+test_printbuf_memset_length: end test
+========================================
+test_printbuf_memappend: starting test
+Buffer length: 0
+Appended 32 bytes for resize: [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]
+Partial append: 3, [blu]
+With embedded \0 character: 4, [ab]
+Append to just before resize: 31, [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]
+Append to just after resize: 32, [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]
+test_printbuf_memappend: end test
+========================================
+test_sprintbuf: starting test
+Buffer length: 0
+sprintbuf to just after resize(31+1): 32, [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX], strlen(buf)=32
+5, [plain]
+6, [plain1]
+16, [plain12147483647]
+27, [plain12147483647-2147483648]
+29, [plain12147483647-2147483648%s]
+test_sprintbuf: end test
+========================================
diff --git a/json-c/src/tests/test_printbuf.test b/json-c/src/tests/test_printbuf.test
new file mode 100644
index 0000000..8da4fb5
--- /dev/null
+++ b/json-c/src/tests/test_printbuf.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test_printbuf
+exit $?
diff --git a/json-c/src/tests/test_set_serializer.c b/json-c/src/tests/test_set_serializer.c
new file mode 100644
index 0000000..e79b00d
--- /dev/null
+++ b/json-c/src/tests/test_set_serializer.c
@@ -0,0 +1,71 @@
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "json.h"
+#include "printbuf.h"
+
+struct myinfo {
+ int value;
+};
+
+static int freeit_was_called = 0;
+static void freeit(json_object *jso, void *userdata)
+{
+ struct myinfo *info = userdata;
+ printf("freeit, value=%d\n", info->value);
+ // Don't actually free anything here, the userdata is stack allocated.
+ freeit_was_called = 1;
+}
+static int custom_serializer(struct json_object *o,
+ struct printbuf *pb,
+ int level,
+ int flags)
+{
+ sprintbuf(pb, "Custom Output");
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ json_object *my_object;
+
+ MC_SET_DEBUG(1);
+
+ printf("Test setting, then resetting a custom serializer:\n");
+ my_object = json_object_new_object();
+ json_object_object_add(my_object, "abc", json_object_new_int(12));
+ json_object_object_add(my_object, "foo", json_object_new_string("bar"));
+
+ printf("my_object.to_string(standard)=%s\n", json_object_to_json_string(my_object));
+
+ struct myinfo userdata = { .value = 123 };
+ json_object_set_serializer(my_object, custom_serializer, &userdata, freeit);
+
+ printf("my_object.to_string(custom serializer)=%s\n", json_object_to_json_string(my_object));
+
+ printf("Next line of output should be from the custom freeit function:\n");
+ freeit_was_called = 0;
+ json_object_set_serializer(my_object, NULL, NULL, NULL);
+ assert(freeit_was_called);
+
+ printf("my_object.to_string(standard)=%s\n", json_object_to_json_string(my_object));
+
+ json_object_put(my_object);
+
+ // ============================================
+
+ my_object = json_object_new_object();
+ printf("Check that the custom serializer isn't free'd until the last json_object_put:\n");
+ json_object_set_serializer(my_object, custom_serializer, &userdata, freeit);
+ json_object_get(my_object);
+ json_object_put(my_object);
+ printf("my_object.to_string(custom serializer)=%s\n", json_object_to_json_string(my_object));
+ printf("Next line of output should be from the custom freeit function:\n");
+
+ freeit_was_called = 0;
+ json_object_put(my_object);
+ assert(freeit_was_called);
+
+ return 0;
+}
diff --git a/json-c/src/tests/test_set_serializer.expected b/json-c/src/tests/test_set_serializer.expected
new file mode 100644
index 0000000..f5d3747
--- /dev/null
+++ b/json-c/src/tests/test_set_serializer.expected
@@ -0,0 +1,10 @@
+Test setting, then resetting a custom serializer:
+my_object.to_string(standard)={ "abc": 12, "foo": "bar" }
+my_object.to_string(custom serializer)=Custom Output
+Next line of output should be from the custom freeit function:
+freeit, value=123
+my_object.to_string(standard)={ "abc": 12, "foo": "bar" }
+Check that the custom serializer isn't free'd until the last json_object_put:
+my_object.to_string(custom serializer)=Custom Output
+Next line of output should be from the custom freeit function:
+freeit, value=123
diff --git a/json-c/src/tests/test_set_serializer.test b/json-c/src/tests/test_set_serializer.test
new file mode 100644
index 0000000..0034183
--- /dev/null
+++ b/json-c/src/tests/test_set_serializer.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test_set_serializer
+exit $?