Compare commits

..

73 Commits

Author SHA1 Message Date
Christopher Dunn
2760c7902a fix #290 2015-06-10 21:22:24 -05:00
Christopher Dunn
f40dd0f3ed Merge branch 'master' into 0.y.z
BORLANDC compilation issues
2015-04-28 05:09:58 +01:00
Christopher Dunn
5256551b03 address compilation probs for C++ Builder
BORLANDC compiler strangeness. Thanks to:

* Dan Liu
* Victor Chen

close #269
close #252
2015-04-28 05:08:58 +01:00
Christopher Dunn
6649009ffa another fix for BORLANDC 2015-04-28 04:57:49 +01:00
Christopher Dunn
2a10f4a3b8 move ctors for BORLAND 2015-04-28 04:55:12 +01:00
Christopher Dunn
c334ac0376 Merge branch 'master' into 0.y.z
- fix for "C++ Builder" IDE
- Travis CI/AppVeyor
- **cmake** tweak
- fix memory leak in unit-test

See #268 and #252.
2015-04-27 18:33:07 -07:00
Christopher Dunn
28d086e1d9 Merge pull request #266 from cdunn2001/issue-252
Use unsigned for DuplicationPolicy, to fix a problem with "C++ Builder"
IDE.

Fixes #252.

Thanks to:

* Dan Liu -- http://blog.csdn.net/gzliudan/article/details/45264201)
* Victor Chen -- http://www.cppfans.com/sdk/json/jsoncpp.asp
2015-04-27 18:28:06 -07:00
Christopher Dunn
a0a7c5f6de a little test for issue 252, but does not fail for me 2015-04-27 18:14:09 -07:00
Dan Liu
fcbab02e4a fix crash for "C++ Builder" IDE
http://blog.csdn.net/gzliudan/article/details/45264201
2015-04-27 18:10:12 -07:00
Christopher Dunn
f4ee48bc21 Merge pull request #265 from cdunn2001/valgrind
run valgrind in Travis CI
2015-04-26 20:08:17 -07:00
Christopher Dunn
88184d142b run valgrind in Travis CI
Because this runs apt-get, it will not work as-is for OSX. So when
we have OSX in Travis, we will have to wrap this somehow. See #250.

Closes #222.
2015-04-27 04:03:34 +01:00
Christopher Dunn
ae177fd901 Merge pull request #263 from cdunn2001/static-shared
Use standard **cmake** variables, to support superprojects better.

- `JSONCPP_LIB_BUILD_SHARED` -> `BUILD_SHARED_LIBS`
- `JSONCPP_LIB_BUILD_STATIC` -> `BUILD_STATIC_LIBS`
2015-04-23 08:58:38 -07:00
Gaurav
3f6345234f Use standard CMake variables - static/shared lib.
Replace JSONCPP_LIB_BUILD_SHARED => BUILD_SHARED_LIBS
2015-04-23 07:32:19 -07:00
Gaurav
a53070c42b Use standard CMake variables - static/shared lib.
Replace JSONCPP_LIB_BUILD_SHARED => BUILD_SHARED_LIBS
2015-04-23 07:32:19 -07:00
Gaurav
c09e121aeb Use standard CMake variables - static/shared lib.
Replace JSONCPP_LIB_BUILD_SHARED => BUILD_SHARED_LIBS
2015-04-23 07:32:18 -07:00
Gaurav
4f8ec9d207 Use standard CMake variables - static/shared lib.
Replaced JSONCPP_LIB_BUILD_SHARED => BUILD_SHARED_LIBS
Replaced JSONCPP_LIB_BUILD_STATIC => BUILD_STATIC_LIBS
2015-04-23 07:32:18 -07:00
Gaurav
0fe61a68f8 Use standard CMake variables - static/shared lib.
Replaced JSONCPP_LIB_BUILD_SHARED => BUILD_SHARED_LIBS
2015-04-23 07:32:18 -07:00
Gaurav
43019088f0 Use standard CMake variables - static/shared lib.
Replaced JSONCPP_LIB_BUILD_SHARED => BUILD_SHARED_LIBS
Moved flag JSON_DLL to line no 8.
2015-04-23 07:32:18 -07:00
Gaurav
0c1c076b7c Use standard CMake variables - static/shared lib.
Replaced JSONCPP_LIB_BUILD_SHARED => BUILD_SHARED_LIBS
Moved definition DJSON_DLL to line 11.
2015-04-23 07:32:18 -07:00
Gaurav
11130997c3 Use standard CMake variables - static/shared lib.
Replace JSONCPP_LIB_BUILD_SHARED => BUILD_SHARED_LIBS
Replace JSONCPP_LIB_BUILD_STATIC => BUILD_STATIC_LIBS
Removed workaround  https://github.com/open-source-parsers/jsoncpp/issues/51
Removed OPTION for shared/static in this file.
2015-04-23 07:32:17 -07:00
Gaurav
30bb4ccb67 Use standard CMake variables - static/shared lib.
Currently JSONCPP_LIB_BUILD_SHARED variable is used as option to build static/shared libraries.
The current patch uses standard CMake variables for this.
Such a workaround is done in https://github.com/open-source-parsers/jsoncpp/issues/51
Current patch will make it generic.
2015-04-23 18:39:00 +05:30
Christopher Dunn
74143f39e7 fix leak in unit-tests 2015-04-22 19:33:41 -07:00
Christopher Dunn
56650e83c5 swap docs for default vs. strictMode 2015-04-20 13:10:31 -07:00
Christopher Dunn
c66cc277f5 Merge pull request #249 from cdunn2001/master
Merge appveyor changes into 0.y.z
2015-04-18 18:27:32 -07:00
Christopher Dunn
441f8cdfa1 Merge pull request #244 from cdunn2001/appveyor
New `appveyor.yml`: All tests pass, in both Appveyor and Travis!

Henceforth, GitHub will run both for any pull-request, so this file will be needed in the `0.y.z` branch too.
2015-04-18 17:14:33 -07:00
Christopher Dunn
a658759039 maybe fix an error 2015-04-16 18:33:39 -07:00
Christopher Dunn
0eb0e502c8 add a comment, to force a build 2015-04-16 18:30:24 -07:00
Marek Kotewicz
e983204906 appveyor deploy init 2015-04-16 18:12:18 -07:00
Marek Kotewicz
fe06acb587 fixed version on appveyor build 2015-04-16 18:12:17 -07:00
Marek Kotewicz
1b49a55ea1 appveyor multiple platforms 2015-04-16 18:12:17 -07:00
Marek Kotewicz
13c36e9807 appveyor.yml 2015-04-16 18:12:17 -07:00
Sam Clegg
db7ad75794 Don't use unique_ptr on pre-c++11 branch
Don't use C++11 unique_ptr in the 0.y.z branch.
Although this usage is guarded with __cplusplus >= 201103
some build configurations (notably chromium) use a
C++11-compliant compiler but a pre-11 library.

pull #238
2015-04-12 00:39:25 -05:00
Christopher Dunn
f4bdc1b602 partially revert 'Added features that allow the reader to accept common non-standard JSON.'
revert '642befc836ac5093b528e7d8b4fd66b66735a98c',
but keep the *added* methods for `decodedNumber()` and `decodedDouble()`.
2015-04-11 14:49:59 -05:00
Christopher Dunn
93f45d065c partially revert 'fix bug for static init'
re: 28836b8acc

A global instance of a Value (viz. 'null') was a mistake,
but dropping it breaks binary-compatibility. So we will keep it
everywhere except the one platform where it was crashing, ARM.
2015-04-11 14:49:59 -05:00
Christopher Dunn
6f6ddaa91c revert 'Made it possible to drop null placeholders from array output.'
revert ae3c7a7aab
2015-04-11 14:49:59 -05:00
Christopher Dunn
254fe6a07a Revert "added option to FastWriter which omits the trailing new line character"
This reverts commit 5bf16105b5.
2015-04-11 14:49:59 -05:00
Christopher Dunn
00d7bea0f6 revert 'Added structured error reporting to Reader.'
revert 68db655347
issue #147
2015-04-11 14:49:59 -05:00
Christopher Dunn
a9d06d2650 revert 'Add public semantic error reporting'
for binary-compatibility with 0.6.0
issue #147
was #57
2015-04-11 14:49:59 -05:00
Christopher Dunn
1c4f6a2d79 partially revert "Switch to copy-and-swap idiom for operator=."
This partially reverts commit 45cd9490cd.

Ignored ValueInternal* changes, since those did not produce symbols for
Debian build. (They must not have used the INTERNAL stuff.)

Ignored CZString changes since those are private (and sizeof struct did
not change).

  https://github.com/open-source-parsers/jsoncpp/issues/78

Conflicts:
	include/json/value.h
	src/lib_json/json_internalarray.inl
	src/lib_json/json_internalmap.inl
	src/lib_json/json_value.cpp
