Compare commits
117 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
641002da37 | ||
|
|
9f9c9fe410 | ||
|
|
e39112b29c | ||
|
|
bf2584703a | ||
|
|
db8ca3645f | ||
|
|
0490907fb3 | ||
|
|
c2e8fdde9d | ||
|
|
24c67966aa | ||
|
|
0747d3943f | ||
|
|
5f9ef108d0 | ||
|
|
21599b95f8 | ||
|
|
3196ad48ed | ||
|
|
49ad5328c7 | ||
|
|
71676acd0b | ||
|
|
2489ea90b1 | ||
|
|
11d45b0090 | ||
|
|
8490e377c0 | ||
|
|
ef666519f7 | ||
|
|
6fe231757e | ||
|
|
84b5bfe173 | ||
|
|
d9ee5a7f1b | ||
|
|
19a19d1952 | ||
|
|
68e201add8 | ||
|
|
62531bd012 | ||
|
|
f639fbd2c3 | ||
|
|
a38704df58 | ||
|
|
8d439710cd | ||
|
|
120a90a155 | ||
|
|
c3e9725f02 | ||
|
|
02a3829363 | ||
|
|
018f7fea31 | ||
|
|
e6bd0aba9d | ||
|
|
9e7f11a847 | ||
|
|
042d4b2a6b | ||
|
|
ddd10b5e0b | ||
|
|
2fd66fab1a | ||
|
|
5cc594c9e8 | ||
|
|
ffb7ef4b75 | ||
|
|
b49280be72 | ||
|
|
7121134abd | ||
|
|
e8c812b500 | ||
|
|
6950cd203b | ||
|
|
d3bd463897 | ||
|
|
54d86fb4a4 | ||
|
|
42d398243d | ||
|
|
f675514815 | ||
|
|
5793142861 | ||
|
|
b227f96c45 | ||
|
|
0687442f5d | ||
|
|
8390c90a91 | ||
|
|
3000831365 | ||
|
|
6b1cba94e3 | ||
|
|
9591d3a155 | ||
|
|
83d04ddd68 | ||
|
|
70232676f7 | ||
|
|
257a716073 | ||
|
|
0ccd2c7715 | ||
|
|
42e307b3c5 | ||
|
|
61cba2ae50 | ||
|
|
867079c820 | ||
|
|
d20751d53d | ||
|
|
6281d1c549 | ||
|
|
8fd475bf96 | ||
|
|
bbd3b0ca4f | ||
|
|
7c4f323abc | ||
|
|
1edff47af3 | ||
|
|
dc2d54d9c6 | ||
|
|
263fd0c9d3 | ||
|
|
6db70f0301 | ||
|
|
70f663db29 | ||
|
|
59bc1f42e4 | ||
|
|
b1b4f307d5 | ||
|
|
a3e6369105 | ||
|
|
3d0d61fdaf | ||
|
|
650707fccc | ||
|
|
33b0855b27 | ||
|
|
7214a222c7 | ||
|
|
81ce127048 | ||
|
|
344d2b00ea | ||
|
|
52a8072727 | ||
|
|
741e6915e2 | ||
|
|
e40d52c550 | ||
|
|
3d5bea5714 | ||
|
|
3e03b07831 | ||
|
|
e00cd4f941 | ||
|
|
a1882fee02 | ||
|
|
4a5626695c | ||
|
|
afa1d37e20 | ||
|
|
b9967fdbcf | ||
|
|
ccf6e48a52 | ||
|
|
93a3c7f663 | ||
|
|
5dbac70a67 | ||
|
|
40c2e532b9 | ||
|
|
02beb90db3 | ||
|
|
92bf4f6fa8 | ||
|
|
8ad98c9ad3 | ||
|
|
7a4ec36f31 | ||
|
|
3fab956599 | ||
|
|
a2de27a828 | ||
|
|
99855b2d63 | ||
|
|
08c5ec8f01 | ||
|
|
e9cb9dbf60 | ||
|
|
8284b7d3da | ||
|
|
511db446d7 | ||
|
|
b98be1f18d | ||
|
|
872f847655 | ||
|
|
f86bb0377f | ||
|
|
c82cea9d32 | ||
|
|
67c002f7c9 | ||
|
|
e0a7f81b39 | ||
|
|
7b35a18ac0 | ||
|
|
54d59c743c | ||
|
|
6279610ce4 | ||
|
|
ac0ca9223b | ||
|
|
4853a3454c | ||
|
|
cf1074e70e | ||
|
|
5804e9de9b |
5
.travis.yml
Normal file
5
.travis.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
language: c
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
script: autoreconf -f -i && CFLAGS=-Werror ./configure && make check
|
||||
29
Android.mk
Normal file
29
Android.mk
Normal file
@@ -0,0 +1,29 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_ARM_MODE := arm
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
src/dump.c \
|
||||
src/error.c \
|
||||
src/hashtable.c \
|
||||
src/load.c \
|
||||
src/memory.c \
|
||||
src/pack_unpack.c \
|
||||
src/strbuffer.c \
|
||||
src/strconv.c \
|
||||
src/utf.c \
|
||||
src/value.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LOCAL_PATH) \
|
||||
$(LOCAL_PATH)/android \
|
||||
$(LOCAL_PATH)/src
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_SHARED_LIBRARIES := libc
|
||||
LOCAL_CFLAGS += -O3
|
||||
|
||||
LOCAL_MODULE:= libjansson
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
59
CHANGES
59
CHANGES
@@ -1,3 +1,62 @@
|
||||
Version 2.5
|
||||
===========
|
||||
|
||||
Released 2013-09-19
|
||||
|
||||
* New features:
|
||||
|
||||
- `json_pack()` and friends: Add format specifiers ``s#``, ``+`` and
|
||||
``+#``.
|
||||
|
||||
- Add ``JSON_DECODE_INT_AS_REAL`` decoding flag to treat all numbers
|
||||
as real in the decoder (#123).
|
||||
|
||||
- Add `json_array_foreach()`, paralleling `json_object_foreach()`
|
||||
(#118).
|
||||
|
||||
* Bug fixes:
|
||||
|
||||
- `json_dumps()` and friends: Don't crash if json is *NULL* and
|
||||
``JSON_ENCODE_ANY`` is set.
|
||||
|
||||
- Fix a theoretical integer overflow in `jsonp_strdup()`.
|
||||
|
||||
- Fix `l_isxdigit()` macro (#97).
|
||||
|
||||
- Fix an off-by-one error in `json_array_remove()`.
|
||||
|
||||
* Build:
|
||||
|
||||
- Support CMake in addition to GNU Autotools (#106, #107, #112,
|
||||
#115, #120, #127).
|
||||
|
||||
- Support building for Android (#109).
|
||||
|
||||
- Don't use ``-Werror`` by default.
|
||||
|
||||
- Support building and testing with VPATH (#93).
|
||||
|
||||
- Fix compilation when ``NDEBUG`` is defined (#128)
|
||||
|
||||
* Tests:
|
||||
|
||||
- Fix a refleak in ``test/bin/json_process.c``.
|
||||
|
||||
* Documentation:
|
||||
|
||||
- Clarify the return value of `json_load_callback_t`.
|
||||
|
||||
- Document how to circumvent problems with separate heaps on Windows.
|
||||
|
||||
- Fix memory leaks and warnings in ``github_commits.c``.
|
||||
|
||||
- Use `json_decref()` properly in tutorial.
|
||||
|
||||
* Other:
|
||||
|
||||
- Make it possible to forward declare ``struct json_t``.
|
||||
|
||||
|
||||
Version 2.4
|
||||
===========
|
||||
|
||||
|
||||
481
CMakeLists.txt
Normal file
481
CMakeLists.txt
Normal file
@@ -0,0 +1,481 @@
|
||||
# Notes:
|
||||
#
|
||||
# Author: Paul Harris, June 2012
|
||||
# Additions: Joakim Soderberg, Febuary 2013
|
||||
#
|
||||
# Supports: building static/shared, release/debug/etc, can also build html docs
|
||||
# and some of the tests.
|
||||
# Note that its designed for out-of-tree builds, so it will not pollute your
|
||||
# source tree.
|
||||
#
|
||||
# TODO 1: Finish implementing tests. api tests are working, but the valgrind
|
||||
# variants are not flagging problems.
|
||||
#
|
||||
# TODO 2: There is a check_exports script that would try and incorporate.
|
||||
#
|
||||
# TODO 3: Consolidate version numbers, currently the version number is written
|
||||
# into: * cmake (here) * autotools (the configure) * source code header files.
|
||||
# Should not be written directly into header files, autotools/cmake can do
|
||||
# that job.
|
||||
#
|
||||
# Brief intro on how to use cmake:
|
||||
# > mkdir build (somewhere - we do out-of-tree builds)
|
||||
# > use cmake, ccmake, or cmake-gui to configure the project. for linux, you
|
||||
# can only choose one variant: release,debug,etc... and static or shared.
|
||||
# >> example:
|
||||
# >> cd build
|
||||
# >> ccmake -i ../path_to_jansson_dir
|
||||
# >> inside, configure your options. press C until there are no lines
|
||||
# with * next to them.
|
||||
# >> note, I like to configure the 'install' path to ../install, so I get
|
||||
# self-contained clean installs I can point other projects to.
|
||||
# >> press G to 'generate' the project files.
|
||||
# >> make (to build the project)
|
||||
# >> make install
|
||||
# >> make test (to run the tests, if you enabled them)
|
||||
#
|
||||
# Brief description on how it works:
|
||||
# There is a small heirachy of CMakeLists.txt files which define how the
|
||||
# project is built.
|
||||
# Header file detection etc is done, and the results are written into config.h
|
||||
# and jansson_config.h, which are generated from the corresponding
|
||||
# config.h.cmake and jansson_config.h.cmake template files.
|
||||
# The generated header files end up in the build directory - not in
|
||||
# the source directory.
|
||||
# The rest is down to the usual make process.
|
||||
|
||||
|
||||
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
# required for exports? cmake_minimum_required (VERSION 2.8.6)
|
||||
project (jansson C)
|
||||
|
||||
# Options
|
||||
OPTION (BUILD_SHARED_LIBS "Build shared libraries." OFF)
|
||||
|
||||
if (MSVC)
|
||||
# This option must match the settings used in your program, in particular if you
|
||||
# are linking statically
|
||||
OPTION( STATIC_CRT "Link the static CRT libraries" OFF )
|
||||
endif ()
|
||||
|
||||
# Set some nicer output dirs.
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
|
||||
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
|
||||
|
||||
# Give the debug version a different postfix for windows,
|
||||
# so both the debug and release version can be built in the
|
||||
# same build-tree on Windows (MSVC).
|
||||
if (WIN32)
|
||||
SET (CMAKE_DEBUG_POSTFIX "_d")
|
||||
else (WIN32)
|
||||
endif (WIN32)
|
||||
|
||||
# This is how I thought it should go
|
||||
# set (JANSSON_VERSION "2.3.1")
|
||||
# set (JANSSON_SOVERSION 2)
|
||||
|
||||
set(JANSSON_DISPLAY_VERSION "2.5")
|
||||
|
||||
# This is what is required to match the same numbers as automake's
|
||||
set (JANSSON_VERSION "4.5.0")
|
||||
set (JANSSON_SOVERSION 4)
|
||||
|
||||
# for CheckFunctionKeywords
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
include (CheckFunctionExists)
|
||||
include (CheckFunctionKeywords)
|
||||
include (CheckIncludeFiles)
|
||||
include (CheckTypeSize)
|
||||
|
||||
|
||||
if (MSVC)
|
||||
# Turn off Microsofts "security" warnings.
|
||||
add_definitions( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo" )
|
||||
|
||||
if (STATIC_CRT)
|
||||
set(CMAKE_C_FLAGS_RELEASE "/MT")
|
||||
set(CMAKE_C_FLAGS_DEBUG "/MTd")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_C_FLAGS "-fPIC")
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
# Check for the int-type includes
|
||||
check_include_files (sys/types.h HAVE_SYS_TYPES_H)
|
||||
check_include_files (inttypes.h HAVE_INTTYPES_H)
|
||||
check_include_files (stdint.h HAVE_STDINT_H)
|
||||
|
||||
|
||||
# Check our 64 bit integer sizes
|
||||
check_type_size (__int64 __INT64)
|
||||
check_type_size (int64_t INT64_T)
|
||||
check_type_size ("long long" LONG_LONG_INT)
|
||||
|
||||
# Check our 32 bit integer sizes
|
||||
check_type_size (int32_t INT32_T)
|
||||
check_type_size (__int32 __INT32)
|
||||
check_type_size ("long" LONG_INT)
|
||||
check_type_size ("int" INT)
|
||||
|
||||
if (HAVE_INT32_T)
|
||||
set (JSON_INT32 int32_t)
|
||||
elseif (HAVE___INT32)
|
||||
set (JSON_INT32 __int32)
|
||||
elseif (HAVE_LONG AND (${LONG_INT} EQUAL 4))
|
||||
set (JSON_INT32 long)
|
||||
elseif (HAVE_INT AND (${INT} EQUAL 4))
|
||||
set (JSON_INT32 int)
|
||||
else ()
|
||||
message (FATAL_ERROR "Could not detect a valid 32 bit integer type")
|
||||
endif ()
|
||||
|
||||
# Check for ssize_t and SSIZE_T existance.
|
||||
check_type_size(ssize_t SSIZE_T)
|
||||
check_type_size(SSIZE_T UPPERCASE_SSIZE_T)
|
||||
if(NOT HAVE_SSIZE_T)
|
||||
if(HAVE_UPPERCASE_SSIZE_T)
|
||||
set(JSON_SSIZE SSIZE_T)
|
||||
else()
|
||||
set(JSON_SSIZE int)
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "")
|
||||
|
||||
# Check for all the variants of strtoll
|
||||
check_function_exists (strtoll HAVE_STRTOLL)
|
||||
check_function_exists (strtoq HAVE_STRTOQ)
|
||||
check_function_exists (_strtoi64 HAVE__STRTOI64)
|
||||
|
||||
# Figure out what variant we should use
|
||||
if (HAVE_STRTOLL)
|
||||
set (JSON_STRTOINT strtoll)
|
||||
elseif (HAVE_STRTOQ)
|
||||
set (JSON_STRTOINT strtoq)
|
||||
elseif (HAVE__STRTOI64)
|
||||
set (JSON_STRTOINT _strtoi64)
|
||||
else ()
|
||||
# fallback to strtol (32 bit)
|
||||
# this will set all the required variables
|
||||
set (JSON_STRTOINT strtol)
|
||||
set (JSON_INT_T long)
|
||||
set (JSON_INTEGER_FORMAT "\"ld\"")
|
||||
endif ()
|
||||
|
||||
# if we haven't defined JSON_INT_T, then we have a 64 bit conversion function.
|
||||
# detect what to use for the 64 bit type.
|
||||
# Note: I will prefer long long if I can get it, as that is what the automake system aimed for.
|
||||
if (NOT DEFINED JSON_INT_T)
|
||||
if (HAVE_LONG_LONG_INT AND (${LONG_LONG_INT} EQUAL 8))
|
||||
set (JSON_INT_T "long long")
|
||||
elseif (HAVE_INT64_T)
|
||||
set (JSON_INT_T int64_t)
|
||||
elseif (HAVE___INT64)
|
||||
set (JSON_INT_T __int64)
|
||||
else ()
|
||||
message (FATAL_ERROR "Could not detect 64 bit type, although I detected the strtoll equivalent")
|
||||
endif ()
|
||||
|
||||
# Apparently, Borland BCC and MSVC wants I64d,
|
||||
# Borland BCC could also accept LD
|
||||
# and gcc wants ldd,
|
||||
# I am not sure what cygwin will want, so I will assume I64d
|
||||
|
||||
if (WIN32) # matches both msvc and cygwin
|
||||
set (JSON_INTEGER_FORMAT "\"I64d\"")
|
||||
else ()
|
||||
set (JSON_INTEGER_FORMAT "\"lld\"")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
# If locale.h and localeconv() are available, define to 1, otherwise to 0.
|
||||
check_include_files (locale.h HAVE_LOCALE_H)
|
||||
check_function_exists (localeconv HAVE_LOCALECONV)
|
||||
|
||||
if (HAVE_LOCALECONV AND HAVE_LOCALE_H)
|
||||
set (JSON_HAVE_LOCALECONV 1)
|
||||
else ()
|
||||
set (JSON_HAVE_LOCALECONV 0)
|
||||
endif ()
|
||||
|
||||
|
||||
# check if we have setlocale
|
||||
check_function_exists (setlocale HAVE_SETLOCALE)
|
||||
|
||||
|
||||
# Check what the inline keyword is.
|
||||
# Note that the original JSON_INLINE was always set to just 'inline', so this goes further.
|
||||
check_function_keywords("inline")
|
||||
check_function_keywords("__inline")
|
||||
check_function_keywords("__inline__")
|
||||
|
||||
if (HAVE_INLINE)
|
||||
set (JSON_INLINE inline)
|
||||
elseif (HAVE___INLINE)
|
||||
set (JSON_INLINE __inline)
|
||||
elseif (HAVE___INLINE__)
|
||||
set (JSON_INLINE __inline__)
|
||||
else (HAVE_INLINE)
|
||||
# no inline on this platform
|
||||
set (JSON_INLINE)
|
||||
endif (HAVE_INLINE)
|
||||
|
||||
# Find our snprintf
|
||||
check_function_exists (snprintf HAVE_SNPRINTF)
|
||||
check_function_exists (_snprintf HAVE__SNPRINTF)
|
||||
|
||||
if (HAVE_SNPRINTF)
|
||||
set (JSON_SNPRINTF snprintf)
|
||||
elseif (HAVE__SNPRINTF)
|
||||
set (JSON_SNPRINTF _snprintf)
|
||||
endif ()
|
||||
|
||||
# Create pkg-conf file.
|
||||
# (We use the same files as ./configure does, so we
|
||||
# have to defined the same variables used there).
|
||||
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
|
||||
set(CMAKE_INSTALL_LIBDIR lib)
|
||||
endif(NOT DEFINED CMAKE_INSTALL_LIBDIR)
|
||||
set(prefix ${CMAKE_INSTALL_PREFIX})
|
||||
set(exec_prefix ${CMAKE_INSTALL_PREFIX})
|
||||
set(libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
|
||||
set(VERSION ${JANSSON_DISPLAY_VERSION})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/jansson.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/jansson.pc @ONLY)
|
||||
|
||||
# configure the public config file
|
||||
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/cmake/jansson_config.h.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/jansson_config.h)
|
||||
|
||||
# Copy the jansson.h file to the public include folder
|
||||
file (COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/jansson.h
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/)
|
||||
|
||||
|
||||
# configure the private config file
|
||||
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.h.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/private_include/config.h)
|
||||
|
||||
# and tell the source code to include it
|
||||
add_definitions (-DHAVE_CONFIG_H)
|
||||
|
||||
include_directories (${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
include_directories (${CMAKE_CURRENT_BINARY_DIR}/private_include)
|
||||
|
||||
# Add the lib sources.
|
||||
file (GLOB C_FILES src/*.c)
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
|
||||
add_library (jansson SHARED ${C_FILES} src/jansson.def)
|
||||
|
||||
set_target_properties (jansson PROPERTIES
|
||||
VERSION ${JANSSON_VERSION}
|
||||
SOVERSION ${JANSSON_SOVERSION})
|
||||
|
||||
else ()
|
||||
|
||||
add_library (jansson ${C_FILES})
|
||||
|
||||
endif ()
|
||||
|
||||
# LIBRARY for linux
|
||||
# RUNTIME for windows (when building shared)
|
||||
install (TARGETS jansson
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION bin
|
||||
)
|
||||
|
||||
install (FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/jansson_config.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/jansson.h
|
||||
DESTINATION include)
|
||||
|
||||
install (FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/jansson.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
|
||||
# For building Documentation (uses Sphinx)
|
||||
OPTION (BUILD_DOCS "Build documentation (uses python-sphinx)." ON)
|
||||
if (BUILD_DOCS)
|
||||
find_package(Sphinx)
|
||||
|
||||
if (NOT SPHINX_FOUND)
|
||||
message(WARNING "Sphinx not found. Cannot generate documentation!
|
||||
Set -DBUILD_DOCS=0 to get rid of this message.")
|
||||
else()
|
||||
if (Sphinx_VERSION_STRING VERSION_LESS 1.0)
|
||||
message(WARNING "Your Sphinx version is too old!
|
||||
This project requires Sphinx v1.0 or above to produce
|
||||
proper documentation (you have v${Sphinx_VERSION_STRING}).
|
||||
You will get output but it will have errors.")
|
||||
endif()
|
||||
|
||||
# configured documentation tools and intermediate build results
|
||||
set(BINARY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/_build")
|
||||
|
||||
# Sphinx cache with pickled ReST documents
|
||||
set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees")
|
||||
|
||||
# CMake could be used to build the conf.py file too,
|
||||
# eg it could automatically write the version of the program or change the theme.
|
||||
# if(NOT DEFINED SPHINX_THEME)
|
||||
# set(SPHINX_THEME default)
|
||||
# endif()
|
||||
#
|
||||
# if(NOT DEFINED SPHINX_THEME_DIR)
|
||||
# set(SPHINX_THEME_DIR)
|
||||
# endif()
|
||||
#
|
||||
# configure_file(
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in"
|
||||
# "${BINARY_BUILD_DIR}/conf.py"
|
||||
# @ONLY)
|
||||
|
||||
# TODO: Add support for all sphinx builders: http://sphinx-doc.org/builders.html
|
||||
|
||||
# Add documentation targets.
|
||||
set(DOC_TARGETS html)
|
||||
|
||||
OPTION(BUILD_MAN "Create a target for building man pages." ON)
|
||||
|
||||
if (BUILD_MAN)
|
||||
if (Sphinx_VERSION_STRING VERSION_LESS 1.0)
|
||||
message(WARNING "Sphinx version 1.0 > is required to build man pages. You have v${Sphinx_VERSION_STRING}.")
|
||||
else()
|
||||
list(APPEND DOC_TARGETS man)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
OPTION(BUILD_LATEX "Create a target for building latex docs (to create PDF)." OFF)
|
||||
|
||||
if (BUILD_LATEX)
|
||||
find_package(LATEX)
|
||||
|
||||
if (NOT LATEX_COMPILER)
|
||||
message("Couldn't find Latex, can't build latex docs using Sphinx")
|
||||
else()
|
||||
message("Latex found! If you have problems building, see Sphinx documentation for required Latex packages.")
|
||||
list(APPEND DOC_TARGETS latex)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# The doc target will build all documentation targets.
|
||||
add_custom_target(doc)
|
||||
|
||||
foreach (DOC_TARGET ${DOC_TARGETS})
|
||||
add_custom_target(${DOC_TARGET}
|
||||
${SPHINX_EXECUTABLE}
|
||||
# -q # Enable for quiet mode
|
||||
-b ${DOC_TARGET}
|
||||
-d "${SPHINX_CACHE_DIR}"
|
||||
# -c "${BINARY_BUILD_DIR}" # enable if using cmake-generated conf.py
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/doc"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/doc/${DOC_TARGET}"
|
||||
COMMENT "Building ${DOC_TARGET} documentation with Sphinx")
|
||||
|
||||
add_dependencies(doc ${DOC_TARGET})
|
||||
endforeach()
|
||||
|
||||
message("Building documentation enabled for: ${DOC_TARGETS}")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
|
||||
OPTION (WITHOUT_TESTS "Don't build tests ('make test' to execute tests)" OFF)
|
||||
|
||||
if (NOT WITHOUT_TESTS)
|
||||
OPTION (TEST_WITH_VALGRIND "Enable valgrind tests." OFF)
|
||||
|
||||
ENABLE_TESTING()
|
||||
|
||||
if (TEST_WITH_VALGRIND)
|
||||
# TODO: Add FindValgrind.cmake instead of having a hardcoded path.
|
||||
|
||||
# enable valgrind
|
||||
set(CMAKE_MEMORYCHECK_COMMAND valgrind)
|
||||
set(CMAKE_MEMORYCHECK_COMMAND_OPTIONS
|
||||
"--leak-check=full --show-reachable=yes --track-origins=yes -q")
|
||||
|
||||
set(MEMCHECK_COMMAND
|
||||
"${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS}")
|
||||
separate_arguments(MEMCHECK_COMMAND)
|
||||
endif ()
|
||||
|
||||
#
|
||||
# Test suites.
|
||||
#
|
||||
if (CMAKE_COMPILER_IS_GNUCC)
|
||||
add_definitions(-Wall -Wextra -Wdeclaration-after-statement -Werror)
|
||||
endif ()
|
||||
|
||||
set(api_tests
|
||||
test_array
|
||||
test_copy
|
||||
test_dump
|
||||
test_dump_callback
|
||||
test_equal
|
||||
test_load
|
||||
test_loadb
|
||||
test_number
|
||||
test_object
|
||||
test_pack
|
||||
test_simple
|
||||
test_unpack)
|
||||
|
||||
# Doing arithmetic on void pointers is not allowed by Microsofts compiler
|
||||
# such as secure_malloc and secure_free is doing, so exclude it for now.
|
||||
if (NOT MSVC)
|
||||
list(APPEND api_tests test_memory_funcs)
|
||||
endif()
|
||||
|
||||
# Helper macro for building and linking a test program.
|
||||
macro(build_testprog name dir)
|
||||
add_executable(${name} ${dir}/${name}.c)
|
||||
add_dependencies(${name} jansson)
|
||||
target_link_libraries(${name} jansson)
|
||||
endmacro(build_testprog)
|
||||
|
||||
# Create executables and tests/valgrind tests for API tests.
|
||||
foreach (test ${api_tests})
|
||||
build_testprog(${test} ${PROJECT_SOURCE_DIR}/test/suites/api)
|
||||
add_test(${test} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test})
|
||||
|
||||
if (TEST_WITH_VALGRIND)
|
||||
add_test(memcheck_${test} ${MEMCHECK_COMMAND}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test})
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
# Test harness for the suites tests.
|
||||
build_testprog(json_process ${PROJECT_SOURCE_DIR}/test/bin)
|
||||
|
||||
set(SUITES encoding-flags valid invalid invalid-unicode)
|
||||
foreach (SUITE ${SUITES})
|
||||
file(GLOB TESTDIRS ${jansson_SOURCE_DIR}/test/suites/${SUITE}/*)
|
||||
foreach (TESTDIR ${TESTDIRS})
|
||||
if (IS_DIRECTORY ${TESTDIR})
|
||||
get_filename_component(TNAME ${TESTDIR} NAME)
|
||||
add_test(${SUITE}__${TNAME}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/json_process ${TESTDIR})
|
||||
if ((${SUITE} STREQUAL "valid" OR ${SUITE} STREQUAL "invalid") AND NOT EXISTS ${TESTDIR}/nostrip)
|
||||
add_test(${SUITE}__${TNAME}__strip
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/json_process --strip ${TESTDIR})
|
||||
endif ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
endforeach ()
|
||||
|
||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
|
||||
DEPENDS json_process ${api_tests})
|
||||
endif ()
|
||||
|
||||
49
CleanSpec.mk
Normal file
49
CleanSpec.mk
Normal file
@@ -0,0 +1,49 @@
|
||||
# Copyright (C) 2007 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
# If you don't need to do a full clean build but would like to touch
|
||||
# a file or delete some intermediate files, add a clean step to the end
|
||||
# of the list. These steps will only be run once, if they haven't been
|
||||
# run before.
|
||||
#
|
||||
# E.g.:
|
||||
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
|
||||
# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
|
||||
#
|
||||
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
|
||||
# files that are missing or have been moved.
|
||||
#
|
||||
# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
|
||||
# Use $(OUT_DIR) to refer to the "out" directory.
|
||||
#
|
||||
# If you need to re-do something that's already mentioned, just copy
|
||||
# the command and add it to the bottom of the list. E.g., if a change
|
||||
# that you made last week required touching a file and a change you
|
||||
# made today requires touching the same file, just copy the old
|
||||
# touch step and add it to the end of the list.
|
||||
#
|
||||
# ************************************************
|
||||
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||
# ************************************************
|
||||
|
||||
# For example:
|
||||
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
|
||||
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
|
||||
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
|
||||
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
|
||||
|
||||
# ************************************************
|
||||
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||
# ************************************************
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -8,3 +8,8 @@ dvi:
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = jansson.pc
|
||||
|
||||
if GCC
|
||||
# These flags are gcc specific
|
||||
export AM_CFLAGS = -Wall -Wextra -Wdeclaration-after-statement
|
||||
endif
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
Jansson README
|
||||
==============
|
||||
|
||||
.. image:: https://travis-ci.org/akheron/jansson.png
|
||||
:alt: Build status
|
||||
:target: https://travis-ci.org/akheron/jansson
|
||||
|
||||
Jansson_ is a C library for encoding, decoding and manipulating JSON
|
||||
data. Its main features and design principles are:
|
||||
|
||||
|
||||
39
android/jansson_config.h
Normal file
39
android/jansson_config.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*
|
||||
*
|
||||
* This file specifies a part of the site-specific configuration for
|
||||
* Jansson, namely those things that affect the public API in
|
||||
* jansson.h.
|
||||
*
|
||||
* The configure script copies this file to jansson_config.h and
|
||||
* replaces @var@ substitutions by values that fit your system. If you
|
||||
* cannot run the configure script, you can do the value substitution
|
||||
* by hand.
|
||||
*/
|
||||
|
||||
#ifndef JANSSON_CONFIG_H
|
||||
#define JANSSON_CONFIG_H
|
||||
|
||||
/* If your compiler supports the inline keyword in C, JSON_INLINE is
|
||||
defined to `inline', otherwise empty. In C++, the inline is always
|
||||
supported. */
|
||||
#ifdef __cplusplus
|
||||
#define JSON_INLINE inline
|
||||
#else
|
||||
#define JSON_INLINE inline
|
||||
#endif
|
||||
|
||||
/* If your compiler supports the `long long` type and the strtoll()
|
||||
library function, JSON_INTEGER_IS_LONG_LONG is defined to 1,
|
||||
otherwise to 0. */
|
||||
#define JSON_INTEGER_IS_LONG_LONG 1
|
||||
|
||||
/* If locale.h and localeconv() are available, define to 1,
|
||||
otherwise to 0. */
|
||||
#define JSON_HAVE_LOCALECONV 0
|
||||
|
||||
#endif
|
||||
15
cmake/CheckFunctionKeywords.cmake
Normal file
15
cmake/CheckFunctionKeywords.cmake
Normal file
@@ -0,0 +1,15 @@
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
macro(check_function_keywords _wordlist)
|
||||
set(${_result} "")
|
||||
foreach(flag ${_wordlist})
|
||||
string(REGEX REPLACE "[-+/ ()]" "_" flagname "${flag}")
|
||||
string(TOUPPER "${flagname}" flagname)
|
||||
set(have_flag "HAVE_${flagname}")
|
||||
check_c_source_compiles("${flag} void func(); void func() { } int main() { func(); return 0; }" ${have_flag})
|
||||
if(${have_flag} AND NOT ${_result})
|
||||
set(${_result} "${flag}")
|
||||
# break()
|
||||
endif(${have_flag} AND NOT ${_result})
|
||||
endforeach(flag)
|
||||
endmacro(check_function_keywords)
|
||||
301
cmake/FindSphinx.cmake
Normal file
301
cmake/FindSphinx.cmake
Normal file
@@ -0,0 +1,301 @@
|
||||
#
|
||||
# PART B. DOWNLOADING AGREEMENT - LICENSE FROM SBIA WITH RIGHT TO SUBLICENSE ("SOFTWARE LICENSE").
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# 1. As used in this Software License, "you" means the individual downloading and/or
|
||||
# using, reproducing, modifying, displaying and/or distributing the Software and
|
||||
# the institution or entity which employs or is otherwise affiliated with such
|
||||
# individual in connection therewith. The Section of Biomedical Image Analysis,
|
||||
# Department of Radiology at the Universiy of Pennsylvania ("SBIA") hereby grants
|
||||
# you, with right to sublicense, with respect to SBIA's rights in the software,
|
||||
# and data, if any, which is the subject of this Software License (collectively,
|
||||
# the "Software"), a royalty-free, non-exclusive license to use, reproduce, make
|
||||
# derivative works of, display and distribute the Software, provided that:
|
||||
# (a) you accept and adhere to all of the terms and conditions of this Software
|
||||
# License; (b) in connection with any copy of or sublicense of all or any portion
|
||||
# of the Software, all of the terms and conditions in this Software License shall
|
||||
# appear in and shall apply to such copy and such sublicense, including without
|
||||
# limitation all source and executable forms and on any user documentation,
|
||||
# prefaced with the following words: "All or portions of this licensed product
|
||||
# (such portions are the "Software") have been obtained under license from the
|
||||
# Section of Biomedical Image Analysis, Department of Radiology at the University
|
||||
# of Pennsylvania and are subject to the following terms and conditions:"
|
||||
# (c) you preserve and maintain all applicable attributions, copyright notices
|
||||
# and licenses included in or applicable to the Software; (d) modified versions
|
||||
# of the Software must be clearly identified and marked as such, and must not
|
||||
# be misrepresented as being the original Software; and (e) you consider making,
|
||||
# but are under no obligation to make, the source code of any of your modifications
|
||||
# to the Software freely available to others on an open source basis.
|
||||
#
|
||||
# 2. The license granted in this Software License includes without limitation the
|
||||
# right to (i) incorporate the Software into proprietary programs (subject to
|
||||
# any restrictions applicable to such programs), (ii) add your own copyright
|
||||
# statement to your modifications of the Software, and (iii) provide additional
|
||||
# or different license terms and conditions in your sublicenses of modifications
|
||||
# of the Software; provided that in each case your use, reproduction or
|
||||
# distribution of such modifications otherwise complies with the conditions
|
||||
# stated in this Software License.
|
||||
#
|
||||
# 3. This Software License does not grant any rights with respect to third party
|
||||
# software, except those rights that SBIA has been authorized by a third
|
||||
# party to grant to you, and accordingly you are solely responsible for
|
||||
# (i) obtaining any permissions from third parties that you need to use,
|
||||
# reproduce, make derivative works of, display and distribute the Software,
|
||||
# and (ii) informing your sublicensees, including without limitation your
|
||||
# end-users, of their obligations to secure any such required permissions.
|
||||
#
|
||||
# 4. The Software has been designed for research purposes only and has not been
|
||||
# reviewed or approved by the Food and Drug Administration or by any other
|
||||
# agency. YOU ACKNOWLEDGE AND AGREE THAT CLINICAL APPLICATIONS ARE NEITHER
|
||||
# RECOMMENDED NOR ADVISED. Any commercialization of the Software is at the
|
||||
# sole risk of the party or parties engaged in such commercialization.
|
||||
# You further agree to use, reproduce, make derivative works of, display
|
||||
# and distribute the Software in compliance with all applicable governmental
|
||||
# laws, regulations and orders, including without limitation those relating
|
||||
# to export and import control.
|
||||
#
|
||||
# 5. The Software is provided "AS IS" and neither SBIA nor any contributor to
|
||||
# the software (each a "Contributor") shall have any obligation to provide
|
||||
# maintenance, support, updates, enhancements or modifications thereto.
|
||||
# SBIA AND ALL CONTRIBUTORS SPECIFICALLY DISCLAIM ALL EXPRESS AND IMPLIED
|
||||
# WARRANTIES OF ANY KIND INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
# IN NO EVENT SHALL SBIA OR ANY CONTRIBUTOR BE LIABLE TO ANY PARTY FOR
|
||||
# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY ARISING IN ANY WAY RELATED
|
||||
# TO THE SOFTWARE, EVEN IF SBIA OR ANY CONTRIBUTOR HAS BEEN ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGES. TO THE MAXIMUM EXTENT NOT PROHIBITED BY LAW OR
|
||||
# REGULATION, YOU FURTHER ASSUME ALL LIABILITY FOR YOUR USE, REPRODUCTION,
|
||||
# MAKING OF DERIVATIVE WORKS, DISPLAY, LICENSE OR DISTRIBUTION OF THE SOFTWARE
|
||||
# AND AGREE TO INDEMNIFY AND HOLD HARMLESS SBIA AND ALL CONTRIBUTORS FROM
|
||||
# AND AGAINST ANY AND ALL CLAIMS, SUITS, ACTIONS, DEMANDS AND JUDGMENTS ARISING
|
||||
# THEREFROM.
|
||||
#
|
||||
# 6. None of the names, logos or trademarks of SBIA or any of SBIA's affiliates
|
||||
# or any of the Contributors, or any funding agency, may be used to endorse
|
||||
# or promote products produced in whole or in part by operation of the Software
|
||||
# or derived from or based on the Software without specific prior written
|
||||
# permission from the applicable party.
|
||||
#
|
||||
# 7. Any use, reproduction or distribution of the Software which is not in accordance
|
||||
# with this Software License shall automatically revoke all rights granted to you
|
||||
# under this Software License and render Paragraphs 1 and 2 of this Software
|
||||
# License null and void.
|
||||
#
|
||||
# 8. This Software License does not grant any rights in or to any intellectual
|
||||
# property owned by SBIA or any Contributor except those rights expressly
|
||||
# granted hereunder.
|
||||
#
|
||||
#
|
||||
# PART C. MISCELLANEOUS
|
||||
# ---------------------
|
||||
#
|
||||
# This Agreement shall be governed by and construed in accordance with the laws
|
||||
# of The Commonwealth of Pennsylvania without regard to principles of conflicts
|
||||
# of law. This Agreement shall supercede and replace any license terms that you
|
||||
# may have agreed to previously with respect to Software from SBIA.
|
||||
#
|
||||
##############################################################################
|
||||
# @file FindSphinx.cmake
|
||||
# @brief Find Sphinx documentation build tools.
|
||||
#
|
||||
# @par Input variables:
|
||||
# <table border="0">
|
||||
# <tr>
|
||||
# @tp @b Sphinx_DIR @endtp
|
||||
# <td>Installation directory of Sphinx tools. Can also be set as environment variable.</td>
|
||||
# </tr>
|
||||
# <tr>
|
||||
# @tp @b SPHINX_DIR @endtp
|
||||
# <td>Alternative environment variable for @c Sphinx_DIR.</td>
|
||||
# </tr>
|
||||
# <tr>
|
||||
# @tp @b Sphinx_FIND_COMPONENTS @endtp
|
||||
# <td>Sphinx build tools to look for, i.e., 'apidoc' and/or 'build'.</td>
|
||||
# </tr>
|
||||
# </table>
|
||||
#
|
||||
# @par Output variables:
|
||||
# <table border="0">
|
||||
# <tr>
|
||||
# @tp @b Sphinx_FOUND @endtp
|
||||
# <td>Whether all or only the requested Sphinx build tools were found.</td>
|
||||
# </tr>
|
||||
# <tr>
|
||||
# @tp @b SPHINX_FOUND @endtp
|
||||
# <td>Alias for @c Sphinx_FOUND.<td>
|
||||
# </tr>
|
||||
# <tr>
|
||||
# @tp @b SPHINX_EXECUTABLE @endtp
|
||||
# <td>Non-cached alias for @c Sphinx-build_EXECUTABLE.</td>
|
||||
# </tr>
|
||||
# <tr>
|
||||
# @tp @b Sphinx_PYTHON_EXECUTABLE @endtp
|
||||
# <td>Python executable used to run sphinx-build. This is either the
|
||||
# by default found Python interpreter or a specific version as
|
||||
# specified by the shebang (#!) of the sphinx-build script.</td>
|
||||
# </tr>
|
||||
# <tr>
|
||||
# @tp @b Sphinx_PYTHON_OPTIONS @endtp
|
||||
# <td>A list of Python options extracted from the shebang (#!) of the
|
||||
# sphinx-build script. The -E option is added by this module
|
||||
# if the Python executable is not the system default to avoid
|
||||
# problems with a differing setting of the @c PYTHONHOME.</td>
|
||||
# </tr>
|
||||
# <tr>
|
||||
# @tp @b Sphinx-build_EXECUTABLE @endtp
|
||||
# <td>Absolute path of the found sphinx-build tool.</td>
|
||||
# </tr>
|
||||
# <tr>
|
||||
# @tp @b Sphinx-apidoc_EXECUTABLE @endtp
|
||||
# <td>Absolute path of the found sphinx-apidoc tool.</td>
|
||||
# </tr>
|
||||
# <tr>
|
||||
# @tp @b Sphinx_VERSION_STRING @endtp
|
||||
# <td>Sphinx version found e.g. 1.1.2.</td>
|
||||
# </tr>
|
||||
# <tr>
|
||||
# @tp @b Sphinx_VERSION_MAJOR @endtp
|
||||
# <td>Sphinx major version found e.g. 1.</td>
|
||||
# </tr>
|
||||
# <tr>
|
||||
# @tp @b Sphinx_VERSION_MINOR @endtp
|
||||
# <td>Sphinx minor version found e.g. 1.</td>
|
||||
# </tr>
|
||||
# <tr>
|
||||
# @tp @b Sphinx_VERSION_PATCH @endtp
|
||||
# <td>Sphinx patch version found e.g. 2.</td>
|
||||
# </tr>
|
||||
# </table>
|
||||
#
|
||||
# @ingroup CMakeFindModules
|
||||
##############################################################################
|
||||
|
||||
set (_Sphinx_REQUIRED_VARS)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# initialize search
|
||||
if (NOT Sphinx_DIR)
|
||||
if (NOT $ENV{Sphinx_DIR} STREQUAL "")
|
||||
set (Sphinx_DIR "$ENV{Sphinx_DIR}" CACHE PATH "Installation prefix of Sphinx (docutils)." FORCE)
|
||||
else ()
|
||||
set (Sphinx_DIR "$ENV{SPHINX_DIR}" CACHE PATH "Installation prefix of Sphinx (docutils)." FORCE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# default components to look for
|
||||
if (NOT Sphinx_FIND_COMPONENTS)
|
||||
set (Sphinx_FIND_COMPONENTS "build")
|
||||
elseif (NOT Sphinx_FIND_COMPONENTS MATCHES "^(build|apidoc)$")
|
||||
message (FATAL_ERROR "Invalid Sphinx component in: ${Sphinx_FIND_COMPONENTS}")
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# find components, i.e., build tools
|
||||
foreach (_Sphinx_TOOL IN LISTS Sphinx_FIND_COMPONENTS)
|
||||
if (Sphinx_DIR)
|
||||
find_program (
|
||||
Sphinx-${_Sphinx_TOOL}_EXECUTABLE
|
||||
NAMES sphinx-${_Sphinx_TOOL} sphinx-${_Sphinx_TOOL}.py
|
||||
HINTS "${Sphinx_DIR}"
|
||||
PATH_SUFFIXES bin
|
||||
DOC "The sphinx-${_Sphinx_TOOL} Python script."
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
else ()
|
||||
find_program (
|
||||
Sphinx-${_Sphinx_TOOL}_EXECUTABLE
|
||||
NAMES sphinx-${_Sphinx_TOOL} sphinx-${_Sphinx_TOOL}.py
|
||||
DOC "The sphinx-${_Sphinx_TOOL} Python script."
|
||||
)
|
||||
endif ()
|
||||
mark_as_advanced (Sphinx-${_Sphinx_TOOL}_EXECUTABLE)
|
||||
list (APPEND _Sphinx_REQUIRED_VARS Sphinx-${_Sphinx_TOOL}_EXECUTABLE)
|
||||
endforeach ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# determine Python executable used by Sphinx
|
||||
if (Sphinx-build_EXECUTABLE)
|
||||
# extract python executable from shebang of sphinx-build
|
||||
find_package (PythonInterp QUIET)
|
||||
set (Sphinx_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}")
|
||||
set (Sphinx_PYTHON_OPTIONS)
|
||||
file (STRINGS "${Sphinx-build_EXECUTABLE}" FIRST_LINE LIMIT_COUNT 1)
|
||||
if (FIRST_LINE MATCHES "^#!(.*/python.*)") # does not match "#!/usr/bin/env python" !
|
||||
string (REGEX REPLACE "^ +| +$" "" Sphinx_PYTHON_EXECUTABLE "${CMAKE_MATCH_1}")
|
||||
if (Sphinx_PYTHON_EXECUTABLE MATCHES "([^ ]+) (.*)")
|
||||
set (Sphinx_PYTHON_EXECUTABLE "${CMAKE_MATCH_1}")
|
||||
string (REGEX REPLACE " +" ";" Sphinx_PYTHON_OPTIONS "${CMAKE_MATCH_2}")
|
||||
endif ()
|
||||
endif ()
|
||||
# this is done to avoid problems with multiple Python versions being installed
|
||||
# remember: CMake command if(STR EQUAL STR) is bad and may cause many troubles !
|
||||
string (REGEX REPLACE "([.+*?^$])" "\\\\\\1" _Sphinx_PYTHON_EXECUTABLE_RE "${PYTHON_EXECUTABLE}")
|
||||
list (FIND Sphinx_PYTHON_OPTIONS -E IDX)
|
||||
if (IDX EQUAL -1 AND NOT Sphinx_PYTHON_EXECUTABLE MATCHES "^${_Sphinx_PYTHON_EXECUTABLE_RE}$")
|
||||
list (INSERT Sphinx_PYTHON_OPTIONS 0 -E)
|
||||
endif ()
|
||||
unset (_Sphinx_PYTHON_EXECUTABLE_RE)
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# determine Sphinx version
|
||||
if (Sphinx-build_EXECUTABLE)
|
||||
# intentionally use invalid -h option here as the help that is shown then
|
||||
# will include the Sphinx version information
|
||||
if (Sphinx_PYTHON_EXECUTABLE)
|
||||
execute_process (
|
||||
COMMAND "${Sphinx_PYTHON_EXECUTABLE}" ${Sphinx_PYTHON_OPTIONS} "${Sphinx-build_EXECUTABLE}" -h
|
||||
OUTPUT_VARIABLE _Sphinx_VERSION
|
||||
ERROR_VARIABLE _Sphinx_VERSION
|
||||
)
|
||||
elseif (UNIX)
|
||||
execute_process (
|
||||
COMMAND "${Sphinx-build_EXECUTABLE}" -h
|
||||
OUTPUT_VARIABLE _Sphinx_VERSION
|
||||
ERROR_VARIABLE _Sphinx_VERSION
|
||||
)
|
||||
endif ()
|
||||
|
||||
# The sphinx version can also contain a "b" instead of the last dot.
|
||||
# For example "Sphinx v1.2b1" so we cannot just split on "."
|
||||
if (_Sphinx_VERSION MATCHES "Sphinx v([0-9]+\\.[0-9]+(\\.|b)[0-9]+)")
|
||||
set (Sphinx_VERSION_STRING "${CMAKE_MATCH_1}")
|
||||
string(REGEX REPLACE "([0-9]+)\\.[0-9]+(\\.|b)[0-9]+" "\\1" Sphinx_VERSION_MAJOR ${Sphinx_VERSION_STRING})
|
||||
string(REGEX REPLACE "[0-9]+\\.([0-9]+)(\\.|b)[0-9]+" "\\1" Sphinx_VERSION_MINOR ${Sphinx_VERSION_STRING})
|
||||
string(REGEX REPLACE "[0-9]+\\.[0-9]+(\\.|b)([0-9]+)" "\\1" Sphinx_VERSION_PATCH ${Sphinx_VERSION_STRING})
|
||||
|
||||
# v1.2.0 -> v1.2
|
||||
if (Sphinx_VERSION_PATCH EQUAL 0)
|
||||
string (REGEX REPLACE "\\.0$" "" Sphinx_VERSION_STRING "${Sphinx_VERSION_STRING}")
|
||||
endif ()
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# compatibility with FindPythonInterp.cmake and FindPerl.cmake
|
||||
set (SPHINX_EXECUTABLE "${Sphinx-build_EXECUTABLE}")
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# handle the QUIETLY and REQUIRED arguments and set SPHINX_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
include (FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS (
|
||||
Sphinx
|
||||
REQUIRED_VARS
|
||||
${_Sphinx_REQUIRED_VARS}
|
||||
# VERSION_VAR # This isn't available until CMake 2.8.8 so don't use it.
|
||||
Sphinx_VERSION_STRING
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# set Sphinx_DIR
|
||||
if (NOT Sphinx_DIR AND Sphinx-build_EXECUTABLE)
|
||||
get_filename_component (Sphinx_DIR "${Sphinx-build_EXECUTABLE}" PATH)
|
||||
string (REGEX REPLACE "/bin/?" "" Sphinx_DIR "${Sphinx_DIR}")
|
||||
set (Sphinx_DIR "${Sphinx_DIR}" CACHE PATH "Installation directory of Sphinx tools." FORCE)
|
||||
endif ()
|
||||
|
||||
unset (_Sphinx_VERSION)
|
||||
unset (_Sphinx_REQUIRED_VARS)
|
||||
45
cmake/config.h.cmake
Normal file
45
cmake/config.h.cmake
Normal file
@@ -0,0 +1,45 @@
|
||||
/* Reduced down to the defines that are actually used in the code */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> (and friends) header file. */
|
||||
#cmakedefine HAVE_INTTYPES_H 1
|
||||
#cmakedefine HAVE_STDINT_H 1
|
||||
#cmakedefine HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* We must include this here, as in (eg) utf.h it will want to use
|
||||
the integer type, which in MSVC2010 will be in stdint.h
|
||||
(there is no inttypes.h in MSVC2010) */
|
||||
#if defined(HAVE_STDINT_H)
|
||||
# include <stdint.h>
|
||||
#elif defined(HAVE_INTTYPES_H)
|
||||
# include <inttypes.h>
|
||||
#elif defined(HAVE_SYS_TYPES_H)
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#cmakedefine HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if you have the 'setlocale' function. */
|
||||
#cmakedefine HAVE_SETLOCALE 1
|
||||
|
||||
/* Define to the type of a signed integer type of width exactly 32 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#cmakedefine HAVE_INT32_T 1
|
||||
|
||||
#ifndef HAVE_INT32_T
|
||||
# define int32_t @JSON_INT32@
|
||||
#endif
|
||||
|
||||
#cmakedefine HAVE_SSIZE_T 1
|
||||
|
||||
#ifndef HAVE_SSIZE_T
|
||||
# define ssize_t @JSON_SSIZE@
|
||||
#endif
|
||||
|
||||
#cmakedefine HAVE_SNPRINTF 1
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
# define snprintf @JSON_SNPRINTF@
|
||||
#endif
|
||||
|
||||
#cmakedefine HAVE_VSNPRINTF
|
||||
62
cmake/jansson_config.h.cmake
Normal file
62
cmake/jansson_config.h.cmake
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*
|
||||
*
|
||||
* This file specifies a part of the site-specific configuration for
|
||||
* Jansson, namely those things that affect the public API in
|
||||
* jansson.h.
|
||||
*
|
||||
* The CMake system will generate the jansson_config.h file and
|
||||
* copy it to the build and install directories.
|
||||
*/
|
||||
|
||||
#ifndef JANSSON_CONFIG_H
|
||||
#define JANSSON_CONFIG_H
|
||||
|
||||
/* Define this so that we can disable scattered automake configuration in source files */
|
||||
#define JANSSON_USING_CMAKE
|
||||
|
||||
/* Note: when using cmake, JSON_INTEGER_IS_LONG_LONG is not defined nor used,
|
||||
* as we will also check for __int64 etc types.
|
||||
* (the definition was used in the automake system) */
|
||||
|
||||
/* Bring in the cmake-detected defines */
|
||||
#cmakedefine HAVE_STDINT_H 1
|
||||
#cmakedefine HAVE_INTTYPES_H 1
|
||||
#cmakedefine HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Include our standard type header for the integer typedef */
|
||||
|
||||
#if defined(HAVE_STDINT_H)
|
||||
# include <stdint.h>
|
||||
#elif defined(HAVE_INTTYPES_H)
|
||||
# include <inttypes.h>
|
||||
#elif defined(HAVE_SYS_TYPES_H)
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* If your compiler supports the inline keyword in C, JSON_INLINE is
|
||||
defined to `inline', otherwise empty. In C++, the inline is always
|
||||
supported. */
|
||||
#ifdef __cplusplus
|
||||
#define JSON_INLINE inline
|
||||
#else
|
||||
#define JSON_INLINE @JSON_INLINE@
|
||||
#endif
|
||||
|
||||
|
||||
#define json_int_t @JSON_INT_T@
|
||||
#define json_strtoint @JSON_STRTOINT@
|
||||
#define JSON_INTEGER_FORMAT @JSON_INTEGER_FORMAT@
|
||||
|
||||
|
||||
/* If locale.h and localeconv() are available, define to 1, otherwise to 0. */
|
||||
#define JSON_HAVE_LOCALECONV @JSON_HAVE_LOCALECONV@
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
AC_PREREQ([2.60])
|
||||
AC_INIT([jansson], [2.4], [petri@digip.org])
|
||||
AC_INIT([jansson], [2.5], [petri@digip.org])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.10 foreign])
|
||||
|
||||
|
||||
123
doc/apiref.rst
123
doc/apiref.rst
@@ -168,7 +168,7 @@ The following functions are used to manipulate the reference count.
|
||||
|
||||
.. function:: json_t *json_incref(json_t *json)
|
||||
|
||||
Increment the reference count of *json* if it's not non-*NULL*.
|
||||
Increment the reference count of *json* if it's not *NULL*.
|
||||
Returns *json*.
|
||||
|
||||
.. function:: void json_decref(json_t *json)
|
||||
@@ -357,7 +357,6 @@ information, see :ref:`rfc-conformance`.
|
||||
should use ``json_int_t`` explicitly.
|
||||
|
||||
``JSON_INTEGER_IS_LONG_LONG``
|
||||
|
||||
This is a preprocessor variable that holds the value 1 if
|
||||
:type:`json_int_t` is ``long long``, and 0 if it's ``long``. It
|
||||
can be used as follows::
|
||||
@@ -369,7 +368,6 @@ information, see :ref:`rfc-conformance`.
|
||||
#endif
|
||||
|
||||
``JSON_INTEGER_FORMAT``
|
||||
|
||||
This is a macro that expands to a :func:`printf()` conversion
|
||||
specifier that corresponds to :type:`json_int_t`, without the
|
||||
leading ``%`` sign, i.e. either ``"lld"`` or ``"ld"``. This macro
|
||||
@@ -505,6 +503,35 @@ A JSON array is an ordered collection of other JSON values.
|
||||
Appends all elements in *other_array* to the end of *array*.
|
||||
Returns 0 on success and -1 on error.
|
||||
|
||||
The following macro can be used to iterate through all elements
|
||||
in an array.
|
||||
|
||||
.. function:: json_array_foreach(array, index, value)
|
||||
|
||||
Iterate over every element of ``array``, running the block
|
||||
of code that follows each time with the proper values set to
|
||||
variables ``index`` and ``value``, of types :type:`size_t` and
|
||||
:type:`json_t *` respectively. Example::
|
||||
|
||||
/* array is a JSON array */
|
||||
size_t index;
|
||||
json_t *value;
|
||||
|
||||
json_array_foreach(array, index, value) {
|
||||
/* block of code that uses index and value */
|
||||
}
|
||||
|
||||
The items are returned in increasing index order.
|
||||
|
||||
This macro expands to an ordinary ``for`` statement upon
|
||||
preprocessing, so its performance is equivalent to that of
|
||||
hand-written code using the array access functions.
|
||||
The main advantage of this macro is that it abstracts
|
||||
away the complexity, and makes for shorter, more
|
||||
concise code.
|
||||
|
||||
.. versionadded:: 2.5
|
||||
|
||||
|
||||
Object
|
||||
======
|
||||
@@ -921,6 +948,16 @@ macros can be ORed together to obtain *flags*.
|
||||
|
||||
.. versionadded:: 2.1
|
||||
|
||||
``JSON_DECODE_INT_AS_REAL``
|
||||
JSON defines only one number type. Jansson distinguishes between
|
||||
ints and reals. For more information see :ref:`real-vs-integer`.
|
||||
With this flag enabled the decoder interprets all numbers as real
|
||||
values. Integers that do not have an exact double representation
|
||||
will silently result in a loss of precision. Integers that cause
|
||||
a double overflow will cause an error.
|
||||
|
||||
.. versionadded:: 2.5
|
||||
|
||||
Each function also takes an optional :type:`json_error_t` parameter
|
||||
that is filled with error information if decoding fails. It's also
|
||||
updated on success; the number of bytes of input read is written to
|
||||
@@ -993,9 +1030,10 @@ The following functions perform the actual JSON decoding.
|
||||
*buffer* points to a buffer of *buflen* bytes, and *data* is the
|
||||
corresponding :func:`json_load_callback()` argument passed through.
|
||||
|
||||
On error, the function should return ``(size_t)-1`` to abort the
|
||||
decoding process. When there's no data left, it should return 0 to
|
||||
report that the end of input has been reached.
|
||||
On success, the function should return the number of bytes read; a
|
||||
returned value of 0 indicates that no data was read and that the
|
||||
end of file has been reached. On error, the function should return
|
||||
``(size_t)-1`` to abort the decoding process.
|
||||
|
||||
.. versionadded:: 2.4
|
||||
|
||||
@@ -1033,13 +1071,25 @@ items::
|
||||
/* Create the JSON array ["foo", "bar", true] */
|
||||
json_pack("[ssb]", "foo", "bar", 1);
|
||||
|
||||
Here's the full list of format characters. The type in parentheses
|
||||
Here's the full list of format specifiers. The type in parentheses
|
||||
denotes the resulting JSON type, and the type in brackets (if any)
|
||||
denotes the C type that is expected as the corresponding argument.
|
||||
denotes the C type that is expected as the corresponding argument or
|
||||
arguments.
|
||||
|
||||
``s`` (string) [const char \*]
|
||||
Convert a NULL terminated UTF-8 string to a JSON string.
|
||||
|
||||
``s#`` (string) [const char \*, int]
|
||||
Convert a UTF-8 buffer of a given length to a JSON string.
|
||||
|
||||
``+`` [const char \*]
|
||||
Like ``s``, but concatenate to the previous string. Only valid
|
||||
after ``s``, ``s#``, ``+`` or ``+#``.
|
||||
|
||||
``+#`` [const char \*, int]
|
||||
Like ``s#``, but concatenate to the previous string. Only valid
|
||||
after ``s``, ``s#``, ``+`` or ``+#``.
|
||||
|
||||
``n`` (null)
|
||||
Output a JSON null value. No argument is consumed.
|
||||
|
||||
@@ -1074,10 +1124,11 @@ denotes the C type that is expected as the corresponding argument.
|
||||
|
||||
``{fmt}`` (object)
|
||||
Build an object with contents from the inner format string
|
||||
``fmt``. The first, third, etc. format character represent a key,
|
||||
and must be ``s`` (as object keys are always strings). The second,
|
||||
fourth, etc. format character represent a value. Any value may be
|
||||
an object or array, i.e. recursive value building is supported.
|
||||
``fmt``. The first, third, etc. format specifier represent a key,
|
||||
and must be a string (see ``s``, ``s#``, ``+`` and ``+#`` above),
|
||||
as object keys are always strings. The second, fourth, etc. format
|
||||
specifier represent a value. Any value may be an object or array,
|
||||
i.e. recursive value building is supported.
|
||||
|
||||
Whitespace, ``:`` and ``,`` are ignored.
|
||||
|
||||
@@ -1088,9 +1139,9 @@ The following functions compose the value building API:
|
||||
.. refcounting:: new
|
||||
|
||||
Build a new JSON value according to the format string *fmt*. For
|
||||
each format character (except for ``{}[]n``), one argument is
|
||||
consumed and used to build the corresponding value. Returns *NULL*
|
||||
on error.
|
||||
each format specifier (except for ``{}[]n``), one or more arguments
|
||||
are consumed and used to build the corresponding value. Returns
|
||||
*NULL* on error.
|
||||
|
||||
.. function:: json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...)
|
||||
json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap)
|
||||
@@ -1119,13 +1170,20 @@ More examples::
|
||||
/* Build the JSON array [[1, 2], {"cool": true}] */
|
||||
json_pack("[[i,i],{s:b}]", 1, 2, "cool", 1);
|
||||
|
||||
/* Build a string from a non-NUL terminated buffer */
|
||||
char buffer[4] = {'t', 'e', 's', 't'};
|
||||
json_pack("s#", buffer, 4);
|
||||
|
||||
/* Concatentate strings together to build the JSON string "foobarbaz" */
|
||||
json_pack("s++", "foo", "bar", "baz");
|
||||
|
||||
|
||||
.. _apiref-unpack:
|
||||
|
||||
Parsing and Validating Values
|
||||
=============================
|
||||
|
||||
This sectinon describes functions that help to validate complex values
|
||||
This section describes functions that help to validate complex values
|
||||
and extract, or *unpack*, data from them. Like :ref:`building values
|
||||
<apiref-pack>`, this is also based on format strings.
|
||||
|
||||
@@ -1133,10 +1191,10 @@ While a JSON value is unpacked, the type specified in the format
|
||||
string is checked to match that of the JSON value. This is the
|
||||
validation part of the process. In addition to this, the unpacking
|
||||
functions can also check that all items of arrays and objects are
|
||||
unpacked. This check be enabled with the format character ``!`` or by
|
||||
unpacked. This check be enabled with the format specifier ``!`` or by
|
||||
using the flag ``JSON_STRICT``. See below for details.
|
||||
|
||||
Here's the full list of format characters. The type in parentheses
|
||||
Here's the full list of format specifiers. The type in parentheses
|
||||
denotes the JSON type, and the type in brackets (if any) denotes the C
|
||||
type whose address should be passed.
|
||||
|
||||
@@ -1178,10 +1236,10 @@ type whose address should be passed.
|
||||
|
||||
``{fmt}`` (object)
|
||||
Convert each item in the JSON object according to the inner format
|
||||
string ``fmt``. The first, third, etc. format character represent
|
||||
string ``fmt``. The first, third, etc. format specifier represent
|
||||
a key, and must be ``s``. The corresponding argument to unpack
|
||||
functions is read as the object key. The second fourth, etc.
|
||||
format character represent a value and is written to the address
|
||||
format specifier represent a value and is written to the address
|
||||
given as the corresponding argument. **Note** that every other
|
||||
argument is read from and every other is written to.
|
||||
|
||||
@@ -1194,17 +1252,17 @@ type whose address should be passed.
|
||||
extracted. See below for an example.
|
||||
|
||||
``!``
|
||||
This special format character is used to enable the check that
|
||||
This special format specifier is used to enable the check that
|
||||
all object and array items are accessed, on a per-value basis. It
|
||||
must appear inside an array or object as the last format character
|
||||
must appear inside an array or object as the last format specifier
|
||||
before the closing bracket or brace. To enable the check globally,
|
||||
use the ``JSON_STRICT`` unpacking flag.
|
||||
|
||||
``*``
|
||||
This special format character is the opposite of ``!``. If the
|
||||
This special format specifier is the opposite of ``!``. If the
|
||||
``JSON_STRICT`` flag is used, ``*`` can be used to disable the
|
||||
strict check on a per-value basis. It must appear inside an array
|
||||
or object as the last format character before the closing bracket
|
||||
or object as the last format specifier before the closing bracket
|
||||
or brace.
|
||||
|
||||
Whitespace, ``:`` and ``,`` are ignored.
|
||||
@@ -1229,13 +1287,13 @@ The following functions compose the parsing and validation API:
|
||||
|
||||
The first argument of all unpack functions is ``json_t *root``
|
||||
instead of ``const json_t *root``, because the use of ``O`` format
|
||||
character causes the reference count of ``root``, or some value
|
||||
specifier causes the reference count of ``root``, or some value
|
||||
reachable from ``root``, to be increased. Furthermore, the ``o``
|
||||
format character may be used to extract a value as-is, which allows
|
||||
format specifier may be used to extract a value as-is, which allows
|
||||
modifying the structure or contents of a value reachable from
|
||||
``root``.
|
||||
|
||||
If the ``O`` and ``o`` format characters are not used, it's
|
||||
If the ``O`` and ``o`` format specifiers are not used, it's
|
||||
perfectly safe to cast a ``const json_t *`` variable to plain
|
||||
``json_t *`` when used with these functions.
|
||||
|
||||
@@ -1244,7 +1302,7 @@ The following unpacking flags are available:
|
||||
``JSON_STRICT``
|
||||
Enable the extra validation step checking that all object and
|
||||
array items are unpacked. This is equivalent to appending the
|
||||
format character ``!`` to the end of every array and object in the
|
||||
format specifier ``!`` to the end of every array and object in the
|
||||
format string.
|
||||
|
||||
``JSON_VALIDATE_ONLY``
|
||||
@@ -1343,7 +1401,7 @@ copied in a recursive fashion.
|
||||
|
||||
Returns a shallow copy of *value*, or *NULL* on error.
|
||||
|
||||
.. function:: json_t *json_deep_copy(json_t *value)
|
||||
.. function:: json_t *json_deep_copy(const json_t *value)
|
||||
|
||||
.. refcounting:: new
|
||||
|
||||
@@ -1380,7 +1438,12 @@ behavior is needed.
|
||||
Jansson's API functions to ensure that all memory operations use
|
||||
the same functions.
|
||||
|
||||
Examples:
|
||||
**Examples:**
|
||||
|
||||
Circumvent problems with different CRT heaps on Windows by using
|
||||
application's :func:`malloc()` and :func:`free()`::
|
||||
|
||||
json_set_alloc_funcs(malloc, free);
|
||||
|
||||
Use the `Boehm's conservative garbage collector`_ for memory
|
||||
operations::
|
||||
|
||||
@@ -41,14 +41,14 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Jansson'
|
||||
copyright = u'2009-2012, Petri Lehtinen'
|
||||
copyright = u'2009-2013, Petri Lehtinen'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '2.4'
|
||||
version = '2.5'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = version
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ strings.
|
||||
Numbers
|
||||
=======
|
||||
|
||||
.. _real-vs-integer:
|
||||
|
||||
Real vs. Integer
|
||||
----------------
|
||||
|
||||
@@ -51,7 +53,8 @@ A JSON number is considered to be a real number if its lexical
|
||||
representation includes one of ``e``, ``E``, or ``.``; regardless if
|
||||
its actual numeric value is a true integer (e.g., all of ``1E6``,
|
||||
``3.0``, ``400E-2``, and ``3.14E3`` are mathematical integers, but
|
||||
will be treated as real values).
|
||||
will be treated as real values). With the ``JSON_DECODE_INT_AS_REAL``
|
||||
decoder flag set all numbers are interpreted as real.
|
||||
|
||||
All other JSON numbers are considered integers.
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
<description of the json_object function>
|
||||
|
||||
:copyright: Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
:copyright: Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
:license: MIT, see LICENSE for details.
|
||||
"""
|
||||
|
||||
|
||||
@@ -54,9 +54,120 @@ used as described above.
|
||||
.. _libtool: http://www.gnu.org/software/libtool/
|
||||
|
||||
|
||||
.. _build-cmake:
|
||||
|
||||
CMake (various platforms, including Windows)
|
||||
--------------------------------------------
|
||||
|
||||
Jansson can be built using CMake_. Create a build directory for an
|
||||
out-of-tree build, change to that directory, and run ``cmake`` (or ``ccmake``,
|
||||
``cmake-gui``, or similar) to configure the project.
|
||||
|
||||
See the examples below for more detailed information.
|
||||
|
||||
.. note:: In the below examples ``..`` is used as an argument for ``cmake``.
|
||||
This is simply the path to the jansson project root directory.
|
||||
In the example it is assumed you've created a sub-directory ``build``
|
||||
and are using that. You could use any path you want.
|
||||
|
||||
.. _build-cmake-unix:
|
||||
|
||||
Unix (Make files)
|
||||
^^^^^^^^^^^^^^^^^
|
||||
Generating make files on unix:
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
bunzip2 -c jansson-|release|.tar.bz2 | tar xf -
|
||||
cd jansson-|release|
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. # or `ccmake ..` for a GUI.
|
||||
|
||||
Then to build::
|
||||
|
||||
make
|
||||
make check
|
||||
make install
|
||||
|
||||
Windows (Visual Studio)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Creating Visual Studio project files from the command line:
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
<unpack>
|
||||
cd jansson-|release|
|
||||
|
||||
md build
|
||||
cd build
|
||||
cmake -G "Visual Studio 10" ..
|
||||
|
||||
You will now have a *Visual Studio Solution* in your build directory.
|
||||
To run the unit tests build the ``RUN_TESTS`` project.
|
||||
|
||||
If you prefer a GUI the ``cmake`` line in the above example can
|
||||
be replaced with::
|
||||
|
||||
cmake-gui ..
|
||||
|
||||
For command line help (including a list of available generators)
|
||||
for CMake_ simply run::
|
||||
|
||||
cmake
|
||||
|
||||
To list available CMake_ settings (and what they are currently set to)
|
||||
for the project, run::
|
||||
|
||||
cmake -LH ..
|
||||
|
||||
Mac OSX (Xcode)
|
||||
^^^^^^^^^^^^^^^
|
||||
If you prefer using Xcode instead of make files on OSX,
|
||||
do the following. (Use the same steps as
|
||||
for :ref:`Unix <build-cmake-unix>`)::
|
||||
|
||||
...
|
||||
cmake -G "Xcode" ..
|
||||
|
||||
Additional CMake settings
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Shared library
|
||||
""""""""""""""
|
||||
By default the CMake_ project will generate build files for building the
|
||||
static library. To build the shared version use::
|
||||
|
||||
...
|
||||
cmake -DBUILD_SHARED=1 ..
|
||||
|
||||
Changing install directory (same as autoconf --prefix)
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
Just as with the autoconf_ project you can change the destination directory
|
||||
for ``make install``. The equivalent for autoconfs ``./configure --prefix``
|
||||
in CMake_ is::
|
||||
|
||||
...
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=/some/other/path ..
|
||||
make install
|
||||
|
||||
.. _CMake: http://www.cmake.org
|
||||
|
||||
Android
|
||||
-------
|
||||
|
||||
Jansson can be built for Android platforms. Android.mk is in the
|
||||
source root directory. The configuration header file is located in the
|
||||
``android`` directory in the source distribution.
|
||||
|
||||
|
||||
Windows
|
||||
-------
|
||||
|
||||
**This method is deprecated**. Using :ref:`CMake <build-cmake>` is now
|
||||
preferred.
|
||||
|
||||
Jansson can be built with Visual Studio 2010 (and probably newer
|
||||
versions, too). The solution and project files are in the
|
||||
``win32/vs2010/`` directory in the source distribution.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -51,15 +51,19 @@ static size_t write_response(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
|
||||
static char *request(const char *url)
|
||||
{
|
||||
CURL *curl;
|
||||
CURL *curl = NULL;
|
||||
CURLcode status;
|
||||
char *data;
|
||||
char *data = NULL;
|
||||
long code;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl = curl_easy_init();
|
||||
if(!curl)
|
||||
goto error;
|
||||
|
||||
data = malloc(BUFFER_SIZE);
|
||||
if(!curl || !data)
|
||||
return NULL;
|
||||
if(!data)
|
||||
goto error;
|
||||
|
||||
struct write_result write_result = {
|
||||
.data = data,
|
||||
@@ -75,14 +79,14 @@ static char *request(const char *url)
|
||||
{
|
||||
fprintf(stderr, "error: unable to request data from %s:\n", url);
|
||||
fprintf(stderr, "%s\n", curl_easy_strerror(status));
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
|
||||
if(code != 200)
|
||||
{
|
||||
fprintf(stderr, "error: server responded with code %ld\n", code);
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
@@ -92,6 +96,14 @@ static char *request(const char *url)
|
||||
data[write_result.pos] = '\0';
|
||||
|
||||
return data;
|
||||
|
||||
error:
|
||||
if(data)
|
||||
free(data);
|
||||
if(curl)
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@@ -128,6 +140,7 @@ int main(int argc, char *argv[])
|
||||
if(!json_is_array(root))
|
||||
{
|
||||
fprintf(stderr, "error: root is not an array\n");
|
||||
json_decref(root);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -139,28 +152,31 @@ int main(int argc, char *argv[])
|
||||
data = json_array_get(root, i);
|
||||
if(!json_is_object(data))
|
||||
{
|
||||
fprintf(stderr, "error: commit data %d is not an object\n", i + 1);
|
||||
fprintf(stderr, "error: commit data %d is not an object\n", (int)(i + 1));
|
||||
json_decref(root);
|
||||
return 1;
|
||||
}
|
||||
|
||||
sha = json_object_get(data, "sha");
|
||||
if(!json_is_string(sha))
|
||||
{
|
||||
fprintf(stderr, "error: commit %d: sha is not a string\n", i + 1);
|
||||
fprintf(stderr, "error: commit %d: sha is not a string\n", (int)(i + 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
commit = json_object_get(data, "commit");
|
||||
if(!json_is_object(commit))
|
||||
{
|
||||
fprintf(stderr, "error: commit %d: commit is not an object\n", i + 1);
|
||||
fprintf(stderr, "error: commit %d: commit is not an object\n", (int)(i + 1));
|
||||
json_decref(root);
|
||||
return 1;
|
||||
}
|
||||
|
||||
message = json_object_get(commit, "message");
|
||||
if(!json_is_string(message))
|
||||
{
|
||||
fprintf(stderr, "error: commit %d: message is not a string\n", i + 1);
|
||||
fprintf(stderr, "error: commit %d: message is not a string\n", (int)(i + 1));
|
||||
json_decref(root);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -178,6 +178,7 @@ We check that the returned value really is an array::
|
||||
if(!json_is_array(root))
|
||||
{
|
||||
fprintf(stderr, "error: root is not an array\n");
|
||||
json_decref(root);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -192,6 +193,7 @@ Then we proceed to loop over all the commits in the array::
|
||||
if(!json_is_object(data))
|
||||
{
|
||||
fprintf(stderr, "error: commit data %d is not an object\n", i + 1);
|
||||
json_decref(root);
|
||||
return 1;
|
||||
}
|
||||
...
|
||||
@@ -209,6 +211,7 @@ object. We also do proper type checks::
|
||||
if(!json_is_string(sha))
|
||||
{
|
||||
fprintf(stderr, "error: commit %d: sha is not a string\n", i + 1);
|
||||
json_decref(root);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -216,6 +219,7 @@ object. We also do proper type checks::
|
||||
if(!json_is_object(commit))
|
||||
{
|
||||
fprintf(stderr, "error: commit %d: commit is not an object\n", i + 1);
|
||||
json_decref(root);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -223,6 +227,7 @@ object. We also do proper type checks::
|
||||
if(!json_is_string(message))
|
||||
{
|
||||
fprintf(stderr, "error: commit %d: message is not a string\n", i + 1);
|
||||
json_decref(root);
|
||||
return 1;
|
||||
}
|
||||
...
|
||||
|
||||
70
release.sh
Executable file
70
release.sh
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Use this script to easily make releases of Jansson. It configures
|
||||
# the source tree, and builds and signs all tarballs.
|
||||
|
||||
die() {
|
||||
echo $1 >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
confirm() {
|
||||
local answer
|
||||
read -p "$1 [yN]: " answer
|
||||
[ "$answer" = "Y" -o "$answer" = "y" ] || exit 0
|
||||
}
|
||||
|
||||
set -e
|
||||
[ -f configure.ac ] || die "Must be run at project root directory"
|
||||
|
||||
# Determine version
|
||||
v=$(grep AC_INIT configure.ac | sed -r 's/.*, \[(.+?)\],.*/\1/')
|
||||
[ -n "$v" ] || die "Unable to determine version"
|
||||
confirm "Version is $v, proceed?"
|
||||
|
||||
# Sanity checks
|
||||
vi=$(grep version-info src/Makefile.am | sed 's/^[ \t]*//g' | cut -d" " -f2)
|
||||
confirm "Libtool version-info is $vi, proceed?"
|
||||
|
||||
r=$(grep 'Released ' CHANGES | head -n 1)
|
||||
confirm "Last CHANGES entry says \"$r\", proceed??"
|
||||
|
||||
dv=$(grep ^version doc/conf.py | sed -r "s/.*'(.*)'.*/\1/")
|
||||
if [ "$dv" != "$v" ]; then
|
||||
die "Documentation version ($dv) doesn't match library version"
|
||||
fi
|
||||
|
||||
[ -f Makefile ] && make distclean || true
|
||||
rm -f jansson-$v.tar.*
|
||||
rm -rf jansson-$v-doc
|
||||
rm -f jansson-$v-doc.tar.*
|
||||
|
||||
autoreconf -fi
|
||||
./configure
|
||||
|
||||
# Run tests and make gz source tarball
|
||||
: ${VALGRIND:=1}
|
||||
export VALGRIND
|
||||
make distcheck
|
||||
|
||||
# Make bzip2 source tarball
|
||||
make dist-bzip2
|
||||
|
||||
# Sign source tarballs
|
||||
for s in gz bz2; do
|
||||
gpg --detach-sign --armor jansson-$v.tar.$s
|
||||
done
|
||||
|
||||
# Build documentation
|
||||
make html
|
||||
mv doc/_build/html jansson-$v-doc
|
||||
|
||||
# Make and sign documentation tarballs
|
||||
for s in gz bz2; do
|
||||
[ $s = gz ] && compress=gzip
|
||||
[ $s = bz2 ] && compress=bzip2
|
||||
tar cf - jansson-$v-doc | $compress -9 -c > jansson-$v-doc.tar.$s
|
||||
gpg --detach-sign --armor jansson-$v-doc.tar.$s
|
||||
done
|
||||
|
||||
echo "All done"
|
||||
@@ -21,9 +21,4 @@ libjansson_la_SOURCES = \
|
||||
libjansson_la_LDFLAGS = \
|
||||
-no-undefined \
|
||||
-export-symbols-regex '^json_' \
|
||||
-version-info 8:0:4
|
||||
|
||||
if GCC
|
||||
# These flags are gcc specific
|
||||
AM_CFLAGS = -Wall -Wextra -Wdeclaration-after-statement -Werror
|
||||
endif
|
||||
-version-info 9:0:5
|
||||
|
||||
10
src/dump.c
10
src/dump.c
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -38,7 +41,7 @@ static int dump_to_file(const char *buffer, size_t size, void *data)
|
||||
}
|
||||
|
||||
/* 32 spaces (the maximum indentation size) */
|
||||
static char whitespace[] = " ";
|
||||
static const char whitespace[] = " ";
|
||||
|
||||
static int dump_indent(size_t flags, int depth, int space, json_dump_callback_t dump, void *data)
|
||||
{
|
||||
@@ -171,6 +174,9 @@ static int object_key_compare_serials(const void *key1, const void *key2)
|
||||
static int do_dump(const json_t *json, size_t flags, int depth,
|
||||
json_dump_callback_t dump, void *data)
|
||||
{
|
||||
if(!json)
|
||||
return -1;
|
||||
|
||||
switch(json_typeof(json)) {
|
||||
case JSON_NULL:
|
||||
return dump("null", 4, data);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -74,7 +74,7 @@ static void insert_to_bucket(hashtable_t *hashtable, bucket_t *bucket,
|
||||
}
|
||||
}
|
||||
|
||||
static size_t primes[] = {
|
||||
static const size_t primes[] = {
|
||||
5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
|
||||
49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469,
|
||||
12582917, 25165843, 50331653, 100663319, 201326611, 402653189,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
LIBRARY "jansson"
|
||||
|
||||
EXPORTS
|
||||
json_delete
|
||||
json_true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -21,11 +21,11 @@ extern "C" {
|
||||
/* version */
|
||||
|
||||
#define JANSSON_MAJOR_VERSION 2
|
||||
#define JANSSON_MINOR_VERSION 4
|
||||
#define JANSSON_MINOR_VERSION 5
|
||||
#define JANSSON_MICRO_VERSION 0
|
||||
|
||||
/* Micro version is omitted if it's 0 */
|
||||
#define JANSSON_VERSION "2.4"
|
||||
#define JANSSON_VERSION "2.5"
|
||||
|
||||
/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this
|
||||
for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */
|
||||
@@ -47,11 +47,12 @@ typedef enum {
|
||||
JSON_NULL
|
||||
} json_type;
|
||||
|
||||
typedef struct {
|
||||
typedef struct json_t {
|
||||
json_type type;
|
||||
size_t refcount;
|
||||
} json_t;
|
||||
|
||||
#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */
|
||||
#if JSON_INTEGER_IS_LONG_LONG
|
||||
#ifdef _WIN32
|
||||
#define JSON_INTEGER_FORMAT "I64d"
|
||||
@@ -63,6 +64,7 @@ typedef long long json_int_t;
|
||||
#define JSON_INTEGER_FORMAT "ld"
|
||||
typedef long json_int_t;
|
||||
#endif /* JSON_INTEGER_IS_LONG_LONG */
|
||||
#endif
|
||||
|
||||
#define json_typeof(json) ((json)->type)
|
||||
#define json_is_object(json) (json && json_typeof(json) == JSON_OBJECT)
|
||||
@@ -146,6 +148,11 @@ int json_object_iter_set_new(json_t *object, void *iter, json_t *value);
|
||||
key && (value = json_object_iter_value(json_object_key_to_iter(key))); \
|
||||
key = json_object_iter_key(json_object_iter_next(object, json_object_key_to_iter(key))))
|
||||
|
||||
#define json_array_foreach(array, index, value) \
|
||||
for(index = 0; \
|
||||
index < json_array_size(array) && (value = json_array_get(array, index)); \
|
||||
index++)
|
||||
|
||||
static JSON_INLINE
|
||||
int json_object_set(json_t *object, const char *key, json_t *value)
|
||||
{
|
||||
@@ -174,9 +181,9 @@ int json_array_clear(json_t *array);
|
||||
int json_array_extend(json_t *array, json_t *other);
|
||||
|
||||
static JSON_INLINE
|
||||
int json_array_set(json_t *array, size_t index, json_t *value)
|
||||
int json_array_set(json_t *array, size_t ind, json_t *value)
|
||||
{
|
||||
return json_array_set_new(array, index, json_incref(value));
|
||||
return json_array_set_new(array, ind, json_incref(value));
|
||||
}
|
||||
|
||||
static JSON_INLINE
|
||||
@@ -186,9 +193,9 @@ int json_array_append(json_t *array, json_t *value)
|
||||
}
|
||||
|
||||
static JSON_INLINE
|
||||
int json_array_insert(json_t *array, size_t index, json_t *value)
|
||||
int json_array_insert(json_t *array, size_t ind, json_t *value)
|
||||
{
|
||||
return json_array_insert_new(array, index, json_incref(value));
|
||||
return json_array_insert_new(array, ind, json_incref(value));
|
||||
}
|
||||
|
||||
const char *json_string_value(const json_t *string);
|
||||
@@ -224,14 +231,15 @@ int json_equal(json_t *value1, json_t *value2);
|
||||
/* copying */
|
||||
|
||||
json_t *json_copy(json_t *value);
|
||||
json_t *json_deep_copy(json_t *value);
|
||||
json_t *json_deep_copy(const json_t *value);
|
||||
|
||||
|
||||
/* decoding */
|
||||
|
||||
#define JSON_REJECT_DUPLICATES 0x1
|
||||
#define JSON_DISABLE_EOF_CHECK 0x2
|
||||
#define JSON_DECODE_ANY 0x4
|
||||
#define JSON_REJECT_DUPLICATES 0x1
|
||||
#define JSON_DISABLE_EOF_CHECK 0x2
|
||||
#define JSON_DECODE_ANY 0x4
|
||||
#define JSON_DECODE_INT_AS_REAL 0x8
|
||||
|
||||
typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2010-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -81,6 +81,7 @@ int jsonp_dtostr(char *buffer, size_t size, double value);
|
||||
/* Wrappers for custom memory functions */
|
||||
void* jsonp_malloc(size_t size);
|
||||
void jsonp_free(void *ptr);
|
||||
char *jsonp_strndup(const char *str, size_t length);
|
||||
char *jsonp_strdup(const char *str);
|
||||
|
||||
/* Windows compatibility */
|
||||
|
||||
33
src/load.c
33
src/load.c
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
@@ -37,7 +40,7 @@
|
||||
#define l_isalpha(c) (l_isupper(c) || l_islower(c))
|
||||
#define l_isdigit(c) ('0' <= (c) && (c) <= '9')
|
||||
#define l_isxdigit(c) \
|
||||
(l_isdigit(c) || 'A' <= (c) || (c) <= 'F' || 'a' <= (c) || (c) <= 'f')
|
||||
(l_isdigit(c) || ('A' <= (c) && (c) <= 'F') || ('a' <= (c) && (c) <= 'f'))
|
||||
|
||||
/* Read one byte from stream, convert to unsigned char, then int, and
|
||||
return. return EOF on end of file. This corresponds to the
|
||||
@@ -250,9 +253,18 @@ static void lex_unget(lex_t *lex, int c)
|
||||
static void lex_unget_unsave(lex_t *lex, int c)
|
||||
{
|
||||
if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) {
|
||||
/* Since we treat warnings as errors, when assertions are turned
|
||||
* off the "d" variable would be set but never used. Which is
|
||||
* treated as an error by GCC.
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
char d;
|
||||
#endif
|
||||
stream_unget(&lex->stream, c);
|
||||
d = strbuffer_pop(&lex->saved_text);
|
||||
#ifndef NDEBUG
|
||||
d =
|
||||
#endif
|
||||
strbuffer_pop(&lex->saved_text);
|
||||
assert(c == d);
|
||||
}
|
||||
}
|
||||
@@ -446,8 +458,9 @@ out:
|
||||
jsonp_free(lex->value.string);
|
||||
}
|
||||
|
||||
#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */
|
||||
#if JSON_INTEGER_IS_LONG_LONG
|
||||
#ifdef _MSC_VER // Microsoft Visual Studio
|
||||
#ifdef _MSC_VER /* Microsoft Visual Studio */
|
||||
#define json_strtoint _strtoi64
|
||||
#else
|
||||
#define json_strtoint strtoll
|
||||
@@ -455,6 +468,7 @@ out:
|
||||
#else
|
||||
#define json_strtoint strtol
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int lex_scan_number(lex_t *lex, int c, json_error_t *error)
|
||||
{
|
||||
@@ -770,6 +784,7 @@ error:
|
||||
static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
|
||||
{
|
||||
json_t *json;
|
||||
double value;
|
||||
|
||||
switch(lex->token) {
|
||||
case TOKEN_STRING: {
|
||||
@@ -778,7 +793,15 @@ static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
|
||||
}
|
||||
|
||||
case TOKEN_INTEGER: {
|
||||
json = json_integer(lex->value.integer);
|
||||
if (flags & JSON_DECODE_INT_AS_REAL) {
|
||||
if(jsonp_strtod(&lex->saved_text, &value)) {
|
||||
error_set(error, lex, "real number overflow");
|
||||
return NULL;
|
||||
}
|
||||
json = json_real(value);
|
||||
} else {
|
||||
json = json_integer(lex->value.integer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
11
src/memory.c
11
src/memory.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2011-2012 Basile Starynkevitch <basile@starynkevitch.net>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify it
|
||||
@@ -35,12 +35,17 @@ void jsonp_free(void *ptr)
|
||||
char *jsonp_strdup(const char *str)
|
||||
{
|
||||
char *new_str;
|
||||
size_t len;
|
||||
|
||||
new_str = jsonp_malloc(strlen(str) + 1);
|
||||
len = strlen(str);
|
||||
if(len == (size_t)-1)
|
||||
return NULL;
|
||||
|
||||
new_str = jsonp_malloc(len + 1);
|
||||
if(!new_str)
|
||||
return NULL;
|
||||
|
||||
strcpy(new_str, str);
|
||||
memcpy(new_str, str, len + 1);
|
||||
return new_str;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2011-2012 Graeme Smecher <graeme.smecher@mail.mcgill.ca>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
@@ -11,17 +11,29 @@
|
||||
#include "jansson_private.h"
|
||||
#include "utf.h"
|
||||
|
||||
typedef struct {
|
||||
int line;
|
||||
int column;
|
||||
size_t pos;
|
||||
char token;
|
||||
} token_t;
|
||||
|
||||
typedef struct {
|
||||
const char *start;
|
||||
const char *fmt;
|
||||
char token;
|
||||
token_t prev_token;
|
||||
token_t token;
|
||||
token_t next_token;
|
||||
json_error_t *error;
|
||||
size_t flags;
|
||||
int line;
|
||||
int column;
|
||||
size_t pos;
|
||||
} scanner_t;
|
||||
|
||||
static const char *type_names[] = {
|
||||
#define token(scanner) ((scanner)->token.token)
|
||||
|
||||
static const char * const type_names[] = {
|
||||
"object",
|
||||
"array",
|
||||
"string",
|
||||
@@ -34,7 +46,7 @@ static const char *type_names[] = {
|
||||
|
||||
#define type_name(x) type_names[json_typeof(x)]
|
||||
|
||||
static const char *unpack_value_starters = "{[siIbfFOon";
|
||||
static const char unpack_value_starters[] = "{[siIbfFOon";
|
||||
|
||||
|
||||
static void scanner_init(scanner_t *s, json_error_t *error,
|
||||
@@ -43,14 +55,28 @@ static void scanner_init(scanner_t *s, json_error_t *error,
|
||||
s->error = error;
|
||||
s->flags = flags;
|
||||
s->fmt = s->start = fmt;
|
||||
memset(&s->prev_token, 0, sizeof(token_t));
|
||||
memset(&s->token, 0, sizeof(token_t));
|
||||
memset(&s->next_token, 0, sizeof(token_t));
|
||||
s->line = 1;
|
||||
s->column = 0;
|
||||
s->pos = 0;
|
||||
}
|
||||
|
||||
static void next_token(scanner_t *s)
|
||||
{
|
||||
const char *t = s->fmt;
|
||||
const char *t;
|
||||
s->prev_token = s->token;
|
||||
|
||||
if(s->next_token.line) {
|
||||
s->token = s->next_token;
|
||||
s->next_token.line = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
t = s->fmt;
|
||||
s->column++;
|
||||
s->pos++;
|
||||
|
||||
/* skip space and ignored chars */
|
||||
while(*t == ' ' || *t == '\t' || *t == '\n' || *t == ',' || *t == ':') {
|
||||
@@ -61,23 +87,32 @@ static void next_token(scanner_t *s)
|
||||
else
|
||||
s->column++;
|
||||
|
||||
s->pos++;
|
||||
t++;
|
||||
}
|
||||
|
||||
s->token = *t;
|
||||
s->token.token = *t;
|
||||
s->token.line = s->line;
|
||||
s->token.column = s->column;
|
||||
s->token.pos = s->pos;
|
||||
|
||||
t++;
|
||||
s->fmt = t;
|
||||
}
|
||||
|
||||
static void prev_token(scanner_t *s)
|
||||
{
|
||||
s->next_token = s->token;
|
||||
s->token = s->prev_token;
|
||||
}
|
||||
|
||||
static void set_error(scanner_t *s, const char *source, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
size_t pos;
|
||||
va_start(ap, fmt);
|
||||
|
||||
pos = (size_t)(s->fmt - s->start);
|
||||
jsonp_error_vset(s->error, s->line, s->column, pos, fmt, ap);
|
||||
jsonp_error_vset(s->error, s->token.line, s->token.column, s->token.pos,
|
||||
fmt, ap);
|
||||
|
||||
jsonp_error_set_source(s->error, source);
|
||||
|
||||
@@ -86,35 +121,107 @@ static void set_error(scanner_t *s, const char *source, const char *fmt, ...)
|
||||
|
||||
static json_t *pack(scanner_t *s, va_list *ap);
|
||||
|
||||
|
||||
/* ours will be set to 1 if jsonp_free() must be called for the result
|
||||
afterwards */
|
||||
static char *read_string(scanner_t *s, va_list *ap,
|
||||
const char *purpose, int *ours)
|
||||
{
|
||||
char t;
|
||||
strbuffer_t strbuff;
|
||||
const char *str;
|
||||
size_t length;
|
||||
char *result;
|
||||
|
||||
next_token(s);
|
||||
t = token(s);
|
||||
prev_token(s);
|
||||
|
||||
if(t != '#' && t != '+') {
|
||||
/* Optimize the simple case */
|
||||
str = va_arg(*ap, const char *);
|
||||
|
||||
if(!str) {
|
||||
set_error(s, "<args>", "NULL string argument");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!utf8_check_string(str, -1)) {
|
||||
set_error(s, "<args>", "Invalid UTF-8 %s", purpose);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*ours = 0;
|
||||
return (char *)str;
|
||||
}
|
||||
|
||||
strbuffer_init(&strbuff);
|
||||
|
||||
while(1) {
|
||||
str = va_arg(*ap, const char *);
|
||||
if(!str) {
|
||||
set_error(s, "<args>", "NULL string argument");
|
||||
strbuffer_close(&strbuff);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
next_token(s);
|
||||
|
||||
if(token(s) == '#') {
|
||||
length = va_arg(*ap, int);
|
||||
}
|
||||
else {
|
||||
prev_token(s);
|
||||
length = strlen(str);
|
||||
}
|
||||
|
||||
if(strbuffer_append_bytes(&strbuff, str, length) == -1) {
|
||||
set_error(s, "<internal>", "Out of memory");
|
||||
strbuffer_close(&strbuff);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
next_token(s);
|
||||
if(token(s) != '+') {
|
||||
prev_token(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result = strbuffer_steal_value(&strbuff);
|
||||
|
||||
if(!utf8_check_string(result, -1)) {
|
||||
set_error(s, "<args>", "Invalid UTF-8 %s", purpose);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*ours = 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
static json_t *pack_object(scanner_t *s, va_list *ap)
|
||||
{
|
||||
json_t *object = json_object();
|
||||
next_token(s);
|
||||
|
||||
while(s->token != '}') {
|
||||
const char *key;
|
||||
while(token(s) != '}') {
|
||||
char *key;
|
||||
int ours;
|
||||
json_t *value;
|
||||
|
||||
if(!s->token) {
|
||||
if(!token(s)) {
|
||||
set_error(s, "<format>", "Unexpected end of format string");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(s->token != 's') {
|
||||
set_error(s, "<format>", "Expected format 's', got '%c'", s->token);
|
||||
if(token(s) != 's') {
|
||||
set_error(s, "<format>", "Expected format 's', got '%c'", token(s));
|
||||
goto error;
|
||||
}
|
||||
|
||||
key = va_arg(*ap, const char *);
|
||||
if(!key) {
|
||||
set_error(s, "<args>", "NULL object key");
|
||||
key = read_string(s, ap, "object key", &ours);
|
||||
if(!key)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(!utf8_check_string(key, -1)) {
|
||||
set_error(s, "<args>", "Invalid UTF-8 in object key");
|
||||
goto error;
|
||||
}
|
||||
|
||||
next_token(s);
|
||||
|
||||
@@ -123,10 +230,16 @@ static json_t *pack_object(scanner_t *s, va_list *ap)
|
||||
goto error;
|
||||
|
||||
if(json_object_set_new_nocheck(object, key, value)) {
|
||||
if(ours)
|
||||
jsonp_free(key);
|
||||
|
||||
set_error(s, "<internal>", "Unable to add key \"%s\"", key);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(ours)
|
||||
jsonp_free(key);
|
||||
|
||||
next_token(s);
|
||||
}
|
||||
|
||||
@@ -142,10 +255,10 @@ static json_t *pack_array(scanner_t *s, va_list *ap)
|
||||
json_t *array = json_array();
|
||||
next_token(s);
|
||||
|
||||
while(s->token != ']') {
|
||||
while(token(s) != ']') {
|
||||
json_t *value;
|
||||
|
||||
if(!s->token) {
|
||||
if(!token(s)) {
|
||||
set_error(s, "<format>", "Unexpected end of format string");
|
||||
goto error;
|
||||
}
|
||||
@@ -170,25 +283,27 @@ error:
|
||||
|
||||
static json_t *pack(scanner_t *s, va_list *ap)
|
||||
{
|
||||
switch(s->token) {
|
||||
switch(token(s)) {
|
||||
case '{':
|
||||
return pack_object(s, ap);
|
||||
|
||||
case '[':
|
||||
return pack_array(s, ap);
|
||||
|
||||
case 's': /* string */
|
||||
{
|
||||
const char *str = va_arg(*ap, const char *);
|
||||
if(!str) {
|
||||
set_error(s, "<args>", "NULL string argument");
|
||||
case 's': { /* string */
|
||||
char *str;
|
||||
int ours;
|
||||
json_t *result;
|
||||
|
||||
str = read_string(s, ap, "string", &ours);
|
||||
if(!str)
|
||||
return NULL;
|
||||
}
|
||||
if(!utf8_check_string(str, -1)) {
|
||||
set_error(s, "<args>", "Invalid UTF-8 string");
|
||||
return NULL;
|
||||
}
|
||||
return json_string_nocheck(str);
|
||||
|
||||
result = json_string_nocheck(str);
|
||||
if(ours)
|
||||
jsonp_free(str);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
case 'n': /* null */
|
||||
@@ -214,7 +329,7 @@ static json_t *pack(scanner_t *s, va_list *ap)
|
||||
|
||||
default:
|
||||
set_error(s, "<format>", "Unexpected format character '%c'",
|
||||
s->token);
|
||||
token(s));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -245,30 +360,30 @@ static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
|
||||
}
|
||||
next_token(s);
|
||||
|
||||
while(s->token != '}') {
|
||||
while(token(s) != '}') {
|
||||
const char *key;
|
||||
json_t *value;
|
||||
int opt = 0;
|
||||
|
||||
if(strict != 0) {
|
||||
set_error(s, "<format>", "Expected '}' after '%c', got '%c'",
|
||||
(strict == 1 ? '!' : '*'), s->token);
|
||||
(strict == 1 ? '!' : '*'), token(s));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(!s->token) {
|
||||
if(!token(s)) {
|
||||
set_error(s, "<format>", "Unexpected end of format string");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(s->token == '!' || s->token == '*') {
|
||||
strict = (s->token == '!' ? 1 : -1);
|
||||
if(token(s) == '!' || token(s) == '*') {
|
||||
strict = (token(s) == '!' ? 1 : -1);
|
||||
next_token(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(s->token != 's') {
|
||||
set_error(s, "<format>", "Expected format 's', got '%c'", s->token);
|
||||
if(token(s) != 's') {
|
||||
set_error(s, "<format>", "Expected format 's', got '%c'", token(s));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -280,7 +395,7 @@ static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
|
||||
|
||||
next_token(s);
|
||||
|
||||
if(s->token == '?') {
|
||||
if(token(s) == '?') {
|
||||
opt = 1;
|
||||
next_token(s);
|
||||
}
|
||||
@@ -331,30 +446,30 @@ static int unpack_array(scanner_t *s, json_t *root, va_list *ap)
|
||||
}
|
||||
next_token(s);
|
||||
|
||||
while(s->token != ']') {
|
||||
while(token(s) != ']') {
|
||||
json_t *value;
|
||||
|
||||
if(strict != 0) {
|
||||
set_error(s, "<format>", "Expected ']' after '%c', got '%c'",
|
||||
(strict == 1 ? '!' : '*'),
|
||||
s->token);
|
||||
token(s));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!s->token) {
|
||||
if(!token(s)) {
|
||||
set_error(s, "<format>", "Unexpected end of format string");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(s->token == '!' || s->token == '*') {
|
||||
strict = (s->token == '!' ? 1 : -1);
|
||||
if(token(s) == '!' || token(s) == '*') {
|
||||
strict = (token(s) == '!' ? 1 : -1);
|
||||
next_token(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!strchr(unpack_value_starters, s->token)) {
|
||||
if(!strchr(unpack_value_starters, token(s))) {
|
||||
set_error(s, "<format>", "Unexpected format character '%c'",
|
||||
s->token);
|
||||
token(s));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -392,7 +507,7 @@ static int unpack_array(scanner_t *s, json_t *root, va_list *ap)
|
||||
|
||||
static int unpack(scanner_t *s, json_t *root, va_list *ap)
|
||||
{
|
||||
switch(s->token)
|
||||
switch(token(s))
|
||||
{
|
||||
case '{':
|
||||
return unpack_object(s, root, ap);
|
||||
@@ -521,7 +636,7 @@ static int unpack(scanner_t *s, json_t *root, va_list *ap)
|
||||
|
||||
default:
|
||||
set_error(s, "<format>", "Unexpected format character '%c'",
|
||||
s->token);
|
||||
token(s));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -551,7 +666,7 @@ json_t *json_vpack_ex(json_error_t *error, size_t flags,
|
||||
return NULL;
|
||||
|
||||
next_token(&s);
|
||||
if(s.token) {
|
||||
if(token(&s)) {
|
||||
json_decref(value);
|
||||
set_error(&s, "<format>", "Garbage after format string");
|
||||
return NULL;
|
||||
@@ -614,7 +729,7 @@ int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags,
|
||||
va_end(ap_copy);
|
||||
|
||||
next_token(&s);
|
||||
if(s.token) {
|
||||
if(token(&s)) {
|
||||
set_error(&s, "<format>", "Garbage after format string");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jansson_private.h"
|
||||
@@ -31,7 +34,9 @@ int strbuffer_init(strbuffer_t *strbuff)
|
||||
|
||||
void strbuffer_close(strbuffer_t *strbuff)
|
||||
{
|
||||
jsonp_free(strbuff->value);
|
||||
if(strbuff->value)
|
||||
jsonp_free(strbuff->value);
|
||||
|
||||
strbuff->size = 0;
|
||||
strbuff->length = 0;
|
||||
strbuff->value = NULL;
|
||||
@@ -51,7 +56,7 @@ const char *strbuffer_value(const strbuffer_t *strbuff)
|
||||
char *strbuffer_steal_value(strbuffer_t *strbuff)
|
||||
{
|
||||
char *result = strbuff->value;
|
||||
strbuffer_init(strbuff);
|
||||
strbuff->value = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -20,6 +20,8 @@ void strbuffer_close(strbuffer_t *strbuff);
|
||||
void strbuffer_clear(strbuffer_t *strbuff);
|
||||
|
||||
const char *strbuffer_value(const strbuffer_t *strbuff);
|
||||
|
||||
/* Steal the value and close the strbuffer */
|
||||
char *strbuffer_steal_value(strbuffer_t *strbuff);
|
||||
|
||||
int strbuffer_append(strbuffer_t *strbuff, const char *string);
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
#include "jansson_private.h"
|
||||
#include "strbuffer.h"
|
||||
|
||||
/* need config.h to get the correct snprintf */
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if JSON_HAVE_LOCALECONV
|
||||
#include <locale.h>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
39
src/value.c
39
src/value.c
@@ -1,11 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
@@ -290,19 +292,27 @@ static json_t *json_object_copy(json_t *object)
|
||||
return result;
|
||||
}
|
||||
|
||||
static json_t *json_object_deep_copy(json_t *object)
|
||||
static json_t *json_object_deep_copy(const json_t *object)
|
||||
{
|
||||
json_t *result;
|
||||
|
||||
const char *key;
|
||||
json_t *value;
|
||||
void *iter;
|
||||
|
||||
result = json_object();
|
||||
if(!result)
|
||||
return NULL;
|
||||
|
||||
json_object_foreach(object, key, value)
|
||||
/* Cannot use json_object_foreach because object has to be cast
|
||||
non-const */
|
||||
iter = json_object_iter((json_t *)object);
|
||||
while(iter) {
|
||||
const char *key;
|
||||
const json_t *value;
|
||||
key = json_object_iter_key(iter);
|
||||
value = json_object_iter_value(iter);
|
||||
|
||||
json_object_set_new_nocheck(result, key, json_deep_copy(value));
|
||||
iter = json_object_iter_next((json_t *)object, iter);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -509,7 +519,10 @@ int json_array_remove(json_t *json, size_t index)
|
||||
|
||||
json_decref(array->table[index]);
|
||||
|
||||
array_move(array, index, index + 1, array->entries - index);
|
||||
/* If we're removing the last element, nothing has to be moved */
|
||||
if(index < array->entries - 1)
|
||||
array_move(array, index, index + 1, array->entries - index - 1);
|
||||
|
||||
array->entries--;
|
||||
|
||||
return 0;
|
||||
@@ -590,7 +603,7 @@ static json_t *json_array_copy(json_t *array)
|
||||
return result;
|
||||
}
|
||||
|
||||
static json_t *json_array_deep_copy(json_t *array)
|
||||
static json_t *json_array_deep_copy(const json_t *array)
|
||||
{
|
||||
json_t *result;
|
||||
size_t i;
|
||||
@@ -682,7 +695,7 @@ static int json_string_equal(json_t *string1, json_t *string2)
|
||||
return strcmp(json_string_value(string1), json_string_value(string2)) == 0;
|
||||
}
|
||||
|
||||
static json_t *json_string_copy(json_t *string)
|
||||
static json_t *json_string_copy(const json_t *string)
|
||||
{
|
||||
return json_string_nocheck(json_string_value(string));
|
||||
}
|
||||
@@ -729,7 +742,7 @@ static int json_integer_equal(json_t *integer1, json_t *integer2)
|
||||
return json_integer_value(integer1) == json_integer_value(integer2);
|
||||
}
|
||||
|
||||
static json_t *json_integer_copy(json_t *integer)
|
||||
static json_t *json_integer_copy(const json_t *integer)
|
||||
{
|
||||
return json_integer(json_integer_value(integer));
|
||||
}
|
||||
@@ -781,7 +794,7 @@ static int json_real_equal(json_t *real1, json_t *real2)
|
||||
return json_real_value(real1) == json_real_value(real2);
|
||||
}
|
||||
|
||||
static json_t *json_real_copy(json_t *real)
|
||||
static json_t *json_real_copy(const json_t *real)
|
||||
{
|
||||
return json_real(json_real_value(real));
|
||||
}
|
||||
@@ -907,7 +920,7 @@ json_t *json_copy(json_t *json)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
json_t *json_deep_copy(json_t *json)
|
||||
json_t *json_deep_copy(const json_t *json)
|
||||
{
|
||||
if(!json)
|
||||
return NULL;
|
||||
@@ -931,7 +944,7 @@ json_t *json_deep_copy(json_t *json)
|
||||
return json_real_copy(json);
|
||||
|
||||
if(json_is_true(json) || json_is_false(json) || json_is_null(json))
|
||||
return json;
|
||||
return (json_t *)json;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
check_PROGRAMS = json_process
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src
|
||||
AM_CFLAGS = -Wall -Werror
|
||||
AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||
LDFLAGS = -static # for speed and Valgrind
|
||||
LDADD = $(top_builddir)/src/libjansson.la
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -15,17 +15,208 @@
|
||||
#include <ctype.h>
|
||||
#include <jansson.h>
|
||||
|
||||
#if HAVE_LOCALE_H
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if _WIN32
|
||||
#include <io.h> /* for _setmode() */
|
||||
#include <fcntl.h> /* for _O_BINARY */
|
||||
|
||||
static const char dir_sep = '\\';
|
||||
#else
|
||||
static const char dir_sep = '/';
|
||||
#endif
|
||||
|
||||
|
||||
struct config {
|
||||
int indent;
|
||||
int compact;
|
||||
int preserve_order;
|
||||
int ensure_ascii;
|
||||
int sort_keys;
|
||||
int strip;
|
||||
int use_env;
|
||||
} conf;
|
||||
|
||||
#define l_isspace(c) ((c) == ' ' || (c) == '\n' || (c) == '\r' || (c) == '\t')
|
||||
|
||||
/* Return a pointer to the first non-whitespace character of str.
|
||||
Modifies str so that all trailing whitespace characters are
|
||||
replaced by '\0'. */
|
||||
static const char *strip(char *str)
|
||||
{
|
||||
size_t length;
|
||||
char *result = str;
|
||||
while (*result && l_isspace(*result))
|
||||
result++;
|
||||
|
||||
length = strlen(result);
|
||||
if (length == 0)
|
||||
return result;
|
||||
|
||||
while (l_isspace(result[length - 1]))
|
||||
result[--length] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static char *loadfile(FILE *file)
|
||||
{
|
||||
long fsize, ret;
|
||||
char *buf;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
fsize = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
buf = malloc(fsize+1);
|
||||
ret = fread(buf, 1, fsize, file);
|
||||
if (ret != fsize)
|
||||
exit(1);
|
||||
buf[fsize] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
static void read_conf(FILE *conffile)
|
||||
{
|
||||
char *buffer, *line, *val;
|
||||
|
||||
buffer = loadfile(conffile);
|
||||
line = strtok(buffer, "\r\n");
|
||||
while (line) {
|
||||
val = strchr(line, '=');
|
||||
if (!val) {
|
||||
printf("invalid configuration line\n");
|
||||
break;
|
||||
}
|
||||
*val++ = '\0';
|
||||
|
||||
if (!strcmp(line, "JSON_INDENT"))
|
||||
conf.indent = atoi(val);
|
||||
if (!strcmp(line, "JSON_COMPACT"))
|
||||
conf.compact = atoi(val);
|
||||
if (!strcmp(line, "JSON_ENSURE_ASCII"))
|
||||
conf.ensure_ascii = atoi(val);
|
||||
if (!strcmp(line, "JSON_PRESERVE_ORDER"))
|
||||
conf.preserve_order = atoi(val);
|
||||
if (!strcmp(line, "JSON_SORT_KEYS"))
|
||||
conf.sort_keys = atoi(val);
|
||||
if (!strcmp(line, "STRIP"))
|
||||
conf.strip = atoi(val);
|
||||
|
||||
line = strtok(NULL, "\r\n");
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
static int cmpfile(const char *str, const char *path, const char *fname)
|
||||
{
|
||||
char filename[1024], *buffer;
|
||||
int ret;
|
||||
FILE *file;
|
||||
|
||||
sprintf(filename, "%s%c%s", path, dir_sep, fname);
|
||||
file = fopen(filename, "rb");
|
||||
if (!file) {
|
||||
if (conf.strip)
|
||||
strcat(filename, ".strip");
|
||||
else
|
||||
strcat(filename, ".normal");
|
||||
file = fopen(filename, "rb");
|
||||
}
|
||||
if (!file) {
|
||||
printf("Error: test result file could not be opened.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
buffer = loadfile(file);
|
||||
if (strcmp(buffer, str) != 0)
|
||||
ret = 1;
|
||||
else
|
||||
ret = 0;
|
||||
free(buffer);
|
||||
fclose(file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int use_conf(char *test_path)
|
||||
{
|
||||
int ret;
|
||||
size_t flags = 0;
|
||||
char filename[1024], errstr[1024];
|
||||
char *buffer;
|
||||
FILE *infile, *conffile;
|
||||
json_t *json;
|
||||
json_error_t error;
|
||||
|
||||
sprintf(filename, "%s%cinput", test_path, dir_sep);
|
||||
if (!(infile = fopen(filename, "rb"))) {
|
||||
fprintf(stderr, "Could not open \"%s\"\n", filename);
|
||||
return 2;
|
||||
}
|
||||
|
||||
sprintf(filename, "%s%cenv", test_path, dir_sep);
|
||||
conffile = fopen(filename, "rb");
|
||||
if (conffile) {
|
||||
read_conf(conffile);
|
||||
fclose(conffile);
|
||||
}
|
||||
|
||||
if (conf.indent < 0 || conf.indent > 255) {
|
||||
fprintf(stderr, "invalid value for JSON_INDENT: %d\n", conf.indent);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (conf.indent)
|
||||
flags |= JSON_INDENT(conf.indent);
|
||||
|
||||
if (conf.compact)
|
||||
flags |= JSON_COMPACT;
|
||||
|
||||
if (conf.ensure_ascii)
|
||||
flags |= JSON_ENSURE_ASCII;
|
||||
|
||||
if (conf.preserve_order)
|
||||
flags |= JSON_PRESERVE_ORDER;
|
||||
|
||||
if (conf.sort_keys)
|
||||
flags |= JSON_SORT_KEYS;
|
||||
|
||||
if (conf.strip) {
|
||||
/* Load to memory, strip leading and trailing whitespace */
|
||||
buffer = loadfile(infile);
|
||||
json = json_loads(strip(buffer), 0, &error);
|
||||
free(buffer);
|
||||
}
|
||||
else
|
||||
json = json_loadf(infile, 0, &error);
|
||||
|
||||
fclose(infile);
|
||||
|
||||
if (!json) {
|
||||
sprintf(errstr, "%d %d %d\n%s\n",
|
||||
error.line, error.column, error.position,
|
||||
error.text);
|
||||
|
||||
ret = cmpfile(errstr, test_path, "error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
buffer = json_dumps(json, flags);
|
||||
ret = cmpfile(buffer, test_path, "output");
|
||||
free(buffer);
|
||||
json_decref(json);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int getenv_int(const char *name)
|
||||
{
|
||||
char *value, *end;
|
||||
@@ -42,49 +233,19 @@ static int getenv_int(const char *name)
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
/* Return a pointer to the first non-whitespace character of str.
|
||||
Modifies str so that all trailing whitespace characters are
|
||||
replaced by '\0'. */
|
||||
static const char *strip(char *str)
|
||||
int use_env()
|
||||
{
|
||||
size_t length;
|
||||
char *result = str;
|
||||
while(*result && l_isspace(*result))
|
||||
result++;
|
||||
|
||||
length = strlen(result);
|
||||
if(length == 0)
|
||||
return result;
|
||||
|
||||
while(l_isspace(result[length - 1]))
|
||||
result[--length] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int indent = 0;
|
||||
int indent;
|
||||
size_t flags = 0;
|
||||
|
||||
json_t *json;
|
||||
json_error_t error;
|
||||
|
||||
#if HAVE_SETLOCALE
|
||||
setlocale(LC_ALL, "");
|
||||
#endif
|
||||
|
||||
if(argc != 1) {
|
||||
fprintf(stderr, "usage: %s\n", argv[0]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _WIN32
|
||||
/* On Windows, set stdout and stderr to binary mode to avoid
|
||||
outputting DOS line terminators */
|
||||
_setmode(_fileno(stdout), _O_BINARY);
|
||||
_setmode(_fileno(stderr), _O_BINARY);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
indent = getenv_int("JSON_INDENT");
|
||||
if(indent < 0 || indent > 255) {
|
||||
@@ -105,7 +266,7 @@ int main(int argc, char *argv[])
|
||||
flags |= JSON_PRESERVE_ORDER;
|
||||
|
||||
if(getenv_int("JSON_SORT_KEYS"))
|
||||
flags |= JSON_SORT_KEYS;
|
||||
flags |= JSON_SORT_KEYS;
|
||||
|
||||
if(getenv_int("STRIP")) {
|
||||
/* Load to memory, strip leading and trailing whitespace */
|
||||
@@ -113,7 +274,7 @@ int main(int argc, char *argv[])
|
||||
char *buffer = NULL;
|
||||
|
||||
while(1) {
|
||||
int count;
|
||||
size_t count;
|
||||
|
||||
size = (size == 0 ? 128 : size * 2);
|
||||
buffer = realloc(buffer, size);
|
||||
@@ -138,8 +299,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
if(!json) {
|
||||
fprintf(stderr, "%d %d %d\n%s\n",
|
||||
error.line, error.column, error.position,
|
||||
error.text);
|
||||
error.line, error.column,
|
||||
error.position, error.text);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -148,3 +309,41 @@ int main(int argc, char *argv[])
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
char *test_path = NULL;
|
||||
|
||||
#ifdef HAVE_SETLOCALE
|
||||
setlocale(LC_ALL, "");
|
||||
#endif
|
||||
|
||||
if (argc < 2) {
|
||||
goto usage;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "--strip"))
|
||||
conf.strip = 1;
|
||||
else if (!strcmp(argv[i], "--env"))
|
||||
conf.use_env = 1;
|
||||
else
|
||||
test_path = argv[i];
|
||||
}
|
||||
|
||||
if (conf.use_env)
|
||||
return use_env();
|
||||
else
|
||||
{
|
||||
if (!test_path)
|
||||
goto usage;
|
||||
|
||||
return use_conf(test_path);
|
||||
}
|
||||
|
||||
usage:
|
||||
fprintf(stderr, "argc =%d\n", argc);
|
||||
fprintf(stderr, "usage: %s [--strip] [--env] test_dir\n", argv[0]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
2
test/suites/.gitattributes
vendored
Normal file
2
test/suites/.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
api/ text=auto
|
||||
* text eol=lf
|
||||
@@ -29,7 +29,6 @@ test_pack_SOURCES = test_pack.c util.h
|
||||
test_simple_SOURCES = test_simple.c util.h
|
||||
test_unpack_SOURCES = test_unpack.c util.h
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src
|
||||
AM_CFLAGS = -Wall -Werror
|
||||
AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||
LDFLAGS = -static # for speed and Valgrind
|
||||
LDADD = $(top_builddir)/src/libjansson.la
|
||||
|
||||
@@ -15,7 +15,7 @@ grep 'json_' $top_srcdir/src/jansson.def \
|
||||
nm -D $SOFILE >/dev/null >$test_log/symbols 2>/dev/null \
|
||||
|| exit 77 # Skip if "nm -D" doesn't seem to work
|
||||
|
||||
grep ' [DT] ' $test_log/symbols | cut -d' ' -f3 | sort >$test_log/output
|
||||
grep ' [DT] ' $test_log/symbols | cut -d' ' -f3 | grep -v '^_' | sort >$test_log/output
|
||||
|
||||
if ! cmp -s $test_log/exports $test_log/output; then
|
||||
diff -u $test_log/exports $test_log/output >&2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -11,7 +11,7 @@
|
||||
static void test_misc(void)
|
||||
{
|
||||
json_t *array, *five, *seven, *value;
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
array = json_array();
|
||||
five = json_integer(5);
|
||||
@@ -206,6 +206,7 @@ static void test_insert(void)
|
||||
static void test_remove(void)
|
||||
{
|
||||
json_t *array, *five, *seven;
|
||||
int i;
|
||||
|
||||
array = json_array();
|
||||
five = json_integer(5);
|
||||
@@ -253,6 +254,19 @@ static void test_remove(void)
|
||||
json_array_get(array, 2) != seven)
|
||||
fail("remove works incorrectly");
|
||||
|
||||
json_decref(array);
|
||||
|
||||
array = json_array();
|
||||
for(i = 0; i < 4; i++) {
|
||||
json_array_append(array, five);
|
||||
json_array_append(array, seven);
|
||||
}
|
||||
if(json_array_size(array) != 8)
|
||||
fail("unable to append 8 items to array");
|
||||
|
||||
/* Remove an element from a "full" array. */
|
||||
json_array_remove(array, 5);
|
||||
|
||||
json_decref(five);
|
||||
json_decref(seven);
|
||||
json_decref(array);
|
||||
@@ -386,6 +400,25 @@ static void test_circular()
|
||||
json_decref(array1);
|
||||
}
|
||||
|
||||
static void test_array_foreach()
|
||||
{
|
||||
size_t index;
|
||||
json_t *array1, *array2, *value;
|
||||
|
||||
array1 = json_pack("[sisisi]", "foo", 1, "bar", 2, "baz", 3);
|
||||
array2 = json_array();
|
||||
|
||||
json_array_foreach(array1, index, value) {
|
||||
json_array_append(array2, value);
|
||||
}
|
||||
|
||||
if(!json_equal(array1, array2))
|
||||
fail("json_array_foreach failed to iterate all elements");
|
||||
|
||||
json_decref(array1);
|
||||
json_decref(array2);
|
||||
}
|
||||
|
||||
|
||||
static void run_tests()
|
||||
{
|
||||
@@ -395,4 +428,5 @@ static void run_tests()
|
||||
test_clear();
|
||||
test_extend();
|
||||
test_circular();
|
||||
test_array_foreach();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -9,6 +9,29 @@
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
|
||||
static int encode_null_callback(const char *buffer, size_t size, void *data)
|
||||
{
|
||||
(void)buffer;
|
||||
(void)size;
|
||||
(void)data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void encode_null()
|
||||
{
|
||||
if(json_dumps(NULL, JSON_ENCODE_ANY) != NULL)
|
||||
fail("json_dumps didn't fail for NULL");
|
||||
|
||||
if(json_dumpf(NULL, stderr, JSON_ENCODE_ANY) != -1)
|
||||
fail("json_dumpf didn't fail for NULL");
|
||||
|
||||
/* Don't test json_dump_file to avoid creating a file */
|
||||
|
||||
if(json_dump_callback(NULL, encode_null_callback, NULL, JSON_ENCODE_ANY) != -1)
|
||||
fail("json_dump_callback didn't fail for NULL");
|
||||
}
|
||||
|
||||
|
||||
static void encode_twice()
|
||||
{
|
||||
/* Encode an empty object/array, add an item, encode again */
|
||||
@@ -159,6 +182,7 @@ static void escape_slashes()
|
||||
|
||||
static void run_tests()
|
||||
{
|
||||
encode_null();
|
||||
encode_twice();
|
||||
circular_references();
|
||||
encode_other_than_array_or_object();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -87,6 +87,34 @@ static void decode_any()
|
||||
json_decref(json);
|
||||
}
|
||||
|
||||
static void decode_int_as_real()
|
||||
{
|
||||
json_t *json;
|
||||
json_error_t error;
|
||||
|
||||
#if JSON_INTEGER_IS_LONG_LONG
|
||||
const char *imprecise;
|
||||
json_int_t expected;
|
||||
#endif
|
||||
|
||||
json = json_loads("42", JSON_DECODE_INT_AS_REAL | JSON_DECODE_ANY, &error);
|
||||
if (!json || !json_is_real(json) || json_real_value(json) != 42.0)
|
||||
fail("json_load decode int as real failed - int");
|
||||
json_decref(json);
|
||||
|
||||
#if JSON_INTEGER_IS_LONG_LONG
|
||||
/* This number cannot be represented exactly by a double */
|
||||
imprecise = "9007199254740993";
|
||||
expected = 9007199254740992ll;
|
||||
|
||||
json = json_loads(imprecise, JSON_DECODE_INT_AS_REAL | JSON_DECODE_ANY,
|
||||
&error);
|
||||
if (!json || !json_is_real(json) || expected != (json_int_t)json_real_value(json))
|
||||
fail("json_load decode int as real failed - expected imprecision");
|
||||
json_decref(json);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void load_wrong_args()
|
||||
{
|
||||
json_t *json;
|
||||
@@ -132,6 +160,7 @@ static void run_tests()
|
||||
reject_duplicates();
|
||||
disable_eof_check();
|
||||
decode_any();
|
||||
decode_int_as_real();
|
||||
load_wrong_args();
|
||||
position();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -12,7 +12,7 @@
|
||||
static void run_tests()
|
||||
{
|
||||
json_t *integer, *real;
|
||||
int i;
|
||||
json_int_t i;
|
||||
double d;
|
||||
|
||||
integer = json_integer(5);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -94,7 +94,7 @@ static void test_update()
|
||||
/* perform the same update again */
|
||||
|
||||
if(json_object_update(object, other))
|
||||
fail("unable to update an empty object");
|
||||
fail("unable to update a non-empty object");
|
||||
|
||||
if(json_object_size(object) != 5)
|
||||
fail("invalid size after update");
|
||||
@@ -479,7 +479,7 @@ static void test_preserve_order()
|
||||
json_decref(object);
|
||||
}
|
||||
|
||||
static void test_foreach()
|
||||
static void test_object_foreach()
|
||||
{
|
||||
const char *key;
|
||||
json_t *object1, *object2, *value;
|
||||
@@ -507,5 +507,5 @@ static void run_tests()
|
||||
test_set_nocheck();
|
||||
test_iterators();
|
||||
test_preserve_order();
|
||||
test_foreach();
|
||||
test_object_foreach();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2010-2012 Graeme Smecher <graeme.smecher@mail.mcgill.ca>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <jansson_config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <jansson.h>
|
||||
#include <stdio.h>
|
||||
@@ -15,12 +21,12 @@ static void run_tests()
|
||||
{
|
||||
json_t *value;
|
||||
int i;
|
||||
char buffer[4] = {'t', 'e', 's', 't'};
|
||||
json_error_t error;
|
||||
|
||||
/*
|
||||
* Simple, valid json_pack cases
|
||||
*/
|
||||
|
||||
/* true */
|
||||
value = json_pack("b", 1);
|
||||
if(!json_is_true(value))
|
||||
@@ -77,6 +83,38 @@ static void run_tests()
|
||||
fail("json_pack string refcount failed");
|
||||
json_decref(value);
|
||||
|
||||
/* string and length */
|
||||
value = json_pack("s#", "test asdf", 4);
|
||||
if(!json_is_string(value) || strcmp("test", json_string_value(value)))
|
||||
fail("json_pack string and length failed");
|
||||
if(value->refcount != (size_t)1)
|
||||
fail("json_pack string and length refcount failed");
|
||||
json_decref(value);
|
||||
|
||||
/* string and length, non-NUL terminated string */
|
||||
value = json_pack("s#", buffer, 4);
|
||||
if(!json_is_string(value) || strcmp("test", json_string_value(value)))
|
||||
fail("json_pack string and length failed");
|
||||
if(value->refcount != (size_t)1)
|
||||
fail("json_pack string and length refcount failed");
|
||||
json_decref(value);
|
||||
|
||||
/* string concatenation */
|
||||
value = json_pack("s++", "te", "st", "ing");
|
||||
if(!json_is_string(value) || strcmp("testing", json_string_value(value)))
|
||||
fail("json_pack string concatenation failed");
|
||||
if(value->refcount != (size_t)1)
|
||||
fail("json_pack string concatenation refcount failed");
|
||||
json_decref(value);
|
||||
|
||||
/* string concatenation and length */
|
||||
value = json_pack("s#+#+", "test", 1, "test", 2, "test");
|
||||
if(!json_is_string(value) || strcmp("ttetest", json_string_value(value)))
|
||||
fail("json_pack string concatenation and length failed");
|
||||
if(value->refcount != (size_t)1)
|
||||
fail("json_pack string concatenation and length refcount failed");
|
||||
json_decref(value);
|
||||
|
||||
/* empty object */
|
||||
value = json_pack("{}", 1.0);
|
||||
if(!json_is_object(value) || json_object_size(value) != 0)
|
||||
@@ -120,6 +158,16 @@ static void run_tests()
|
||||
fail("json_pack object refcount failed");
|
||||
json_decref(value);
|
||||
|
||||
/* object with complex key */
|
||||
value = json_pack("{s+#+: []}", "foo", "barbar", 3, "baz");
|
||||
if(!json_is_object(value) || json_object_size(value) != 1)
|
||||
fail("json_pack array failed");
|
||||
if(!json_is_array(json_object_get(value, "foobarbaz")))
|
||||
fail("json_pack array failed");
|
||||
if(json_object_get(value, "foobarbaz")->refcount != (size_t)1)
|
||||
fail("json_pack object refcount failed");
|
||||
json_decref(value);
|
||||
|
||||
/* simple array */
|
||||
value = json_pack("[i,i,i]", 0, 1, 2);
|
||||
if(!json_is_array(value) || json_array_size(value) != 3)
|
||||
@@ -193,6 +241,11 @@ static void run_tests()
|
||||
fail("json_pack failed to catch null argument string");
|
||||
check_error("NULL string argument", "<args>", 1, 1, 1);
|
||||
|
||||
/* + on its own */
|
||||
if(json_pack_ex(&error, 0, "+", NULL))
|
||||
fail("json_pack failed to a lone +");
|
||||
check_error("Unexpected format character '+'", "<format>", 1, 1, 1);
|
||||
|
||||
/* NULL format */
|
||||
if(json_pack_ex(&error, 0, NULL))
|
||||
fail("json_pack failed to catch NULL format string");
|
||||
@@ -201,7 +254,7 @@ static void run_tests()
|
||||
/* NULL key */
|
||||
if(json_pack_ex(&error, 0, "{s:i}", NULL, 1))
|
||||
fail("json_pack failed to catch NULL key");
|
||||
check_error("NULL object key", "<args>", 1, 2, 2);
|
||||
check_error("NULL string argument", "<args>", 1, 2, 2);
|
||||
|
||||
/* More complicated checks for row/columns */
|
||||
if(json_pack_ex(&error, 0, "{ {}: s }", "foo"))
|
||||
@@ -221,7 +274,7 @@ static void run_tests()
|
||||
/* Invalid UTF-8 in object key */
|
||||
if(json_pack_ex(&error, 0, "{s:i}", "\xff\xff", 42))
|
||||
fail("json_pack failed to catch invalid UTF-8 in an object key");
|
||||
check_error("Invalid UTF-8 in object key", "<args>", 1, 2, 2);
|
||||
check_error("Invalid UTF-8 object key", "<args>", 1, 2, 2);
|
||||
|
||||
/* Invalid UTF-8 in a string */
|
||||
if(json_pack_ex(&error, 0, "{s:s}", "foo", "\xff\xff"))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2010-2012 Graeme Smecher <graeme.smecher@mail.mcgill.ca>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
@@ -96,14 +96,14 @@ static void run_tests()
|
||||
/* non-incref'd object */
|
||||
j = json_object();
|
||||
rv = json_unpack(j, "o", &j2);
|
||||
if(j2 != j || j->refcount != 1)
|
||||
if(rv || j2 != j || j->refcount != 1)
|
||||
fail("json_unpack object failed");
|
||||
json_decref(j);
|
||||
|
||||
/* incref'd object */
|
||||
j = json_object();
|
||||
rv = json_unpack(j, "O", &j2);
|
||||
if(j2 != j || j->refcount != 2)
|
||||
if(rv || j2 != j || j->refcount != 2)
|
||||
fail("json_unpack object failed");
|
||||
json_decref(j);
|
||||
json_decref(j);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -14,7 +14,7 @@ run_test() {
|
||||
if [ -f $test_path/env ]; then
|
||||
. $test_path/env
|
||||
fi
|
||||
$json_process <$test_path/input >$test_log/stdout 2>$test_log/stderr
|
||||
$json_process --env <$test_path/input >$test_log/stdout 2>$test_log/stderr
|
||||
)
|
||||
valgrind_check $test_log/stderr || return 1
|
||||
cmp -s $test_path/output $test_log/stdout
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -10,7 +10,7 @@ is_test() {
|
||||
}
|
||||
|
||||
run_test() {
|
||||
$json_process <$test_path/input >$test_log/stdout 2>$test_log/stderr
|
||||
$json_process --env <$test_path/input >$test_log/stdout 2>$test_log/stderr
|
||||
valgrind_check $test_log/stderr || return 1
|
||||
cmp -s $test_path/error $test_log/stderr
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -20,7 +20,7 @@ do_run() {
|
||||
strip=1
|
||||
fi
|
||||
|
||||
STRIP=$strip $json_process \
|
||||
STRIP=$strip $json_process --env \
|
||||
<$test_path/input >$test_log/stdout$s 2>$test_log/stderr$s
|
||||
valgrind_check $test_log/stderr$s || return 1
|
||||
|
||||
|
||||
1
test/suites/valid/complex-array/env
Normal file
1
test/suites/valid/complex-array/env
Normal file
@@ -0,0 +1 @@
|
||||
JSON_SORT_KEYS=1
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
|
||||
# Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
|
||||
#
|
||||
# Jansson is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -19,7 +19,7 @@ do_run() {
|
||||
strip=0
|
||||
[ "$variant" = "strip" ] && strip=1
|
||||
|
||||
STRIP=$strip $json_process \
|
||||
STRIP=$strip $json_process --env \
|
||||
<$test_path/input >$test_log/stdout$s 2>$test_log/stderr$s
|
||||
valgrind_check $test_log/stderr$s || return 1
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 Petri Lehtinen <petri@digip.org>
|
||||
* Copyright (c) 2010-2013 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
Reference in New Issue
Block a user