@@ -72,7 +72,6 @@ | |||||
*.dmg | *.dmg | ||||
*.ipa | *.ipa | ||||
/INSTALL | |||||
.deps/ | .deps/ | ||||
.libs/ | .libs/ | ||||
/aclocal.m4 | /aclocal.m4 | ||||
@@ -99,3 +98,11 @@ | |||||
/missing | /missing | ||||
/stamp-h1 | /stamp-h1 | ||||
/stamp-h2 | /stamp-h2 | ||||
# cmake auto-generated files | |||||
/CMakeCache.txt | |||||
/CMakeFiles | |||||
/cmake_install.cmake | |||||
/include | |||||
/libjson-c.a | |||||
/libjson-c.so |
@@ -16,6 +16,7 @@ os: | |||||
before_install: | before_install: | ||||
- echo $LANG | - echo $LANG | ||||
- echo $LC_ALL | - echo $LC_ALL | ||||
- set -e | |||||
install: | install: | ||||
- sh autogen.sh | - sh autogen.sh | ||||
@@ -28,4 +29,4 @@ script: | |||||
after_success: | after_success: | ||||
- make check | - make check | ||||
- cppcheck --quiet *.h *.c tests/ | |||||
- if type cppcheck &> /dev/null ; then cppcheck --error-exitcode=1 --quiet *.h *.c tests/ ; fi |
@@ -11,12 +11,24 @@ if(MSVC) | |||||
file(RENAME ${CMAKE_CURRENT_BINARY_DIR}/include/config.h.win32 ${CMAKE_CURRENT_BINARY_DIR}/include/config.h) | file(RENAME ${CMAKE_CURRENT_BINARY_DIR}/include/config.h.win32 ${CMAKE_CURRENT_BINARY_DIR}/include/config.h) | ||||
file(COPY ./json_config.h.win32 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/) | file(COPY ./json_config.h.win32 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/) | ||||
file(RENAME ${CMAKE_CURRENT_BINARY_DIR}/include/json_config.h.win32 ${CMAKE_CURRENT_BINARY_DIR}/include/json_config.h) | file(RENAME ${CMAKE_CURRENT_BINARY_DIR}/include/json_config.h.win32 ${CMAKE_CURRENT_BINARY_DIR}/include/json_config.h) | ||||
elseif(MINGW) | |||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -D_GNU_SOURCE=1") | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -D_GNU_SOURCE=1") | |||||
if (MSYS OR CMAKE_GENERATOR STREQUAL "Unix Makefiles") | |||||
execute_process(COMMAND echo ${CMAKE_CURRENT_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | |||||
execute_process(COMMAND sh autogen.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | |||||
execute_process(COMMAND sh ./configure WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | |||||
file(COPY ./config.h DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/) | |||||
file(COPY ./json_config.h DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/) | |||||
else() | |||||
file(COPY ./config.h.win32 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/) | |||||
file(RENAME ${CMAKE_CURRENT_BINARY_DIR}/include/config.h.win32 ${CMAKE_CURRENT_BINARY_DIR}/include/config.h) | |||||
file(COPY ./json_config.h.win32 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/) | |||||
file(RENAME ${CMAKE_CURRENT_BINARY_DIR}/include/json_config.h.win32 ${CMAKE_CURRENT_BINARY_DIR}/include/json_config.h) | |||||
endif() | |||||
elseif(UNIX) | elseif(UNIX) | ||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") | ||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") | |||||
if(CMAKE_COMPILER_IS_GNUCC) | |||||
add_definitions(-D_GNU_SOURCE) | |||||
endif() | |||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -D_GNU_SOURCE") | |||||
execute_process(COMMAND echo ${CMAKE_CURRENT_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | execute_process(COMMAND echo ${CMAKE_CURRENT_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | ||||
execute_process(COMMAND sh autogen.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | execute_process(COMMAND sh autogen.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | ||||
execute_process(COMMAND ./configure WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | execute_process(COMMAND ./configure WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | ||||
@@ -56,16 +68,26 @@ set(JSON_C_SOURCES | |||||
./linkhash.c | ./linkhash.c | ||||
./printbuf.c | ./printbuf.c | ||||
./random_seed.c | ./random_seed.c | ||||
./strerror_override.c | |||||
) | ) | ||||
add_library(json-c | add_library(json-c | ||||
SHARED | |||||
${JSON_C_SOURCES} | |||||
${JSON_C_HEADERS} | |||||
) | |||||
add_library(json-c-static | |||||
STATIC | |||||
${JSON_C_SOURCES} | ${JSON_C_SOURCES} | ||||
${JSON_C_HEADERS} | ${JSON_C_HEADERS} | ||||
) | ) | ||||
set_property(TARGET json-c PROPERTY C_STANDARD 99) | set_property(TARGET json-c PROPERTY C_STANDARD 99) | ||||
set_property(TARGET json-c-static PROPERTY C_STANDARD 99) | |||||
set_target_properties(json-c-static PROPERTIES OUTPUT_NAME json-c) | |||||
install(TARGETS json-c | |||||
install(TARGETS json-c json-c-static | |||||
RUNTIME DESTINATION bin | RUNTIME DESTINATION bin | ||||
LIBRARY DESTINATION lib | LIBRARY DESTINATION lib | ||||
ARCHIVE DESTINATION lib | ARCHIVE DESTINATION lib | ||||
@@ -0,0 +1,3 @@ | |||||
See README.md for installation instructions. | |||||
@@ -1,6 +1,6 @@ | |||||
EXTRA_DIST = README.md README.html README-WIN32.html | EXTRA_DIST = README.md README.html README-WIN32.html | ||||
EXTRA_DIST += config.h.win32 json-c.vcproj json-c.vcxproj json-c.vcxproj.filters | EXTRA_DIST += config.h.win32 json-c.vcproj json-c.vcxproj json-c.vcxproj.filters | ||||
EXTRA_DIST += Doxyfile doc | |||||
EXTRA_DIST += Doxyfile | |||||
dist-hook: | dist-hook: | ||||
test -d "$(distdir)/doc" || mkdir "$(distdir)/doc" | test -d "$(distdir)/doc" || mkdir "$(distdir)/doc" | ||||
@@ -35,7 +35,8 @@ libjson_cinclude_HEADERS = \ | |||||
strdup_compat.h \ | strdup_compat.h \ | ||||
vasprintf_compat.h \ | vasprintf_compat.h \ | ||||
printbuf.h \ | printbuf.h \ | ||||
random_seed.h | |||||
random_seed.h \ | |||||
strerror_override.h | |||||
libjson_c_la_LDFLAGS = -version-info 3:0:0 -no-undefined @JSON_BSYMBOLIC_LDFLAGS@ | libjson_c_la_LDFLAGS = -version-info 3:0:0 -no-undefined @JSON_BSYMBOLIC_LDFLAGS@ | ||||
@@ -51,16 +52,47 @@ libjson_c_la_SOURCES = \ | |||||
json_visit.c \ | json_visit.c \ | ||||
linkhash.c \ | linkhash.c \ | ||||
printbuf.c \ | printbuf.c \ | ||||
random_seed.c | |||||
random_seed.c \ | |||||
strerror_override.c \ | |||||
strerror_override_private.h | |||||
DISTCLEANFILES= | |||||
DISTCLEANFILES+= \ | |||||
config.h \ | |||||
json-c-uninstalled.pc \ | |||||
json-c.pc \ | |||||
json_config.h | |||||
distclean-local: | distclean-local: | ||||
-rm -rf $(testsubdir) | -rm -rf $(testsubdir) | ||||
-rm -rf config.h.in~ Makefile.in aclocal.m4 autom4te.cache/ config.guess config.sub depcomp install-sh ltmain.sh missing | |||||
-rm -f INSTALL test-driver tests/Makefile.in compile | |||||
maintainer-clean-local: | |||||
-rm -rf configure | |||||
JSON_CLEANFILES= | |||||
JSON_CLEANFILES+= \ | |||||
Makefile.in \ | |||||
aclocal.m4 \ | |||||
autom4te.cache/ \ | |||||
compile \ | |||||
config.guess \ | |||||
config.h.in \ | |||||
config.sub \ | |||||
configure \ | |||||
depcomp \ | |||||
install-sh \ | |||||
ltmain.sh \ | |||||
missing \ | |||||
test-driver \ | |||||
tests/Makefile.in | |||||
JSON_CLEANFILES+= \ | |||||
libtool \ | |||||
stamp-h1 \ | |||||
stamp-h2 | |||||
# There's no built-in way to remove these after all the other | |||||
# maintainer-clean steps happen, so do it explicitly here. | |||||
really-clean: | |||||
$(MAKE) maintainer-clean | |||||
rm -rf ${JSON_CLEANFILES} | |||||
uninstall-local: | uninstall-local: | ||||
rm -rf "$(DESTDIR)@includedir@/json-c" | rm -rf "$(DESTDIR)@includedir@/json-c" | ||||
@@ -4,6 +4,10 @@ | |||||
JSON-C - A JSON implementation in C | JSON-C - A JSON implementation in C | ||||
----------------------------------- | ----------------------------------- | ||||
Build Status | |||||
* [](https://ci.appveyor.com/project/hawicz/json-c) | |||||
* [](https://travis-ci.org/json-c/json-c) | |||||
JSON-C implements a reference counting object model that allows you to easily | JSON-C implements a reference counting object model that allows you to easily | ||||
construct JSON objects in C, output them as JSON formatted strings and parse | construct JSON objects in C, output them as JSON formatted strings and parse | ||||
JSON formatted strings back into the C representation of JSON objects. | JSON formatted strings back into the C representation of JSON objects. | ||||
@@ -14,7 +18,9 @@ Building on Unix with `git`, `gcc` and `autotools` | |||||
Home page for json-c: https://github.com/json-c/json-c/wiki | Home page for json-c: https://github.com/json-c/json-c/wiki | ||||
Prerequisites: | |||||
### Prerequisites: | |||||
See also the "Installing prerequisites" section below. | |||||
- `gcc`, `clang`, or another C compiler | - `gcc`, `clang`, or another C compiler | ||||
- `libtool>=2.2.6b` | - `libtool>=2.2.6b` | ||||
@@ -26,6 +32,8 @@ If you're not using a release tarball, you'll also need: | |||||
Make sure you have a complete `libtool` install, including `libtoolize`. | Make sure you have a complete `libtool` install, including `libtoolize`. | ||||
### Build instructions: | |||||
`json-c` GitHub repo: https://github.com/json-c/json-c | `json-c` GitHub repo: https://github.com/json-c/json-c | ||||
```sh | ```sh | ||||
@@ -66,3 +74,52 @@ JSON_C_DIR=/path/to/json_c/install | |||||
CFLAGS += -I$(JSON_C_DIR)/include/json-c | CFLAGS += -I$(JSON_C_DIR)/include/json-c | ||||
LDFLAGS+= -L$(JSON_C_DIR)/lib -ljson-c | LDFLAGS+= -L$(JSON_C_DIR)/lib -ljson-c | ||||
``` | ``` | ||||
Install prerequisites | |||||
----------------------- | |||||
If you are on a relatively modern system, you'll likely be able to install | |||||
the prerequisites using your OS's packaging system. | |||||
### Install using apt (e.g. Ubuntu 16.04.2 LTS) | |||||
```sh | |||||
sudo apt install git | |||||
sudo apt install autoconf automake libtool | |||||
sudo apt install valgrind # optional | |||||
``` | |||||
Then start from the "git clone" command, above. | |||||
### Manually install and build autoconf, automake and libtool | |||||
For older OS's that don't have up-to-date version of the packages will | |||||
require a bit more work. For example, CentOS release 5.11, etc... | |||||
```sh | |||||
curl -O http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz | |||||
curl -O http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz | |||||
curl -O http://ftp.gnu.org/gnu/libtool/libtool-2.2.6b.tar.gz | |||||
tar xzf autoconf-2.69.tar.gz | |||||
tar xzf automake-1.15.tar.gz | |||||
tar xzf libtool-2.2.6b.tar.gz | |||||
export PATH=${HOME}/ac_install/bin:$PATH | |||||
(cd autoconf-2.69 && \ | |||||
./configure --prefix ${HOME}/ac_install && \ | |||||
make && \ | |||||
make install) | |||||
(cd automake-1.15 && \ | |||||
./configure --prefix ${HOME}/ac_install && \ | |||||
make && \ | |||||
make install) | |||||
(cd libtool-2.2.6b && \ | |||||
./configure --prefix ${HOME}/ac_install && \ | |||||
make && \ | |||||
make install) | |||||
``` | |||||
@@ -98,7 +98,8 @@ array_list_put_idx(struct array_list *arr, size_t idx, void *data) | |||||
{ | { | ||||
if (idx > SIZE_T_MAX - 1 ) return -1; | if (idx > SIZE_T_MAX - 1 ) return -1; | ||||
if(array_list_expand_internal(arr, idx+1)) return -1; | if(array_list_expand_internal(arr, idx+1)) return -1; | ||||
if(arr->array[idx]) arr->free_fn(arr->array[idx]); | |||||
if(idx < arr->length && arr->array[idx]) | |||||
arr->free_fn(arr->array[idx]); | |||||
arr->array[idx] = data; | arr->array[idx] = data; | ||||
if(arr->length <= idx) arr->length = idx + 1; | if(arr->length <= idx) arr->length = idx + 1; | ||||
return 0; | return 0; | ||||
@@ -8,24 +8,24 @@ | |||||
/* Define to 1 if you have the declaration of `INFINITY', and to 0 if you | /* Define to 1 if you have the declaration of `INFINITY', and to 0 if you | ||||
don't. */ | don't. */ | ||||
#if defined(_MSC_VER) && _MSC_VER >= 1800 | |||||
#if (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(__MINGW32__) | |||||
#define HAVE_DECL_INFINITY 1 | #define HAVE_DECL_INFINITY 1 | ||||
#endif | #endif | ||||
/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't. | /* Define to 1 if you have the declaration of `isinf', and to 0 if you don't. | ||||
*/ | */ | ||||
#if defined(_MSC_VER) && _MSC_VER >= 1800 | |||||
#if (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(__MINGW32__) | |||||
#define HAVE_DECL_ISINF 1 | #define HAVE_DECL_ISINF 1 | ||||
#endif | #endif | ||||
/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't. | /* Define to 1 if you have the declaration of `isnan', and to 0 if you don't. | ||||
*/ | */ | ||||
#if defined(_MSC_VER) && _MSC_VER >= 1800 | |||||
#if (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(__MINGW32__) | |||||
#define HAVE_DECL_ISNAN 1 | #define HAVE_DECL_ISNAN 1 | ||||
#endif | #endif | ||||
/* Define to 1 if you have the declaration of `nan', and to 0 if you don't. */ | /* Define to 1 if you have the declaration of `nan', and to 0 if you don't. */ | ||||
#if defined(_MSC_VER) && _MSC_VER >= 1800 | |||||
#if (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(__MINGW32__) | |||||
#define HAVE_DECL_NAN 1 | #define HAVE_DECL_NAN 1 | ||||
#endif | #endif | ||||
@@ -76,7 +76,11 @@ | |||||
#define HAVE_SETLOCALE 1 | #define HAVE_SETLOCALE 1 | ||||
/* Define to 1 if you have the `snprintf' function. */ | /* Define to 1 if you have the `snprintf' function. */ | ||||
#if defined(__MINGW32__) | |||||
#define HAVE_SNPRINTF 1 | |||||
#else | |||||
#undef HAVE_SNPRINTF | #undef HAVE_SNPRINTF | ||||
#endif | |||||
/* Define to 1 if you have the <stdarg.h> header file. */ | /* Define to 1 if you have the <stdarg.h> header file. */ | ||||
#define HAVE_STDARG_H 1 | #define HAVE_STDARG_H 1 | ||||
@@ -103,7 +107,11 @@ | |||||
#define HAVE_STRING_H 1 | #define HAVE_STRING_H 1 | ||||
/* Define to 1 if you have the `strncasecmp' function. */ | /* Define to 1 if you have the `strncasecmp' function. */ | ||||
#if defined(__MINGW32__) | |||||
#define HAVE_STRNCASECMP 1 | |||||
#else | |||||
#undef HAVE_STRNCASECMP | #undef HAVE_STRNCASECMP | ||||
#endif | |||||
/* Define to 1 if you have the <syslog.h> header file. */ | /* Define to 1 if you have the <syslog.h> header file. */ | ||||
#undef HAVE_SYSLOG_H | #undef HAVE_SYSLOG_H | ||||
@@ -112,7 +120,11 @@ | |||||
#define HAVE_SYS_CDEFS_H 1 | #define HAVE_SYS_CDEFS_H 1 | ||||
/* Define to 1 if you have the <sys/param.h> header file. */ | /* Define to 1 if you have the <sys/param.h> header file. */ | ||||
#if defined(__MINGW32__) | |||||
#define HAVE_SYS_PARAM_H 1 | |||||
#else | |||||
#undef HAVE_SYS_PARAM_H | #undef HAVE_SYS_PARAM_H | ||||
#endif | |||||
/* Define to 1 if you have the <sys/stat.h> header file. */ | /* Define to 1 if you have the <sys/stat.h> header file. */ | ||||
#define HAVE_SYS_STAT_H 1 | #define HAVE_SYS_STAT_H 1 | ||||
@@ -121,10 +133,18 @@ | |||||
#define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_TYPES_H 1 | ||||
/* Define to 1 if you have the <unistd.h> header file. */ | /* Define to 1 if you have the <unistd.h> header file. */ | ||||
#if defined(__MINGW32__) | |||||
#define HAVE_UNISTD_H 1 | |||||
#else | |||||
#undef HAVE_UNISTD_H | #undef HAVE_UNISTD_H | ||||
#endif | |||||
/* Define to 1 if you have the `vasprintf' function. */ | /* Define to 1 if you have the `vasprintf' function. */ | ||||
#if defined(__MINGW32__) | |||||
#define HAVE_VASPRINTF 1 | |||||
#else | |||||
#undef HAVE_VASPRINTF | #undef HAVE_VASPRINTF | ||||
#endif | |||||
/* Define to 1 if you have the `vprintf' function. */ | /* Define to 1 if you have the `vprintf' function. */ | ||||
#define HAVE_VPRINTF 1 | #define HAVE_VPRINTF 1 | ||||
@@ -7,6 +7,8 @@ AM_INIT_AUTOMAKE | |||||
AC_PROG_MAKE_SET | AC_PROG_MAKE_SET | ||||
AC_CANONICAL_HOST | |||||
AC_ARG_ENABLE(rdrand, | AC_ARG_ENABLE(rdrand, | ||||
AS_HELP_STRING([--enable-rdrand], | AS_HELP_STRING([--enable-rdrand], | ||||
[Enable RDRAND Hardware RNG Hash Seed generation on supported x86/x64 platforms.]), | [Enable RDRAND Hardware RNG Hash Seed generation on supported x86/x64 platforms.]), | ||||
@@ -41,6 +43,18 @@ AC_CHECK_HEADER(inttypes.h,[AC_DEFINE([JSON_C_HAVE_INTTYPES_H],[1],[Public defin | |||||
AC_C_CONST | AC_C_CONST | ||||
AC_TYPE_SIZE_T | AC_TYPE_SIZE_T | ||||
AC_CACHE_CHECK([for __thread support], ac_cv___thread, [dnl | |||||
AC_LINK_IFELSE([dnl | |||||
AC_LANG_PROGRAM([[#undef __thread | |||||
static __thread int a; int foo (int b) { return a + b; }]], | |||||
[[exit (foo (0));]])], | |||||
ac_cv___thread=yes, ac_cv___thread=no) | |||||
]) | |||||
AS_IF([test "x$ac_cv___thread" != xno], | |||||
[AC_DEFINE(HAVE___THREAD, 1, [Have __thread]) | |||||
AC_DEFINE(SPEC___THREAD, [__thread], [Specifier for __thread])] | |||||
) | |||||
# Checks for library functions. | # Checks for library functions. | ||||
AC_FUNC_VPRINTF | AC_FUNC_VPRINTF | ||||
AC_FUNC_MEMCMP | AC_FUNC_MEMCMP | ||||
@@ -53,6 +67,14 @@ AC_CHECK_DECLS([isinf], [], [], [[#include <math.h>]]) | |||||
AC_CHECK_DECLS([_isnan], [], [], [[#include <float.h>]]) | AC_CHECK_DECLS([_isnan], [], [], [[#include <float.h>]]) | ||||
AC_CHECK_DECLS([_finite], [], [], [[#include <float.h>]]) | AC_CHECK_DECLS([_finite], [], [], [[#include <float.h>]]) | ||||
case "${host_os}" in | |||||
linux*) | |||||
AC_CHECK_FUNCS([uselocale]) | |||||
;; | |||||
*) # Nothing | |||||
;; | |||||
esac | |||||
if test "$ac_cv_have_decl_isnan" = "yes" ; then | 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"]) | AC_TRY_LINK([#include <math.h>], [float f = 0.0; return isnan(f)], [], [LIBS="$LIBS -lm"]) | ||||
fi | fi | ||||
@@ -75,7 +97,7 @@ int main(int c,char* v) {return 0;} | |||||
AC_LANG_POP([C]) | AC_LANG_POP([C]) | ||||
AM_PROG_LIBTOOL | |||||
LT_INIT | |||||
# Check for the -Bsymbolic-functions linker flag | # Check for the -Bsymbolic-functions linker flag | ||||
AC_ARG_ENABLE([Bsymbolic], | AC_ARG_ENABLE([Bsymbolic], | ||||
@@ -12,13 +12,14 @@ | |||||
#include "config.h" | #include "config.h" | ||||
#include "strerror_override.h" | |||||
#include <assert.h> | #include <assert.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stddef.h> | #include <stddef.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <math.h> | #include <math.h> | ||||
#include <errno.h> | |||||
#include "debug.h" | #include "debug.h" | ||||
#include "printbuf.h" | #include "printbuf.h" | ||||
@@ -30,13 +31,7 @@ | |||||
#include "json_util.h" | #include "json_util.h" | ||||
#include "math_compat.h" | #include "math_compat.h" | ||||
#include "strdup_compat.h" | #include "strdup_compat.h" | ||||
#if !defined(HAVE_SNPRINTF) && defined(_MSC_VER) | |||||
/* MSC has the version as _snprintf */ | |||||
# define snprintf _snprintf | |||||
#elif !defined(HAVE_SNPRINTF) | |||||
# error You do not have snprintf on your system. | |||||
#endif /* HAVE_SNPRINTF */ | |||||
#include "snprintf_compat.h" | |||||
// Don't define this. It's not thread-safe. | // Don't define this. It's not thread-safe. | ||||
/* #define REFCOUNT_DEBUG 1 */ | /* #define REFCOUNT_DEBUG 1 */ | ||||
@@ -143,11 +138,11 @@ static int json_escape_str(struct printbuf *pb, const char *str, int len, int fl | |||||
default: | default: | ||||
if(c < ' ') | if(c < ' ') | ||||
{ | { | ||||
char sbuf[7]; | |||||
if(pos - start_offset > 0) | if(pos - start_offset > 0) | ||||
printbuf_memappend(pb, | printbuf_memappend(pb, | ||||
str + start_offset, | str + start_offset, | ||||
pos - start_offset); | pos - start_offset); | ||||
static char sbuf[7]; | |||||
snprintf(sbuf, sizeof(sbuf), | snprintf(sbuf, sizeof(sbuf), | ||||
"\\u00%c%c", | "\\u00%c%c", | ||||
json_hex_chars[c >> 4], | json_hex_chars[c >> 4], | ||||
@@ -589,7 +584,7 @@ static int json_object_int_to_json_string(struct json_object* jso, | |||||
int flags) | int flags) | ||||
{ | { | ||||
/* room for 19 digits, the sign char, and a null term */ | /* room for 19 digits, the sign char, and a null term */ | ||||
static char sbuf[21]; | |||||
char sbuf[21]; | |||||
snprintf(sbuf, sizeof(sbuf), "%" PRId64, jso->o.c_int64); | snprintf(sbuf, sizeof(sbuf), "%" PRId64, jso->o.c_int64); | ||||
return printbuf_memappend (pb, sbuf, strlen(sbuf)); | return printbuf_memappend (pb, sbuf, strlen(sbuf)); | ||||
} | } | ||||
@@ -634,6 +629,10 @@ int32_t json_object_get_int(const struct json_object *jso) | |||||
return INT32_MAX; | return INT32_MAX; | ||||
return (int32_t) cint64; | return (int32_t) cint64; | ||||
case json_type_double: | case json_type_double: | ||||
if (jso->o.c_double <= INT32_MIN) | |||||
return INT32_MIN; | |||||
if (jso->o.c_double >= INT32_MAX) | |||||
return INT32_MAX; | |||||
return (int32_t)jso->o.c_double; | return (int32_t)jso->o.c_double; | ||||
case json_type_boolean: | case json_type_boolean: | ||||
return jso->o.c_boolean; | return jso->o.c_boolean; | ||||
@@ -692,52 +691,122 @@ int json_object_set_int64(struct json_object *jso,int64_t new_value){ | |||||
/* json_object_double */ | /* json_object_double */ | ||||
#ifdef HAVE___THREAD | |||||
// i.e. __thread or __declspec(thread) | |||||
static SPEC___THREAD char *tls_serialization_float_format = NULL; | |||||
#endif | |||||
static char *global_serialization_float_format = NULL; | |||||
int json_c_set_serialization_double_format(const char *double_format, int global_or_thread) | |||||
{ | |||||
if (global_or_thread == JSON_C_OPTION_GLOBAL) | |||||
{ | |||||
#ifdef HAVE___THREAD | |||||
if (tls_serialization_float_format) | |||||
{ | |||||
free(tls_serialization_float_format); | |||||
tls_serialization_float_format = NULL; | |||||
} | |||||
#endif | |||||
if (global_serialization_float_format) | |||||
free(global_serialization_float_format); | |||||
global_serialization_float_format = double_format ? strdup(double_format) : NULL; | |||||
} | |||||
else if (global_or_thread == JSON_C_OPTION_THREAD) | |||||
{ | |||||
#ifdef HAVE___THREAD | |||||
if (tls_serialization_float_format) | |||||
{ | |||||
free(tls_serialization_float_format); | |||||
tls_serialization_float_format = NULL; | |||||
} | |||||
tls_serialization_float_format = double_format ? strdup(double_format) : NULL; | |||||
#else | |||||
_set_last_err("json_c_set_option: not compiled with __thread support\n"); | |||||
return -1; | |||||
#endif | |||||
} | |||||
else | |||||
{ | |||||
_set_last_err("json_c_set_option: invalid global_or_thread value: %d\n", global_or_thread); | |||||
return -1; | |||||
} | |||||
return 0; | |||||
} | |||||
static int json_object_double_to_json_string_format(struct json_object* jso, | static int json_object_double_to_json_string_format(struct json_object* jso, | ||||
struct printbuf *pb, | struct printbuf *pb, | ||||
int level, | int level, | ||||
int flags, | int flags, | ||||
const char *format) | const char *format) | ||||
{ | { | ||||
char buf[128], *p, *q; | |||||
int size; | |||||
double dummy; /* needed for modf() */ | |||||
/* Although JSON RFC does not support | |||||
NaN or Infinity as numeric values | |||||
ECMA 262 section 9.8.1 defines | |||||
how to handle these cases as strings */ | |||||
if(isnan(jso->o.c_double)) | |||||
size = snprintf(buf, sizeof(buf), "NaN"); | |||||
else if(isinf(jso->o.c_double)) | |||||
if(jso->o.c_double > 0) | |||||
size = snprintf(buf, sizeof(buf), "Infinity"); | |||||
else | |||||
size = snprintf(buf, sizeof(buf), "-Infinity"); | |||||
else | |||||
size = snprintf(buf, sizeof(buf), | |||||
format ? format : | |||||
(modf(jso->o.c_double, &dummy) == 0) ? "%.17g.0" : "%.17g", | |||||
jso->o.c_double); | |||||
if(size < 0 || size >= (int)sizeof(buf)) | |||||
size = (int)sizeof(buf); | |||||
p = strchr(buf, ','); | |||||
if (p) { | |||||
*p = '.'; | |||||
} else { | |||||
p = strchr(buf, '.'); | |||||
} | |||||
if (p && (flags & JSON_C_TO_STRING_NOZERO)) { | |||||
/* last useful digit, always keep 1 zero */ | |||||
p++; | |||||
for (q=p ; *q ; q++) { | |||||
if (*q!='0') p=q; | |||||
} | |||||
/* drop trailing zeroes */ | |||||
*(++p) = 0; | |||||
size = p-buf; | |||||
} | |||||
printbuf_memappend(pb, buf, size); | |||||
return size; | |||||
char buf[128], *p, *q; | |||||
int size; | |||||
double dummy; /* needed for modf() */ | |||||
/* Although JSON RFC does not support | |||||
NaN or Infinity as numeric values | |||||
ECMA 262 section 9.8.1 defines | |||||
how to handle these cases as strings */ | |||||
if (isnan(jso->o.c_double)) | |||||
{ | |||||
size = snprintf(buf, sizeof(buf), "NaN"); | |||||
} | |||||
else if (isinf(jso->o.c_double)) | |||||
{ | |||||
if(jso->o.c_double > 0) | |||||
size = snprintf(buf, sizeof(buf), "Infinity"); | |||||
else | |||||
size = snprintf(buf, sizeof(buf), "-Infinity"); | |||||
} | |||||
else | |||||
{ | |||||
const char *std_format = "%.17g"; | |||||
#ifdef HAVE___THREAD | |||||
if (tls_serialization_float_format) | |||||
std_format = tls_serialization_float_format; | |||||
else | |||||
#endif | |||||
if (global_serialization_float_format) | |||||
std_format = global_serialization_float_format; | |||||
if (!format) | |||||
format = std_format; | |||||
size = snprintf(buf, sizeof(buf), format, jso->o.c_double); | |||||
if (modf(jso->o.c_double, &dummy) == 0 && size >= 0 && size < (int)sizeof(buf) - 2) | |||||
{ | |||||
// Ensure it looks like a float, even if snprintf didn't. | |||||
strcat(buf, ".0"); | |||||
size += 2; | |||||
} | |||||
} | |||||
// although unlikely, snprintf can fail | |||||
if (size < 0) | |||||
return -1; | |||||
p = strchr(buf, ','); | |||||
if (p) | |||||
*p = '.'; | |||||
else | |||||
p = strchr(buf, '.'); | |||||
if (p && (flags & JSON_C_TO_STRING_NOZERO)) | |||||
{ | |||||
/* last useful digit, always keep 1 zero */ | |||||
p++; | |||||
for (q=p ; *q ; q++) { | |||||
if (*q!='0') p=q; | |||||
} | |||||
/* drop trailing zeroes */ | |||||
*(++p) = 0; | |||||
size = p-buf; | |||||
} | |||||
if (size >= (int)sizeof(buf)) | |||||
// The standard formats are guaranteed not to overrun the buffer, | |||||
// but if a custom one happens to do so, just silently truncate. | |||||
size = sizeof(buf) - 1; | |||||
printbuf_memappend(pb, buf, size); | |||||
return size; | |||||
} | } | ||||
static int json_object_double_to_json_string_default(struct json_object* jso, | static int json_object_double_to_json_string_default(struct json_object* jso, | ||||
@@ -1072,7 +1141,7 @@ struct json_object* json_object_array_bsearch( | |||||
assert(json_object_get_type(jso) == json_type_array); | assert(json_object_get_type(jso) == json_type_array); | ||||
result = (struct json_object **)array_list_bsearch( | result = (struct json_object **)array_list_bsearch( | ||||
(const void **)&key, jso->o.c_array, sort_fn); | |||||
(const void **)(void *)&key, jso->o.c_array, sort_fn); | |||||
if (!result) | if (!result) | ||||
return NULL; | return NULL; | ||||
@@ -1139,7 +1208,7 @@ static int json_object_all_values_equal(struct json_object* jso1, | |||||
/* Iterate over jso1 keys and see if they exist and are equal in jso2 */ | /* Iterate over jso1 keys and see if they exist and are equal in jso2 */ | ||||
json_object_object_foreachC(jso1, iter) { | json_object_object_foreachC(jso1, iter) { | ||||
if (!lh_table_lookup_ex(jso2->o.c_object, (void*)iter.key, | if (!lh_table_lookup_ex(jso2->o.c_object, (void*)iter.key, | ||||
(void**)&sub)) | |||||
(void**)(void *)&sub)) | |||||
return 0; | return 0; | ||||
if (!json_object_equal(iter.val, sub)) | if (!json_object_equal(iter.val, sub)) | ||||
return 0; | return 0; | ||||
@@ -1148,7 +1217,7 @@ static int json_object_all_values_equal(struct json_object* jso1, | |||||
/* Iterate over jso2 keys to see if any exist that are not in jso1 */ | /* Iterate over jso2 keys to see if any exist that are not in jso1 */ | ||||
json_object_object_foreachC(jso2, iter) { | json_object_object_foreachC(jso2, iter) { | ||||
if (!lh_table_lookup_ex(jso1->o.c_object, (void*)iter.key, | if (!lh_table_lookup_ex(jso1->o.c_object, (void*)iter.key, | ||||
(void**)&sub)) | |||||
(void**)(void *)&sub)) | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -21,6 +21,12 @@ | |||||
#define THIS_FUNCTION_IS_DEPRECATED(func) func | #define THIS_FUNCTION_IS_DEPRECATED(func) func | ||||
#endif | #endif | ||||
#if defined(_MSC_VER) | |||||
#define JSON_EXPORT __declspec(dllexport) | |||||
#else | |||||
#define JSON_EXPORT extern | |||||
#endif | |||||
#include <stddef.h> | #include <stddef.h> | ||||
#include "json_inttypes.h" | #include "json_inttypes.h" | ||||
@@ -105,6 +111,22 @@ extern "C" { | |||||
#undef TRUE | #undef TRUE | ||||
#define TRUE ((json_bool)1) | #define TRUE ((json_bool)1) | ||||
/** | |||||
* Set the global value of an option, which will apply to all | |||||
* current and future threads that have not set a thread-local value. | |||||
* | |||||
* @see json_c_set_serialization_double_format | |||||
*/ | |||||
#define JSON_C_OPTION_GLOBAL (0) | |||||
/** | |||||
* Set a thread-local value of an option, overriding the global value. | |||||
* This will fail if json-c is not compiled with threading enabled, and | |||||
* with the __thread specifier (or equivalent) available. | |||||
* | |||||
* @see json_c_set_serialization_double_format | |||||
*/ | |||||
#define JSON_C_OPTION_THREAD (1) | |||||
extern const char *json_number_chars; | extern const char *json_number_chars; | ||||
extern const char *json_hex_chars; | extern const char *json_hex_chars; | ||||
@@ -160,7 +182,7 @@ typedef enum json_type { | |||||
* | * | ||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
*/ | */ | ||||
extern struct json_object* json_object_get(struct json_object *obj); | |||||
JSON_EXPORT struct json_object* json_object_get(struct json_object *obj); | |||||
/** | /** | ||||
* Decrement the reference count of json_object and free if it reaches zero. | * Decrement the reference count of json_object and free if it reaches zero. | ||||
@@ -170,7 +192,7 @@ extern struct json_object* json_object_get(struct json_object *obj); | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns 1 if the object was freed. | * @returns 1 if the object was freed. | ||||
*/ | */ | ||||
int json_object_put(struct json_object *obj); | |||||
JSON_EXPORT int json_object_put(struct json_object *obj); | |||||
/** | /** | ||||
* Check if the json_object is of a given type | * Check if the json_object is of a given type | ||||
@@ -184,7 +206,7 @@ int json_object_put(struct json_object *obj); | |||||
json_type_array, | json_type_array, | ||||
json_type_string | json_type_string | ||||
*/ | */ | ||||
extern int json_object_is_type(const struct json_object *obj, enum json_type type); | |||||
JSON_EXPORT int json_object_is_type(const struct json_object *obj, enum json_type type); | |||||
/** | /** | ||||
* Get the type of the json_object. See also json_type_to_name() to turn this | * Get the type of the json_object. See also json_type_to_name() to turn this | ||||
@@ -200,7 +222,7 @@ extern int json_object_is_type(const struct json_object *obj, enum json_type typ | |||||
json_type_array, | json_type_array, | ||||
json_type_string | json_type_string | ||||
*/ | */ | ||||
extern enum json_type json_object_get_type(const struct json_object *obj); | |||||
JSON_EXPORT enum json_type json_object_get_type(const struct json_object *obj); | |||||
/** Stringify object to json format. | /** Stringify object to json format. | ||||
@@ -212,7 +234,7 @@ extern enum json_type json_object_get_type(const struct json_object *obj); | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns a string in JSON format | * @returns a string in JSON format | ||||
*/ | */ | ||||
extern const char* json_object_to_json_string(struct json_object *obj); | |||||
JSON_EXPORT const char* json_object_to_json_string(struct json_object *obj); | |||||
/** Stringify object to json format | /** Stringify object to json format | ||||
* @see json_object_to_json_string() for details on how to free string. | * @see json_object_to_json_string() for details on how to free string. | ||||
@@ -220,7 +242,7 @@ extern const char* json_object_to_json_string(struct json_object *obj); | |||||
* @param flags formatting options, see JSON_C_TO_STRING_PRETTY and other constants | * @param flags formatting options, see JSON_C_TO_STRING_PRETTY and other constants | ||||
* @returns a string in JSON format | * @returns a string in JSON format | ||||
*/ | */ | ||||
extern const char* json_object_to_json_string_ext(struct json_object *obj, int | |||||
JSON_EXPORT const char* json_object_to_json_string_ext(struct json_object *obj, int | |||||
flags); | flags); | ||||
/** Stringify object to json format | /** Stringify object to json format | ||||
@@ -230,7 +252,7 @@ flags); | |||||
* @param length a pointer where, if not NULL, the length (without null) is stored | * @param length a pointer where, if not NULL, the length (without null) is stored | ||||
* @returns a string in JSON format and the length if not NULL | * @returns a string in JSON format and the length if not NULL | ||||
*/ | */ | ||||
extern const char* json_object_to_json_string_length(struct json_object *obj, int | |||||
JSON_EXPORT const char* json_object_to_json_string_length(struct json_object *obj, int | |||||
flags, size_t *length); | flags, size_t *length); | ||||
/** | /** | ||||
@@ -239,7 +261,7 @@ flags, size_t *length); | |||||
* | * | ||||
* @param jso the object to return the userdata for | * @param jso the object to return the userdata for | ||||
*/ | */ | ||||
extern void* json_object_get_userdata(json_object *jso); | |||||
JSON_EXPORT void* json_object_get_userdata(json_object *jso); | |||||
/** | /** | ||||
* Set an opaque userdata value for an object | * Set an opaque userdata value for an object | ||||
@@ -266,7 +288,7 @@ extern void* json_object_get_userdata(json_object *jso); | |||||
* @param userdata an optional opaque cookie | * @param userdata an optional opaque cookie | ||||
* @param user_delete an optional function from freeing userdata | * @param user_delete an optional function from freeing userdata | ||||
*/ | */ | ||||
extern void json_object_set_userdata(json_object *jso, void *userdata, | |||||
JSON_EXPORT void json_object_set_userdata(json_object *jso, void *userdata, | |||||
json_object_delete_fn *user_delete); | json_object_delete_fn *user_delete); | ||||
/** | /** | ||||
@@ -299,7 +321,7 @@ extern void json_object_set_userdata(json_object *jso, void *userdata, | |||||
* @param userdata an optional opaque cookie | * @param userdata an optional opaque cookie | ||||
* @param user_delete an optional function from freeing userdata | * @param user_delete an optional function from freeing userdata | ||||
*/ | */ | ||||
extern void json_object_set_serializer(json_object *jso, | |||||
JSON_EXPORT void json_object_set_serializer(json_object *jso, | |||||
json_object_to_json_string_fn to_string_func, | json_object_to_json_string_fn to_string_func, | ||||
void *userdata, | void *userdata, | ||||
json_object_delete_fn *user_delete); | json_object_delete_fn *user_delete); | ||||
@@ -337,18 +359,18 @@ json_object_to_json_string_fn json_object_userdata_to_json_string; | |||||
* | * | ||||
* @returns a json_object of type json_type_object | * @returns a json_object of type json_type_object | ||||
*/ | */ | ||||
extern struct json_object* json_object_new_object(void); | |||||
JSON_EXPORT struct json_object* json_object_new_object(void); | |||||
/** Get the hashtable of a json_object of type json_type_object | /** Get the hashtable of a json_object of type json_type_object | ||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns a linkhash | * @returns a linkhash | ||||
*/ | */ | ||||
extern struct lh_table* json_object_get_object(const struct json_object *obj); | |||||
JSON_EXPORT struct lh_table* json_object_get_object(const struct json_object *obj); | |||||
/** Get the size of an object in terms of the number of fields it has. | /** Get the size of an object in terms of the number of fields it has. | ||||
* @param obj the json_object whose length to return | * @param obj the json_object whose length to return | ||||
*/ | */ | ||||
extern int json_object_object_length(const struct json_object* obj); | |||||
JSON_EXPORT int json_object_object_length(const struct json_object* obj); | |||||
/** Add an object field to a json_object of type json_type_object | /** Add an object field to a json_object of type json_type_object | ||||
* | * | ||||
@@ -369,7 +391,7 @@ extern int json_object_object_length(const struct json_object* obj); | |||||
* @return On success, <code>0</code> is returned. | * @return On success, <code>0</code> is returned. | ||||
* On error, a negative value is returned. | * On error, a negative value is returned. | ||||
*/ | */ | ||||
extern int json_object_object_add(struct json_object* obj, const char *key, | |||||
JSON_EXPORT int json_object_object_add(struct json_object* obj, const char *key, | |||||
struct json_object *val); | struct json_object *val); | ||||
/** Add an object field to a json_object of type json_type_object | /** Add an object field to a json_object of type json_type_object | ||||
@@ -385,7 +407,7 @@ extern int json_object_object_add(struct json_object* obj, const char *key, | |||||
* @param opts process-modifying options. To specify multiple options, use | * @param opts process-modifying options. To specify multiple options, use | ||||
* arithmetic or (OPT1|OPT2) | * arithmetic or (OPT1|OPT2) | ||||
*/ | */ | ||||
extern int json_object_object_add_ex(struct json_object* obj, | |||||
JSON_EXPORT int json_object_object_add_ex(struct json_object* obj, | |||||
const char *const key, | const char *const key, | ||||
struct json_object *const val, | struct json_object *const val, | ||||
const unsigned opts); | const unsigned opts); | ||||
@@ -411,7 +433,7 @@ extern int json_object_object_add_ex(struct json_object* obj, | |||||
* @returns the json_object associated with the given field name | * @returns the json_object associated with the given field name | ||||
* @deprecated Please use json_object_object_get_ex | * @deprecated Please use json_object_object_get_ex | ||||
*/ | */ | ||||
extern struct json_object* json_object_object_get(const struct json_object* obj, | |||||
JSON_EXPORT struct json_object* json_object_object_get(const struct json_object* obj, | |||||
const char *key); | const char *key); | ||||
/** Get the json_object associated with a given object field. | /** Get the json_object associated with a given object field. | ||||
@@ -432,7 +454,7 @@ extern struct json_object* json_object_object_get(const struct json_object* obj, | |||||
* It is safe to pass a NULL value. | * It is safe to pass a NULL value. | ||||
* @returns whether or not the key exists | * @returns whether or not the key exists | ||||
*/ | */ | ||||
extern json_bool json_object_object_get_ex(const struct json_object* obj, | |||||
JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object* obj, | |||||
const char *key, | const char *key, | ||||
struct json_object **value); | struct json_object **value); | ||||
@@ -445,7 +467,7 @@ extern json_bool json_object_object_get_ex(const struct json_object* obj, | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @param key the object field name | * @param key the object field name | ||||
*/ | */ | ||||
extern void json_object_object_del(struct json_object* obj, const char *key); | |||||
JSON_EXPORT void json_object_object_del(struct json_object* obj, const char *key); | |||||
/** | /** | ||||
* Iterate through all keys and values of an object. | * Iterate through all keys and values of an object. | ||||
@@ -504,19 +526,19 @@ extern void json_object_object_del(struct json_object* obj, const char *key); | |||||
/** Create a new empty json_object of type json_type_array | /** Create a new empty json_object of type json_type_array | ||||
* @returns a json_object of type json_type_array | * @returns a json_object of type json_type_array | ||||
*/ | */ | ||||
extern struct json_object* json_object_new_array(void); | |||||
JSON_EXPORT struct json_object* json_object_new_array(void); | |||||
/** Get the arraylist of a json_object of type json_type_array | /** Get the arraylist of a json_object of type json_type_array | ||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns an arraylist | * @returns an arraylist | ||||
*/ | */ | ||||
extern struct array_list* json_object_get_array(const struct json_object *obj); | |||||
JSON_EXPORT struct array_list* json_object_get_array(const struct json_object *obj); | |||||
/** Get the length of a json_object of type json_type_array | /** Get the length of a json_object of type json_type_array | ||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns an int | * @returns an int | ||||
*/ | */ | ||||
extern size_t json_object_array_length(const struct json_object *obj); | |||||
JSON_EXPORT size_t json_object_array_length(const struct json_object *obj); | |||||
/** Sorts the elements of jso of type json_type_array | /** Sorts the elements of jso of type json_type_array | ||||
* | * | ||||
@@ -526,7 +548,7 @@ extern size_t json_object_array_length(const struct json_object *obj); | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @param sort_fn a sorting function | * @param sort_fn a sorting function | ||||
*/ | */ | ||||
extern void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *)); | |||||
JSON_EXPORT void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *)); | |||||
/** Binary search a sorted array for a specified key object. | /** Binary search a sorted array for a specified key object. | ||||
* | * | ||||
@@ -542,7 +564,7 @@ extern void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const | |||||
* | * | ||||
* @return the wanted json_object instance | * @return the wanted json_object instance | ||||
*/ | */ | ||||
extern struct json_object* json_object_array_bsearch( | |||||
JSON_EXPORT struct json_object* json_object_array_bsearch( | |||||
const struct json_object *key, | const struct json_object *key, | ||||
const struct json_object *jso, | const struct json_object *jso, | ||||
int (*sort_fn)(const void *, const void *)); | int (*sort_fn)(const void *, const void *)); | ||||
@@ -556,7 +578,7 @@ extern struct json_object* json_object_array_bsearch( | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @param val the json_object to be added | * @param val the json_object to be added | ||||
*/ | */ | ||||
extern int json_object_array_add(struct json_object *obj, | |||||
JSON_EXPORT int json_object_array_add(struct json_object *obj, | |||||
struct json_object *val); | struct json_object *val); | ||||
/** Insert or replace an element at a specified index in an array (a json_object of type json_type_array) | /** Insert or replace an element at a specified index in an array (a json_object of type json_type_array) | ||||
@@ -574,7 +596,7 @@ extern int json_object_array_add(struct json_object *obj, | |||||
* @param idx the index to insert the element at | * @param idx the index to insert the element at | ||||
* @param val the json_object to be added | * @param val the json_object to be added | ||||
*/ | */ | ||||
extern int json_object_array_put_idx(struct json_object *obj, size_t idx, | |||||
JSON_EXPORT int json_object_array_put_idx(struct json_object *obj, size_t idx, | |||||
struct json_object *val); | struct json_object *val); | ||||
/** Get the element at specificed index of the array (a json_object of type json_type_array) | /** Get the element at specificed index of the array (a json_object of type json_type_array) | ||||
@@ -582,7 +604,7 @@ extern int json_object_array_put_idx(struct json_object *obj, size_t idx, | |||||
* @param idx the index to get the element at | * @param idx the index to get the element at | ||||
* @returns the json_object at the specified index (or NULL) | * @returns the json_object at the specified index (or NULL) | ||||
*/ | */ | ||||
extern struct json_object* json_object_array_get_idx(const struct json_object *obj, | |||||
JSON_EXPORT struct json_object* json_object_array_get_idx(const struct json_object *obj, | |||||
size_t idx); | size_t idx); | ||||
/** Delete an elements from a specified index in an array (a json_object of type json_type_array) | /** Delete an elements from a specified index in an array (a json_object of type json_type_array) | ||||
@@ -596,7 +618,7 @@ extern struct json_object* json_object_array_get_idx(const struct json_object *o | |||||
* @param count the number of elements to delete | * @param count the number of elements to delete | ||||
* @returns 0 if the elements were successfully deleted | * @returns 0 if the elements were successfully deleted | ||||
*/ | */ | ||||
extern int json_object_array_del_idx(struct json_object *obj, size_t idx, size_t count); | |||||
JSON_EXPORT int json_object_array_del_idx(struct json_object *obj, size_t idx, size_t count); | |||||
/* json_bool type methods */ | /* json_bool type methods */ | ||||
@@ -604,7 +626,7 @@ extern int json_object_array_del_idx(struct json_object *obj, size_t idx, size_t | |||||
* @param b a json_bool TRUE or FALSE (1 or 0) | * @param b a json_bool TRUE or FALSE (1 or 0) | ||||
* @returns a json_object of type json_type_boolean | * @returns a json_object of type json_type_boolean | ||||
*/ | */ | ||||
extern struct json_object* json_object_new_boolean(json_bool b); | |||||
JSON_EXPORT struct json_object* json_object_new_boolean(json_bool b); | |||||
/** Get the json_bool value of a json_object | /** Get the json_bool value of a json_object | ||||
* | * | ||||
@@ -617,7 +639,7 @@ extern struct json_object* json_object_new_boolean(json_bool b); | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns a json_bool | * @returns a json_bool | ||||
*/ | */ | ||||
extern json_bool json_object_get_boolean(const struct json_object *obj); | |||||
JSON_EXPORT json_bool json_object_get_boolean(const struct json_object *obj); | |||||
/** Set the json_bool value of a json_object | /** Set the json_bool value of a json_object | ||||
@@ -630,7 +652,7 @@ extern json_bool json_object_get_boolean(const struct json_object *obj); | |||||
* @param new_value the value to be set | * @param new_value the value to be set | ||||
* @returns 1 if value is set correctly, 0 otherwise | * @returns 1 if value is set correctly, 0 otherwise | ||||
*/ | */ | ||||
extern int json_object_set_boolean(struct json_object *obj,json_bool new_value); | |||||
JSON_EXPORT int json_object_set_boolean(struct json_object *obj,json_bool new_value); | |||||
/* int type methods */ | /* int type methods */ | ||||
@@ -641,14 +663,14 @@ extern int json_object_set_boolean(struct json_object *obj,json_bool new_value); | |||||
* @param i the integer | * @param i the integer | ||||
* @returns a json_object of type json_type_int | * @returns a json_object of type json_type_int | ||||
*/ | */ | ||||
extern struct json_object* json_object_new_int(int32_t i); | |||||
JSON_EXPORT struct json_object* json_object_new_int(int32_t i); | |||||
/** Create a new empty json_object of type json_type_int | /** Create a new empty json_object of type json_type_int | ||||
* @param i the integer | * @param i the integer | ||||
* @returns a json_object of type json_type_int | * @returns a json_object of type json_type_int | ||||
*/ | */ | ||||
extern struct json_object* json_object_new_int64(int64_t i); | |||||
JSON_EXPORT struct json_object* json_object_new_int64(int64_t i); | |||||
/** Get the int value of a json_object | /** Get the int value of a json_object | ||||
@@ -665,7 +687,7 @@ extern struct json_object* json_object_new_int64(int64_t i); | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns an int | * @returns an int | ||||
*/ | */ | ||||
extern int32_t json_object_get_int(const struct json_object *obj); | |||||
JSON_EXPORT int32_t json_object_get_int(const struct json_object *obj); | |||||
/** Set the int value of a json_object | /** Set the int value of a json_object | ||||
* | * | ||||
@@ -677,7 +699,7 @@ extern int32_t json_object_get_int(const struct json_object *obj); | |||||
* @param new_value the value to be set | * @param new_value the value to be set | ||||
* @returns 1 if value is set correctly, 0 otherwise | * @returns 1 if value is set correctly, 0 otherwise | ||||
*/ | */ | ||||
extern int json_object_set_int(struct json_object *obj,int new_value); | |||||
JSON_EXPORT int json_object_set_int(struct json_object *obj,int new_value); | |||||
/** Get the int value of a json_object | /** Get the int value of a json_object | ||||
@@ -693,7 +715,7 @@ extern int json_object_set_int(struct json_object *obj,int new_value); | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns an int64 | * @returns an int64 | ||||
*/ | */ | ||||
extern int64_t json_object_get_int64(const struct json_object *obj); | |||||
JSON_EXPORT int64_t json_object_get_int64(const struct json_object *obj); | |||||
/** Set the int64_t value of a json_object | /** Set the int64_t value of a json_object | ||||
@@ -706,7 +728,7 @@ extern int64_t json_object_get_int64(const struct json_object *obj); | |||||
* @param new_value the value to be set | * @param new_value the value to be set | ||||
* @returns 1 if value is set correctly, 0 otherwise | * @returns 1 if value is set correctly, 0 otherwise | ||||
*/ | */ | ||||
extern int json_object_set_int64(struct json_object *obj,int64_t new_value); | |||||
JSON_EXPORT int json_object_set_int64(struct json_object *obj,int64_t new_value); | |||||
/* double type methods */ | /* double type methods */ | ||||
@@ -718,7 +740,7 @@ extern int json_object_set_int64(struct json_object *obj,int64_t new_value); | |||||
* @param d the double | * @param d the double | ||||
* @returns a json_object of type json_type_double | * @returns a json_object of type json_type_double | ||||
*/ | */ | ||||
extern struct json_object* json_object_new_double(double d); | |||||
JSON_EXPORT struct json_object* json_object_new_double(double d); | |||||
/** | /** | ||||
* Create a new json_object of type json_type_double, using | * Create a new json_object of type json_type_double, using | ||||
@@ -746,7 +768,22 @@ extern struct json_object* json_object_new_double(double d); | |||||
* @param d the numeric value of the double. | * @param d the numeric value of the double. | ||||
* @param ds the string representation of the double. This will be copied. | * @param ds the string representation of the double. This will be copied. | ||||
*/ | */ | ||||
extern struct json_object* json_object_new_double_s(double d, const char *ds); | |||||
JSON_EXPORT struct json_object* json_object_new_double_s(double d, const char *ds); | |||||
/** | |||||
* Set a global or thread-local json-c option, depending on whether | |||||
* JSON_C_OPTION_GLOBAL or JSON_C_OPTION_THREAD is passed. | |||||
* Thread-local options default to undefined, and inherit from the global | |||||
* value, even if the global value is changed after the thread is created. | |||||
* Attempting to set thread-local options when threading is not compiled in | |||||
* will result in an error. Be sure to check the return value. | |||||
* | |||||
* double_format is a "%g" printf format, such as "%.20g" | |||||
* | |||||
* @return -1 on errors, 0 on success. | |||||
*/ | |||||
int json_c_set_serialization_double_format(const char *double_format, int global_or_thread); | |||||
/** Serialize a json_object of type json_type_double to a string. | /** Serialize a json_object of type json_type_double to a string. | ||||
@@ -768,7 +805,7 @@ extern struct json_object* json_object_new_double_s(double d, const char *ds); | |||||
* @param level Ignored. | * @param level Ignored. | ||||
* @param flags Ignored. | * @param flags Ignored. | ||||
*/ | */ | ||||
extern int json_object_double_to_json_string(struct json_object* jso, | |||||
JSON_EXPORT int json_object_double_to_json_string(struct json_object* jso, | |||||
struct printbuf *pb, | struct printbuf *pb, | ||||
int level, | int level, | ||||
int flags); | int flags); | ||||
@@ -796,7 +833,7 @@ extern int json_object_double_to_json_string(struct json_object* jso, | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns a double floating point number | * @returns a double floating point number | ||||
*/ | */ | ||||
extern double json_object_get_double(const struct json_object *obj); | |||||
JSON_EXPORT double json_object_get_double(const struct json_object *obj); | |||||
/** Set the double value of a json_object | /** Set the double value of a json_object | ||||
@@ -809,7 +846,7 @@ extern double json_object_get_double(const struct json_object *obj); | |||||
* @param new_value the value to be set | * @param new_value the value to be set | ||||
* @returns 1 if value is set correctly, 0 otherwise | * @returns 1 if value is set correctly, 0 otherwise | ||||
*/ | */ | ||||
extern int json_object_set_double(struct json_object *obj,double new_value); | |||||
JSON_EXPORT int json_object_set_double(struct json_object *obj,double new_value); | |||||
@@ -822,9 +859,9 @@ extern int json_object_set_double(struct json_object *obj,double new_value); | |||||
* @param s the string | * @param s the string | ||||
* @returns a json_object of type json_type_string | * @returns a json_object of type json_type_string | ||||
*/ | */ | ||||
extern struct json_object* json_object_new_string(const char *s); | |||||
JSON_EXPORT struct json_object* json_object_new_string(const char *s); | |||||
extern struct json_object* json_object_new_string_len(const char *s, int len); | |||||
JSON_EXPORT struct json_object* json_object_new_string_len(const char *s, int len); | |||||
/** Get the string value of a json_object | /** Get the string value of a json_object | ||||
* | * | ||||
@@ -842,7 +879,7 @@ extern struct json_object* json_object_new_string_len(const char *s, int len); | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns a string or NULL | * @returns a string or NULL | ||||
*/ | */ | ||||
extern const char* json_object_get_string(struct json_object *obj); | |||||
JSON_EXPORT const char* json_object_get_string(struct json_object *obj); | |||||
/** Get the string length of a json_object | /** Get the string length of a json_object | ||||
* | * | ||||
@@ -852,14 +889,14 @@ extern const char* json_object_get_string(struct json_object *obj); | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns int | * @returns int | ||||
*/ | */ | ||||
extern int json_object_get_string_len(const struct json_object *obj); | |||||
JSON_EXPORT int json_object_get_string_len(const struct json_object *obj); | |||||
/** Set the string value of a json_object with zero terminated strings | /** Set the string value of a json_object with zero terminated strings | ||||
* equivalent to json_object_set_string_len (obj, new_value, strlen(new_value)) | * equivalent to json_object_set_string_len (obj, new_value, strlen(new_value)) | ||||
* @returns 1 if value is set correctly, 0 otherwise | * @returns 1 if value is set correctly, 0 otherwise | ||||
*/ | */ | ||||
extern int json_object_set_string(json_object* obj, const char* new_value); | |||||
JSON_EXPORT int json_object_set_string(json_object* obj, const char* new_value); | |||||
/** Set the string value of a json_object str | /** Set the string value of a json_object str | ||||
* | * | ||||
@@ -872,7 +909,7 @@ extern int json_object_set_string(json_object* obj, const char* new_value); | |||||
* @param len the length of new_value | * @param len the length of new_value | ||||
* @returns 1 if value is set correctly, 0 otherwise | * @returns 1 if value is set correctly, 0 otherwise | ||||
*/ | */ | ||||
extern int json_object_set_string_len(json_object* obj, const char* new_value, int len); | |||||
JSON_EXPORT int json_object_set_string_len(json_object* obj, const char* new_value, int len); | |||||
/** Check if two json_object's are equal | /** Check if two json_object's are equal | ||||
* | * | ||||
@@ -891,7 +928,7 @@ extern int json_object_set_string_len(json_object* obj, const char* new_value, i | |||||
* @param obj2 the second json_object instance | * @param obj2 the second json_object instance | ||||
* @returns whether both objects are equal or not | * @returns whether both objects are equal or not | ||||
*/ | */ | ||||
extern int json_object_equal(struct json_object *obj1, | |||||
JSON_EXPORT int json_object_equal(struct json_object *obj1, | |||||
struct json_object *obj2); | struct json_object *obj2); | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -48,6 +48,8 @@ struct json_object | |||||
void *_userdata; | void *_userdata; | ||||
}; | }; | ||||
void _set_last_err(const char *err_fmt, ...); | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
#endif | #endif | ||||
@@ -8,10 +8,11 @@ | |||||
#include "config.h" | #include "config.h" | ||||
#include "strerror_override.h" | |||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <errno.h> | |||||
#include <string.h> | #include <string.h> | ||||
#include <ctype.h> | #include <ctype.h> | ||||
@@ -116,19 +116,19 @@ const char *json_tokener_error_desc(enum json_tokener_error jerr); | |||||
* | * | ||||
* See also json_tokener_error_desc(). | * See also json_tokener_error_desc(). | ||||
*/ | */ | ||||
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok); | |||||
JSON_EXPORT enum json_tokener_error json_tokener_get_error(struct json_tokener *tok); | |||||
extern struct json_tokener* json_tokener_new(void); | |||||
extern struct json_tokener* json_tokener_new_ex(int depth); | |||||
extern void json_tokener_free(struct json_tokener *tok); | |||||
extern void json_tokener_reset(struct json_tokener *tok); | |||||
extern struct json_object* json_tokener_parse(const char *str); | |||||
extern struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error); | |||||
JSON_EXPORT struct json_tokener* json_tokener_new(void); | |||||
JSON_EXPORT struct json_tokener* json_tokener_new_ex(int depth); | |||||
JSON_EXPORT void json_tokener_free(struct json_tokener *tok); | |||||
JSON_EXPORT void json_tokener_reset(struct json_tokener *tok); | |||||
JSON_EXPORT struct json_object* json_tokener_parse(const char *str); | |||||
JSON_EXPORT struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error); | |||||
/** | /** | ||||
* Set flags that control how parsing will be done. | * Set flags that control how parsing will be done. | ||||
*/ | */ | ||||
extern void json_tokener_set_flags(struct json_tokener *tok, int flags); | |||||
JSON_EXPORT void json_tokener_set_flags(struct json_tokener *tok, int flags); | |||||
/** | /** | ||||
* Parse a string and return a non-NULL json_object if a valid JSON value | * Parse a string and return a non-NULL json_object if a valid JSON value | ||||
@@ -198,7 +198,7 @@ if (tok->char_offset < stringlen) // XXX shouldn't access internal fields | |||||
* @param str an string with any valid JSON expression, or portion of. This does not need to be null terminated. | * @param str an string with any valid JSON expression, or portion of. This does not need to be null terminated. | ||||
* @param len the length of str | * @param len the length of str | ||||
*/ | */ | ||||
extern struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||||
JSON_EXPORT struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||||
const char *str, int len); | const char *str, int len); | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -12,13 +12,14 @@ | |||||
#include "config.h" | #include "config.h" | ||||
#undef realloc | #undef realloc | ||||
#include "strerror_override.h" | |||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stddef.h> | #include <stddef.h> | ||||
#include <limits.h> | #include <limits.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <errno.h> | |||||
#include <ctype.h> | #include <ctype.h> | ||||
#ifdef HAVE_SYS_TYPES_H | #ifdef HAVE_SYS_TYPES_H | ||||
@@ -47,12 +48,7 @@ | |||||
# define open _open | # define open _open | ||||
#endif | #endif | ||||
#if !defined(HAVE_SNPRINTF) && defined(_MSC_VER) | |||||
/* MSC has the version as _snprintf */ | |||||
# define snprintf _snprintf | |||||
#elif !defined(HAVE_SNPRINTF) | |||||
# error You do not have snprintf on your system. | |||||
#endif /* HAVE_SNPRINTF */ | |||||
#include "snprintf_compat.h" | |||||
#include "debug.h" | #include "debug.h" | ||||
#include "printbuf.h" | #include "printbuf.h" | ||||
@@ -64,7 +60,8 @@ | |||||
static int sscanf_is_broken = 0; | static int sscanf_is_broken = 0; | ||||
static int sscanf_is_broken_testdone = 0; | static int sscanf_is_broken_testdone = 0; | ||||
static void sscanf_is_broken_test(void); | static void sscanf_is_broken_test(void); | ||||
static void _set_last_err(const char *err_fmt, ...); | |||||
static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename); | |||||
static char _last_err[256] = ""; | static char _last_err[256] = ""; | ||||
@@ -75,7 +72,7 @@ const char *json_util_get_last_err() | |||||
return _last_err; | return _last_err; | ||||
} | } | ||||
static void _set_last_err(const char *err_fmt, ...) | |||||
void _set_last_err(const char *err_fmt, ...) | |||||
{ | { | ||||
va_list ap; | va_list ap; | ||||
va_start(ap, err_fmt); | va_start(ap, err_fmt); | ||||
@@ -127,42 +124,61 @@ struct json_object* json_object_from_file(const char *filename) | |||||
int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags) | int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags) | ||||
{ | { | ||||
const char *json_str; | |||||
int fd, ret; | |||||
unsigned int wpos, wsize; | |||||
int fd, ret; | |||||
int saved_errno; | |||||
if(!obj) { | |||||
_set_last_err("json_object_to_file: object is null\n"); | |||||
return -1; | |||||
} | |||||
if (!obj) { | |||||
_set_last_err("json_object_to_file: object is null\n"); | |||||
return -1; | |||||
} | |||||
if((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) { | |||||
_set_last_err("json_object_to_file: error opening file %s: %s\n", | |||||
filename, strerror(errno)); | |||||
return -1; | |||||
} | |||||
if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) { | |||||
_set_last_err("json_object_to_file: error opening file %s: %s\n", | |||||
filename, strerror(errno)); | |||||
return -1; | |||||
} | |||||
ret = _json_object_to_fd(fd, obj, flags, filename); | |||||
saved_errno = errno; | |||||
close(fd); | |||||
errno = saved_errno; | |||||
return ret; | |||||
} | |||||
if(!(json_str = json_object_to_json_string_ext(obj,flags))) { | |||||
close(fd); | |||||
return -1; | |||||
} | |||||
int json_object_to_fd(int fd, struct json_object *obj, int flags) | |||||
{ | |||||
if (!obj) { | |||||
_set_last_err("json_object_to_fd: object is null\n"); | |||||
return -1; | |||||
} | |||||
wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */ | |||||
wpos = 0; | |||||
while(wpos < wsize) { | |||||
if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) { | |||||
close(fd); | |||||
_set_last_err("json_object_to_file: error writing file %s: %s\n", | |||||
filename, strerror(errno)); | |||||
return -1; | |||||
} | |||||
return _json_object_to_fd(fd, obj, flags, NULL); | |||||
} | |||||
static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename) | |||||
{ | |||||
int ret; | |||||
const char *json_str; | |||||
unsigned int wpos, wsize; | |||||
/* because of the above check for ret < 0, we can safely cast and add */ | |||||
wpos += (unsigned int)ret; | |||||
} | |||||
filename = filename ? filename : "(fd)"; | |||||
close(fd); | |||||
return 0; | |||||
if (!(json_str = json_object_to_json_string_ext(obj,flags))) { | |||||
return -1; | |||||
} | |||||
wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */ | |||||
wpos = 0; | |||||
while(wpos < wsize) { | |||||
if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) { | |||||
_set_last_err("json_object_to_file: error writing file %s: %s\n", | |||||
filename, strerror(errno)); | |||||
return -1; | |||||
} | |||||
/* because of the above check for ret < 0, we can safely cast and add */ | |||||
wpos += (unsigned int)ret; | |||||
} | |||||
return 0; | |||||
} | } | ||||
// backwards compatible "format and write to file" function | // backwards compatible "format and write to file" function | ||||
@@ -174,7 +190,9 @@ int json_object_to_file(const char *filename, struct json_object *obj) | |||||
int json_parse_double(const char *buf, double *retval) | int json_parse_double(const char *buf, double *retval) | ||||
{ | { | ||||
return (sscanf(buf, "%lf", retval)==1 ? 0 : 1); | |||||
char *end; | |||||
*retval = strtod(buf, &end); | |||||
return end == buf ? 1 : 0; | |||||
} | } | ||||
/* | /* | ||||
@@ -67,7 +67,18 @@ extern int json_object_to_file(const char *filename, struct json_object *obj); | |||||
extern int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags); | extern int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags); | ||||
/** | /** | ||||
* Return the last error from json_object_to_file{,_ext} or | |||||
* Convert the json_object to a string and write it to the file descriptor. | |||||
* Handles partial writes and will keep writing until done, or an error | |||||
* occurs. | |||||
* | |||||
* @param flags flags to pass to json_object_to_json_string_ext() | |||||
* @return -1 if something fails. See json_util_get_last_err() for details. | |||||
*/ | |||||
extern int json_object_to_fd(int fd, struct json_object *obj, int flags); | |||||
/** | |||||
* Return the last error from json_object_to_file{,_ext}, | |||||
* json_object_to_fd() or | |||||
* json_object_from_{file,fd}, or NULL if there is none. | * json_object_from_{file,fd}, or NULL if there is none. | ||||
*/ | */ | ||||
const char *json_util_get_last_err(void); | const char *json_util_get_last_err(void); | ||||
@@ -23,7 +23,7 @@ | |||||
# include <endian.h> /* attempt to define endianness */ | # include <endian.h> /* attempt to define endianness */ | ||||
#endif | #endif | ||||
#ifdef _MSC_VER | |||||
#if defined(_MSC_VER) || defined(__MINGW32__) | |||||
# define WIN32_LEAN_AND_MEAN | # define WIN32_LEAN_AND_MEAN | ||||
# include <windows.h> /* Get InterlockedCompareExchange */ | # include <windows.h> /* Get InterlockedCompareExchange */ | ||||
#endif | #endif | ||||
@@ -452,7 +452,7 @@ static unsigned long lh_perllike_str_hash(const void *k) | |||||
static unsigned long lh_char_hash(const void *k) | static unsigned long lh_char_hash(const void *k) | ||||
{ | { | ||||
#if defined _MSC_VER | |||||
#if defined _MSC_VER || defined __MINGW32__ | |||||
#define RANDOM_SEED_TYPE LONG | #define RANDOM_SEED_TYPE LONG | ||||
#else | #else | ||||
#define RANDOM_SEED_TYPE int | #define RANDOM_SEED_TYPE int | ||||
@@ -474,10 +474,10 @@ static unsigned long lh_char_hash(const void *k) | |||||
#endif | #endif | ||||
#if defined USE_SYNC_COMPARE_AND_SWAP | #if defined USE_SYNC_COMPARE_AND_SWAP | ||||
(void)__sync_val_compare_and_swap(&random_seed, -1, seed); | (void)__sync_val_compare_and_swap(&random_seed, -1, seed); | ||||
#elif defined _MSC_VER | |||||
#elif defined _MSC_VER || defined __MINGW32__ | |||||
InterlockedCompareExchange(&random_seed, seed, -1); | InterlockedCompareExchange(&random_seed, seed, -1); | ||||
#else | #else | ||||
#warning "racy random seed initializtion if used by multiple threads" | |||||
//#warning "racy random seed initializtion if used by multiple threads" | |||||
random_seed = seed; /* potentially racy */ | random_seed = seed; /* potentially racy */ | ||||
#endif | #endif | ||||
} | } | ||||
@@ -27,6 +27,7 @@ | |||||
#include "debug.h" | #include "debug.h" | ||||
#include "printbuf.h" | #include "printbuf.h" | ||||
#include "snprintf_compat.h" | |||||
#include "vasprintf_compat.h" | #include "vasprintf_compat.h" | ||||
static int printbuf_extend(struct printbuf *p, int min_size); | static int printbuf_extend(struct printbuf *p, int min_size); | ||||
@@ -9,6 +9,7 @@ | |||||
* | * | ||||
*/ | */ | ||||
#include "strerror_override.h" | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include "config.h" | #include "config.h" | ||||
#include "random_seed.h" | #include "random_seed.h" | ||||
@@ -128,7 +129,6 @@ retry: | |||||
#include <string.h> | #include <string.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <errno.h> | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
@@ -0,0 +1,36 @@ | |||||
#ifndef __snprintf_compat_h | |||||
#define __snprintf_compat_h | |||||
/* | |||||
* Microsoft's _vsnprintf and _snprint don't always terminate | |||||
* the string, so use wrappers that ensure that. | |||||
*/ | |||||
#include <stdarg.h> | |||||
#if !defined(HAVE_SNPRINTF) && defined(_MSC_VER) | |||||
static int json_c_vsnprintf(char *str, size_t size, const char *format, va_list ap) | |||||
{ | |||||
int ret; | |||||
ret = _vsnprintf(str, size, format, ap); | |||||
str[size - 1] = '\0'; | |||||
return ret; | |||||
} | |||||
#define vsnprintf json_c_vsnprintf | |||||
static int json_c_snprintf(char *str, size_t size, const char *format, ...) | |||||
{ | |||||
va_list ap; | |||||
int ret; | |||||
va_start(ap, format); | |||||
ret = json_c_vsnprintf(str, size, format, ap); | |||||
va_end(ap); | |||||
return ret; | |||||
} | |||||
#define snprintf json_c_snprintf | |||||
#elif !defined(HAVE_SNPRINTF) /* !HAVE_SNPRINTF */ | |||||
# error Need vsnprintf! | |||||
#endif /* !HAVE_SNPRINTF && defined(WIN32) */ | |||||
#endif /* __snprintf_compat_h */ |
@@ -1,4 +1,5 @@ | |||||
#include <errno.h> | |||||
#define STRERROR_OVERRIDE_IMPL 1 | |||||
#include "strerror_override.h" | |||||
/* | /* | ||||
* Override strerror() to get consistent output across platforms. | * Override strerror() to get consistent output across platforms. | ||||
@@ -52,14 +53,20 @@ static struct { | |||||
{ 0, (char *)0 } | { 0, (char *)0 } | ||||
}; | }; | ||||
// Enabled during tests | |||||
int _json_c_strerror_enable = 0; | |||||
#define PREFIX "ERRNO=" | #define PREFIX "ERRNO=" | ||||
static char errno_buf[128] = PREFIX; | static char errno_buf[128] = PREFIX; | ||||
char *strerror(int errno_in) | |||||
char *_json_c_strerror(int errno_in) | |||||
{ | { | ||||
int start_idx; | int start_idx; | ||||
char digbuf[20]; | char digbuf[20]; | ||||
int ii, jj; | int ii, jj; | ||||
if (!_json_c_strerror_enable) | |||||
return strerror(errno_in); | |||||
// Avoid standard functions, so we don't need to include any | // Avoid standard functions, so we don't need to include any | ||||
// headers, or guess at signatures. | // headers, or guess at signatures. | ||||
@@ -0,0 +1,25 @@ | |||||
#ifndef _json_strerror_override_h_ | |||||
#define _json_strerror_override_h_ | |||||
#include "config.h" | |||||
#include <errno.h> | |||||
#include "json_object.h" /* for JSON_EXPORT */ | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
JSON_EXPORT char *_json_c_strerror(int errno_in); | |||||
#ifndef STRERROR_OVERRIDE_IMPL | |||||
#define strerror _json_c_strerror | |||||
#else | |||||
#include <string.h> | |||||
#endif | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif | |||||
#endif /* _json_strerror_override_h_ */ |
@@ -0,0 +1,7 @@ | |||||
#ifndef __json_strerror_override_private_h__ | |||||
#define __json_strerror_override_private_h__ | |||||
/* Used by tests to get consistent output */ | |||||
extern int _json_c_strerror_enable; | |||||
#endif |
@@ -52,7 +52,7 @@ EXTRA_DIST+= test2Formatted_plain.expected | |||||
EXTRA_DIST+= test2Formatted_pretty.expected | EXTRA_DIST+= test2Formatted_pretty.expected | ||||
EXTRA_DIST+= test2Formatted_spaced.expected | EXTRA_DIST+= test2Formatted_spaced.expected | ||||
test_util_file_SOURCES = test_util_file.c strerror_override.c | |||||
test_util_file_SOURCES = test_util_file.c | |||||
testsubdir=testSubDir | testsubdir=testSubDir | ||||
TESTS_ENVIRONMENT = top_builddir=$(top_builddir) | TESTS_ENVIRONMENT = top_builddir=$(top_builddir) | ||||
@@ -50,6 +50,14 @@ echo "=== Running test $progname" | |||||
CMP="${CMP-cmp}" | CMP="${CMP-cmp}" | ||||
use_valgrind=${USE_VALGRIND-1} | use_valgrind=${USE_VALGRIND-1} | ||||
case "${use_valgrind}" in | |||||
[0Nn]*) | |||||
use_valgrind=0 | |||||
;; | |||||
*) | |||||
use_valgrind=1 | |||||
;; | |||||
esac | |||||
valgrind_path=$(which valgrind 2> /dev/null) | valgrind_path=$(which valgrind 2> /dev/null) | ||||
if [ -z "${valgrind_path}" -o ! -x "${valgrind_path}" ] ; then | if [ -z "${valgrind_path}" -o ! -x "${valgrind_path}" ] ; then | ||||
use_valgrind=0 | use_valgrind=0 | ||||
@@ -120,6 +120,19 @@ void test_array_del_idx() | |||||
(int)(orig_array_len + 1), rc, json_object_to_json_string(my_array)); | (int)(orig_array_len + 1), rc, json_object_to_json_string(my_array)); | ||||
json_object_put(my_array); | json_object_put(my_array); | ||||
/* Delete some array indexes, then add more */ | |||||
my_array = make_array(); | |||||
rc = json_object_array_del_idx(my_array, 0, orig_array_len - 1); | |||||
printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", | |||||
(int)(orig_array_len - 1), rc, json_object_to_json_string(my_array)); | |||||
json_object_array_add(my_array, json_object_new_string("s1")); | |||||
json_object_array_add(my_array, json_object_new_string("s2")); | |||||
json_object_array_add(my_array, json_object_new_string("s3")); | |||||
printf("after adding more entries, my_array.to_string()=%s\n", | |||||
json_object_to_json_string(my_array)); | |||||
json_object_put(my_array); | |||||
} | } | ||||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
@@ -38,6 +38,8 @@ after del_idx(0,1)=0, my_array.to_string()=[ ] | |||||
after del_idx(0,1)=-1, my_array.to_string()=[ ] | after del_idx(0,1)=-1, my_array.to_string()=[ ] | ||||
after del_idx(0,7)=0, my_array.to_string()=[ ] | after del_idx(0,7)=0, my_array.to_string()=[ ] | ||||
after del_idx(0,8)=-1, my_array.to_string()=[ 1, 2, 3, 4, 5, null, 7 ] | after del_idx(0,8)=-1, my_array.to_string()=[ 1, 2, 3, 4, 5, null, 7 ] | ||||
after del_idx(0,6)=0, my_array.to_string()=[ 7 ] | |||||
after adding more entries, my_array.to_string()=[ 7, "s1", "s2", "s3" ] | |||||
my_array= | my_array= | ||||
[0]=3 | [0]=3 | ||||
[1]=1 | [1]=1 | ||||
@@ -38,6 +38,8 @@ after del_idx(0,1)=0, my_array.to_string()=[] | |||||
after del_idx(0,1)=-1, my_array.to_string()=[] | after del_idx(0,1)=-1, my_array.to_string()=[] | ||||
after del_idx(0,7)=0, my_array.to_string()=[] | after del_idx(0,7)=0, my_array.to_string()=[] | ||||
after del_idx(0,8)=-1, my_array.to_string()=[1,2,3,4,5,null,7] | after del_idx(0,8)=-1, my_array.to_string()=[1,2,3,4,5,null,7] | ||||
after del_idx(0,6)=0, my_array.to_string()=[7] | |||||
after adding more entries, my_array.to_string()=[7,"s1","s2","s3"] | |||||
my_array= | my_array= | ||||
[0]=3 | [0]=3 | ||||
[1]=1 | [1]=1 | ||||
@@ -44,6 +44,8 @@ after del_idx(0,1)=0, my_array.to_string()=[] | |||||
after del_idx(0,1)=-1, my_array.to_string()=[] | after del_idx(0,1)=-1, my_array.to_string()=[] | ||||
after del_idx(0,7)=0, my_array.to_string()=[] | after del_idx(0,7)=0, my_array.to_string()=[] | ||||
after del_idx(0,8)=-1, my_array.to_string()=[1,2,3,4,5,null,7] | after del_idx(0,8)=-1, my_array.to_string()=[1,2,3,4,5,null,7] | ||||
after del_idx(0,6)=0, my_array.to_string()=[7] | |||||
after adding more entries, my_array.to_string()=[7,"s1","s2","s3"] | |||||
my_array= | my_array= | ||||
[0]=3 | [0]=3 | ||||
[1]=1 | [1]=1 | ||||
@@ -38,6 +38,8 @@ after del_idx(0,1)=0, my_array.to_string()=[] | |||||
after del_idx(0,1)=-1, my_array.to_string()=[] | after del_idx(0,1)=-1, my_array.to_string()=[] | ||||
after del_idx(0,7)=0, my_array.to_string()=[] | after del_idx(0,7)=0, my_array.to_string()=[] | ||||
after del_idx(0,8)=-1, my_array.to_string()=[1,2,3,4,5,null,7] | after del_idx(0,8)=-1, my_array.to_string()=[1,2,3,4,5,null,7] | ||||
after del_idx(0,6)=0, my_array.to_string()=[7] | |||||
after adding more entries, my_array.to_string()=[7,"s1","s2","s3"] | |||||
my_array= | my_array= | ||||
[0]=3 | [0]=3 | ||||
[1]=1 | [1]=1 | ||||
@@ -1,12 +0,0 @@ | |||||
#!/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 $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,12 +0,0 @@ | |||||
#!/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 $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -0,0 +1,19 @@ | |||||
#!/bin/sh | |||||
# Common definitions | |||||
if test -z "$srcdir"; then | |||||
srcdir="${0%/*}" | |||||
test "$srcdir" = "$0" && srcdir=. | |||||
test -z "$srcdir" && srcdir=. | |||||
fi | |||||
. "$srcdir/test-defs.sh" | |||||
filename=$(basename "$0") | |||||
filename="${filename%.*}" | |||||
# This is only for the test_util_file.test ; | |||||
# more stuff could be extended | |||||
cp -f "$srcdir/valid.json" . | |||||
run_output_test $filename "$srcdir" | |||||
exit $? |
@@ -1,12 +0,0 @@ | |||||
#!/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 $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,12 +0,0 @@ | |||||
#!/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 $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,12 +0,0 @@ | |||||
#!/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_compare | |||||
exit $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -27,5 +27,31 @@ int main() | |||||
json_object_set_serializer(obj, NULL, NULL, NULL); | json_object_set_serializer(obj, NULL, NULL, NULL); | ||||
printf("obj.to_string(reset)=%s\n", json_object_to_json_string(obj)); | printf("obj.to_string(reset)=%s\n", json_object_to_json_string(obj)); | ||||
json_object_put(obj); | |||||
obj = json_object_new_double(0.52381); | |||||
printf("obj.to_string(default format)=%s\n", json_object_to_json_string(obj)); | |||||
if (json_c_set_serialization_double_format("x%0.3fy", JSON_C_OPTION_GLOBAL) < 0) | |||||
printf("ERROR: json_c_set_serialization_double_format() failed"); | |||||
printf("obj.to_string(with global format)=%s\n", json_object_to_json_string(obj)); | |||||
#ifdef HAVE___THREAD | |||||
if (json_c_set_serialization_double_format("T%0.2fX", JSON_C_OPTION_THREAD) < 0) | |||||
printf("ERROR: json_c_set_serialization_double_format() failed"); | |||||
printf("obj.to_string(with thread format)=%s\n", json_object_to_json_string(obj)); | |||||
if (json_c_set_serialization_double_format("Ttttttttttttt%0.2fxxxxxxxxxxxxxxxxxxX", JSON_C_OPTION_THREAD) < 0) | |||||
printf("ERROR: json_c_set_serialization_double_format() failed"); | |||||
printf("obj.to_string(long thread format)=%s\n", json_object_to_json_string(obj)); | |||||
if (json_c_set_serialization_double_format(NULL, JSON_C_OPTION_THREAD) < 0) | |||||
printf("ERROR: json_c_set_serialization_double_format() failed"); | |||||
printf("obj.to_string(back to global format)=%s\n", json_object_to_json_string(obj)); | |||||
#else | |||||
// Just fake it up, so the output matches. | |||||
printf("obj.to_string(with thread format)=%s\n", "T0.52X"); | |||||
printf("obj.to_string(back to global format)=%s\n", "x0.524y"); | |||||
#endif | |||||
if (json_c_set_serialization_double_format(NULL, JSON_C_OPTION_GLOBAL) < 0) | |||||
printf("ERROR: json_c_set_serialization_double_format() failed"); | |||||
printf("obj.to_string(back to default format)=%s\n", json_object_to_json_string(obj)); | |||||
json_object_put(obj); | json_object_put(obj); | ||||
} | } |
@@ -6,3 +6,9 @@ Test explicit serializer with custom userdata: | |||||
obj.to_string(custom)=test | obj.to_string(custom)=test | ||||
Test reset serializer: | Test reset serializer: | ||||
obj.to_string(reset)=0.5 | obj.to_string(reset)=0.5 | ||||
obj.to_string(default format)=0.52381 | |||||
obj.to_string(with global format)=x0.524y | |||||
obj.to_string(with thread format)=T0.52X | |||||
obj.to_string(long thread format)=Ttttttttttttt0.52xxxxxxxxxxxxxxxxxxX | |||||
obj.to_string(back to global format)=x0.524y | |||||
obj.to_string(back to default format)=0.52381 |
@@ -1,12 +0,0 @@ | |||||
#!/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_double_serializer | |||||
exit $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,12 +0,0 @@ | |||||
#!/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_float | |||||
exit $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,4 +1,5 @@ | |||||
#include <errno.h> | |||||
#include "strerror_override.h" | |||||
#include "strerror_override_private.h" | |||||
#include <assert.h> | #include <assert.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <string.h> | #include <string.h> | ||||
@@ -280,6 +281,8 @@ static void test_wrong_inputs_set() | |||||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
{ | { | ||||
_json_c_strerror_enable = 1; | |||||
test_example_get(); | test_example_get(); | ||||
test_recursion_get(); | test_recursion_get(); | ||||
test_wrong_inputs_get(); | test_wrong_inputs_get(); | ||||
@@ -1,12 +0,0 @@ | |||||
#!/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_json_pointer | |||||
exit $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -7,6 +7,7 @@ | |||||
#include "config.h" | #include "config.h" | ||||
#include "json.h" | #include "json.h" | ||||
#include "json_tokener.h" | #include "json_tokener.h" | ||||
#include "snprintf_compat.h" | |||||
#ifdef HAVE_LOCALE_H | #ifdef HAVE_LOCALE_H | ||||
#include <locale.h> | #include <locale.h> | ||||
@@ -1,12 +0,0 @@ | |||||
#!/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 $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,12 +0,0 @@ | |||||
#!/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 $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,12 +0,0 @@ | |||||
#!/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 $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,12 +0,0 @@ | |||||
#!/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 $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,12 +0,0 @@ | |||||
#!/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 $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,12 +0,0 @@ | |||||
#!/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 $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,12 +0,0 @@ | |||||
#!/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_value | |||||
exit $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,4 +1,5 @@ | |||||
#include <errno.h> | |||||
#include "strerror_override.h" | |||||
#include "strerror_override_private.h" | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stddef.h> | #include <stddef.h> | ||||
@@ -49,6 +50,25 @@ static void test_write_to_file() | |||||
(rv == 0) ? "OK" : "FAIL", outfile2, rv); | (rv == 0) ? "OK" : "FAIL", outfile2, rv); | ||||
if (rv == 0) | if (rv == 0) | ||||
stat_and_cat(outfile2); | stat_and_cat(outfile2); | ||||
const char *outfile3 = "json3.out"; | |||||
int d = open(outfile3, O_WRONLY|O_CREAT, 0600); | |||||
if (d < 0) | |||||
{ | |||||
printf("FAIL: unable to open %s %s\n", outfile3, strerror(errno)); | |||||
return; | |||||
} | |||||
rv = json_object_to_fd(d, jso, JSON_C_TO_STRING_PRETTY); | |||||
printf("%s: json_object_to_fd(%s, jso, JSON_C_TO_STRING_PRETTY)=%d\n", | |||||
(rv == 0) ? "OK" : "FAIL", outfile3, rv); | |||||
// Write the same object twice | |||||
rv = json_object_to_fd(d, jso, JSON_C_TO_STRING_PLAIN); | |||||
printf("%s: json_object_to_fd(%s, jso, JSON_C_TO_STRING_PLAIN)=%d\n", | |||||
(rv == 0) ? "OK" : "FAIL", outfile3, rv); | |||||
close(d); | |||||
if (rv == 0) | |||||
stat_and_cat(outfile3); | |||||
json_object_put(jso); | json_object_put(jso); | ||||
} | } | ||||
@@ -87,6 +107,7 @@ static void stat_and_cat(const char *file) | |||||
buf[sb.st_size] = '\0'; | buf[sb.st_size] = '\0'; | ||||
printf("file[%s], size=%d, contents=%s\n", file, (int)sb.st_size, buf); | printf("file[%s], size=%d, contents=%s\n", file, (int)sb.st_size, buf); | ||||
free(buf); | free(buf); | ||||
close(d); | |||||
} | } | ||||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
@@ -94,6 +115,8 @@ int main(int argc, char **argv) | |||||
// json_object_to_file(file, obj); | // json_object_to_file(file, obj); | ||||
// json_object_to_file_ext(file, obj, flags); | // json_object_to_file_ext(file, obj, flags); | ||||
_json_c_strerror_enable = 1; | |||||
const char *testdir; | const char *testdir; | ||||
if (argc < 2) | if (argc < 2) | ||||
{ | { | ||||
@@ -19,3 +19,17 @@ file[json2.out], size=367, contents={ | |||||
"foo8":"abcdefghijklmnopqrstuvwxyz", | "foo8":"abcdefghijklmnopqrstuvwxyz", | ||||
"foo9":"abcdefghijklmnopqrstuvwxyz" | "foo9":"abcdefghijklmnopqrstuvwxyz" | ||||
} | } | ||||
OK: json_object_to_fd(json3.out, jso, JSON_C_TO_STRING_PRETTY)=0 | |||||
OK: json_object_to_fd(json3.out, jso, JSON_C_TO_STRING_PLAIN)=0 | |||||
file[json3.out], size=703, contents={ | |||||
"foo":1234, | |||||
"foo1":"abcdefghijklmnopqrstuvwxyz", | |||||
"foo2":"abcdefghijklmnopqrstuvwxyz", | |||||
"foo3":"abcdefghijklmnopqrstuvwxyz", | |||||
"foo4":"abcdefghijklmnopqrstuvwxyz", | |||||
"foo5":"abcdefghijklmnopqrstuvwxyz", | |||||
"foo6":"abcdefghijklmnopqrstuvwxyz", | |||||
"foo7":"abcdefghijklmnopqrstuvwxyz", | |||||
"foo8":"abcdefghijklmnopqrstuvwxyz", | |||||
"foo9":"abcdefghijklmnopqrstuvwxyz" | |||||
}{"foo":1234,"foo1":"abcdefghijklmnopqrstuvwxyz","foo2":"abcdefghijklmnopqrstuvwxyz","foo3":"abcdefghijklmnopqrstuvwxyz","foo4":"abcdefghijklmnopqrstuvwxyz","foo5":"abcdefghijklmnopqrstuvwxyz","foo6":"abcdefghijklmnopqrstuvwxyz","foo7":"abcdefghijklmnopqrstuvwxyz","foo8":"abcdefghijklmnopqrstuvwxyz","foo9":"abcdefghijklmnopqrstuvwxyz"} |
@@ -1,15 +0,0 @@ | |||||
#!/bin/sh | |||||
# Common definitions | |||||
if test -z "$srcdir"; then | |||||
srcdir="${0%/*}" | |||||
test "$srcdir" = "$0" && srcdir=. | |||||
test -z "$srcdir" && srcdir=. | |||||
fi | |||||
. "$srcdir/test-defs.sh" | |||||
cp -f "$srcdir/valid.json" . | |||||
run_output_test test_util_file "$srcdir" | |||||
_err=$? | |||||
exit $_err |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,12 +0,0 @@ | |||||
#!/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_visit | |||||
exit $? |
@@ -0,0 +1 @@ | |||||
test_basic.test |
@@ -1,11 +1,7 @@ | |||||
#ifndef __vasprintf_compat_h | #ifndef __vasprintf_compat_h | ||||
#define __vasprintf_compat_h | #define __vasprintf_compat_h | ||||
#if !defined(HAVE_VSNPRINTF) && defined(_MSC_VER) | |||||
# define vsnprintf _vsnprintf | |||||
#elif !defined(HAVE_VSNPRINTF) /* !HAVE_VSNPRINTF */ | |||||
# error Need vsnprintf! | |||||
#endif /* !HAVE_VSNPRINTF && defined(WIN32) */ | |||||
#include "snprintf_compat.h" | |||||
#if !defined(HAVE_VASPRINTF) | #if !defined(HAVE_VASPRINTF) | ||||
/* CAW: compliant version of vasprintf */ | /* CAW: compliant version of vasprintf */ | ||||