2015-04-11 14:49:59 -05:00
Christopher Dunn
e49bd30950 NOT C++11 2015-04-11 14:49:59 -05:00
Christopher Dunn
13d78e3da3 0.10.z (based on 1.6.z, but binary-compat w/ 0.6.0-rc2) 2015-04-11 14:49:59 -05:00
Christopher Dunn
50069d72da prefer std::string for setComment()
in case of embedded nulls
2015-04-11 14:49:28 -05:00
Christopher Dunn
24682e37bf 1.6.2 <- 1.6.1
Fix UTF-8 for old (deprecated) Writers.

* Do not truncate at embedded zeroes.
2015-04-11 14:45:33 -05:00
Christopher Dunn
c2b988ee74 Merge pull request #241 from cdunn2001/fix-more-utf8
support UTF-8 (specifically, embedded zeroes) in old Writers
2015-04-11 14:44:41 -05:00
Christopher Dunn
e255ce31a4 support UTF-8 in old Writers
We had already fixed Value to hold UTF-8 properly, but only the newer
StreamWriter was writing UTF-8 properly.

Old FasterWriter etc. were using asCString() instead of asString() in
Value::writeValue().

Hopefully this change does not break any existing code. Seems unlikely.

issue #240
2015-04-11 14:41:30 -05:00
Christopher Dunn
779b5bc5ba Merge pull request #239 from sbc100/copyright
Add copyright information to .py files
2015-04-11 14:41:03 -05:00
Sam Clegg
63860617b3 Add copyright information to .py files
This change adds explicit copyright information too python
files files.  The copyright year used in each case is the
date of the first git commit of each file.

The goal is to allow jsoncpp to be integrated into the
chromium source tree which requires license information in
each source file.

fixes #234
2015-04-09 18:05:47 -07:00
Christopher Dunn
9cb88d2ca6 1.6.1 <- 1.6.0 2015-03-31 15:07:14 -05:00
Christopher Dunn
363e51c0a9 Merge pull request #232 from cdunn2001/fix-snprintf
Fix snprintf

Well, it passes Travis. But when we have time, we should clean up how snprintf is used in both reader and writer.
2015-03-31 15:06:11 -05:00
Christopher Dunn
240ddb6a1b use std::snprintf for C++11 2015-03-31 15:04:24 -05:00
Baruch Siach
9dd77dc0ef Revert "Use std namespace for snprintf."
This reverts commit 1c58876185.

std::snprintf() is only available in C++11, which is not provided by
all compilers. Since the C library snprintf() can easily be used as a
replacement on Linux systems, this patch changes jsoncpp to use the C
library snprintf() instead of C++11 std::snprintf(), fixing the build error
below:

    src/lib_json/json_writer.cpp:33:18: error: 'snprintf' is not a member of 'std'

See #231, #224, and #218.
2015-03-31 15:04:24 -05:00
Christopher Dunn
244b1496e1 Merge pull request #225 from selaselah/master
fix find_program() bug: no result in not-win sys
2015-03-31 11:32:06 -05:00
selaselah
c083835261 fix find_program() bug: no result in not-win sys 2015-03-19 19:18:58 +08:00
Christopher Dunn
cbe7e7c9cb Merge pull request #221 from btolfa/forgotten-virtual-dtor
Added forgotten virtual dtor for `Json::CharReader::Factory`.

