@@ -72,7 +72,6 @@ | |||
*.dmg | |||
*.ipa | |||
/INSTALL | |||
.deps/ | |||
.libs/ | |||
/aclocal.m4 | |||
@@ -99,3 +98,11 @@ | |||
/missing | |||
/stamp-h1 | |||
/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: | |||
- echo $LANG | |||
- echo $LC_ALL | |||
- set -e | |||
install: | |||
- sh autogen.sh | |||
@@ -28,4 +29,4 @@ script: | |||
after_success: | |||
- 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(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) | |||
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) | |||
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 sh autogen.sh 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 | |||
./printbuf.c | |||
./random_seed.c | |||
./strerror_override.c | |||
) | |||
add_library(json-c | |||
SHARED | |||
${JSON_C_SOURCES} | |||
${JSON_C_HEADERS} | |||
) | |||
add_library(json-c-static | |||
STATIC | |||
${JSON_C_SOURCES} | |||
${JSON_C_HEADERS} | |||
) | |||
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 | |||
LIBRARY 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 += config.h.win32 json-c.vcproj json-c.vcxproj json-c.vcxproj.filters | |||
EXTRA_DIST += Doxyfile doc | |||
EXTRA_DIST += Doxyfile | |||
dist-hook: | |||
test -d "$(distdir)/doc" || mkdir "$(distdir)/doc" | |||
@@ -35,7 +35,8 @@ libjson_cinclude_HEADERS = \ | |||
strdup_compat.h \ | |||
vasprintf_compat.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@ | |||
@@ -51,16 +52,47 @@ libjson_c_la_SOURCES = \ | |||
json_visit.c \ | |||
linkhash.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: | |||
-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: | |||
rm -rf "$(DESTDIR)@includedir@/json-c" | |||
@@ -4,6 +4,10 @@ | |||
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 | |||
construct JSON objects in C, output them as JSON formatted strings and parse | |||
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 | |||
Prerequisites: | |||
### Prerequisites: | |||
See also the "Installing prerequisites" section below. | |||
- `gcc`, `clang`, or another C compiler | |||
- `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`. | |||
### Build instructions: | |||
`json-c` GitHub repo: https://github.com/json-c/json-c | |||
```sh | |||
@@ -66,3 +74,52 @@ JSON_C_DIR=/path/to/json_c/install | |||
CFLAGS += -I$(JSON_C_DIR)/include/json-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(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; | |||
if(arr->length <= idx) arr->length = idx + 1; | |||
return 0; | |||
@@ -8,24 +8,24 @@ | |||
/* Define to 1 if you have the declaration of `INFINITY', 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_INFINITY 1 | |||
#endif | |||
/* 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 | |||
#endif | |||
/* 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 | |||
#endif | |||
/* 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 | |||
#endif | |||
@@ -76,7 +76,11 @@ | |||
#define HAVE_SETLOCALE 1 | |||
/* Define to 1 if you have the `snprintf' function. */ | |||
#if defined(__MINGW32__) | |||
#define HAVE_SNPRINTF 1 | |||
#else | |||
#undef HAVE_SNPRINTF | |||
#endif | |||
/* Define to 1 if you have the <stdarg.h> header file. */ | |||
#define HAVE_STDARG_H 1 | |||
@@ -103,7 +107,11 @@ | |||
#define HAVE_STRING_H 1 | |||
/* Define to 1 if you have the `strncasecmp' function. */ | |||
#if defined(__MINGW32__) | |||
#define HAVE_STRNCASECMP 1 | |||
#else | |||
#undef HAVE_STRNCASECMP | |||
#endif | |||
/* Define to 1 if you have the <syslog.h> header file. */ | |||
#undef HAVE_SYSLOG_H | |||
@@ -112,7 +120,11 @@ | |||
#define HAVE_SYS_CDEFS_H 1 | |||
/* 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 | |||
#endif | |||
/* Define to 1 if you have the <sys/stat.h> header file. */ | |||
#define HAVE_SYS_STAT_H 1 | |||
@@ -121,10 +133,18 @@ | |||
#define HAVE_SYS_TYPES_H 1 | |||
/* Define to 1 if you have the <unistd.h> header file. */ | |||
#if defined(__MINGW32__) | |||
#define HAVE_UNISTD_H 1 | |||
#else | |||
#undef HAVE_UNISTD_H | |||
#endif | |||
/* Define to 1 if you have the `vasprintf' function. */ | |||
#if defined(__MINGW32__) | |||
#define HAVE_VASPRINTF 1 | |||
#else | |||
#undef HAVE_VASPRINTF | |||
#endif | |||
/* Define to 1 if you have the `vprintf' function. */ | |||
#define HAVE_VPRINTF 1 | |||
@@ -7,6 +7,8 @@ AM_INIT_AUTOMAKE | |||
AC_PROG_MAKE_SET | |||
AC_CANONICAL_HOST | |||
AC_ARG_ENABLE(rdrand, | |||
AS_HELP_STRING([--enable-rdrand], | |||
[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_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. | |||
AC_FUNC_VPRINTF | |||
AC_FUNC_MEMCMP | |||
@@ -53,6 +67,14 @@ AC_CHECK_DECLS([isinf], [], [], [[#include <math.h>]]) | |||
AC_CHECK_DECLS([_isnan], [], [], [[#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 | |||
AC_TRY_LINK([#include <math.h>], [float f = 0.0; return isnan(f)], [], [LIBS="$LIBS -lm"]) | |||
fi | |||
@@ -75,7 +97,7 @@ int main(int c,char* v) {return 0;} | |||
AC_LANG_POP([C]) | |||
AM_PROG_LIBTOOL | |||
LT_INIT | |||
# Check for the -Bsymbolic-functions linker flag | |||
AC_ARG_ENABLE([Bsymbolic], | |||
@@ -12,13 +12,14 @@ | |||
#include "config.h" | |||
#include "strerror_override.h" | |||
#include <assert.h> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <stddef.h> | |||
#include <string.h> | |||
#include <math.h> | |||
#include <errno.h> | |||
#include "debug.h" | |||
#include "printbuf.h" | |||
@@ -30,13 +31,7 @@ | |||
#include "json_util.h" | |||
#include "math_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. | |||
/* #define REFCOUNT_DEBUG 1 */ | |||
@@ -143,11 +138,11 @@ static int json_escape_str(struct printbuf *pb, const char *str, int len, int fl | |||
default: | |||
if(c < ' ') | |||
{ | |||
char sbuf[7]; | |||
if(pos - start_offset > 0) | |||
printbuf_memappend(pb, | |||
str + start_offset, | |||
pos - start_offset); | |||
static char sbuf[7]; | |||
snprintf(sbuf, sizeof(sbuf), | |||
"\\u00%c%c", | |||
json_hex_chars[c >> 4], | |||
@@ -589,7 +584,7 @@ static int json_object_int_to_json_string(struct json_object* jso, | |||
int flags) | |||
{ | |||
/* 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); | |||
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_t) cint64; | |||
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; | |||
case json_type_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 */ | |||
#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, | |||
struct printbuf *pb, | |||
int level, | |||
int flags, | |||
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, | |||
@@ -1072,7 +1141,7 @@ struct json_object* json_object_array_bsearch( | |||
assert(json_object_get_type(jso) == json_type_array); | |||
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) | |||
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 */ | |||
json_object_object_foreachC(jso1, iter) { | |||
if (!lh_table_lookup_ex(jso2->o.c_object, (void*)iter.key, | |||
(void**)&sub)) | |||
(void**)(void *)&sub)) | |||
return 0; | |||
if (!json_object_equal(iter.val, sub)) | |||
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 */ | |||
json_object_object_foreachC(jso2, iter) { | |||
if (!lh_table_lookup_ex(jso1->o.c_object, (void*)iter.key, | |||
(void**)&sub)) | |||
(void**)(void *)&sub)) | |||
return 0; | |||
} | |||
@@ -21,6 +21,12 @@ | |||
#define THIS_FUNCTION_IS_DEPRECATED(func) func | |||
#endif | |||
#if defined(_MSC_VER) | |||
#define JSON_EXPORT __declspec(dllexport) | |||
#else | |||
#define JSON_EXPORT extern | |||
#endif | |||
#include <stddef.h> | |||
#include "json_inttypes.h" | |||
@@ -105,6 +111,22 @@ extern "C" { | |||
#undef TRUE | |||
#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_hex_chars; | |||
@@ -160,7 +182,7 @@ typedef enum json_type { | |||
* | |||
* @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. | |||
@@ -170,7 +192,7 @@ extern struct json_object* json_object_get(struct json_object *obj); | |||
* @param obj the json_object instance | |||
* @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 | |||
@@ -184,7 +206,7 @@ int json_object_put(struct json_object *obj); | |||
json_type_array, | |||
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 | |||
@@ -200,7 +222,7 @@ extern int json_object_is_type(const struct json_object *obj, enum json_type typ | |||
json_type_array, | |||
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. | |||
@@ -212,7 +234,7 @@ extern enum json_type json_object_get_type(const struct json_object *obj); | |||
* @param obj the json_object instance | |||
* @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 | |||
* @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 | |||
* @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); | |||
/** Stringify object to json format | |||
@@ -230,7 +252,7 @@ flags); | |||
* @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 | |||
*/ | |||
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); | |||
/** | |||
@@ -239,7 +261,7 @@ flags, size_t *length); | |||
* | |||
* @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 | |||
@@ -266,7 +288,7 @@ extern void* json_object_get_userdata(json_object *jso); | |||
* @param userdata an optional opaque cookie | |||
* @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); | |||
/** | |||
@@ -299,7 +321,7 @@ extern void json_object_set_userdata(json_object *jso, void *userdata, | |||
* @param userdata an optional opaque cookie | |||
* @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, | |||
void *userdata, | |||
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 | |||
*/ | |||
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 | |||
* @param obj the json_object instance | |||
* @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. | |||
* @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 | |||
* | |||
@@ -369,7 +391,7 @@ extern int json_object_object_length(const struct json_object* obj); | |||
* @return On success, <code>0</code> 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); | |||
/** 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 | |||
* 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, | |||
struct json_object *const val, | |||
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 | |||
* @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); | |||
/** 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. | |||
* @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, | |||
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 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. | |||
@@ -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 | |||
* @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 | |||
* @param obj the json_object instance | |||
* @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 | |||
* @param obj the json_object instance | |||
* @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 | |||
* | |||
@@ -526,7 +548,7 @@ extern size_t json_object_array_length(const struct json_object *obj); | |||
* @param obj the json_object instance | |||
* @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. | |||
* | |||
@@ -542,7 +564,7 @@ extern void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const | |||
* | |||
* @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 *jso, | |||
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 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); | |||
/** 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 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); | |||
/** 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 | |||
* @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); | |||
/** 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 | |||
* @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 */ | |||
@@ -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) | |||
* @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 | |||
* | |||
@@ -617,7 +639,7 @@ extern struct json_object* json_object_new_boolean(json_bool b); | |||
* @param obj the json_object instance | |||
* @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 | |||
@@ -630,7 +652,7 @@ extern json_bool json_object_get_boolean(const struct json_object *obj); | |||
* @param new_value the value to be set | |||
* @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 */ | |||
@@ -641,14 +663,14 @@ extern int json_object_set_boolean(struct json_object *obj,json_bool new_value); | |||
* @param i the integer | |||
* @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 | |||
* @param i the integer | |||
* @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 | |||
@@ -665,7 +687,7 @@ extern struct json_object* json_object_new_int64(int64_t i); | |||
* @param obj the json_object instance | |||
* @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 | |||
* | |||
@@ -677,7 +699,7 @@ extern int32_t json_object_get_int(const struct json_object *obj); | |||
* @param new_value the value to be set | |||
* @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 | |||
@@ -693,7 +715,7 @@ extern int json_object_set_int(struct json_object *obj,int new_value); | |||
* @param obj the json_object instance | |||
* @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 | |||
@@ -706,7 +728,7 @@ extern int64_t json_object_get_int64(const struct json_object *obj); | |||
* @param new_value the value to be set | |||
* @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 */ | |||
@@ -718,7 +740,7 @@ extern int json_object_set_int64(struct json_object *obj,int64_t new_value); | |||
* @param d the 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 | |||
@@ -746,7 +768,22 @@ extern struct json_object* json_object_new_double(double d); | |||
* @param d the numeric value of the double. | |||
* @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. | |||
@@ -768,7 +805,7 @@ extern struct json_object* json_object_new_double_s(double d, const char *ds); | |||
* @param level 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, | |||
int level, | |||
int flags); | |||
@@ -796,7 +833,7 @@ extern int json_object_double_to_json_string(struct json_object* jso, | |||
* @param obj the json_object instance | |||
* @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 | |||
@@ -809,7 +846,7 @@ extern double json_object_get_double(const struct json_object *obj); | |||
* @param new_value the value to be set | |||
* @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 | |||
* @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 | |||
* | |||
@@ -842,7 +879,7 @@ extern struct json_object* json_object_new_string_len(const char *s, int len); | |||
* @param obj the json_object instance | |||
* @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 | |||
* | |||
@@ -852,14 +889,14 @@ extern const char* json_object_get_string(struct json_object *obj); | |||
* @param obj the json_object instance | |||
* @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 | |||
* equivalent to json_object_set_string_len (obj, new_value, strlen(new_value)) | |||
* @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 | |||
* | |||
@@ -872,7 +909,7 @@ extern int json_object_set_string(json_object* obj, const char* new_value); | |||
* @param len the length of new_value | |||
* @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 | |||
* | |||
@@ -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 | |||
* @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); | |||
#ifdef __cplusplus | |||
@@ -48,6 +48,8 @@ struct json_object | |||
void *_userdata; | |||
}; | |||
void _set_last_err(const char *err_fmt, ...); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
@@ -8,10 +8,11 @@ | |||
#include "config.h" | |||
#include "strerror_override.h" | |||
#include <stdarg.h> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <errno.h> | |||
#include <string.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(). | |||
*/ | |||
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. | |||
*/ | |||
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 | |||
@@ -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 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); | |||
#ifdef __cplusplus | |||
@@ -12,13 +12,14 @@ | |||
#include "config.h" | |||
#undef realloc | |||
#include "strerror_override.h" | |||
#include <stdarg.h> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <stddef.h> | |||
#include <limits.h> | |||
#include <string.h> | |||
#include <errno.h> | |||
#include <ctype.h> | |||
#ifdef HAVE_SYS_TYPES_H | |||
@@ -47,12 +48,7 @@ | |||
# define open _open | |||
#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 "printbuf.h" | |||
@@ -64,7 +60,8 @@ | |||
static int sscanf_is_broken = 0; | |||
static int sscanf_is_broken_testdone = 0; | |||
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] = ""; | |||
@@ -75,7 +72,7 @@ const char *json_util_get_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_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) | |||
{ | |||
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 | |||
@@ -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) | |||
{ | |||
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); | |||
/** | |||
* 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. | |||
*/ | |||
const char *json_util_get_last_err(void); | |||
@@ -23,7 +23,7 @@ | |||
# include <endian.h> /* attempt to define endianness */ | |||
#endif | |||
#ifdef _MSC_VER | |||
#if defined(_MSC_VER) || defined(__MINGW32__) | |||
# define WIN32_LEAN_AND_MEAN | |||
# include <windows.h> /* Get InterlockedCompareExchange */ | |||
#endif | |||
@@ -452,7 +452,7 @@ static unsigned long lh_perllike_str_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 | |||
#else | |||
#define RANDOM_SEED_TYPE int | |||
@@ -474,10 +474,10 @@ static unsigned long lh_char_hash(const void *k) | |||
#endif | |||
#if defined USE_SYNC_COMPARE_AND_SWAP | |||
(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); | |||
#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 */ | |||
#endif | |||
} | |||
@@ -27,6 +27,7 @@ | |||
#include "debug.h" | |||
#include "printbuf.h" | |||
#include "snprintf_compat.h" | |||
#include "vasprintf_compat.h" | |||
static int printbuf_extend(struct printbuf *p, int min_size); | |||
@@ -9,6 +9,7 @@ | |||
* | |||
*/ | |||
#include "strerror_override.h" | |||
#include <stdio.h> | |||
#include "config.h" | |||
#include "random_seed.h" | |||
@@ -128,7 +129,6 @@ retry: | |||
#include <string.h> | |||
#include <fcntl.h> | |||
#include <unistd.h> | |||
#include <errno.h> | |||
#include <stdlib.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. | |||
@@ -52,14 +53,20 @@ static struct { | |||
{ 0, (char *)0 } | |||
}; | |||
// Enabled during tests | |||
int _json_c_strerror_enable = 0; | |||
#define PREFIX "ERRNO=" | |||
static char errno_buf[128] = PREFIX; | |||
char *strerror(int errno_in) | |||
char *_json_c_strerror(int errno_in) | |||
{ | |||
int start_idx; | |||
char digbuf[20]; | |||
int ii, jj; | |||
if (!_json_c_strerror_enable) | |||
return strerror(errno_in); | |||
// Avoid standard functions, so we don't need to include any | |||
// 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_spaced.expected | |||
test_util_file_SOURCES = test_util_file.c strerror_override.c | |||
test_util_file_SOURCES = test_util_file.c | |||
testsubdir=testSubDir | |||
TESTS_ENVIRONMENT = top_builddir=$(top_builddir) | |||
@@ -50,6 +50,14 @@ echo "=== Running test $progname" | |||
CMP="${CMP-cmp}" | |||
use_valgrind=${USE_VALGRIND-1} | |||
case "${use_valgrind}" in | |||
[0Nn]*) | |||
use_valgrind=0 | |||
;; | |||
*) | |||
use_valgrind=1 | |||
;; | |||
esac | |||
valgrind_path=$(which valgrind 2> /dev/null) | |||
if [ -z "${valgrind_path}" -o ! -x "${valgrind_path}" ] ; then | |||
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)); | |||
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) | |||
@@ -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,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,6)=0, my_array.to_string()=[ 7 ] | |||
after adding more entries, my_array.to_string()=[ 7, "s1", "s2", "s3" ] | |||
my_array= | |||
[0]=3 | |||
[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,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,6)=0, my_array.to_string()=[7] | |||
after adding more entries, my_array.to_string()=[7,"s1","s2","s3"] | |||
my_array= | |||
[0]=3 | |||
[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,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,6)=0, my_array.to_string()=[7] | |||
after adding more entries, my_array.to_string()=[7,"s1","s2","s3"] | |||
my_array= | |||
[0]=3 | |||
[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,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,6)=0, my_array.to_string()=[7] | |||
after adding more entries, my_array.to_string()=[7,"s1","s2","s3"] | |||
my_array= | |||
[0]=3 | |||
[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); | |||
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); | |||
} |
@@ -6,3 +6,9 @@ Test explicit serializer with custom userdata: | |||
obj.to_string(custom)=test | |||
Test reset serializer: | |||
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 <stdio.h> | |||
#include <string.h> | |||
@@ -280,6 +281,8 @@ static void test_wrong_inputs_set() | |||
int main(int argc, char **argv) | |||
{ | |||
_json_c_strerror_enable = 1; | |||
test_example_get(); | |||
test_recursion_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 "json.h" | |||
#include "json_tokener.h" | |||
#include "snprintf_compat.h" | |||
#ifdef HAVE_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 <stdlib.h> | |||
#include <stddef.h> | |||
@@ -49,6 +50,25 @@ static void test_write_to_file() | |||
(rv == 0) ? "OK" : "FAIL", outfile2, rv); | |||
if (rv == 0) | |||
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); | |||
} | |||
@@ -87,6 +107,7 @@ static void stat_and_cat(const char *file) | |||
buf[sb.st_size] = '\0'; | |||
printf("file[%s], size=%d, contents=%s\n", file, (int)sb.st_size, buf); | |||
free(buf); | |||
close(d); | |||
} | |||
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_ext(file, obj, flags); | |||
_json_c_strerror_enable = 1; | |||
const char *testdir; | |||
if (argc < 2) | |||
{ | |||
@@ -19,3 +19,17 @@ file[json2.out], size=367, contents={ | |||
"foo8":"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 | |||
#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) | |||
/* CAW: compliant version of vasprintf */ | |||