(Without this, the destructor of the derived `CharReaderBuilder` would not be called, which is a small memory leak.)
2015-03-15 13:49:24 -05:00
Tengiz Sharafiev
be183def8f Update reader.h 2015-03-14 21:30:00 +03:00
Christopher Dunn
951bd3d05d Merge pull request #219 from cdunn2001/c-std-headers
Close #218. Fix #214.
2015-03-11 21:36:51 -05:00
Connor Manning
1c58876185 Use std namespace for snprintf. 2015-03-11 21:33:08 -05:00
Connor Manning
2f2034629e Constrain MSVC _isfinite to before 2013, remove duplicate includes. 2015-03-11 21:33:08 -05:00
Dani-Hub
7020451b44 Fix isfinite for MSVC. 2015-03-11 21:32:59 -05:00
Connor Manning
80497f102e Use C++ standard headers. 2015-03-10 18:48:45 -05:00
Dani-Hub
f9feb66be2 Change exception data member
from "reference to string" to "string" (Resolves the most serious part of issue #216)
2015-03-09 18:42:16 -05:00
Christopher Dunn
ed495edcc1 prefer ValueIterator::name() to ::memberName()
in case of embedded nulls
2015-03-08 14:35:00 -05:00
Christopher Dunn
3c0a383877 Merge pull request #212 from cdunn2001/macro-deprec
close #210
2015-03-08 13:10:37 -05:00
Dani-Hub
5003983029 Make preprocessor query robust against older gcc versions 2015-03-08 13:07:27 -05:00
Dani-Hub
871b311e7e Provide JSONCPP_DEPRECATED definitions for clang and gcc 2015-03-08 13:07:27 -05:00
Christopher Dunn
cdbc35f6ac 1.6.0 2015-03-08 12:57:13 -05:00
Christopher Dunn
4e30c4fcdb comments 2015-03-08 12:56:32 -05:00
Christopher Dunn
0d33cb3639 Merge pull request #211 from cdunn2001/except
* Add Json::Exception and derivatives.
* Clarify when exceptions are thrown, to avoid crashes caused by malicious input.
* Use our own type (derived fro std::exception) so they are trappable.
2015-03-08 12:50:34 -05:00
Christopher Dunn
2250b3c29d use Json::RuntimeError 2015-03-08 12:44:55 -05:00
Christopher Dunn
9376368d86 use Json::LogicError in macros 2015-03-08 12:42:53 -05:00
Christopher Dunn
5383794cc9 Runtime/LogicError and throwers 2015-03-08 12:31:57 -05:00
Christopher Dunn
75279ccec2 base Json::Exception 2015-03-08 12:20:06 -05:00
Christopher Dunn
717b08695e clarify errors
* use macros for logic errors, not input errors
* throw on parsing failure in `operator>>()`, not assert
* throw on malloc, not assert
2015-03-08 12:06:22 -05:00
39 changed files with 439 additions and 456 deletions

View File

@@ -2,12 +2,20 @@
# http://about.travis-ci.org/docs/user/build-configuration/
# This file can be validated on:
# http://lint.travis-ci.org/
before_install: sudo apt-get install cmake
#before_install: sudo apt-get install -y cmake
# cmake is pre-installed in Travis for both linux and osx
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq valgrind
os:
- linux
language: cpp
compiler:
- gcc
- clang
script: cmake -DJSONCPP_WITH_CMAKE_PACKAGE=$CMAKE_PKG -DJSONCPP_LIB_BUILD_SHARED=$SHARED_LIB -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_VERBOSE_MAKEFILE=$VERBOSE_MAKE . && make && make jsoncpp_check
script: ./travis.sh
env:
matrix:
- SHARED_LIB=ON STATIC_LIB=ON CMAKE_PKG=ON BUILD_TYPE=release VERBOSE_MAKE=false

View File

@@ -9,6 +9,8 @@ OPTION(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post
OPTION(JSONCPP_WITH_WARNING_AS_ERROR "Force compilation to fail if a warning occurs" OFF)
OPTION(JSONCPP_WITH_PKGCONFIG_SUPPORT "Generate and install .pc files" ON)
OPTION(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" OFF)
OPTION(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." OFF)
OPTION(BUILD_STATIC_LIBS "Build jsoncpp_lib static library." ON)
# Ensures that CMAKE_BUILD_TYPE is visible in cmake-gui on Unix
IF(NOT WIN32)
@@ -60,7 +62,7 @@ ENDMACRO(jsoncpp_parse_version)
#SET( JSONCPP_VERSION_MAJOR X )
#SET( JSONCPP_VERSION_MINOR Y )
#SET( JSONCPP_VERSION_PATCH Z )
SET( JSONCPP_VERSION 1.5.4 )
SET( JSONCPP_VERSION 0.10.2 )
jsoncpp_parse_version( ${JSONCPP_VERSION} JSONCPP_VERSION )
#IF(NOT JSONCPP_VERSION_FOUND)
# MESSAGE(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z")
@@ -94,10 +96,10 @@ endif( MSVC )
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# using regular Clang or AppleClang
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# using GCC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall -Wextra -pedantic")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic")
endif()
IF(JSONCPP_WITH_WARNING_AS_ERROR)

View File

@@ -58,7 +58,7 @@ Steps for generating solution/makefiles using `cmake-gui`:
* Make "source code" point to the source directory.
* Make "where to build the binary" point to the directory to use for the build.
* Click on the "Grouped" check box.
* Review JsonCpp build options (tick `JSONCPP_LIB_BUILD_SHARED` to build as a
* Review JsonCpp build options (tick `BUILD_SHARED_LIBS` to build as a
dynamic library).
* Click the configure button at the bottom, then the generate button.
* The generated solution/makefiles can be found in the binary directory.
@@ -67,7 +67,7 @@ Alternatively, from the command-line on Unix in the source directory:
mkdir -p build/debug
cd build/debug
cmake -DCMAKE_BUILD_TYPE=debug -DJSONCPP_LIB_BUILD_STATIC=ON -DJSONCPP_LIB_BUILD_SHARED=OFF -G "Unix Makefiles" ../..
cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -G "Unix Makefiles" ../..
make
Running `cmake -`" will display the list of available generators (passed using

34
appveyor.yml Normal file
View File

@@ -0,0 +1,34 @@
# This is a comment.
version: build.{build}
os: Windows Server 2012 R2
clone_folder: c:\projects\jsoncpp
platform:
- Win32
- x64
configuration:
- Debug
- Release
# scripts to run before build
before_build:
- echo "Running cmake..."
- cd c:\projects\jsoncpp
- cmake --version
- if %PLATFORM% == Win32 cmake .
- if %PLATFORM% == x64 cmake -G "Visual Studio 12 2013 Win64" .
build:
project: jsoncpp.sln # path to Visual Studio solution or project
deploy:
provider: GitHub
auth_token:
secure: K2Tp1q8pIZ7rs0Ot24ZMWuwr12Ev6Tc6QkhMjGQxoQG3ng1pXtgPasiJ45IDXGdg
on:
branch: master
appveyor_repo_tag: true

View File

@@ -16,7 +16,7 @@ dox:
# Then 'git add -A' and 'git push' in jsoncpp-docs.
build:
mkdir -p build/debug
cd build/debug; cmake -DCMAKE_BUILD_TYPE=debug -DJSONCPP_LIB_BUILD_SHARED=ON -G "Unix Makefiles" ../..
cd build/debug; cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_SHARED_LIBS=ON -G "Unix Makefiles" ../..
make -C build/debug
# Currently, this depends on include/json/version.h generated
@@ -26,6 +26,9 @@ test-amalgamate:
python3.4 amalgamate.py
cd dist; gcc -I. -c jsoncpp.cpp
valgrind:
valgrind --error-exitcode=42 --leak-check=full ./build/debug/src/test_lib_json/jsoncpp_test
clean:
\rm -rf *.gz *.asc dist/

View File

@@ -1 +1,6 @@
# module
# Copyright 2010 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
# module

View File

@@ -19,8 +19,8 @@
},
{"name": "shared_dll",
"variables": [
["JSONCPP_LIB_BUILD_SHARED=true"],
["JSONCPP_LIB_BUILD_SHARED=false"]
["BUILD_SHARED_LIBS=true"],
["BUILD_SHARED_LIBS=false"]
]
},
{"name": "build_type",

View File

@@ -12,8 +12,8 @@
},
{"name": "shared_dll",
"variables": [
["JSONCPP_LIB_BUILD_SHARED=true"],
["JSONCPP_LIB_BUILD_SHARED=false"]
["BUILD_SHARED_LIBS=true"],
["BUILD_SHARED_LIBS=false"]
]
},
{"name": "build_type",

View File

@@ -1,6 +1,9 @@
#!/usr/bin/env python
# encoding: utf-8
# Baptiste Lepilleur, 2009
# Copyright 2009 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
from __future__ import print_function
from dircache import listdir

View File

@@ -1,3 +1,8 @@
# Copyright 2010 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
from __future__ import print_function
import os.path

View File

@@ -1,3 +1,8 @@
# Copyright 2010 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
from contextlib import closing
import os
import tarfile

View File

@@ -31,7 +31,7 @@ def find_program(*filenames):
paths = os.environ.get('PATH', '').split(os.pathsep)
suffixes = ('win32' in sys.platform) and '.exe .com .bat .cmd' or ''
for filename in filenames:
for name in [filename+ext for ext in suffixes.split()]:
for name in [filename+ext for ext in suffixes.split(' ')]:
for directory in paths:
full_path = os.path.join(directory, name)
if os.path.isfile(full_path):

View File

@@ -13,22 +13,30 @@
#include "config.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
/** It should not be possible for a maliciously designed file to
* cause an abort() or seg-fault, so these macros are used only
* for pre-condition violations and internal logic errors.
*/
#if JSON_USE_EXCEPTION
#include <stdexcept>
#define JSON_ASSERT(condition) \
{if (!(condition)) {throw std::logic_error( "assert json failed" );}} // @todo <= add detail about condition in exception
#define JSON_FAIL_MESSAGE(message) \
// @todo <= add detail about condition in exception
# define JSON_ASSERT(condition) \
{if (!(condition)) {Json::throwLogicError( "assert json failed" );}}
# define JSON_FAIL_MESSAGE(message) \
{ \
std::ostringstream oss; oss << message; \
throw std::logic_error(oss.str()); \
Json::throwLogicError(oss.str()); \
abort(); \
}
//#define JSON_FAIL_MESSAGE(message) throw std::logic_error(message)
#else // JSON_USE_EXCEPTION
#define JSON_ASSERT(condition) assert(condition)
# define JSON_ASSERT(condition) assert(condition)
// The call to assert() will show the failure message in debug builds. In
// release bugs we abort, for a core-dump or debugger.
#define JSON_FAIL_MESSAGE(message) \
// release builds we abort, for a core-dump or debugger.
# define JSON_FAIL_MESSAGE(message) \
{ \
std::ostringstream oss; oss << message; \
assert(false && oss.str().c_str()); \

View File

@@ -70,6 +70,14 @@
#if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008
/// Indicates that the following function is deprecated.
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#elif defined(__clang__) && defined(__has_feature)
#if __has_feature(attribute_deprecated_with_message)
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
#endif
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
#endif
#if !defined(JSONCPP_DEPRECATED)

View File

@@ -44,12 +44,6 @@ public:
/// \c true if root must be either an array or an object value. Default: \c
/// false.
bool strictRoot_;
/// \c true if dropped null placeholders are allowed. Default: \c false.
bool allowDroppedNullPlaceholders_;
/// \c true if numeric object key are allowed. Default: \c false.
bool allowNumericKeys_;
};
} // namespace Json

View File

@@ -35,18 +35,6 @@ public:
typedef char Char;
typedef const Char* Location;
/** \brief An error tagged with where in the JSON text it was encountered.
*
* The offsets give the [start, limit) range of bytes within the text. Note
* that this is bytes, not codepoints.
*
*/
struct StructuredError {
size_t offset_start;
size_t offset_limit;
std::string message;
};
/** \brief Constructs a Reader allowing all features
* for parsing.
*/
@@ -110,7 +98,7 @@ public:
* during parsing.
* \deprecated Use getFormattedErrorMessages() instead (typo fix).
*/
JSONCPP_DEPRECATED("Use getFormattedErrorMessages instead")
JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
std::string getFormatedErrorMessages() const;
/** \brief Returns a user friendly string that list errors in the parsed
@@ -123,38 +111,6 @@ public:
*/
std::string getFormattedErrorMessages() const;
/** \brief Returns a vector of structured erros encounted while parsing.
* \return A (possibly empty) vector of StructuredError objects. Currently
* only one error can be returned, but the caller should tolerate
* multiple
* errors. This can occur if the parser recovers from a non-fatal
* parse error and then encounters additional errors.
*/
std::vector<StructuredError> getStructuredErrors() const;
/** \brief Add a semantic error message.
* \param value JSON Value location associated with the error
* \param message The error message.
* \return \c true if the error was successfully added, \c false if the
* Value offset exceeds the document size.
*/
bool pushError(const Value& value, const std::string& message);
/** \brief Add a semantic error message with extra context.
* \param value JSON Value location associated with the error
* \param message The error message.
* \param extra Additional JSON Value location to contextualize the error
* \return \c true if the error was successfully added, \c false if either
* Value offset exceeds the document size.
*/
bool pushError(const Value& value, const std::string& message, const Value& extra);
/** \brief Return whether there are any errors.
* \return \c true if there are no errors to report \c false if
* errors have occurred.
*/
bool good() const;
private:
enum TokenType {
tokenEndOfStream = 0,
@@ -270,6 +226,7 @@ public:
class Factory {
public:
virtual ~Factory() {}
/** \brief Allocate a CharReader via operator new().
* \throw std::exception if something goes wrong (e.g. invalid settings)
*/
@@ -279,8 +236,6 @@ public:
/** \brief Build a CharReader implementation.
\deprecated This is experimental and will be altered before the next release.
Usage:
\code
using namespace Json;
@@ -347,13 +302,13 @@ public:
/** Called by ctor, but you can use this to reset settings_.
* \pre 'settings' != NULL (but Json::null is fine)
* \remark Defaults:
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
*/
static void setDefaults(Json::Value* settings);
/** Same as old Features::strictMode().
* \pre 'settings' != NULL (but Json::null is fine)
* \remark Defaults:
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
*/
static void strictMode(Json::Value* settings);
};

View File

@@ -11,6 +11,7 @@
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <string>
#include <vector>
#include <exception>
#ifndef JSON_USE_CPPTL_SMALLMAP
#include <map>
@@ -32,6 +33,31 @@
*/
namespace Json {
/** Base class for all exceptions we throw.
*
* We use nothing but these internally. Of course, STL can throw others.
*/
class JSON_API Exception;
/** Exceptions which the user cannot easily avoid.
*
* E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
*
* \remark derived from Json::Exception
*/
class JSON_API RuntimeError;
/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
*
* These are precondition-violations (user bugs) and internal errors (our bugs).
*
* \remark derived from Json::Exception
*/
class JSON_API LogicError;
/// used internally
void throwRuntimeError(std::string const& msg);
/// used internally
void throwLogicError(std::string const& msg);
/** \brief Type of the value held by a Value object.
*/
enum ValueType {
@@ -134,8 +160,11 @@ public:
typedef Json::LargestUInt LargestUInt;
typedef Json::ArrayIndex ArrayIndex;
static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value().
static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null
static const Value& nullRef;
#if !defined(__ARMEL__)
/// \deprecated This exists for binary compatibility only. Use nullRef.
static const Value null;
#endif
/// Minimum signed integer value that can be stored in a Json::Value.
static const LargestInt minLargestInt;
/// Maximum signed integer value that can be stored in a Json::Value.
@@ -185,7 +214,7 @@ private:
void swap(CZString& other);
struct StringStorage {
DuplicationPolicy policy_: 2;
unsigned policy_: 2;
unsigned length_: 30; // 1GB max
};
@@ -257,7 +286,7 @@ Json::Value obj_value(Json::objectValue); // {}
/// Deep copy, then swap(other).
/// \note Over-write existing comments. To preserve comments, use #swapPayload().
Value& operator=(Value other);
Value &operator=(const Value &other);
/// Swap everything.
void swap(Value& other);
/// Swap values but leave comments and source offsets in place.
@@ -486,6 +515,7 @@ Json::Value obj_value(Json::objectValue); // {}
//# endif
/// \deprecated Always pass len.
JSONCPP_DEPRECATED("Use setComment(std::string const&) instead.")
void setComment(const char* comment, CommentPlacement placement);
/// Comments must be //... or /* ... */
void setComment(const char* comment, size_t len, CommentPlacement placement);
@@ -503,13 +533,6 @@ Json::Value obj_value(Json::objectValue); // {}
iterator begin();
iterator end();
// Accessors for the [start, limit) range of bytes within the JSON text from
// which this value was parsed, if any.
void setOffsetStart(size_t start);
void setOffsetLimit(size_t limit);
size_t getOffsetStart() const;
size_t getOffsetLimit() const;
private:
void initBasic(ValueType type, bool allocated = false);
@@ -546,11 +569,6 @@ private:
unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
// If not allocated_, string_ must be null-terminated.
CommentInfo* comments_;
// [start, limit) byte offsets in the source JSON text from which this Value
// was extracted.
size_t start_;
size_t limit_;
};
/** \brief Experimental and untested: represents an element of the "path" to
@@ -626,9 +644,6 @@ public:
typedef int difference_type;
typedef ValueIteratorBase SelfType;
ValueIteratorBase();
explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
bool operator==(const SelfType& other) const { return isEqual(other); }
bool operator!=(const SelfType& other) const { return !isEqual(other); }
@@ -641,16 +656,22 @@ public:
/// Value.
Value key() const;
/// Return the index of the referenced Value. -1 if it is not an arrayValue.
/// Return the index of the referenced Value, or -1 if it is not an arrayValue.
UInt index() const;
/// Return the member name of the referenced Value, or "" if it is not an
/// objectValue.
/// \note Avoid `c_str()` on result, as embedded zeroes are possible.
std::string name() const;
/// Return the member name of the referenced Value. "" if it is not an
/// objectValue.
/// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.
JSONCPP_DEPRECATED("Use `key = name();` instead.")
char const* memberName() const;
/// Return the member name of the referenced Value, or NULL if it is not an
/// objectValue.
/// Better version than memberName(). Allows embedded nulls.
/// \note Better version than memberName(). Allows embedded nulls.
char const* memberName(char const** end) const;
protected:
@@ -670,6 +691,12 @@ private:
Value::ObjectValues::iterator current_;
// Indicates that iterator is for a null value.
bool isNull_;
public:
// For some reason, BORLAND needs these at the end, rather
// than earlier. No idea why.
ValueIteratorBase();
explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
};
/** \brief const iterator for object and array value.

View File

@@ -4,10 +4,10 @@
#ifndef JSON_VERSION_H_INCLUDED
# define JSON_VERSION_H_INCLUDED
# define JSONCPP_VERSION_STRING "1.5.4"
# define JSONCPP_VERSION_MAJOR 1
# define JSONCPP_VERSION_MINOR 5
# define JSONCPP_VERSION_PATCH 4
# define JSONCPP_VERSION_STRING "0.10.2"
# define JSONCPP_VERSION_MAJOR 0
# define JSONCPP_VERSION_MINOR 10
# define JSONCPP_VERSION_PATCH 2
# define JSONCPP_VERSION_QUALIFIER
# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))

View File

@@ -46,7 +46,7 @@ public:
/** Write Value into document as configured in sub-class.
Do not take ownership of sout, but maintain a reference during function.
\pre sout != NULL
\return zero on success
\return zero on success (For now, we always return zero, so check the stream instead.)
\throw std::exception possibly, depending on configuration
*/
virtual int write(Value const& root, std::ostream* sout) = 0;
@@ -132,7 +132,7 @@ public:
};
/** \brief Abstract class for writers.
* \deprecated Use StreamWriter.
* \deprecated Use StreamWriter. (And really, this is an implementation detail.)
*/
class JSON_API Writer {
public:
@@ -151,21 +151,13 @@ public:
* \deprecated Use StreamWriterBuilder.
*/
class JSON_API FastWriter : public Writer {
public:
FastWriter();
virtual ~FastWriter() {}
void enableYAMLCompatibility();
/** \brief Drop the "null" string from the writer's output for nullValues.
* Strictly speaking, this is not valid JSON. But when the output is being
* fed to a browser's Javascript, it makes for smaller output and the
* browser can handle the output just fine.
*/
void dropNullPlaceholders();
void omitEndingLineFeed();
public: // overridden from Writer
virtual std::string write(const Value& root);
@@ -174,8 +166,6 @@ private:
std::string document_;
bool yamlCompatiblityEnabled_;
bool dropNullPlaceholders_;
bool omitEndingLineFeed_;
};
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a

View File

@@ -1,3 +1,8 @@
# Copyright 2010 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
"""Tag the sandbox for release, make source and doc tarballs.
Requires Python 2.6
@@ -14,6 +19,7 @@ python makerelease.py 0.5.0 0.6.0-dev
Note: This was for Subversion. Now that we are in GitHub, we do not
need to build versioned tarballs anymore, so makerelease.py is defunct.
"""
from __future__ import print_function
import os.path
import subprocess

View File

@@ -1,3 +1,8 @@
# Copyright 2009 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
import fnmatch
import os

View File

@@ -1,3 +1,8 @@
# Copyright 2007 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
import os
import os.path
from fnmatch import fnmatch

View File

@@ -1,3 +1,8 @@
# Copyright 2010 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
import re
from SCons.Script import * # the usual scons stuff you get in a SConscript
import collections

View File

@@ -1,3 +1,8 @@
# Copyright 2007 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
"""tarball
Tool-specific initialization for tarball.

View File

@@ -1,18 +1,15 @@
FIND_PACKAGE(PythonInterp 2.6)
IF(JSONCPP_LIB_BUILD_SHARED)
ADD_DEFINITIONS( -DJSON_DLL )
ENDIF(JSONCPP_LIB_BUILD_SHARED)
ADD_EXECUTABLE(jsontestrunner_exe
main.cpp
)
IF(JSONCPP_LIB_BUILD_SHARED)
IF(BUILD_SHARED_LIBS)
ADD_DEFINITIONS( -DJSON_DLL )
TARGET_LINK_LIBRARIES(jsontestrunner_exe jsoncpp_lib)
ELSE(JSONCPP_LIB_BUILD_SHARED)
ELSE(BUILD_SHARED_LIBS)
TARGET_LINK_LIBRARIES(jsontestrunner_exe jsoncpp_lib_static)
ENDIF(JSONCPP_LIB_BUILD_SHARED)
ENDIF(BUILD_SHARED_LIBS)
SET_TARGET_PROPERTIES(jsontestrunner_exe PROPERTIES OUTPUT_NAME jsontestrunner_exe)

View File

@@ -1,10 +1,3 @@
OPTION(JSONCPP_LIB_BUILD_SHARED "Build jsoncpp_lib as a shared library." OFF)
OPTION(JSONCPP_LIB_BUILD_STATIC "Build jsoncpp_lib static library." ON)
IF(BUILD_SHARED_LIBS)
SET(JSONCPP_LIB_BUILD_SHARED ON)
ENDIF(BUILD_SHARED_LIBS)
if( CMAKE_COMPILER_IS_GNUCXX )
#Get compiler version.
execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion
@@ -46,7 +39,7 @@ ELSE(JSONCPP_WITH_CMAKE_PACKAGE)
SET(INSTALL_EXPORT)
ENDIF(JSONCPP_WITH_CMAKE_PACKAGE)
IF(JSONCPP_LIB_BUILD_SHARED)
IF(BUILD_SHARED_LIBS)
ADD_DEFINITIONS( -DJSON_DLL_BUILD )
ADD_LIBRARY(jsoncpp_lib SHARED ${PUBLIC_HEADERS} ${jsoncpp_sources})
SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_VERSION_MAJOR})
@@ -65,7 +58,7 @@ IF(JSONCPP_LIB_BUILD_SHARED)
ENDIF()
IF(JSONCPP_LIB_BUILD_STATIC)
IF(BUILD_STATIC_LIBS)
ADD_LIBRARY(jsoncpp_lib_static STATIC ${PUBLIC_HEADERS} ${jsoncpp_sources})
SET_TARGET_PROPERTIES( jsoncpp_lib_static PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_VERSION_MAJOR})
SET_TARGET_PROPERTIES( jsoncpp_lib_static PROPERTIES OUTPUT_NAME jsoncpp )

View File

@@ -17,7 +17,6 @@
#include <sstream>
#include <memory>
#include <set>
#include <stdexcept>
#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
#define snprintf _snprintf
@@ -33,27 +32,20 @@ static int stackDepth_g = 0; // see readValue()
namespace Json {
#if __cplusplus >= 201103L
typedef std::unique_ptr<CharReader> CharReaderPtr;
#else
typedef std::auto_ptr<CharReader> CharReaderPtr;
#endif
// Implementation of class Features
// ////////////////////////////////
Features::Features()
: allowComments_(true), strictRoot_(false),
allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {}
: allowComments_(true), strictRoot_(false)
{}
Features Features::all() { return Features(); }
Features Features::strictMode() {
Features features;
features.allowComments_ = false;
features.strictRoot_ = true;
features.allowDroppedNullPlaceholders_ = false;
features.allowNumericKeys_ = false;
return features;
}
@@ -148,7 +140,7 @@ bool Reader::readValue() {
// But this deprecated class has a security problem: Bad input can
// cause a seg-fault. This seems like a fair, binary-compatible way
// to prevent the problem.
if (stackDepth_g >= stackLimit_g) throw std::runtime_error("Exceeded stackLimit in readValue().");
if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
++stackDepth_g;
Token token;
@@ -163,11 +155,9 @@ bool Reader::readValue() {
switch (token.type_) {
case tokenObjectBegin:
successful = readObject(token);
currentValue().setOffsetLimit(current_ - begin_);
break;
case tokenArrayBegin:
successful = readArray(token);
currentValue().setOffsetLimit(current_ - begin_);
break;
case tokenNumber:
successful = decodeNumber(token);
@@ -179,42 +169,22 @@ bool Reader::readValue() {
{
Value v(true);
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case tokenFalse:
{
Value v(false);
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case tokenNull:
{
Value v;
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case tokenArraySeparator:
case tokenObjectEnd:
case tokenArrayEnd:
if (features_.allowDroppedNullPlaceholders_) {
// "Un-read" the current token and mark the current value as a null
// token.
current_--;
Value v;
currentValue().swapPayload(v);
currentValue().setOffsetStart(current_ - begin_ - 1);
currentValue().setOffsetLimit(current_ - begin_);
break;
} // Else, fall through...
// Else, fall through...
default:
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return addError("Syntax error: value, object or array expected.", token);
}
@@ -442,12 +412,11 @@ bool Reader::readString() {
return c == '"';
}
bool Reader::readObject(Token& tokenStart) {
bool Reader::readObject(Token& /*tokenStart*/) {
Token tokenName;
std::string name;
Value init(objectValue);
currentValue().swapPayload(init);
currentValue().setOffsetStart(tokenStart.start_ - begin_);
while (readToken(tokenName)) {
bool initialTokenOk = true;
while (tokenName.type_ == tokenComment && initialTokenOk)
@@ -460,11 +429,6 @@ bool Reader::readObject(Token& tokenStart) {
if (tokenName.type_ == tokenString) {
if (!decodeString(tokenName, name))
return recoverFromError(tokenObjectEnd);
} else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
Value numberName;
if (!decodeNumber(tokenName, numberName))
return recoverFromError(tokenObjectEnd);
name = numberName.asString();
} else {
break;
}
@@ -498,10 +462,9 @@ bool Reader::readObject(Token& tokenStart) {
"Missing '}' or object member name", tokenName, tokenObjectEnd);
}
bool Reader::readArray(Token& tokenStart) {
bool Reader::readArray(Token& /*tokenStart*/) {
Value init(arrayValue);
currentValue().swapPayload(init);
currentValue().setOffsetStart(tokenStart.start_ - begin_);
skipSpaces();
if (*current_ == ']') // empty array
{
@@ -541,8 +504,6 @@ bool Reader::decodeNumber(Token& token) {
if (!decodeNumber(token, decoded))
return false;
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
@@ -591,8 +552,6 @@ bool Reader::decodeDouble(Token& token) {
if (!decodeDouble(token, decoded))
return false;
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
@@ -638,8 +597,6 @@ bool Reader::decodeString(Token& token) {
return false;
Value decoded(decoded_string);
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
@@ -851,59 +808,8 @@ std::string Reader::getFormattedErrorMessages() const {
return formattedMessage;
}
std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
std::vector<Reader::StructuredError> allErrors;
for (Errors::const_iterator itError = errors_.begin();
itError != errors_.end();
++itError) {
const ErrorInfo& error = *itError;
Reader::StructuredError structured;
structured.offset_start = error.token_.start_ - begin_;
structured.offset_limit = error.token_.end_ - begin_;
structured.message = error.message_;
allErrors.push_back(structured);
}
return allErrors;
}
bool Reader::pushError(const Value& value, const std::string& message) {
size_t length = end_ - begin_;
if(value.getOffsetStart() > length
|| value.getOffsetLimit() > length)
return false;
Token token;
token.type_ = tokenError;
token.start_ = begin_ + value.getOffsetStart();
token.end_ = end_ + value.getOffsetLimit();
ErrorInfo info;
info.token_ = token;
info.message_ = message;
info.extra_ = 0;
errors_.push_back(info);
return true;
}
bool Reader::pushError(const Value& value, const std::string& message, const Value& extra) {
size_t length = end_ - begin_;
if(value.getOffsetStart() > length
|| value.getOffsetLimit() > length
|| extra.getOffsetLimit() > length)
return false;
Token token;
token.type_ = tokenError;
token.start_ = begin_ + value.getOffsetStart();
token.end_ = begin_ + value.getOffsetLimit();
ErrorInfo info;
info.token_ = token;
info.message_ = message;
info.extra_ = begin_ + extra.getOffsetStart();
errors_.push_back(info);
return true;
}
bool Reader::good() const {
return !errors_.size();
}
// Reader
/////////////////////////
// exact copy of Features
class OurFeatures {
@@ -953,10 +859,6 @@ public:
Value& root,
bool collectComments = true);
std::string getFormattedErrorMessages() const;
std::vector<StructuredError> getStructuredErrors() const;
bool pushError(const Value& value, const std::string& message);
bool pushError(const Value& value, const std::string& message, const Value& extra);
bool good() const;
private:
OurReader(OurReader const&); // no impl
@@ -1107,7 +1009,7 @@ bool OurReader::parse(const char* beginDoc,
}
bool OurReader::readValue() {
if (stackDepth_ >= features_.stackLimit_) throw std::runtime_error("Exceeded stackLimit in readValue().");
if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
++stackDepth_;
Token token;
skipCommentTokens(token);
@@ -1121,11 +1023,9 @@ bool OurReader::readValue() {
switch (token.type_) {
case tokenObjectBegin:
successful = readObject(token);
currentValue().setOffsetLimit(current_ - begin_);
break;
case tokenArrayBegin:
successful = readArray(token);
currentValue().setOffsetLimit(current_ - begin_);
break;
case tokenNumber:
successful = decodeNumber(token);
@@ -1137,24 +1037,18 @@ bool OurReader::readValue() {
{
Value v(true);
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case tokenFalse:
{
Value v(false);
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case tokenNull:
{
Value v;
currentValue().swapPayload(v);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
}
break;
case tokenArraySeparator:
@@ -1166,13 +1060,9 @@ bool OurReader::readValue() {
current_--;
Value v;
currentValue().swapPayload(v);
currentValue().setOffsetStart(current_ - begin_ - 1);
currentValue().setOffsetLimit(current_ - begin_);
break;
} // else, fall through ...
default:
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return addError("Syntax error: value, object or array expected.", token);
}
@@ -1404,7 +1294,6 @@ bool OurReader::readObject(Token& tokenStart) {
std::string name;
Value init(objectValue);
currentValue().swapPayload(init);
currentValue().setOffsetStart(tokenStart.start_ - begin_);
while (readToken(tokenName)) {
bool initialTokenOk = true;
while (tokenName.type_ == tokenComment && initialTokenOk)
@@ -1431,7 +1320,7 @@ bool OurReader::readObject(Token& tokenStart) {
return addErrorAndRecover(
"Missing ':' after object member name", colon, tokenObjectEnd);
}
if (name.length() >= (1U<<30)) throw std::runtime_error("keylength >= 2^30");
if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30");
if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
std::string msg = "Duplicate key: '" + name + "'";
return addErrorAndRecover(
@@ -1464,7 +1353,6 @@ bool OurReader::readObject(Token& tokenStart) {
bool OurReader::readArray(Token& tokenStart) {
Value init(arrayValue);
currentValue().swapPayload(init);
currentValue().setOffsetStart(tokenStart.start_ - begin_);
skipSpaces();
if (*current_ == ']') // empty array
{
@@ -1504,8 +1392,6 @@ bool OurReader::decodeNumber(Token& token) {
if (!decodeNumber(token, decoded))
return false;
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
@@ -1554,8 +1440,6 @@ bool OurReader::decodeDouble(Token& token) {
if (!decodeDouble(token, decoded))
return false;
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
@@ -1601,8 +1485,6 @@ bool OurReader::decodeString(Token& token) {
return false;
Value decoded(decoded_string);
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
@@ -1809,60 +1691,6 @@ std::string OurReader::getFormattedErrorMessages() const {
return formattedMessage;
}
std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
std::vector<OurReader::StructuredError> allErrors;
for (Errors::const_iterator itError = errors_.begin();
itError != errors_.end();
++itError) {
const ErrorInfo& error = *itError;
OurReader::StructuredError structured;
structured.offset_start = error.token_.start_ - begin_;
structured.offset_limit = error.token_.end_ - begin_;
structured.message = error.message_;
allErrors.push_back(structured);
}
return allErrors;
}
bool OurReader::pushError(const Value& value, const std::string& message) {
size_t length = end_ - begin_;
if(value.getOffsetStart() > length
|| value.getOffsetLimit() > length)
return false;
Token token;
token.type_ = tokenError;
token.start_ = begin_ + value.getOffsetStart();
token.end_ = end_ + value.getOffsetLimit();
ErrorInfo info;
info.token_ = token;
info.message_ = message;
info.extra_ = 0;
errors_.push_back(info);
return true;
}
bool OurReader::pushError(const Value& value, const std::string& message, const Value& extra) {
size_t length = end_ - begin_;
if(value.getOffsetStart() > length
|| value.getOffsetLimit() > length
|| extra.getOffsetLimit() > length)
return false;
Token token;
token.type_ = tokenError;
token.start_ = begin_ + value.getOffsetStart();
token.end_ = begin_ + value.getOffsetLimit();
ErrorInfo info;
info.token_ = token;
info.message_ = message;
info.extra_ = begin_ + extra.getOffsetStart();
errors_.push_back(info);
return true;
}
bool OurReader::good() const {
return !errors_.size();
}
class OurCharReader : public CharReader {
bool const collectComments_;
@@ -1994,7 +1822,7 @@ std::istream& operator>>(std::istream& sin, Value& root) {
"Error from reader: %s",
errs.c_str());
JSON_FAIL_MESSAGE("reader error");
throwRuntimeError("reader error");
}
return sin;
}

View File

@@ -29,12 +29,13 @@ namespace Json {
#if defined(__ARMEL__)
#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
#else
// This exists for binary compatibility only. Use nullRef.
const Value Value::null;
#define ALIGNAS(byte_alignment)
#endif
static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
const unsigned char& kNullRef = kNull[0];
const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
const Value& Value::nullRef = null;
const Value& Value::nullRef = reinterpret_cast<const Value&>(kNullRef);
const Int Value::minInt = Int(~(UInt(-1) / 2));
const Int Value::maxInt = Int(UInt(-1) / 2);
@@ -87,9 +88,11 @@ static inline char* duplicateStringValue(const char* value,
length = Value::maxInt - 1;
char* newString = static_cast<char*>(malloc(length + 1));
JSON_ASSERT_MESSAGE(newString != 0,
"in Json::Value::duplicateStringValue(): "
"Failed to allocate string value buffer");
if (newString == NULL) {
throwRuntimeError(
"in Json::Value::duplicateStringValue(): "
"Failed to allocate string value buffer");
}
memcpy(newString, value, length);
newString[length] = 0;
return newString;
@@ -108,9 +111,11 @@ static inline char* duplicateAndPrefixStringValue(
"length too big for prefixing");
unsigned actualLength = length + sizeof(unsigned) + 1U;
char* newString = static_cast<char*>(malloc(actualLength));
JSON_ASSERT_MESSAGE(newString != 0,
"in Json::Value::duplicateAndPrefixStringValue(): "
"Failed to allocate string value buffer");
if (newString == 0) {
throwRuntimeError(
"in Json::Value::duplicateAndPrefixStringValue(): "
"Failed to allocate string value buffer");
}
*reinterpret_cast<unsigned*>(newString) = length;
memcpy(newString + sizeof(unsigned), value, length);
newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later
@@ -148,6 +153,47 @@ static inline void releaseStringValue(char* value) { free(value); }
namespace Json {
class JSON_API Exception : public std::exception {
public:
Exception(std::string const& msg);
virtual ~Exception() throw();
virtual char const* what() const throw();
protected:
std::string const msg_;
};
class JSON_API RuntimeError : public Exception {
public:
RuntimeError(std::string const& msg);
};
class JSON_API LogicError : public Exception {
public:
LogicError(std::string const& msg);
};
Exception::Exception(std::string const& msg)
: msg_(msg)
{}
Exception::~Exception() throw()
{}
char const* Exception::what() const throw()
{
return msg_.c_str();
}
RuntimeError::RuntimeError(std::string const& msg)
: Exception(msg)
{}
LogicError::LogicError(std::string const& msg)
: Exception(msg)
{}
void throwRuntimeError(std::string const& msg)
{
throw RuntimeError(msg);
}
void throwLogicError(std::string const& msg)
{
throw LogicError(msg);
}
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
@@ -356,7 +402,7 @@ Value::Value(bool value) {
Value::Value(Value const& other)
: type_(other.type_), allocated_(false)
,
comments_(0), start_(other.start_), limit_(other.limit_)
comments_(0)
{
switch (type_) {
case nullValue:
@@ -421,8 +467,9 @@ Value::~Value() {
delete[] comments_;
}
Value& Value::operator=(Value other) {
swap(other);
Value &Value::operator=(const Value &other) {
Value temp(other);
swap(temp);
return *this;
}
@@ -439,8 +486,6 @@ void Value::swapPayload(Value& other) {
void Value::swap(Value& other) {
swapPayload(other);
std::swap(comments_, other.comments_);
std::swap(start_, other.start_);
std::swap(limit_, other.limit_);
}
ValueType Value::type() const { return type_; }
@@ -842,8 +887,6 @@ void Value::clear() {
JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
type_ == objectValue,
"in Json::Value::clear(): requires complex value");
start_ = 0;
limit_ = 0;
switch (type_) {
case arrayValue:
case objectValue:
@@ -919,8 +962,6 @@ void Value::initBasic(ValueType type, bool allocated) {
type_ = type;
allocated_ = allocated;
comments_ = 0;
start_ = 0;
limit_ = 0;
}
// Access an object value by name, create a null member if it does not exist.
@@ -1290,14 +1331,6 @@ std::string Value::getComment(CommentPlacement placement) const {
return "";
}
void Value::setOffsetStart(size_t start) { start_ = start; }
void Value::setOffsetLimit(size_t limit) { limit_ = limit; }
size_t Value::getOffsetStart() const { return start_; }
size_t Value::getOffsetLimit() const { return limit_; }
std::string Value::toStyledString() const {
StyledWriter writer;
return writer.write(*this);

View File

@@ -92,6 +92,14 @@ UInt ValueIteratorBase::index() const {
return Value::UInt(-1);
}
std::string ValueIteratorBase::name() const {
char const* key;
char const* end;
key = memberName(&end);
if (!key) return std::string();
return std::string(key, end);
}
char const* ValueIteratorBase::memberName() const {
const char* name = (*current_).first.data();
return name ? name : "";

View File

@@ -12,13 +12,28 @@
#include <sstream>
#include <utility>
#include <set>
#include <stdexcept>
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <cassert>
#include <cstring>
#include <cstdio>
#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0
#include <float.h>
#define isfinite _finite
#elif defined(__sun) && defined(__SVR4) //Solaris
#include <ieeefp.h>
#define isfinite finite
#else
#include <cmath>
#define isfinite std::isfinite
#endif
#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
#define snprintf _snprintf
#elif __cplusplus >= 201103L
#define snprintf std::snprintf
#endif
#if defined(__BORLANDC__)
#include <float.h>
#define isfinite _finite
#define snprintf _snprintf
@@ -29,18 +44,9 @@
#pragma warning(disable : 4996)
#endif
#if defined(__sun) && defined(__SVR4) //Solaris
#include <ieeefp.h>
#define isfinite finite
#endif
namespace Json {
#if __cplusplus >= 201103L
typedef std::unique_ptr<StreamWriter> StreamWriterPtr;
#else
typedef std::auto_ptr<StreamWriter> StreamWriterPtr;
#endif
static bool containsControlCharacter(const char* str) {
while (*str) {
@@ -280,28 +286,21 @@ Writer::~Writer() {}
// //////////////////////////////////////////////////////////////////
FastWriter::FastWriter()
: yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
omitEndingLineFeed_(false) {}
: yamlCompatiblityEnabled_(false) {}
void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; }
void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }
void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }
std::string FastWriter::write(const Value& root) {
document_ = "";
writeValue(root);
if (!omitEndingLineFeed_)
document_ += "\n";
document_ += "\n";
return document_;
}
void FastWriter::writeValue(const Value& value) {
switch (value.type()) {
case nullValue:
if (!dropNullPlaceholders_)
document_ += "null";
document_ += "null";
break;
case intValue:
document_ += valueToString(value.asLargestInt());
@@ -313,8 +312,14 @@ void FastWriter::writeValue(const Value& value) {
document_ += valueToString(value.asDouble());
break;
case stringValue:
document_ += valueToQuotedString(value.asCString());
{
// Is NULL possible for value.string_?
char const* str;
char const* end;
bool ok = value.getString(&str, &end);
if (ok) document_ += valueToQuotedStringN(str, static_cast<unsigned>(end-str));
break;
}
case booleanValue:
document_ += valueToString(value.asBool());
break;
@@ -378,7 +383,7 @@ void StyledWriter::writeValue(const Value& value) {
break;
case stringValue:
{
// Is NULL is possible for value.string_?
// Is NULL possible for value.string_?
char const* str;
char const* end;
bool ok = value.getString(&str, &end);
@@ -595,8 +600,15 @@ void StyledStreamWriter::writeValue(const Value& value) {
pushValue(valueToString(value.asDouble()));
break;
case stringValue:
pushValue(valueToQuotedString(value.asCString()));
{
// Is NULL possible for value.string_?
char const* str;
char const* end;
bool ok = value.getString(&str, &end);
if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
else pushValue("");
break;
}
case booleanValue:
pushValue(valueToString(value.asBool()));
break;
@@ -1080,7 +1092,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
} else if (cs_str == "None") {
cs = CommentStyle::None;
} else {
throw std::runtime_error("commentStyle must be 'All' or 'None'");
throwRuntimeError("commentStyle must be 'All' or 'None'");
}
std::string colonSymbol = " : ";
if (eyc) {

View File

@@ -1,9 +1,5 @@
# vim: et ts=4 sts=4 sw=4 tw=0
IF(JSONCPP_LIB_BUILD_SHARED)
ADD_DEFINITIONS( -DJSON_DLL )
ENDIF(JSONCPP_LIB_BUILD_SHARED)
ADD_EXECUTABLE( jsoncpp_test
jsontest.cpp
jsontest.h
@@ -11,11 +7,12 @@ ADD_EXECUTABLE( jsoncpp_test
)
IF(JSONCPP_LIB_BUILD_SHARED)
IF(BUILD_SHARED_LIBS)
ADD_DEFINITIONS( -DJSON_DLL )
TARGET_LINK_LIBRARIES(jsoncpp_test jsoncpp_lib)
ELSE(JSONCPP_LIB_BUILD_SHARED)
ELSE(BUILD_SHARED_LIBS)
TARGET_LINK_LIBRARIES(jsoncpp_test jsoncpp_lib_static)
ENDIF(JSONCPP_LIB_BUILD_SHARED)
ENDIF(BUILD_SHARED_LIBS)
# another way to solve issue #90
#set_target_properties(jsoncpp_test PROPERTIES COMPILE_FLAGS -ffloat-store)
@@ -23,19 +20,19 @@ ENDIF(JSONCPP_LIB_BUILD_SHARED)
# Run unit tests in post-build
# (default cmake workflow hides away the test result into a file, resulting in poor dev workflow?!?)
IF(JSONCPP_WITH_POST_BUILD_UNITTEST)
IF(JSONCPP_LIB_BUILD_SHARED)
IF(BUILD_SHARED_LIBS)
# First, copy the shared lib, for Microsoft.
# Then, run the test executable.
ADD_CUSTOM_COMMAND( TARGET jsoncpp_test
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:jsoncpp_lib> $<TARGET_FILE_DIR:jsoncpp_test>
COMMAND $<TARGET_FILE:jsoncpp_test>)
ELSE(JSONCPP_LIB_BUILD_SHARED)
ELSE(BUILD_SHARED_LIBS)
# Just run the test executable.
ADD_CUSTOM_COMMAND( TARGET jsoncpp_test
POST_BUILD
COMMAND $<TARGET_FILE:jsoncpp_test>)
ENDIF(JSONCPP_LIB_BUILD_SHARED)
ENDIF(BUILD_SHARED_LIBS)
ENDIF(JSONCPP_WITH_POST_BUILD_UNITTEST)
SET_TARGET_PROPERTIES(jsoncpp_test PROPERTIES OUTPUT_NAME jsoncpp_test)

View File

@@ -6,7 +6,6 @@
#include "jsontest.h"
#include <json/config.h>
#include <json/json.h>
#include <stdexcept>
#include <cstring>
// Make numeric limits more convenient to talk about.
@@ -258,6 +257,20 @@ JSONTEST_FIXTURE(ValueTest, arrays) {
JSONTEST_ASSERT_EQUAL(Json::Value(17), got);
JSONTEST_ASSERT_EQUAL(false, array1_.removeIndex(2, &got)); // gone now
}
JSONTEST_FIXTURE(ValueTest, arrayIssue252)
{
int count = 5;
Json::Value root;
Json::Value item;
root["array"] = Json::Value::nullRef;
for (int i = 0; i < count; i++)
{
item["a"] = i;
item["b"] = i;
root["array"][i] = item;
}
//JSONTEST_ASSERT_EQUAL(5, root["array"].size());
}
JSONTEST_FIXTURE(ValueTest, null) {
JSONTEST_ASSERT_EQUAL(Json::nullValue, null_.type());
@@ -283,7 +296,10 @@ JSONTEST_FIXTURE(ValueTest, null) {
JSONTEST_ASSERT_EQUAL(0.0, null_.asFloat());
JSONTEST_ASSERT_STRING_EQUAL("", null_.asString());
#if !defined(__ARMEL__)
// See line #165 of include/json/value.h
JSONTEST_ASSERT_EQUAL(Json::Value::null, null_);
#endif
}
JSONTEST_FIXTURE(ValueTest, strings) {
@@ -1499,25 +1515,6 @@ JSONTEST_FIXTURE(ValueTest, typeChecksThrowExceptions) {
#endif
}
JSONTEST_FIXTURE(ValueTest, offsetAccessors) {
Json::Value x;
JSONTEST_ASSERT(x.getOffsetStart() == 0);
JSONTEST_ASSERT(x.getOffsetLimit() == 0);
x.setOffsetStart(10);
x.setOffsetLimit(20);
JSONTEST_ASSERT(x.getOffsetStart() == 10);
JSONTEST_ASSERT(x.getOffsetLimit() == 20);
Json::Value y(x);
JSONTEST_ASSERT(y.getOffsetStart() == 10);
JSONTEST_ASSERT(y.getOffsetLimit() == 20);
Json::Value z;
z.swap(y);
JSONTEST_ASSERT(z.getOffsetStart() == 10);
JSONTEST_ASSERT(z.getOffsetLimit() == 20);
JSONTEST_ASSERT(y.getOffsetStart() == 0);
JSONTEST_ASSERT(y.getOffsetLimit() == 0);
}
JSONTEST_FIXTURE(ValueTest, StaticString) {
char mutant[] = "hello";
Json::StaticString ss(mutant);
@@ -1543,7 +1540,7 @@ JSONTEST_FIXTURE(ValueTest, StaticString) {
JSONTEST_FIXTURE(ValueTest, CommentBefore) {
Json::Value val; // fill val
val.setComment("// this comment should appear before", Json::commentBefore);
val.setComment(std::string("// this comment should appear before"), Json::commentBefore);
Json::StreamWriterBuilder wbuilder;
wbuilder.settings_["commentStyle"] = "All";
{
@@ -1638,17 +1635,6 @@ JSONTEST_FIXTURE(ValueTest, zeroesInKeys) {
}
}
struct WriterTest : JsonTest::TestCase {};
JSONTEST_FIXTURE(WriterTest, dropNullPlaceholders) {
Json::FastWriter writer;
Json::Value nullValue;
JSONTEST_ASSERT(writer.write(nullValue) == "null\n");
writer.dropNullPlaceholders();
JSONTEST_ASSERT(writer.write(nullValue) == "\n");
}
struct StreamWriterTest : JsonTest::TestCase {};
JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) {
@@ -1690,7 +1676,6 @@ JSONTEST_FIXTURE(ReaderTest, parseWithNoErrors) {
bool ok = reader.parse("{ \"property\" : \"value\" }", root);
JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(reader.getFormattedErrorMessages().size() == 0);
JSONTEST_ASSERT(reader.getStructuredErrors().size() == 0);
}
JSONTEST_FIXTURE(ReaderTest, parseWithNoErrorsTestingOffsets) {
@@ -1702,25 +1687,6 @@ JSONTEST_FIXTURE(ReaderTest, parseWithNoErrorsTestingOffsets) {
root);
JSONTEST_ASSERT(ok);
JSONTEST_ASSERT(reader.getFormattedErrorMessages().size() == 0);
JSONTEST_ASSERT(reader.getStructuredErrors().size() == 0);
JSONTEST_ASSERT(root["property"].getOffsetStart() == 15);
JSONTEST_ASSERT(root["property"].getOffsetLimit() == 34);
JSONTEST_ASSERT(root["property"][0].getOffsetStart() == 16);
JSONTEST_ASSERT(root["property"][0].getOffsetLimit() == 23);
JSONTEST_ASSERT(root["property"][1].getOffsetStart() == 25);
JSONTEST_ASSERT(root["property"][1].getOffsetLimit() == 33);
JSONTEST_ASSERT(root["obj"].getOffsetStart() == 44);
JSONTEST_ASSERT(root["obj"].getOffsetLimit() == 76);
JSONTEST_ASSERT(root["obj"]["nested"].getOffsetStart() == 57);
JSONTEST_ASSERT(root["obj"]["nested"].getOffsetLimit() == 60);
JSONTEST_ASSERT(root["obj"]["bool"].getOffsetStart() == 71);
JSONTEST_ASSERT(root["obj"]["bool"].getOffsetLimit() == 75);
JSONTEST_ASSERT(root["null"].getOffsetStart() == 87);
JSONTEST_ASSERT(root["null"].getOffsetLimit() == 91);
JSONTEST_ASSERT(root["false"].getOffsetStart() == 103);
JSONTEST_ASSERT(root["false"].getOffsetLimit() == 108);
JSONTEST_ASSERT(root.getOffsetStart() == 0);
JSONTEST_ASSERT(root.getOffsetLimit() == 110);
}
JSONTEST_FIXTURE(ReaderTest, parseWithOneError) {
@@ -1731,13 +1697,6 @@ JSONTEST_FIXTURE(ReaderTest, parseWithOneError) {
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
"* Line 1, Column 15\n Syntax error: value, object or array "
"expected.\n");
std::vector<Json::Reader::StructuredError> errors =
reader.getStructuredErrors();
JSONTEST_ASSERT(errors.size() == 1);
JSONTEST_ASSERT(errors.at(0).offset_start == 14);
JSONTEST_ASSERT(errors.at(0).offset_limit == 15);
JSONTEST_ASSERT(errors.at(0).message ==
"Syntax error: value, object or array expected.");
}
JSONTEST_FIXTURE(ReaderTest, parseChineseWithOneError) {
@@ -1748,13 +1707,6 @@ JSONTEST_FIXTURE(ReaderTest, parseChineseWithOneError) {
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
"* Line 1, Column 19\n Syntax error: value, object or array "
"expected.\n");
std::vector<Json::Reader::StructuredError> errors =
reader.getStructuredErrors();
JSONTEST_ASSERT(errors.size() == 1);
JSONTEST_ASSERT(errors.at(0).offset_start == 18);
JSONTEST_ASSERT(errors.at(0).offset_limit == 19);
JSONTEST_ASSERT(errors.at(0).message ==
"Syntax error: value, object or array expected.");
}
JSONTEST_FIXTURE(ReaderTest, parseWithDetailError) {
@@ -1765,12 +1717,6 @@ JSONTEST_FIXTURE(ReaderTest, parseWithDetailError) {
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
"* Line 1, Column 16\n Bad escape sequence in string\nSee "
"Line 1, Column 20 for detail.\n");
std::vector<Json::Reader::StructuredError> errors =
reader.getStructuredErrors();
JSONTEST_ASSERT(errors.size() == 1);
JSONTEST_ASSERT(errors.at(0).offset_start == 15);
JSONTEST_ASSERT(errors.at(0).offset_limit == 23);
JSONTEST_ASSERT(errors.at(0).message == "Bad escape sequence in string");
}
struct CharReaderTest : JsonTest::TestCase {};
@@ -2210,6 +2156,7 @@ JSONTEST_FIXTURE(CharReaderAllowSingleQuotesTest, issue182) {
JSONTEST_ASSERT_STRING_EQUAL("x", root["a"].asString());
JSONTEST_ASSERT_STRING_EQUAL("y", root["b"].asString());
}
delete reader;
}
struct CharReaderAllowZeroesTest : JsonTest::TestCase {};
@@ -2242,6 +2189,7 @@ JSONTEST_FIXTURE(CharReaderAllowZeroesTest, issue176) {
JSONTEST_ASSERT_STRING_EQUAL("x", root["a"].asString());
JSONTEST_ASSERT_STRING_EQUAL("y", root["b"].asString());
}
delete reader;
}
struct BuilderTest : JsonTest::TestCase {};
@@ -2283,12 +2231,49 @@ JSONTEST_FIXTURE(IteratorTest, distance) {
JSONTEST_ASSERT_STRING_EQUAL("b", str);
}
JSONTEST_FIXTURE(IteratorTest, names) {
Json::Value json;
json["k1"] = "a";
json["k2"] = "b";
Json::ValueIterator it = json.begin();
JSONTEST_ASSERT(it != json.end());
JSONTEST_ASSERT_EQUAL(Json::Value("k1"), it.key());
JSONTEST_ASSERT_STRING_EQUAL("k1", it.name());
JSONTEST_ASSERT_EQUAL(-1, it.index());
++it;
JSONTEST_ASSERT(it != json.end());
JSONTEST_ASSERT_EQUAL(Json::Value("k2"), it.key());
JSONTEST_ASSERT_STRING_EQUAL("k2", it.name());
JSONTEST_ASSERT_EQUAL(-1, it.index());
++it;
JSONTEST_ASSERT(it == json.end());
}
JSONTEST_FIXTURE(IteratorTest, indexes) {
Json::Value json;
json[0] = "a";
json[1] = "b";
Json::ValueIterator it = json.begin();
JSONTEST_ASSERT(it != json.end());
JSONTEST_ASSERT_EQUAL(Json::Value(Json::ArrayIndex(0)), it.key());
JSONTEST_ASSERT_STRING_EQUAL("", it.name());
JSONTEST_ASSERT_EQUAL(0, it.index());
++it;
JSONTEST_ASSERT(it != json.end());
JSONTEST_ASSERT_EQUAL(Json::Value(Json::ArrayIndex(1)), it.key());
JSONTEST_ASSERT_STRING_EQUAL("", it.name());
JSONTEST_ASSERT_EQUAL(1, it.index());
++it;
JSONTEST_ASSERT(it == json.end());
}
int main(int argc, const char* argv[]) {
JsonTest::Runner runner;
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, memberCount);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, objects);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, arrays);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, arrayIssue252);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, null);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, strings);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, bools);
@@ -2303,7 +2288,6 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareArray);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareObject);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareType);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, offsetAccessors);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, typeChecksThrowExceptions);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, StaticString);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, CommentBefore);
@@ -2311,7 +2295,6 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroes);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroesInKeys);
JSONTEST_REGISTER_FIXTURE(runner, WriterTest, dropNullPlaceholders);
JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, dropNullPlaceholders);
JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeZeroes);
@@ -2347,6 +2330,8 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, BuilderTest, settings);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, distance);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, names);
JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, indexes);
return runner.runCommandLine(argc, argv);
}

View File

@@ -1,4 +1,10 @@
# removes all files created during testing
# Copyright 2007 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
"""Removes all files created during testing."""
import glob
import os

View File

@@ -1,3 +1,8 @@
# Copyright 2007 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
from __future__ import print_function
import glob
import os.path

View File

@@ -1,4 +1,11 @@
# Simple implementation of a json test runner to run the test against json-py.
# Copyright 2007 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
"""Simple implementation of a json test runner to run the test against
json-py."""
from __future__ import print_function
import sys
import os.path

View File

@@ -1,3 +1,8 @@
# Copyright 2007 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
from __future__ import print_function
from __future__ import unicode_literals
from io import open

View File

@@ -1,3 +1,8 @@
# Copyright 2009 Baptiste Lepilleur
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
from __future__ import print_function
from __future__ import unicode_literals
from io import open

29
travis.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/usr/bin/env sh
# This is called by `.travis.yml` via Travis CI.
# Travis supplies $TRAVIS_OS_NAME.
# http://docs.travis-ci.com/user/multi-os/
# Our .travis.yml also defines:
# - SHARED_LIB=ON/OFF
# - STATIC_LIB=ON/OFF
# - CMAKE_PKG=ON/OFF
# - BUILD_TYPE=release/debug
# - VERBOSE_MAKE=false/true
# - VERBOSE (set or not)
# -e: fail on error
# -v: show commands
# -x: show expanded commands
set -vex
env | sort
cmake -DJSONCPP_WITH_CMAKE_PACKAGE=$CMAKE_PKG -DBUILD_SHARED_LIBS=$SHARED_LIB -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_VERBOSE_MAKEFILE=$VERBOSE_MAKE .
make
# Python is not available in Travis for osx.
# https://github.com/travis-ci/travis-ci/issues/2320
if [ "$TRAVIS_OS_NAME" != "osx" ]
then
make jsoncpp_check
valgrind --error-exitcode=42 --leak-check=full ./src/test_lib_json/jsoncpp_test
fi

View File

@@ -1 +1 @@
1.5.4
0.10.2