Compare commits

..

No commits in common. "master" and "1.7.7" have entirely different histories.

237 changed files with 6500 additions and 7279 deletions

View File

@ -1,4 +1,47 @@
BasedOnStyle: LLVM ---
DerivePointerAlignment: false # BasedOnStyle: LLVM
PointerAlignment: Left AccessModifierOffset: -2
ConstructorInitializerIndentWidth: 4
AlignEscapedNewlinesLeft: false
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakTemplateDeclarations: false
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: false
ColumnLimit: 80
ConstructorInitializerAllOnOneLineOrOnePerLine: false
DerivePointerBinding: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 60
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerBindsToType: true
SpacesBeforeTrailingComments: 1 SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: false
Standard: Cpp03
IndentWidth: 2
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Attach
IndentFunctionDeclarationAfterType: false
SpacesInParentheses: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpaceAfterControlStatementKeyword: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
...

View File

@ -1,11 +0,0 @@
---
Checks: 'google-readability-casting,modernize-deprecated-headers,modernize-loop-convert,modernize-use-auto,modernize-use-default-member-init,modernize-use-using,readability-else-after-return,readability-redundant-member-init,readability-redundant-string-cstr'
WarningsAsErrors: ''
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
FormatStyle: none
CheckOptions:
- key: modernize-use-using.IgnoreMacros
value: '0'
...

View File

@ -1,26 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Meson version
- Ninja version
**Additional context**
Add any other context about the problem here.

View File

@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -1,20 +0,0 @@
name: clang-format check
on: [check_run, pull_request, push]
jobs:
formatting-check:
name: formatting check
runs-on: ubuntu-latest
strategy:
matrix:
path:
- 'src'
- 'examples'
- 'include'
steps:
- uses: actions/checkout@v4
- name: runs clang-format style check for C/C++/Protobuf programs.
uses: jidicula/clang-format-action@v4.13.0
with:
clang-format-version: '18'
check-path: ${{ matrix.path }}

View File

@ -1,18 +0,0 @@
name: cmake
on: [check_run, push, pull_request]
jobs:
cmake-publish:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: checkout project
uses: actions/checkout@v4
- name: build project
uses: threeal/cmake-action@v2.0.0

View File

@ -1,65 +0,0 @@
name: meson build and test
run-name: update pushed to ${{ github.ref }}
on: [check_run, push, pull_request]
jobs:
meson-publish:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: setup python
uses: actions/setup-python@v5
- name: meson build
uses: BSFishy/meson-build@v1.0.3
with:
meson-version: 1.5.1
ninja-version: 1.11.1.1
action: build
- name: meson test
uses: BSFishy/meson-build@v1.0.3
with:
meson-version: 1.5.1
ninja-version: 1.11.1.1
action: test
meson-coverage:
runs-on: ubuntu-latest
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: setup python
uses: actions/setup-python@v5
- name: meson build
uses: BSFishy/meson-build@v1.0.3
with:
meson-version: 1.5.1
ninja-version: 1.11.1.1
setup-options: -Db_coverage=true
action: build
- name: meson test
uses: BSFishy/meson-build@v1.0.3
with:
meson-version: 1.5.1
ninja-version: 1.11.1.1
setup-options: -Db_coverage=true
action: test
- name: generate code coverage report
uses: threeal/gcovr-action@v1.0.0
with:
coveralls-send: true
github-token: ${{ secrets.GITHUB_TOKEN }}

21
.gitignore vendored
View File

@ -1,5 +1,4 @@
/build/ /build/
/build-*/
*.pyc *.pyc
*.swp *.swp
*.actual *.actual
@ -7,10 +6,12 @@
*.process-output *.process-output
*.rewrite *.rewrite
/bin/ /bin/
/buildscons/
/libs/ /libs/
/doc/doxyfile /doc/doxyfile
/dist/ /dist/
/.cache/ #/version
#/include/json/version.h
# MSVC project files: # MSVC project files:
*.sln *.sln
@ -29,9 +30,10 @@
# CMake-generated files: # CMake-generated files:
CMakeFiles/ CMakeFiles/
/pkg-config/jsoncpp.pc CTestTestFile.cmake
cmake_install.cmake
pkg-config/jsoncpp.pc
jsoncpp_lib_static.dir/ jsoncpp_lib_static.dir/
compile_commands.json
# In case someone runs cmake in the root-dir: # In case someone runs cmake in the root-dir:
/CMakeCache.txt /CMakeCache.txt
@ -43,19 +45,8 @@ compile_commands.json
/src/lib_json/Makefile /src/lib_json/Makefile
/src/test_lib_json/Makefile /src/test_lib_json/Makefile
/src/test_lib_json/jsoncpp_test /src/test_lib_json/jsoncpp_test
*.a
# eclipse project files # eclipse project files
.project .project
.cproject .cproject
/.settings/ /.settings/
# DS_Store
.DS_Store
# temps
/version
# Bazel output paths
/bazel-*
/MODULE.bazel.lock

43
.travis.yml Normal file
View File

@ -0,0 +1,43 @@
# Build matrix / environment variable are explained on:
# http://about.travis-ci.org/docs/user/build-configuration/
# This file can be validated on:
# http://lint.travis-ci.org/
# See also
# http://stackoverflow.com/questions/22111549/travis-ci-with-clang-3-4-and-c11/30925448#30925448
# to allow C++11, though we are not yet building with -std=c++11
install:
# /usr/bin/gcc is 4.6 always, but gcc-X.Y is available.
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
# /usr/bin/clang is our version already, and clang-X.Y does not exist.
#- if [ "$CXX" = "clang++" ]; then export CXX="clang++-3.7" CC="clang-3.7"; fi
- echo ${PATH}
- ls /usr/local
- ls /usr/local/bin
- export PATH=/usr/local/bin:/usr/bin:${PATH}
- echo ${CXX}
- ${CXX} --version
- which valgrind
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.9
- g++-4.9
- clang
- valgrind
os:
- linux
language: cpp
compiler:
- gcc
- clang
script: ./travis.sh
env:
matrix:
- SHARED_LIB=ON STATIC_LIB=ON CMAKE_PKG=ON BUILD_TYPE=release VERBOSE_MAKE=false
- SHARED_LIB=OFF STATIC_LIB=ON CMAKE_PKG=OFF BUILD_TYPE=debug VERBOSE_MAKE=true VERBOSE
notifications:
email: false
sudo: false

114
AUTHORS
View File

@ -1,115 +1 @@
Baptiste Lepilleur <blep@users.sourceforge.net> Baptiste Lepilleur <blep@users.sourceforge.net>
Aaron Jacobs <aaronjjacobs@gmail.com>
Aaron Jacobs <jacobsa@google.com>
Adam Boseley <ABoseley@agjunction.com>
Adam Boseley <adam.boseley@gmail.com>
Aleksandr Derbenev <13alexac@gmail.com>
Alexander Gazarov <DrMetallius@users.noreply.github.com>
Alexander V. Brezgin <abrezgin@appliedtech.ru>
Alexandr Brezgin <albrezgin@mail.ru>
Alexey Kruchinin <alexey@mopals.com>
Anton Indrawan <anton.indrawan@gmail.com>
Baptiste Jonglez <git@bitsofnetworks.org>
Baptiste Lepilleur <baptiste.lepilleur@gmail.com>
Baruch Siach <baruch@tkos.co.il>
Ben Boeckel <mathstuf@gmail.com>
Benjamin Knecht <bknecht@logitech.com>
Bernd Kuhls <bernd.kuhls@t-online.de>
Billy Donahue <billy.donahue@gmail.com>
Braden McDorman <bmcdorman@gmail.com>
Brandon Myers <bmyers1788@gmail.com>
Brendan Drew <brendan.drew@daqri.com>
chason <cxchao802@gmail.com>
chenguoping <chenguopingdota@163.com>
Chris Gilling <cgilling@iparadigms.com>
Christopher Dawes <christopher.dawes.1981@googlemail.com>
Christopher Dunn <cdunn2001@gmail.com>
Chuck Atkins <chuck.atkins@kitware.com>
Cody P Schafer <dev@codyps.com>
Connor Manning <connor@hobu.co>
Cory Quammen <cory.quammen@kitware.com>
Cristóvão B da Cruz e Silva <CrisXed@gmail.com>
Daniel Krügler <daniel.kruegler@gmail.com>
Dani-Hub <daniel.kruegler@googlemail.com>
Dan Liu <gzliudan>
datadiode <datadiode@users.noreply.github.com>
datadiode <jochen.neubeck@vodafone.de>
David Seifert <soap@gentoo.org>
David West <david-west@idexx.com>
dawesc <chris.dawes@eftlab.co.uk>
Devin Jeanpierre <jeanpierreda@google.com>
Dmitry Marakasov <amdmi3@amdmi3.ru>
dominicpezzuto <dom@dompezzuto.com>
Don Milham <dmilham@gmail.com>
drgler <daniel.kruegler@gmail.com>
ds283 <D.Seery@sussex.ac.uk>
Egor Tensin <Egor.Tensin@gmail.com>
eightnoteight <mr.eightnoteight@gmail.com>
Evince <baneyue@gmail.com>
filipjs <filipjs@users.noreply.github.com>
findblar <ft@finbarr.ca>
Florian Meier <florian.meier@koalo.de>
Gaëtan Lehmann <gaetan.lehmann@gmail.com>
Gaurav <g.gupta@samsung.com>
Gergely Nagy <ngg@ngg.hu>
Gida Pataki <gida.pataki@prezi.com>
I3ck <buckmartin@buckmartin.de>
Iñaki Baz Castillo <ibc@aliax.net>
Jacco <jacco@geul.net>
Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com>
Jonas Platte <mail@jonasplatte.de>
Jordan Bayles <bayles.jordan@gmail.com>
Jörg Krause <joerg.krause@embedded.rocks>
Keith Lea <keith@whamcitylights.com>
Kevin Grant <kbradleygrant@gmail.com>
Kirill V. Lyadvinsky <jia3ep@gmail.com>
Kirill V. Lyadvinsky <mail@codeatcpp.com>
Kobi Gurkan <kobigurk@gmail.com>
Magnus Bjerke Vik <mbvett@gmail.com>
Malay Shah <malays@users.sourceforge.net>
Mara Kim <hacker.root@gmail.com>
Marek Kotewicz <marek.kotewicz@gmail.com>
Mark Lakata <mark@lakata.org>
Mark Zeren <mzeren@vmware.com>
Martin Buck <buckmartin@buckmartin.de>
Martyn Gigg <martyn.gigg@gmail.com>
Mattes D <github@xoft.cz>
Matthias Loy <matthias.loy@hbm.com>
Merlyn Morgan-Graham <kavika@gmail.com>
Michael Shields <mshields@google.com>
Michał Górny <mgorny@gentoo.org>
Mike Naberezny <mike@naberezny.com>
mloy <matthias.loy@googlemail.com>
Motti <lanzkron@gmail.com>
nnkur <nnkur@mail.ru>
Omkar Wagh <owagh@owaghlinux.ny.tower-research.com>
paulo <paulobrizolara@users.noreply.github.com>
pavel.pimenov <pavel.pimenov@gmail.com>
Paweł Bylica <chfast@gmail.com>
Péricles Lopes Machado <pericles.raskolnikoff@gmail.com>
Peter Spiess-Knafl <psk@autistici.org>
pffang <pffang@vip.qq.com>
Rémi Verschelde <remi@verschelde.fr>
renu555 <renu.tyagi@samsung.com>
Robert Dailey <rcdailey@gmail.com>
Sam Clegg <sbc@chromium.org>
selaselah <selah@outlook.com>
Sergiy80 <sil2004@gmail.com>
sergzub <sergzub@gmail.com>
Stefan Schweter <stefan@schweter.it>
Stefano Fiorentino <stefano.fiore84@gmail.com>
Steffen Kieß <Steffen.Kiess@ipvs.uni-stuttgart.de>
Steven Hahn <hahnse@ornl.gov>
Stuart Eichert <stuart@fivemicro.com>
SuperManitu <supermanitu@gmail.com>
Techwolf <dring@g33kworld.net>
Tengiz Sharafiev <btolfa+github@gmail.com>
Tomasz Maciejewski <tmaciejewsk@gmail.com>
Vicente Olivert Riera <Vincent.Riera@imgtec.com>
xiaoyur347 <xiaoyur347@gmail.com>
ycqiu <429148848@qq.com>
yiqiju <fred_ju@selinc.com>
Yu Xiaolei <dreifachstein@gmail.com>
Google Inc.

View File

@ -1,37 +0,0 @@
licenses(["unencumbered"]) # Public Domain or MIT
exports_files(["LICENSE"])
cc_library(
name = "jsoncpp",
srcs = [
"src/lib_json/json_reader.cpp",
"src/lib_json/json_tool.h",
"src/lib_json/json_value.cpp",
"src/lib_json/json_writer.cpp",
],
hdrs = [
"include/json/allocator.h",
"include/json/assertions.h",
"include/json/config.h",
"include/json/json_features.h",
"include/json/forwards.h",
"include/json/json.h",
"include/json/reader.h",
"include/json/value.h",
"include/json/version.h",
"include/json/writer.h",
],
copts = [
"-DJSON_USE_EXCEPTION=0",
"-DJSON_HAS_INT64",
],
includes = ["include"],
visibility = ["//visibility:public"],
deps = [":private"],
)
cc_library(
name = "private",
textual_hdrs = ["src/lib_json/json_valueiterator.inl"],
)

View File

@ -1,214 +1,160 @@
# vim: et ts=4 sts=4 sw=4 tw=0 # vim: et ts=4 sts=4 sw=4 tw=0
# ==== Define cmake build policies that affect compilation and linkage default behaviors CMAKE_MINIMUM_REQUIRED(VERSION 2.8.5)
# PROJECT(jsoncpp)
# Set the JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION string to the newest cmake version ENABLE_TESTING()
# policies that provide successful builds. By setting JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION
# to a value greater than the oldest policies, all policies between
# JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION and CMAKE_VERSION (used for this build)
# are set to their NEW behavior, thereby suppressing policy warnings related to policies
# between the JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION and CMAKE_VERSION.
#
# CMake versions greater than the JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION policies will
# continue to generate policy warnings "CMake Warning (dev)...Policy CMP0XXX is not set:"
#
set(JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION "3.8.0")
set(JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION "3.13.2")
cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION})
if("${CMAKE_VERSION}" VERSION_LESS "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}")
#Set and use the newest available cmake policies that are validated to work
set(JSONCPP_CMAKE_POLICY_VERSION "${CMAKE_VERSION}")
else()
set(JSONCPP_CMAKE_POLICY_VERSION "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}")
endif()
cmake_policy(VERSION ${JSONCPP_CMAKE_POLICY_VERSION})
if(POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif()
#
# Now enumerate specific policies newer than JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION
# that may need to be individually set to NEW/OLD
#
foreach(pnew "") # Currently Empty
if(POLICY ${pnew})
cmake_policy(SET ${pnew} NEW)
endif()
endforeach()
foreach(pold "") # Currently Empty
if(POLICY ${pold})
cmake_policy(SET ${pold} OLD)
endif()
endforeach()
# Build the library with C++11 standard support, independent from other including OPTION(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON)
# software which may use a different CXX_STANDARD or CMAKE_CXX_STANDARD. OPTION(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON)
set(CMAKE_CXX_STANDARD 11) OPTION(JSONCPP_WITH_WARNING_AS_ERROR "Force compilation to fail if a warning occurs" OFF)
set(CMAKE_CXX_EXTENSIONS OFF) OPTION(JSONCPP_WITH_STRICT_ISO "Issue all the warnings demanded by strict ISO C and ISO C++" ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON) 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)
# Ensure that CMAKE_BUILD_TYPE has a value specified for single configuration generators. # Ensures that CMAKE_BUILD_TYPE is visible in cmake-gui on Unix
if(NOT DEFINED CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES) IF(NOT WIN32)
set(CMAKE_BUILD_TYPE Release CACHE STRING IF(NOT CMAKE_BUILD_TYPE)
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.") SET(CMAKE_BUILD_TYPE Release CACHE STRING
endif() "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage."
FORCE)
ENDIF()
ENDIF()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # Enable runtime search path support for dynamic libraries on OSX
IF(APPLE)
SET(CMAKE_MACOSX_RPATH 1)
ENDIF()
project(jsoncpp SET(DEBUG_LIBNAME_SUFFIX "" CACHE STRING "Optional suffix to append to the library name for a debug build")
# Note: version must be updated in four places when doing a release. This SET(LIB_SUFFIX "" CACHE STRING "Optional arch-dependent suffix for the library installation directory")
# annoying process ensures that amalgamate, CMake, and meson all report the
# correct version.
# 1. ./meson.build
# 2. ./include/json/version.h
# 3. ./CMakeLists.txt
# 4. ./MODULE.bazel
# IMPORTANT: also update the PROJECT_SOVERSION!!
VERSION 1.9.7 # <major>[.<minor>[.<patch>[.<tweak>]]]
LANGUAGES CXX)
message(STATUS "JsonCpp Version: ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") SET(RUNTIME_INSTALL_DIR bin
set(PROJECT_SOVERSION 27) CACHE PATH "Install dir for executables and dlls")
SET(ARCHIVE_INSTALL_DIR lib${LIB_SUFFIX}
CACHE PATH "Install dir for static libraries")
SET(LIBRARY_INSTALL_DIR lib${LIB_SUFFIX}
CACHE PATH "Install dir for shared libraries")
SET(INCLUDE_INSTALL_DIR include
CACHE PATH "Install dir for headers")
SET(PACKAGE_INSTALL_DIR lib${LIB_SUFFIX}/cmake
CACHE PATH "Install dir for cmake package config files")
MARK_AS_ADVANCED( RUNTIME_INSTALL_DIR ARCHIVE_INSTALL_DIR INCLUDE_INSTALL_DIR PACKAGE_INSTALL_DIR )
include(${CMAKE_CURRENT_SOURCE_DIR}/include/PreventInSourceBuilds.cmake) # Set variable named ${VAR_NAME} to value ${VALUE}
include(${CMAKE_CURRENT_SOURCE_DIR}/include/PreventInBuildInstalls.cmake) FUNCTION(set_using_dynamic_name VAR_NAME VALUE)
SET( "${VAR_NAME}" "${VALUE}" PARENT_SCOPE)
ENDFUNCTION()
option(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) # Extract major, minor, patch from version text
option(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON) # Parse a version string "X.Y.Z" and outputs
option(JSONCPP_WITH_WARNING_AS_ERROR "Force compilation to fail if a warning occurs" OFF) # version parts in ${OUPUT_PREFIX}_MAJOR, _MINOR, _PATCH.
option(JSONCPP_WITH_STRICT_ISO "Issue all the warnings demanded by strict ISO C and ISO C++" ON) # If parse succeeds then ${OUPUT_PREFIX}_FOUND is TRUE.
option(JSONCPP_WITH_PKGCONFIG_SUPPORT "Generate and install .pc files" ON) MACRO(jsoncpp_parse_version VERSION_TEXT OUPUT_PREFIX)
option(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" ON) SET(VERSION_REGEX "[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9_]+)?")
option(JSONCPP_WITH_EXAMPLE "Compile JsonCpp example" OFF) IF( ${VERSION_TEXT} MATCHES ${VERSION_REGEX} )
option(JSONCPP_STATIC_WINDOWS_RUNTIME "Use static (MT/MTd) Windows runtime" OFF) STRING(REGEX MATCHALL "[0-9]+|-([A-Za-z0-9_]+)" VERSION_PARTS ${VERSION_TEXT})
option(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." ON) LIST(GET VERSION_PARTS 0 ${OUPUT_PREFIX}_MAJOR)
option(BUILD_STATIC_LIBS "Build jsoncpp_lib as a static library." ON) LIST(GET VERSION_PARTS 1 ${OUPUT_PREFIX}_MINOR)
option(BUILD_OBJECT_LIBS "Build jsoncpp_lib as a object library." ON) LIST(GET VERSION_PARTS 2 ${OUPUT_PREFIX}_PATCH)
set_using_dynamic_name( "${OUPUT_PREFIX}_FOUND" TRUE )
ELSE( ${VERSION_TEXT} MATCHES ${VERSION_REGEX} )
set_using_dynamic_name( "${OUPUT_PREFIX}_FOUND" FALSE )
ENDIF()
ENDMACRO()
# Adhere to GNU filesystem layout conventions # Read out version from "version" file
include(GNUInstallDirs) #FILE(STRINGS "version" JSONCPP_VERSION)
#SET( JSONCPP_VERSION_MAJOR X )
#SET( JSONCPP_VERSION_MINOR Y )
#SET( JSONCPP_VERSION_PATCH Z )
SET( JSONCPP_VERSION 1.7.7 )
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")
#ENDIF(NOT JSONCPP_VERSION_FOUND)
SET( JSONCPP_SOVERSION 11 )
SET( JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL" )
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) MESSAGE(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Archive output dir.") # File version.h is only regenerated on CMake configure step
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Library output dir.") CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/src/lib_json/version.h.in"
set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "PDB (MSVC debug symbol)output dir.") "${PROJECT_SOURCE_DIR}/include/json/version.h"
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Executable/dll output dir.") NEWLINE_STYLE UNIX )
endif() CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/version.in"
"${PROJECT_SOURCE_DIR}/version"
NEWLINE_STYLE UNIX )
include(CheckFunctionExists) macro(UseCompilationWarningAsError)
check_function_exists(memset_s HAVE_MEMSET_S) if ( MSVC )
if(HAVE_MEMSET_S)
add_definitions("-DHAVE_MEMSET_S=1")
endif()
if(JSONCPP_USE_SECURE_MEMORY)
add_definitions("-DJSONCPP_USE_SECURE_MEMORY=1")
endif()
configure_file("${PROJECT_SOURCE_DIR}/version.in"
"${PROJECT_BINARY_DIR}/version"
NEWLINE_STYLE UNIX)
macro(use_compilation_warning_as_error)
if(MSVC)
# Only enabled in debug because some old versions of VS STL generate # Only enabled in debug because some old versions of VS STL generate
# warnings when compiled in release configuration. # warnings when compiled in release configuration.
add_compile_options($<$<CONFIG:Debug>:/WX>) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /WX ")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Werror) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
if(JSONCPP_WITH_STRICT_ISO) if (JSONCPP_WITH_STRICT_ISO)
add_compile_options(-pedantic-errors) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors")
endif() endif ()
endif() endif()
endmacro() endmacro()
# Include our configuration header # Include our configuration header
include_directories(${jsoncpp_SOURCE_DIR}/include) INCLUDE_DIRECTORIES( ${jsoncpp_SOURCE_DIR}/include )
if(MSVC) if ( MSVC )
# Only enabled in debug because some old versions of VS STL generate # Only enabled in debug because some old versions of VS STL generate
# unreachable code warning when compiled in release configuration. # unreachable code warning when compiled in release configuration.
add_compile_options($<$<CONFIG:Debug>:/W4>) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4 ")
if (JSONCPP_STATIC_WINDOWS_RUNTIME)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
endif() endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# using regular Clang or AppleClang # using regular Clang or AppleClang
add_compile_options(-Wall -Wconversion -Wshadow) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(JSONCPP_WITH_WARNING_AS_ERROR)
add_compile_options(-Werror=conversion -Werror=sign-compare)
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# using GCC # using GCC
add_compile_options(-Wall -Wconversion -Wshadow -Wextra) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wconversion -Wshadow -Wextra")
# not yet ready for -Wsign-conversion # not yet ready for -Wsign-conversion
if(JSONCPP_WITH_STRICT_ISO) if (JSONCPP_WITH_STRICT_ISO AND NOT JSONCPP_WITH_WARNING_AS_ERROR)
add_compile_options(-Wpedantic) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=conversion -pedantic")
endif() endif ()
if(JSONCPP_WITH_WARNING_AS_ERROR) elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
add_compile_options(-Werror=conversion)
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
# using Intel compiler # using Intel compiler
add_compile_options(-Wall -Wconversion -Wshadow -Wextra) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wconversion -Wshadow -Wextra -Werror=conversion")
if(JSONCPP_WITH_WARNING_AS_ERROR) if (JSONCPP_WITH_STRICT_ISO AND NOT JSONCPP_WITH_WARNING_AS_ERROR)
add_compile_options(-Werror=conversion) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
elseif(JSONCPP_WITH_STRICT_ISO) endif ()
add_compile_options(-Wpedantic)
endif()
endif() endif()
if(JSONCPP_WITH_WARNING_AS_ERROR) find_program(CCACHE_FOUND ccache)
use_compilation_warning_as_error() if(CCACHE_FOUND)
endif() set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND)
if(JSONCPP_WITH_PKGCONFIG_SUPPORT) IF(JSONCPP_WITH_WARNING_AS_ERROR)
include(JoinPaths) UseCompilationWarningAsError()
ENDIF()
join_paths(libdir_for_pc_file "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}") IF(JSONCPP_WITH_PKGCONFIG_SUPPORT)
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}") CONFIGURE_FILE(
configure_file(
"pkg-config/jsoncpp.pc.in" "pkg-config/jsoncpp.pc.in"
"pkg-config/jsoncpp.pc" "pkg-config/jsoncpp.pc"
@ONLY) @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pkg-config/jsoncpp.pc" INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/pkg-config/jsoncpp.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") DESTINATION "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/pkgconfig")
endif() ENDIF()
if(JSONCPP_WITH_CMAKE_PACKAGE) IF(JSONCPP_WITH_CMAKE_PACKAGE)
include(CMakePackageConfigHelpers) INSTALL(EXPORT jsoncpp
install(EXPORT jsoncpp DESTINATION ${PACKAGE_INSTALL_DIR}/jsoncpp
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp FILE jsoncppConfig.cmake)
FILE jsoncpp-targets.cmake) ENDIF()
configure_package_config_file(jsoncppConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp)
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfig.cmake
${CMAKE_CURRENT_SOURCE_DIR}/jsoncpp-namespaced-targets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp)
endif()
if(JSONCPP_WITH_TESTS)
enable_testing()
include(CTest)
endif()
# Build the different applications # Build the different applications
add_subdirectory(src) ADD_SUBDIRECTORY( src )
#install the includes #install the includes
add_subdirectory(include) ADD_SUBDIRECTORY( include )
#install the example
if(JSONCPP_WITH_EXAMPLE)
add_subdirectory(example)
endif()

View File

@ -1,152 +0,0 @@
# Contributing to JsonCpp
## Building
Both CMake and Meson tools are capable of generating a variety of build environments for you preferred development environment.
Using cmake or meson you can generate an XCode, Visual Studio, Unix Makefile, Ninja, or other environment that fits your needs.
An example of a common Meson/Ninja environment is described next.
## Building and testing with Meson/Ninja
Thanks to David Seifert (@SoapGentoo), we (the maintainers) now use
[meson](http://mesonbuild.com/) and [ninja](https://ninja-build.org/) to build
for debugging, as well as for continuous integration (see
[`./.travis_scripts/meson_builder.sh`](./.travis_scripts/meson_builder.sh) ). Other systems may work, but minor
things like version strings might break.
First, install both meson (which requires Python3) and ninja.
If you wish to install to a directory other than /usr/local, set an environment variable called DESTDIR with the desired path:
DESTDIR=/path/to/install/dir
Then,
```sh
cd jsoncpp/
BUILD_TYPE=debug
#BUILD_TYPE=release
LIB_TYPE=shared
#LIB_TYPE=static
meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . build-${LIB_TYPE}
ninja -v -C build-${LIB_TYPE}
ninja -C build-static/ test
# Or
#cd build-${LIB_TYPE}
#meson test --no-rebuild --print-errorlogs
sudo ninja install
```
## Building and testing with other build systems
See https://github.com/open-source-parsers/jsoncpp/wiki/Building
## Running the tests manually
You need to run tests manually only if you are troubleshooting an issue.
In the instructions below, replace `path/to/jsontest` with the path of the
`jsontest` executable that was compiled on your platform.
cd test
# This will run the Reader/Writer tests
python runjsontests.py path/to/jsontest
# This will run the Reader/Writer tests, using JSONChecker test suite
# (http://www.json.org/JSON_checker/).
# Notes: not all tests pass: JsonCpp is too lenient (for example,
# it allows an integer to start with '0'). The goal is to improve
# strict mode parsing to get all tests to pass.
python runjsontests.py --with-json-checker path/to/jsontest
# This will run the unit tests (mostly Value)
python rununittests.py path/to/test_lib_json
# You can run the tests using valgrind:
python rununittests.py --valgrind path/to/test_lib_json
## Building the documentation
Run the Python script `doxybuild.py` from the top directory:
python doxybuild.py --doxygen=$(which doxygen) --open --with-dot
See `doxybuild.py --help` for options.
## Adding a reader/writer test
To add a test, you need to create two files in test/data:
* a `TESTNAME.json` file, that contains the input document in JSON format.
* a `TESTNAME.expected` file, that contains a flattened representation of the
input document.
The `TESTNAME.expected` file format is as follows:
* Each line represents a JSON element of the element tree represented by the
input document.
* Each line has two parts: the path to access the element separated from the
element value by `=`. Array and object values are always empty (i.e.
represented by either `[]` or `{}`).
* Element path `.` represents the root element, and is used to separate object
members. `[N]` is used to specify the value of an array element at index `N`.
See the examples `test_complex_01.json` and `test_complex_01.expected` to better understand element paths.
## Understanding reader/writer test output
When a test is run, output files are generated beside the input test files. Below is a short description of the content of each file:
* `test_complex_01.json`: input JSON document.
* `test_complex_01.expected`: flattened JSON element tree used to check if
parsing was corrected.
* `test_complex_01.actual`: flattened JSON element tree produced by `jsontest`
from reading `test_complex_01.json`.
* `test_complex_01.rewrite`: JSON document written by `jsontest` using the
`Json::Value` parsed from `test_complex_01.json` and serialized using
`Json::StyledWritter`.
* `test_complex_01.actual-rewrite`: flattened JSON element tree produced by
`jsontest` from reading `test_complex_01.rewrite`.
* `test_complex_01.process-output`: `jsontest` output, typically useful for
understanding parsing errors.
## Versioning rules
Consumers of this library require a strict approach to incrementing versioning of the JsonCpp library. Currently, we follow the below set of rules:
* Any new public symbols require a minor version bump.
* Any alteration or removal of public symbols requires a major version bump, including changing the size of a class. This is necessary for
consumers to do dependency injection properly.
## Preparing code for submission
Generally, JsonCpp's style guide has been pretty relaxed, with the following common themes:
* Variables and function names use lower camel case (E.g. parseValue or collectComments).
* Class use camel case (e.g. OurReader)
* Member variables have a trailing underscore
* Prefer `nullptr` over `NULL`.
* Passing by non-const reference is allowed.
* Single statement if blocks may omit brackets.
* Generally prefer less space over more space.
For an example:
```c++
bool Reader::decodeNumber(Token& token) {
Value decoded;
if (!decodeNumber(token, decoded))
return false;
currentValue().swapPayload(decoded);
currentValue().setOffsetStart(token.start_ - begin_);
currentValue().setOffsetLimit(token.end_ - begin_);
return true;
}
```
Before submitting your code, ensure that you meet the versioning requirements above, follow the style guide of the file you are modifying (or the above rules for new files), and run clang format. Meson exposes clang format with the following command:
```
ninja -v -C build-${LIB_TYPE}/ clang-format
```
For convenience, you can also run the `reformat.sh` script located in the root directory.

View File

@ -1,15 +0,0 @@
## This file should be placed in the root directory of your project.
## Then modify the CMakeLists.txt file in the root directory of your
## project to incorporate the testing dashboard.
##
## # The following are required to submit to the CDash dashboard:
## ENABLE_TESTING()
## INCLUDE(CTest)
set(CTEST_PROJECT_NAME "jsoncpp")
set(CTEST_NIGHTLY_START_TIME "01:23:45 UTC")
set(CTEST_DROP_METHOD "https")
set(CTEST_DROP_SITE "my.cdash.org")
set(CTEST_DROP_LOCATION "/submit.php?project=jsoncpp")
set(CTEST_DROP_SITE_CDASH TRUE)

View File

@ -2,13 +2,13 @@ The JsonCpp library's source code, including accompanying documentation,
tests and demonstration applications, are licensed under the following tests and demonstration applications, are licensed under the following
conditions... conditions...
Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all The author (Baptiste Lepilleur) explicitly disclaims copyright in all
jurisdictions which recognize such a disclaimer. In such jurisdictions, jurisdictions which recognize such a disclaimer. In such jurisdictions,
this software is released into the Public Domain. this software is released into the Public Domain.
In jurisdictions which do not recognize Public Domain property (e.g. Germany as of In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
The JsonCpp Authors, and is released under the terms of the MIT License (see below). released under the terms of the MIT License (see below).
In jurisdictions which recognize Public Domain property, the user of this In jurisdictions which recognize Public Domain property, the user of this
software may choose to accept it either as 1) Public Domain, 2) under the software may choose to accept it either as 1) Public Domain, 2) under the
@ -23,7 +23,7 @@ described in clear, concise terms at:
The full text of the MIT License follows: The full text of the MIT License follows:
======================================================================== ========================================================================
Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors Copyright (c) 2007-2010 Baptiste Lepilleur
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation

View File

@ -1,14 +0,0 @@
module(
name = "jsoncpp",
# Note: version must be updated in four places when doing a release. This
# annoying process ensures that amalgamate, CMake, and meson all report the
# correct version.
# 1. /meson.build
# 2. /include/json/version.h
# 3. /CMakeLists.txt
# 4. /MODULE.bazel
# IMPORTANT: also update the SOVERSION!!
version = "1.9.7",
compatibility_level = 1,
)

175
NEWS.txt Normal file
View File

@ -0,0 +1,175 @@
New in SVN
----------
* Updated the type system's behavior, in order to better support backwards
compatibility with code that was written before 64-bit integer support was
introduced. Here's how it works now:
* isInt, isInt64, isUInt, and isUInt64 return true if and only if the
value can be exactly represented as that type. In particular, a value
constructed with a double like 17.0 will now return true for all of
these methods.
* isDouble and isFloat now return true for all numeric values, since all
numeric values can be converted to a double or float without
truncation. Note however that the conversion may not be exact -- for
example, doubles cannot exactly represent all integers above 2^53 + 1.
* isBool, isNull, isString, isArray, and isObject now return true if and
only if the value is of that type.
* isConvertibleTo(fooValue) indicates that it is safe to call asFoo.
(For each type foo, isFoo always implies isConvertibleTo(fooValue).)
asFoo returns an approximate or exact representation as appropriate.
For example, a double value may be truncated when asInt is called.
* For backwards compatibility with old code, isConvertibleTo(intValue)
may return false even if type() == intValue. This is because the value
may have been constructed with a 64-bit integer larger than maxInt,
and calling asInt() would cause an exception. If you're writing new
code, use isInt64 to find out whether the value is exactly
representable using an Int64, or asDouble() combined with minInt64 and
maxInt64 to figure out whether it is approximately representable.
* Value
- Patch #10: BOOST_FOREACH compatibility. Made Json::iterator more
standard compliant, added missing iterator_category and value_type
typedefs (contribued by Robert A. Iannucci).
* Compilation
- New CMake based build system. Based in part on contribution from
Igor Okulist and Damien Buhl (Patch #14).
- New header json/version.h now contains version number macros
(JSONCPP_VERSION_MAJOR, JSONCPP_VERSION_MINOR, JSONCPP_VERSION_PATCH
and JSONCPP_VERSION_HEXA).
- Patch #11: added missing JSON_API on some classes causing link issues
when building as a dynamic library on Windows
(contributed by Francis Bolduc).
- Visual Studio DLL: suppressed warning "C4251: <data member>: <type>
needs to have dll-interface to be used by..." via pragma push/pop
in json-cpp headers.
- Added Travis CI intregration: https://travis-ci.org/blep/jsoncpp-mirror
* Bug fixes
- Patch #15: Copy constructor does not initialize allocated_ for stringValue
(contributed by rmongia).
- Patch #16: Missing field copy in Json::Value::iterator causing infinite
loop when using experimental internal map (#define JSON_VALUE_USE_INTERNAL_MAP)
(contributed by Ming-Lin Kao).
New in JsonCpp 0.6.0:
---------------------
* Compilation
- LD_LIBRARY_PATH and LIBRARY_PATH environment variables are now
propagated to the build environment as this is required for some
compiler installation.
- Added support for Microsoft Visual Studio 2008 (bug #2930462):
The platform "msvc90" has been added.
Notes: you need to setup the environment by running vcvars32.bat
(e.g. MSVC 2008 command prompt in start menu) before running scons.
- Added support for amalgamated source and header generation (a la sqlite).
Refer to README.md section "Generating amalgamated source and header"
for detail.
* Value
- Removed experimental ValueAllocator, it caused static
initialization/destruction order issues (bug #2934500).
The DefaultValueAllocator has been inlined in code.
- Added support for 64 bits integer:
Types Json::Int64 and Json::UInt64 have been added. They are aliased
to 64 bits integers on system that support them (based on __int64 on
Microsoft Visual Studio platform, and long long on other platforms).
Types Json::LargestInt and Json::LargestUInt have been added. They are
aliased to the largest integer type supported:
either Json::Int/Json::UInt or Json::Int64/Json::UInt64 respectively.
Json::Value::asInt() and Json::Value::asUInt() still returns plain
"int" based types, but asserts if an attempt is made to retrieve
a 64 bits value that can not represented as the return type.
Json::Value::asInt64() and Json::Value::asUInt64() have been added
to obtain the 64 bits integer value.
Json::Value::asLargestInt() and Json::Value::asLargestUInt() returns
the integer as a LargestInt/LargestUInt respectively. Those functions
functions are typically used when implementing writer.
The reader attempts to read number as 64 bits integer, and fall back
to reading a double if the number is not in the range of 64 bits
integer.
Warning: Json::Value::asInt() and Json::Value::asUInt() now returns
long long. This changes break code that was passing the return value
to *printf() function.
Support for 64 bits integer can be disabled by defining the macro
JSON_NO_INT64 (uncomment it in json/config.h for example), though
it should have no impact on existing usage.
- The type Json::ArrayIndex is used for indexes of a JSON value array. It
is an unsigned int (typically 32 bits).
- Array index can be passed as int to operator[], allowing use of literal:
Json::Value array;
array.append( 1234 );
int value = array[0].asInt(); // did not compile previously
- Added float Json::Value::asFloat() to obtain a floating point value as a
float (avoid lost of precision warning caused by used of asDouble()
to initialize a float).
* Reader
- Renamed Reader::getFormatedErrorMessages() to getFormattedErrorMessages.
Bug #3023708 (Formatted has 2 't'). The old member function is deprecated
but still present for backward compatibility.
* Tests
- Added test to ensure that the escape sequence "\/" is corrected handled
by the parser.
* Bug fixes
- Bug #3139677: JSON [1 2 3] was incorrectly parsed as [1, 3]. Error is now
correctly detected.
- Bug #3139678: stack buffer overflow when parsing a double with a
length of 32 characters.
- Fixed Value::operator <= implementation (had the semantic of operator >=).
Found when adding unit tests for comparison operators.
- Value::compare() is now const and has an actual implementation with
unit tests.
- Bug #2407932: strpbrk() can fail for NULL pointer.
- Bug #3306345: Fixed minor typo in Path::resolve().
- Bug #3314841/#3306896: errors in amalgamate.py
- Fixed some Coverity warnings and line-endings.
* License
- See file LICENSE for details. Basically JsonCpp is now licensed under
MIT license, or public domain if desired and recognized in your jurisdiction.
Thanks to Stephan G. Beal [http://wanderinghorse.net/home/stephan/]) who
helped figuring out the solution to the public domain issue.

225
README.md
View File

@ -1,10 +1,5 @@
# JsonCpp Introduction
------------
[![badge](https://img.shields.io/badge/conan.io-jsoncpp%2F1.8.0-green.svg?logo=data:image/png;base64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAA1VBMVEUAAABhlctjlstkl8tlmMtlmMxlmcxmmcxnmsxpnMxpnM1qnc1sn85voM91oM11oc1xotB2oc56pNF6pNJ2ptJ8ptJ8ptN9ptN8p9N5qNJ9p9N9p9R8qtOBqdSAqtOAqtR%2BrNSCrNJ/rdWDrNWCsNWCsNaJs9eLs9iRvNuVvdyVv9yXwd2Zwt6axN6dxt%2Bfx%2BChyeGiyuGjyuCjyuGly%2BGlzOKmzOGozuKoz%2BKqz%2BOq0OOv1OWw1OWw1eWx1eWy1uay1%2Baz1%2Baz1%2Bez2Oe02Oe12ee22ujUGwH3AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgBQkREyOxFIh/AAAAiklEQVQI12NgAAMbOwY4sLZ2NtQ1coVKWNvoc/Eq8XDr2wB5Ig62ekza9vaOqpK2TpoMzOxaFtwqZua2Bm4makIM7OzMAjoaCqYuxooSUqJALjs7o4yVpbowvzSUy87KqSwmxQfnsrPISyFzWeWAXCkpMaBVIC4bmCsOdgiUKwh3JojLgAQ4ZCE0AMm2D29tZwe6AAAAAElFTkSuQmCC)](https://bintray.com/theirix/conan-repo/jsoncpp%3Atheirix)
[![badge](https://img.shields.io/badge/license-MIT-blue)](https://github.com/open-source-parsers/jsoncpp/blob/master/LICENSE)
[![badge](https://img.shields.io/badge/document-doxygen-brightgreen)](http://open-source-parsers.github.io/jsoncpp-docs/doxygen/index.html)
[![Coverage Status](https://coveralls.io/repos/github/open-source-parsers/jsoncpp/badge.svg?branch=master)](https://coveralls.io/github/open-source-parsers/jsoncpp?branch=master)
[JSON][json-org] is a lightweight data-interchange format. It can represent [JSON][json-org] is a lightweight data-interchange format. It can represent
numbers, strings, ordered sequences of values, and collections of name/value numbers, strings, ordered sequences of values, and collections of name/value
@ -12,56 +7,208 @@ pairs.
[json-org]: http://json.org/ [json-org]: http://json.org/
JsonCpp is a C++ library that allows manipulating JSON values, including [JsonCpp][] is a C++ library that allows manipulating JSON values, including
serialization and deserialization to and from strings. It can also preserve serialization and deserialization to and from strings. It can also preserve
existing comment in unserialization/serialization steps, making it a convenient existing comment in unserialization/serialization steps, making it a convenient
format to store user input files. format to store user input files.
[JsonCpp]: http://open-source-parsers.github.io/jsoncpp-docs/doxygen/index.html
## Documentation
[JsonCpp documentation][JsonCpp-documentation] is generated using [Doxygen][].
[JsonCpp-documentation]: http://open-source-parsers.github.io/jsoncpp-docs/doxygen/index.html
[Doxygen]: http://www.doxygen.org
## A note on backward-compatibility ## A note on backward-compatibility
* `1.y.z` is built with C++11. * `1.y.z` is built with C++11.
* `0.y.z` can be used with older compilers. * `0.y.z` can be used with older compilers.
* `00.11.z` can be used both in old and new compilers.
* Major versions maintain binary-compatibility. * Major versions maintain binary-compatibility.
### Special note # Using JsonCpp in your project
The branch `00.11.z`is a new branch, its major version number `00` is to show that it is -----------------------------
different from `0.y.z` and `1.y.z`, the main purpose of this branch is to make a balance The recommended approach to integrating JsonCpp in your project is to include
between the other two branches. Thus, users can use some new features in this new branch the [amalgamated source](#generating-amalgamated-source-and-header) (a single
that introduced in 1.y.z, but can hardly applied into 0.y.z. `.cpp` file and two `.h` files) in your project, and compile and build as you
would any other source file. This ensures consistency of compilation flags and
ABI compatibility, issues which arise when building shared or static
libraries. See the next section for instructions.
## Using JsonCpp in your project The `include/` should be added to your compiler include path. Jsoncpp headers
should be included as follow:
### The vcpkg dependency manager #include <json/json.h>
You can download and install JsonCpp using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
git clone https://github.com/Microsoft/vcpkg.git If JsonCpp was built as a dynamic library on Windows, then your project needs to
cd vcpkg define the macro `JSON_DLL`.
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install jsoncpp
The JsonCpp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. Generating amalgamated source and header
----------------------------------------
JsonCpp is provided with a script to generate a single header and a single
source file to ease inclusion into an existing project. The amalgamated source
can be generated at any time by running the following command from the
top-directory (this requires Python 2.6):
### Amalgamated source python amalgamate.py
https://github.com/open-source-parsers/jsoncpp/wiki/Amalgamated-(Possibly-outdated)
### The Meson Build System It is possible to specify header name. See the `-h` option for detail.
If you are using the [Meson Build System](http://mesonbuild.com), then you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/jsoncpp), or simply use `meson wrap install jsoncpp`.
### Other ways By default, the following files are generated:
If you have trouble, see the [Wiki](https://github.com/open-source-parsers/jsoncpp/wiki), or post a question as an Issue. * `dist/jsoncpp.cpp`: source file that needs to be added to your project.
* `dist/json/json.h`: corresponding header file for use in your project. It is
equivalent to including `json/json.h` in non-amalgamated source. This header
only depends on standard headers.
* `dist/json/json-forwards.h`: header that provides forward declaration of all
JsonCpp types.
## License The amalgamated sources are generated by concatenating JsonCpp source in the
correct order and defining the macro `JSON_IS_AMALGAMATION` to prevent inclusion
of other headers.
# Contributing to JsonCpp
Building and testing with CMake
-------------------------------
[CMake][] is a C++ Makefiles/Solution generator. It is usually available on most
Linux system as package. On Ubuntu:
sudo apt-get install cmake
[CMake]: http://www.cmake.org
Note that Python is also required to run the JSON reader/writer tests. If
missing, the build will skip running those tests.
When running CMake, a few parameters are required:
* a build directory where the makefiles/solution are generated. It is also used
to store objects, libraries and executables files.
* the generator to use: makefiles or Visual Studio solution? What version or
Visual Studio, 32 or 64 bits solution?
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 `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.
Alternatively, from the command-line on Unix in the source directory:
mkdir -p build/debug
cd build/debug
cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ../..
make
Running `cmake -h` will display the list of available generators (passed using
the `-G` option).
By default CMake hides compilation commands. This can be modified by specifying
`-DCMAKE_VERBOSE_MAKEFILE=true` when generating makefiles.
Building and testing with SCons
-------------------------------
**Note:** The SCons-based build system is deprecated. Please use CMake; see the
section above.
JsonCpp can use [Scons][] as a build system. Note that SCons requires Python to
be installed.
[SCons]: http://www.scons.org/
Invoke SCons as follows:
scons platform=$PLATFORM [TARGET]
where `$PLATFORM` may be one of:
* `suncc`: Sun C++ (Solaris)
* `vacpp`: Visual Age C++ (AIX)
* `mingw`
* `msvc6`: Microsoft Visual Studio 6 service pack 5-6
* `msvc70`: Microsoft Visual Studio 2002
* `msvc71`: Microsoft Visual Studio 2003
* `msvc80`: Microsoft Visual Studio 2005
* `msvc90`: Microsoft Visual Studio 2008
* `linux-gcc`: Gnu C++ (linux, also reported to work for Mac OS X)
If you are building with Microsoft Visual Studio 2008, you need to set up the
environment by running `vcvars32.bat` (e.g. MSVC 2008 command prompt) before
running SCons.
## Running the tests manually
You need to run tests manually only if you are troubleshooting an issue.
In the instructions below, replace `path/to/jsontest` with the path of the
`jsontest` executable that was compiled on your platform.
cd test
# This will run the Reader/Writer tests
python runjsontests.py path/to/jsontest
# This will run the Reader/Writer tests, using JSONChecker test suite
# (http://www.json.org/JSON_checker/).
# Notes: not all tests pass: JsonCpp is too lenient (for example,
# it allows an integer to start with '0'). The goal is to improve
# strict mode parsing to get all tests to pass.
python runjsontests.py --with-json-checker path/to/jsontest
# This will run the unit tests (mostly Value)
python rununittests.py path/to/test_lib_json
# You can run the tests using valgrind:
python rununittests.py --valgrind path/to/test_lib_json
## Running the tests using scons
Note that tests can be run using SCons using the `check` target:
scons platform=$PLATFORM check
Building the documentation
--------------------------
Run the Python script `doxybuild.py` from the top directory:
python doxybuild.py --doxygen=$(which doxygen) --open --with-dot
See `doxybuild.py --help` for options.
Adding a reader/writer test
---------------------------
To add a test, you need to create two files in test/data:
* a `TESTNAME.json` file, that contains the input document in JSON format.
* a `TESTNAME.expected` file, that contains a flatened representation of the
input document.
The `TESTNAME.expected` file format is as follows:
* each line represents a JSON element of the element tree represented by the
input document.
* each line has two parts: the path to access the element separated from the
element value by `=`. Array and object values are always empty (i.e.
represented by either `[]` or `{}`).
* element path: `.` represents the root element, and is used to separate object
members. `[N]` is used to specify the value of an array element at index `N`.
See the examples `test_complex_01.json` and `test_complex_01.expected` to better
understand element paths.
Understanding reader/writer test output
---------------------------------------
When a test is run, output files are generated beside the input test files.
Below is a short description of the content of each file:
* `test_complex_01.json`: input JSON document.
* `test_complex_01.expected`: flattened JSON element tree used to check if
parsing was corrected.
* `test_complex_01.actual`: flattened JSON element tree produced by `jsontest`
from reading `test_complex_01.json`.
* `test_complex_01.rewrite`: JSON document written by `jsontest` using the
`Json::Value` parsed from `test_complex_01.json` and serialized using
`Json::StyledWritter`.
* `test_complex_01.actual-rewrite`: flattened JSON element tree produced by
`jsontest` from reading `test_complex_01.rewrite`.
* `test_complex_01.process-output`: `jsontest` output, typically useful for
understanding parsing errors.
License
-------
See the `LICENSE` file for details. In summary, JsonCpp is licensed under the See the `LICENSE` file for details. In summary, JsonCpp is licensed under the
MIT license, or public domain if desired and recognized in your jurisdiction. MIT license, or public domain if desired and recognized in your jurisdiction.

248
SConstruct Normal file
View File

@ -0,0 +1,248 @@
"""
Notes:
- shared library support is buggy: it assumes that a static and dynamic library can be build from the same object files. This is not true on many platforms. For this reason it is only enabled on linux-gcc at the current time.
To add a platform:
- add its name in options allowed_values below
- add tool initialization for this platform. Search for "if platform == 'suncc'" as an example.
"""
import os
import os.path
import sys
JSONCPP_VERSION = open(File('#version').abspath,'rt').read().strip()
DIST_DIR = '#dist'
options = Variables()
options.Add( EnumVariable('platform',
'Platform (compiler/stl) used to build the project',
'msvc71',
allowed_values='suncc vacpp mingw msvc6 msvc7 msvc71 msvc80 msvc90 linux-gcc'.split(),
ignorecase=2) )
try:
platform = ARGUMENTS['platform']
if platform == 'linux-gcc':
CXX = 'g++' # not quite right, but env is not yet available.
import commands
version = commands.getoutput('%s -dumpversion' %CXX)
platform = 'linux-gcc-%s' %version
print "Using platform '%s'" %platform
LD_LIBRARY_PATH = os.environ.get('LD_LIBRARY_PATH', '')
LD_LIBRARY_PATH = "%s:libs/%s" %(LD_LIBRARY_PATH, platform)
os.environ['LD_LIBRARY_PATH'] = LD_LIBRARY_PATH
print "LD_LIBRARY_PATH =", LD_LIBRARY_PATH
except KeyError:
print 'You must specify a "platform"'
sys.exit(2)
print "Building using PLATFORM =", platform
rootbuild_dir = Dir('#buildscons')
build_dir = os.path.join( '#buildscons', platform )
bin_dir = os.path.join( '#bin', platform )
lib_dir = os.path.join( '#libs', platform )
sconsign_dir_path = Dir(build_dir).abspath
sconsign_path = os.path.join( sconsign_dir_path, '.sconsign.dbm' )
# Ensure build directory exist (SConsignFile fail otherwise!)
if not os.path.exists( sconsign_dir_path ):
os.makedirs( sconsign_dir_path )
# Store all dependencies signature in a database
SConsignFile( sconsign_path )
def make_environ_vars():
"""Returns a dictionnary with environment variable to use when compiling."""
# PATH is required to find the compiler
# TEMP is required for at least mingw
# LD_LIBRARY_PATH & co is required on some system for the compiler
vars = {}
for name in ('PATH', 'TEMP', 'TMP', 'LD_LIBRARY_PATH', 'LIBRARY_PATH'):
if name in os.environ:
vars[name] = os.environ[name]
return vars
env = Environment( ENV = make_environ_vars(),
toolpath = ['scons-tools'],
tools=[] ) #, tools=['default'] )
if platform == 'suncc':
env.Tool( 'sunc++' )
env.Tool( 'sunlink' )
env.Tool( 'sunar' )
env.Append( CCFLAGS = ['-mt'] )
elif platform == 'vacpp':
env.Tool( 'default' )
env.Tool( 'aixcc' )
env['CXX'] = 'xlC_r' #scons does not pick-up the correct one !
# using xlC_r ensure multi-threading is enabled:
# http://publib.boulder.ibm.com/infocenter/pseries/index.jsp?topic=/com.ibm.vacpp7a.doc/compiler/ref/cuselect.htm
env.Append( CCFLAGS = '-qrtti=all',
LINKFLAGS='-bh:5' ) # -bh:5 remove duplicate symbol warning
elif platform == 'msvc6':
env['MSVS_VERSION']='6.0'
for tool in ['msvc', 'msvs', 'mslink', 'masm', 'mslib']:
env.Tool( tool )
env['CXXFLAGS']='-GR -GX /nologo /MT'
elif platform == 'msvc70':
env['MSVS_VERSION']='7.0'
for tool in ['msvc', 'msvs', 'mslink', 'masm', 'mslib']:
env.Tool( tool )
env['CXXFLAGS']='-GR -GX /nologo /MT'
elif platform == 'msvc71':
env['MSVS_VERSION']='7.1'
for tool in ['msvc', 'msvs', 'mslink', 'masm', 'mslib']:
env.Tool( tool )
env['CXXFLAGS']='-GR -GX /nologo /MT'
elif platform == 'msvc80':
env['MSVS_VERSION']='8.0'
for tool in ['msvc', 'msvs', 'mslink', 'masm', 'mslib']:
env.Tool( tool )
env['CXXFLAGS']='-GR -EHsc /nologo /MT'
elif platform == 'msvc90':
env['MSVS_VERSION']='9.0'
# Scons 1.2 fails to detect the correct location of the platform SDK.
# So we propagate those from the environment. This requires that the
# user run vcvars32.bat before compiling.
if 'INCLUDE' in os.environ:
env['ENV']['INCLUDE'] = os.environ['INCLUDE']
if 'LIB' in os.environ:
env['ENV']['LIB'] = os.environ['LIB']
for tool in ['msvc', 'msvs', 'mslink', 'masm', 'mslib']:
env.Tool( tool )
env['CXXFLAGS']='-GR -EHsc /nologo /MT'
elif platform == 'mingw':
env.Tool( 'mingw' )
env.Append( CPPDEFINES=[ "WIN32", "NDEBUG", "_MT" ] )
elif platform.startswith('linux-gcc'):
env.Tool( 'default' )
env.Append( LIBS = ['pthread'], CCFLAGS = os.environ.get("CXXFLAGS", "-Wall"), LINKFLAGS=os.environ.get("LDFLAGS", "") )
env['SHARED_LIB_ENABLED'] = True
else:
print "UNSUPPORTED PLATFORM."
env.Exit(1)
env.Tool('targz')
env.Tool('srcdist')
env.Tool('globtool')
env.Append( CPPPATH = ['#include'],
LIBPATH = lib_dir )
short_platform = platform
if short_platform.startswith('msvc'):
short_platform = short_platform[2:]
# Notes: on Windows you need to rebuild the source for each variant
# Build script does not support that yet so we only build static libraries.
# This also fails on AIX because both dynamic and static library ends with
# extension .a.
env['SHARED_LIB_ENABLED'] = env.get('SHARED_LIB_ENABLED', False)
env['LIB_PLATFORM'] = short_platform
env['LIB_LINK_TYPE'] = 'lib' # static
env['LIB_CRUNTIME'] = 'mt'
env['LIB_NAME_SUFFIX'] = '${LIB_PLATFORM}_${LIB_LINK_TYPE}${LIB_CRUNTIME}' # must match autolink naming convention
env['JSONCPP_VERSION'] = JSONCPP_VERSION
env['BUILD_DIR'] = env.Dir(build_dir)
env['ROOTBUILD_DIR'] = env.Dir(rootbuild_dir)
env['DIST_DIR'] = DIST_DIR
if 'TarGz' in env['BUILDERS']:
class SrcDistAdder:
def __init__( self, env ):
self.env = env
def __call__( self, *args, **kw ):
apply( self.env.SrcDist, (self.env['SRCDIST_TARGET'],) + args, kw )
env['SRCDIST_BUILDER'] = env.TarGz
else: # If tarfile module is missing
class SrcDistAdder:
def __init__( self, env ):
pass
def __call__( self, *args, **kw ):
pass
env['SRCDIST_ADD'] = SrcDistAdder( env )
env['SRCDIST_TARGET'] = os.path.join( DIST_DIR, 'jsoncpp-src-%s.tar.gz' % env['JSONCPP_VERSION'] )
env_testing = env.Clone( )
env_testing.Append( LIBS = ['json_${LIB_NAME_SUFFIX}'] )
def buildJSONExample( env, target_sources, target_name ):
env = env.Clone()
env.Append( CPPPATH = ['#'] )
exe = env.Program( target=target_name,
source=target_sources )
env['SRCDIST_ADD']( source=[target_sources] )
global bin_dir
return env.Install( bin_dir, exe )
def buildJSONTests( env, target_sources, target_name ):
jsontests_node = buildJSONExample( env, target_sources, target_name )
check_alias_target = env.Alias( 'check', jsontests_node, RunJSONTests( jsontests_node, jsontests_node ) )
env.AlwaysBuild( check_alias_target )
def buildUnitTests( env, target_sources, target_name ):
jsontests_node = buildJSONExample( env, target_sources, target_name )
check_alias_target = env.Alias( 'check', jsontests_node,
RunUnitTests( jsontests_node, jsontests_node ) )
env.AlwaysBuild( check_alias_target )
def buildLibrary( env, target_sources, target_name ):
static_lib = env.StaticLibrary( target=target_name + '_${LIB_NAME_SUFFIX}',
source=target_sources )
global lib_dir
env.Install( lib_dir, static_lib )
if env['SHARED_LIB_ENABLED']:
shared_lib = env.SharedLibrary( target=target_name + '_${LIB_NAME_SUFFIX}',
source=target_sources )
env.Install( lib_dir, shared_lib )
env['SRCDIST_ADD']( source=[target_sources] )
Export( 'env env_testing buildJSONExample buildLibrary buildJSONTests buildUnitTests' )
def buildProjectInDirectory( target_directory ):
global build_dir
target_build_dir = os.path.join( build_dir, target_directory )
target = os.path.join( target_directory, 'sconscript' )
SConscript( target, build_dir=target_build_dir, duplicate=0 )
env['SRCDIST_ADD']( source=[target] )
def runJSONTests_action( target, source = None, env = None ):
# Add test scripts to python path
jsontest_path = Dir( '#test' ).abspath
sys.path.insert( 0, jsontest_path )
data_path = os.path.join( jsontest_path, 'data' )
import runjsontests
return runjsontests.runAllTests( os.path.abspath(source[0].path), data_path )
def runJSONTests_string( target, source = None, env = None ):
return 'RunJSONTests("%s")' % source[0]
import SCons.Action
ActionFactory = SCons.Action.ActionFactory
RunJSONTests = ActionFactory(runJSONTests_action, runJSONTests_string )
def runUnitTests_action( target, source = None, env = None ):
# Add test scripts to python path
jsontest_path = Dir( '#test' ).abspath
sys.path.insert( 0, jsontest_path )
import rununittests
return rununittests.runAllTests( os.path.abspath(source[0].path) )
def runUnitTests_string( target, source = None, env = None ):
return 'RunUnitTests("%s")' % source[0]
RunUnitTests = ActionFactory(runUnitTests_action, runUnitTests_string )
env.Alias( 'check' )
srcdist_cmd = env['SRCDIST_ADD']( source = """
AUTHORS README.md SConstruct
""".split() )
env.Alias( 'src-dist', srcdist_cmd )
buildProjectInDirectory( 'src/jsontestrunner' )
buildProjectInDirectory( 'src/lib_json' )
buildProjectInDirectory( 'src/test_lib_json' )
#print env.Dump()

View File

@ -1,17 +0,0 @@
# Security Policy
If you have discovered a security vulnerability in this project, please report it
privately. **Do not disclose it as a public issue.** This gives us time to work with you
to fix the issue before public exposure, reducing the chance that the exploit will be
used before a patch is released.
Please submit the report by filling out
[this form](https://github.com/open-source-parsers/jsoncpp/security/advisories/new).
Please provide the following information in your report:
- A description of the vulnerability and its impact
- How to reproduce the issue
This project is maintained by volunteers on a reasonable-effort basis. As such,
we ask that you give us 90 days to work on a fix before public exposure.

86
amalgamate.py Executable file → Normal file
View File

@ -1,19 +1,14 @@
#!/usr/bin/env python """Amalgate json-cpp library sources into a single source and header file.
"""Amalgamate json-cpp library sources into a single source and header file.
Works with python2.6+ and python3.4+. Works with python2.6+ and python3.4+.
Example of invocation (must be invoked from json-cpp top directory): Example of invocation (must be invoked from json-cpp top directory):
python amalgamate.py python amalgate.py
""" """
import os import os
import os.path import os.path
import sys import sys
INCLUDE_PATH = "include/json"
SRC_PATH = "src/lib_json"
class AmalgamationFile: class AmalgamationFile:
def __init__(self, top_dir): def __init__(self, top_dir):
self.top_dir = top_dir self.top_dir = top_dir
@ -55,64 +50,62 @@ class AmalgamationFile:
def amalgamate_source(source_top_dir=None, def amalgamate_source(source_top_dir=None,
target_source_path=None, target_source_path=None,
header_include_path=None): header_include_path=None):
"""Produces amalgamated source. """Produces amalgated source.
Parameters: Parameters:
source_top_dir: top-directory source_top_dir: top-directory
target_source_path: output .cpp path target_source_path: output .cpp path
header_include_path: generated header path relative to target_source_path. header_include_path: generated header path relative to target_source_path.
""" """
print("Amalgamating header...") print("Amalgating header...")
header = AmalgamationFile(source_top_dir) header = AmalgamationFile(source_top_dir)
header.add_text("/// Json-cpp amalgamated header (https://github.com/open-source-parsers/jsoncpp/).") header.add_text("/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/).")
header.add_text('/// It is intended to be used with #include "%s"' % header_include_path) header.add_text('/// It is intended to be used with #include "%s"' % header_include_path)
header.add_file("LICENSE", wrap_in_comment=True) header.add_file("LICENSE", wrap_in_comment=True)
header.add_text("#ifndef JSON_AMALGAMATED_H_INCLUDED") header.add_text("#ifndef JSON_AMALGATED_H_INCLUDED")
header.add_text("# define JSON_AMALGAMATED_H_INCLUDED") header.add_text("# define JSON_AMALGATED_H_INCLUDED")
header.add_text("/// If defined, indicates that the source file is amalgamated") header.add_text("/// If defined, indicates that the source file is amalgated")
header.add_text("/// to prevent private header inclusion.") header.add_text("/// to prevent private header inclusion.")
header.add_text("#define JSON_IS_AMALGAMATION") header.add_text("#define JSON_IS_AMALGAMATION")
header.add_file(os.path.join(INCLUDE_PATH, "version.h")) header.add_file("include/json/version.h")
header.add_file(os.path.join(INCLUDE_PATH, "allocator.h")) #header.add_file("include/json/allocator.h") # Not available here.
header.add_file(os.path.join(INCLUDE_PATH, "config.h")) header.add_file("include/json/config.h")
header.add_file(os.path.join(INCLUDE_PATH, "forwards.h")) header.add_file("include/json/forwards.h")
header.add_file(os.path.join(INCLUDE_PATH, "json_features.h")) header.add_file("include/json/features.h")
header.add_file(os.path.join(INCLUDE_PATH, "value.h")) header.add_file("include/json/value.h")
header.add_file(os.path.join(INCLUDE_PATH, "reader.h")) header.add_file("include/json/reader.h")
header.add_file(os.path.join(INCLUDE_PATH, "writer.h")) header.add_file("include/json/writer.h")
header.add_file(os.path.join(INCLUDE_PATH, "assertions.h")) header.add_file("include/json/assertions.h")
header.add_text("#endif //ifndef JSON_AMALGAMATED_H_INCLUDED") header.add_text("#endif //ifndef JSON_AMALGATED_H_INCLUDED")
target_header_path = os.path.join(os.path.dirname(target_source_path), header_include_path) target_header_path = os.path.join(os.path.dirname(target_source_path), header_include_path)
print("Writing amalgamated header to %r" % target_header_path) print("Writing amalgated header to %r" % target_header_path)
header.write_to(target_header_path) header.write_to(target_header_path)
base, ext = os.path.splitext(header_include_path) base, ext = os.path.splitext(header_include_path)
forward_header_include_path = base + "-forwards" + ext forward_header_include_path = base + "-forwards" + ext
print("Amalgamating forward header...") print("Amalgating forward header...")
header = AmalgamationFile(source_top_dir) header = AmalgamationFile(source_top_dir)
header.add_text("/// Json-cpp amalgamated forward header (https://github.com/open-source-parsers/jsoncpp/).") header.add_text("/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/).")
header.add_text('/// It is intended to be used with #include "%s"' % forward_header_include_path) header.add_text('/// It is intended to be used with #include "%s"' % forward_header_include_path)
header.add_text("/// This header provides forward declaration for all JsonCpp types.") header.add_text("/// This header provides forward declaration for all JsonCpp types.")
header.add_file("LICENSE", wrap_in_comment=True) header.add_file("LICENSE", wrap_in_comment=True)
header.add_text("#ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED") header.add_text("#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED")
header.add_text("# define JSON_FORWARD_AMALGAMATED_H_INCLUDED") header.add_text("# define JSON_FORWARD_AMALGATED_H_INCLUDED")
header.add_text("/// If defined, indicates that the source file is amalgamated") header.add_text("/// If defined, indicates that the source file is amalgated")
header.add_text("/// to prevent private header inclusion.") header.add_text("/// to prevent private header inclusion.")
header.add_text("#define JSON_IS_AMALGAMATION") header.add_text("#define JSON_IS_AMALGAMATION")
header.add_file(os.path.join(INCLUDE_PATH, "version.h")) header.add_file("include/json/config.h")
header.add_file(os.path.join(INCLUDE_PATH, "allocator.h")) header.add_file("include/json/forwards.h")
header.add_file(os.path.join(INCLUDE_PATH, "config.h")) header.add_text("#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED")
header.add_file(os.path.join(INCLUDE_PATH, "forwards.h"))
header.add_text("#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED")
target_forward_header_path = os.path.join(os.path.dirname(target_source_path), target_forward_header_path = os.path.join(os.path.dirname(target_source_path),
forward_header_include_path) forward_header_include_path)
print("Writing amalgamated forward header to %r" % target_forward_header_path) print("Writing amalgated forward header to %r" % target_forward_header_path)
header.write_to(target_forward_header_path) header.write_to(target_forward_header_path)
print("Amalgamating source...") print("Amalgating source...")
source = AmalgamationFile(source_top_dir) source = AmalgamationFile(source_top_dir)
source.add_text("/// Json-cpp amalgamated source (https://github.com/open-source-parsers/jsoncpp/).") source.add_text("/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).")
source.add_text('/// It is intended to be used with #include "%s"' % header_include_path) source.add_text('/// It is intended to be used with #include "%s"' % header_include_path)
source.add_file("LICENSE", wrap_in_comment=True) source.add_file("LICENSE", wrap_in_comment=True)
source.add_text("") source.add_text("")
@ -123,18 +116,19 @@ def amalgamate_source(source_top_dir=None,
#endif #endif
""") """)
source.add_text("") source.add_text("")
source.add_file(os.path.join(SRC_PATH, "json_tool.h")) lib_json = "src/lib_json"
source.add_file(os.path.join(SRC_PATH, "json_reader.cpp")) source.add_file(os.path.join(lib_json, "json_tool.h"))
source.add_file(os.path.join(SRC_PATH, "json_valueiterator.inl")) source.add_file(os.path.join(lib_json, "json_reader.cpp"))
source.add_file(os.path.join(SRC_PATH, "json_value.cpp")) source.add_file(os.path.join(lib_json, "json_valueiterator.inl"))
source.add_file(os.path.join(SRC_PATH, "json_writer.cpp")) source.add_file(os.path.join(lib_json, "json_value.cpp"))
source.add_file(os.path.join(lib_json, "json_writer.cpp"))
print("Writing amalgamated source to %r" % target_source_path) print("Writing amalgated source to %r" % target_source_path)
source.write_to(target_source_path) source.write_to(target_source_path)
def main(): def main():
usage = """%prog [options] usage = """%prog [options]
Generate a single amalgamated source and header file from the sources. Generate a single amalgated source and header file from the sources.
""" """
from optparse import OptionParser from optparse import OptionParser
parser = OptionParser(usage=usage) parser = OptionParser(usage=usage)
@ -142,7 +136,7 @@ Generate a single amalgamated source and header file from the sources.
parser.add_option("-s", "--source", dest="target_source_path", action="store", default="dist/jsoncpp.cpp", parser.add_option("-s", "--source", dest="target_source_path", action="store", default="dist/jsoncpp.cpp",
help="""Output .cpp source path. [Default: %default]""") help="""Output .cpp source path. [Default: %default]""")
parser.add_option("-i", "--include", dest="header_include_path", action="store", default="json/json.h", parser.add_option("-i", "--include", dest="header_include_path", action="store", default="json/json.h",
help="""Header include path. Used to include the header from the amalgamated source file. [Default: %default]""") help="""Header include path. Used to include the header from the amalgated source file. [Default: %default]""")
parser.add_option("-t", "--top-dir", dest="top_dir", action="store", default=os.getcwd(), parser.add_option("-t", "--top-dir", dest="top_dir", action="store", default=os.getcwd(),
help="""Source top-directory. [Default: %default]""") help="""Source top-directory. [Default: %default]""")
parser.enable_interspersed_args() parser.enable_interspersed_args()
@ -155,7 +149,7 @@ Generate a single amalgamated source and header file from the sources.
sys.stderr.write(msg + "\n") sys.stderr.write(msg + "\n")
sys.exit(1) sys.exit(1)
else: else:
print("Source successfully amalgamated") print("Source succesfully amalagated")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -1,32 +1,30 @@
# This is a comment.
version: build.{build}
os: Windows Server 2012 R2
clone_folder: c:\projects\jsoncpp clone_folder: c:\projects\jsoncpp
environment: platform:
- Win32
- x64
matrix: configuration:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - Debug
CMAKE_GENERATOR: Visual Studio 14 2015 - Release
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_GENERATOR: Visual Studio 14 2015 Win64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: Visual Studio 15 2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: Visual Studio 15 2017 Win64
build_script: # scripts to run before build
before_build:
- echo "Running cmake..."
- cd c:\projects\jsoncpp
- cmake --version - cmake --version
# The build script starts in root. - set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH%
- set JSONCPP_FOLDER=%cd% - if %PLATFORM% == Win32 cmake .
- set JSONCPP_BUILD_FOLDER=%JSONCPP_FOLDER%\build\release - if %PLATFORM% == x64 cmake -G "Visual Studio 12 2013 Win64" .
- mkdir -p %JSONCPP_BUILD_FOLDER%
- cd %JSONCPP_BUILD_FOLDER% build:
- cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX:PATH=%CD:\=/%/install -DBUILD_SHARED_LIBS:BOOL=ON %JSONCPP_FOLDER% project: jsoncpp.sln # path to Visual Studio solution or project
# Use ctest to make a dashboard build:
# - ctest -D Experimental(Start|Update|Configure|Build|Test|Coverage|MemCheck|Submit)
# NOTE: Testing on windows is not yet finished:
# - ctest -C Release -D ExperimentalStart -D ExperimentalConfigure -D ExperimentalBuild -D ExperimentalTest -D ExperimentalSubmit
- ctest -C Release -D ExperimentalStart -D ExperimentalConfigure -D ExperimentalBuild -D ExperimentalSubmit
# Final step is to verify that installation succeeds
- cmake --build . --config Release --target install
deploy: deploy:
provider: GitHub provider: GitHub

View File

@ -1,23 +0,0 @@
# This module provides a function for joining paths
# known from most languages
#
# SPDX-License-Identifier: (MIT OR CC0-1.0)
# Copyright 2020 Jan Tojnar
# https://github.com/jtojnar/cmake-snips
#
# Modelled after Pythons os.path.join
# https://docs.python.org/3.7/library/os.path.html#os.path.join
# Windows not supported
function(join_paths joined_path first_path_segment)
set(temp_path "${first_path_segment}")
foreach(current_segment IN LISTS ARGN)
if(NOT ("${current_segment}" STREQUAL ""))
if(IS_ABSOLUTE "${current_segment}")
set(temp_path "${current_segment}")
else()
set(temp_path "${temp_path}/${current_segment}")
endif()
endif()
endforeach()
set(${joined_path} "${temp_path}" PARENT_SCOPE)
endfunction()

View File

@ -4,8 +4,6 @@ VER?=$(shell cat version)
default: default:
@echo "VER=${VER}" @echo "VER=${VER}"
update-version:
perl get_version.pl meson.build >| version
sign: jsoncpp-${VER}.tar.gz sign: jsoncpp-${VER}.tar.gz
gpg --armor --detach-sign $< gpg --armor --detach-sign $<
gpg --verify $<.asc gpg --verify $<.asc
@ -14,7 +12,7 @@ jsoncpp-%.tar.gz:
curl https://github.com/open-source-parsers/jsoncpp/archive/$*.tar.gz -o $@ curl https://github.com/open-source-parsers/jsoncpp/archive/$*.tar.gz -o $@
dox: dox:
python doxybuild.py --doxygen=$$(which doxygen) --in doc/web_doxyfile.in python doxybuild.py --doxygen=$$(which doxygen) --in doc/web_doxyfile.in
rsync -va -c --delete dist/doxygen/jsoncpp-api-html-${VER}/ ../jsoncpp-docs/doxygen/ rsync -va --delete dist/doxygen/jsoncpp-api-html-${VER}/ ../jsoncpp-docs/doxygen/
# Then 'git add -A' and 'git push' in jsoncpp-docs. # Then 'git add -A' and 'git push' in jsoncpp-docs.
build: build:
mkdir -p build/debug mkdir -p build/debug

View File

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

View File

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

View File

@ -9,7 +9,7 @@ import shutil
import string import string
import subprocess import subprocess
import sys import sys
import html import cgi
class BuildDesc: class BuildDesc:
def __init__(self, prepend_envs=None, variables=None, build_type=None, generator=None): def __init__(self, prepend_envs=None, variables=None, build_type=None, generator=None):
@ -195,12 +195,12 @@ def generate_html_report(html_report_path, builds):
for variable in variables: for variable in variables:
build_types = sorted(build_types_by_variable[variable]) build_types = sorted(build_types_by_variable[variable])
nb_build_type = len(build_types_by_variable[variable]) nb_build_type = len(build_types_by_variable[variable])
th_vars.append('<th colspan="%d">%s</th>' % (nb_build_type, html.escape(' '.join(variable)))) th_vars.append('<th colspan="%d">%s</th>' % (nb_build_type, cgi.escape(' '.join(variable))))
for build_type in build_types: for build_type in build_types:
th_build_types.append('<th>%s</th>' % html.escape(build_type)) th_build_types.append('<th>%s</th>' % cgi.escape(build_type))
tr_builds = [] tr_builds = []
for generator in sorted(builds_by_generator): for generator in sorted(builds_by_generator):
tds = [ '<td>%s</td>\n' % html.escape(generator) ] tds = [ '<td>%s</td>\n' % cgi.escape(generator) ]
for variable in variables: for variable in variables:
build_types = sorted(build_types_by_variable[variable]) build_types = sorted(build_types_by_variable[variable])
for build_type in build_types: for build_type in build_types:

View File

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

View File

@ -6,7 +6,7 @@ from __future__ import print_function
# and ends with the first blank line. # and ends with the first blank line.
LICENSE_BEGIN = "// Copyright " LICENSE_BEGIN = "// Copyright "
BRIEF_LICENSE = LICENSE_BEGIN + """2007-2010 Baptiste Lepilleur and The JsonCpp Authors BRIEF_LICENSE = LICENSE_BEGIN + """2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

View File

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

View File

@ -271,7 +271,7 @@ OPTIMIZE_OUTPUT_VHDL = NO
# parses. With this tag you can assign which parser to use for a given # parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it # extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and # using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, # language is one of the parsers supported by doxygen: IDL, Java, Javascript,
# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make # C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
# (default is Fortran), use: inc=Fortran f=C. # (default is Fortran), use: inc=Fortran f=C.
@ -984,8 +984,7 @@ VERBATIM_HEADERS = YES
# classes, structs, unions or interfaces. # classes, structs, unions or interfaces.
# The default value is: YES. # The default value is: YES.
ALPHABETICAL_INDEX = YES ALPHABETICAL_INDEX = NO
TOC_INCLUDE_HEADINGS = 2
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
# which the alphabetical index list will be split. # which the alphabetical index list will be split.
@ -1072,7 +1071,7 @@ HTML_STYLESHEET =
# defined cascading style sheet that is included after the standard style sheets # defined cascading style sheet that is included after the standard style sheets
# created by doxygen. Using this option one can overrule certain style aspects. # created by doxygen. Using this option one can overrule certain style aspects.
# This is preferred over using HTML_STYLESHEET since it does not replace the # This is preferred over using HTML_STYLESHEET since it does not replace the
# standard style sheet and is therefore more robust against future updates. # standard style sheet and is therefor more robust against future updates.
# Doxygen will copy the style sheet file to the output directory. For an example # Doxygen will copy the style sheet file to the output directory. For an example
# see the documentation. # see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
@ -1408,7 +1407,7 @@ FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES FORMULA_TRANSPARENT = YES
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# http://www.mathjax.org) which uses client side JavaScript for the rendering # http://www.mathjax.org) which uses client side Javascript for the rendering
# instead of using prerendered bitmaps. Use this if you do not have LaTeX # instead of using prerendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When # installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path # enabled you may also need to install MathJax separately and configure the path
@ -1478,7 +1477,7 @@ MATHJAX_CODEFILE =
SEARCHENGINE = NO SEARCHENGINE = NO
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be # When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using JavaScript. There # implemented using a web server instead of a web client using Javascript. There
# are two flavours of web server based searching depending on the # are two flavours of web server based searching depending on the
# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
# searching and an index file used by the script. When EXTERNAL_SEARCH is # searching and an index file used by the script. When EXTERNAL_SEARCH is
@ -1944,7 +1943,7 @@ INCLUDE_FILE_PATTERNS = *.h
# recursively expanded use the := operator instead of the = operator. # recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = "_MSC_VER=1800" \ PREDEFINED = "_MSC_VER=1400" \
_CPPRTTI \ _CPPRTTI \
_WIN32 \ _WIN32 \
JSONCPP_DOC_EXCLUDE_IMPLEMENTATION JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
@ -1959,7 +1958,7 @@ PREDEFINED = "_MSC_VER=1800" \
EXPAND_AS_DEFINED = EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have an # remove all refrences to function-like macros that are alone on a line, have an
# all uppercase name, and do not end with a semicolon. Such function macros are # all uppercase name, and do not end with a semicolon. Such function macros are
# typically used for boiler-plate code, and will confuse the parser if not # typically used for boiler-plate code, and will confuse the parser if not
# removed. # removed.

View File

@ -1,21 +1,3 @@
<!-- HTML footer for doxygen 1.8.13--> <hr>
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion </li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/><address class="footer"><small>
$generatedby &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/>
</a> $doxygenversion
</small></address>
<!--END !GENERATE_TREEVIEW-->
</body> </body>
</html> </html>

View File

@ -1,64 +1,24 @@
<!-- HTML header for doxygen 1.8.13--> <html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> <title>
<meta http-equiv="X-UA-Compatible" content="IE=9"/> JsonCpp - JSON data format manipulation library
<meta name="generator" content="Doxygen $doxygenversion"/> </title>
<meta name="viewport" content="width=device-width, initial-scale=1"/> <link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/> <link href="tabs.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
</head> </head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<td>$searchbox</td>
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<table width="100%"> <table width="100%">
<tr> <tr>
<td width="30%" align="left" valign="center"> <td width="40%" align="left" valign="center">
<a href="https://github.com/open-source-parsers/jsoncpp"> <a href="https://github.com/open-source-parsers/jsoncpp">
JsonCpp project page JsonCpp project page
</a> </a>
</td> </td>
<td width="20%" align="center" valign="center"> <td width="40%" align="right" valign="center">
<a href="hierarchy.html">
Classes
</a>
</td>
<td width="20%" align="center" valign="center">
<a href="namespace_json.html">
Namespace
</a>
</td>
<td width="30%" align="right" valign="center">
<a href="http://open-source-parsers.github.io/jsoncpp-docs/doxygen/">JsonCpp home page</a> <a href="http://open-source-parsers.github.io/jsoncpp-docs/doxygen/">JsonCpp home page</a>
</td> </td>
</tr> </tr>
</table> </table>
<hr> <hr>
<!-- end header part -->

View File

@ -44,7 +44,7 @@ PROJECT_NUMBER = %JSONCPP_VERSION%
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short. # quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF = "JSON data format manipulation library" PROJECT_BRIEF =
# With the PROJECT_LOGO tag one can specify an logo or icon that is included in # With the PROJECT_LOGO tag one can specify an logo or icon that is included in
# the documentation. The maximum height of the logo should not exceed 55 pixels # the documentation. The maximum height of the logo should not exceed 55 pixels
@ -271,7 +271,7 @@ OPTIMIZE_OUTPUT_VHDL = NO
# parses. With this tag you can assign which parser to use for a given # parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it # extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and # using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, # language is one of the parsers supported by doxygen: IDL, Java, Javascript,
# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make # C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
# (default is Fortran), use: inc=Fortran f=C. # (default is Fortran), use: inc=Fortran f=C.
@ -984,8 +984,7 @@ VERBATIM_HEADERS = NO
# classes, structs, unions or interfaces. # classes, structs, unions or interfaces.
# The default value is: YES. # The default value is: YES.
ALPHABETICAL_INDEX = YES ALPHABETICAL_INDEX = NO
TOC_INCLUDE_HEADINGS = 2
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
# which the alphabetical index list will be split. # which the alphabetical index list will be split.
@ -1072,7 +1071,7 @@ HTML_STYLESHEET =
# defined cascading style sheet that is included after the standard style sheets # defined cascading style sheet that is included after the standard style sheets
# created by doxygen. Using this option one can overrule certain style aspects. # created by doxygen. Using this option one can overrule certain style aspects.
# This is preferred over using HTML_STYLESHEET since it does not replace the # This is preferred over using HTML_STYLESHEET since it does not replace the
# standard style sheet and is therefore more robust against future updates. # standard style sheet and is therefor more robust against future updates.
# Doxygen will copy the style sheet file to the output directory. For an example # Doxygen will copy the style sheet file to the output directory. For an example
# see the documentation. # see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
@ -1125,7 +1124,7 @@ HTML_COLORSTYLE_GAMMA = 80
# The default value is: YES. # The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = NO HTML_TIMESTAMP = YES
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the # documentation will contain sections that can be hidden and shown after the
@ -1361,7 +1360,7 @@ DISABLE_INDEX = NO
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_TREEVIEW = YES GENERATE_TREEVIEW = NO
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation. # doxygen will group on one line in the generated HTML documentation.
@ -1408,7 +1407,7 @@ FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES FORMULA_TRANSPARENT = YES
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# http://www.mathjax.org) which uses client side JavaScript for the rendering # http://www.mathjax.org) which uses client side Javascript for the rendering
# instead of using prerendered bitmaps. Use this if you do not have LaTeX # instead of using prerendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When # installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path # enabled you may also need to install MathJax separately and configure the path
@ -1478,7 +1477,7 @@ MATHJAX_CODEFILE =
SEARCHENGINE = NO SEARCHENGINE = NO
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be # When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using JavaScript. There # implemented using a web server instead of a web client using Javascript. There
# are two flavours of web server based searching depending on the # are two flavours of web server based searching depending on the
# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
# searching and an index file used by the script. When EXTERNAL_SEARCH is # searching and an index file used by the script. When EXTERNAL_SEARCH is
@ -1798,6 +1797,18 @@ GENERATE_XML = NO
XML_OUTPUT = xml XML_OUTPUT = xml
# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
# validating XML parser to check the syntax of the XML files.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_SCHEMA =
# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
# validating XML parser to check the syntax of the XML files.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_DTD =
# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program # If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
# listings (including syntax highlighting and cross-referencing information) to # listings (including syntax highlighting and cross-referencing information) to
# the XML output. Note that enabling this will significantly increase the size # the XML output. Note that enabling this will significantly increase the size
@ -1932,7 +1943,7 @@ INCLUDE_FILE_PATTERNS = *.h
# recursively expanded use the := operator instead of the = operator. # recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = "_MSC_VER=1800" \ PREDEFINED = "_MSC_VER=1400" \
_CPPRTTI \ _CPPRTTI \
_WIN32 \ _WIN32 \
JSONCPP_DOC_EXCLUDE_IMPLEMENTATION JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
@ -1947,7 +1958,7 @@ PREDEFINED = "_MSC_VER=1800" \
EXPAND_AS_DEFINED = EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have an # remove all refrences to function-like macros that are alone on a line, have an
# all uppercase name, and do not end with a semicolon. Such function macros are # all uppercase name, and do not end with a semicolon. Such function macros are
# typically used for boiler-plate code, and will confuse the parser if not # typically used for boiler-plate code, and will confuse the parser if not
# removed. # removed.

View File

@ -156,7 +156,7 @@ def build_doc(options, make_release=False):
def main(): def main():
usage = """%prog usage = """%prog
Generates doxygen documentation in build/doxygen. Generates doxygen documentation in build/doxygen.
Optionally makes a tarball of the documentation to dist/. Optionaly makes a tarball of the documentation to dist/.
Must be started in the project top directory. Must be started in the project top directory.
""" """

View File

@ -1,33 +0,0 @@
cc_binary(
name = "readFromStream_ok",
srcs = ["readFromStream/readFromStream.cpp"],
deps = ["//:jsoncpp"],
args = ["$(location :readFromStream/withComment.json)"],
data = ["readFromStream/withComment.json"],
)
cc_binary(
name = "readFromStream_err",
srcs = ["readFromStream/readFromStream.cpp"],
deps = ["//:jsoncpp"],
args = ["$(location :readFromStream/errorFormat.json)"],
data = ["readFromStream/errorFormat.json"],
)
cc_binary(
name = "readFromString",
srcs = ["readFromString/readFromString.cpp"],
deps = ["//:jsoncpp"],
)
cc_binary(
name = "streamWrite",
srcs = ["streamWrite/streamWrite.cpp"],
deps = ["//:jsoncpp"],
)
cc_binary(
name = "stringWrite",
srcs = ["stringWrite/stringWrite.cpp"],
deps = ["//:jsoncpp"],
)

View File

@ -1,27 +0,0 @@
#vim: et ts =4 sts = 4 sw = 4 tw = 0
set(EXAMPLES
readFromString
readFromStream
stringWrite
streamWrite
)
add_definitions(-D_GLIBCXX_USE_CXX11_ABI)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(-Wall -Wextra)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
add_definitions(
-D_SCL_SECURE_NO_WARNINGS
-D_CRT_SECURE_NO_WARNINGS
-D_WIN32_WINNT=0x601
-D_WINSOCK_DEPRECATED_NO_WARNINGS
)
endif()
foreach(example ${EXAMPLES})
add_executable(${example} ${example}/${example}.cpp)
target_include_directories(${example} PUBLIC ${CMAKE_SOURCE_DIR}/include)
target_link_libraries(${example} jsoncpp_lib)
endforeach()
add_custom_target(examples ALL DEPENDS ${EXAMPLES})

View File

@ -1,13 +0,0 @@
***NOTE***
If you get linker errors about undefined references to symbols that involve types in the `std::__cxx11` namespace or the tag
`[abi:cxx11]` then it probably indicates that you are trying to link together object files that were compiled with different
values for the _GLIBCXX_USE_CXX11_ABI marco. This commonly happens when linking to a third-party library that was compiled with
an older version of GCC. If the third-party library cannot be rebuilt with the new ABI, then you need to recompile your code with
the old ABI,just like:
**g++ stringWrite.cpp -ljsoncpp -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -o stringWrite**
Not all of uses of the new ABI will cause changes in symbol names, for example a class with a `std::string` member variable will
have the same mangled name whether compiled with the older or new ABI. In order to detect such problems, the new types and functions
are annotated with the abi_tag attribute, allowing the compiler to warn about potential ABI incompatibilities in code using them.
Those warnings can be enabled with the `-Wabi-tag` option.

View File

@ -1,3 +0,0 @@
{
1: "value"
}

View File

@ -1,30 +0,0 @@
#include "json/json.h"
#include <fstream>
#include <iostream>
/** \brief Parse from stream, collect comments and capture error info.
* Example Usage:
* $g++ readFromStream.cpp -ljsoncpp -std=c++11 -o readFromStream
* $./readFromStream
* // comment head
* {
* // comment before
* "key" : "value"
* }
* // comment after
* // comment tail
*/
int main(int argc, char* argv[]) {
Json::Value root;
std::ifstream ifs;
ifs.open(argv[1]);
Json::CharReaderBuilder builder;
builder["collectComments"] = true;
JSONCPP_STRING errs;
if (!parseFromStream(builder, ifs, &root, &errs)) {
std::cout << errs << std::endl;
return EXIT_FAILURE;
}
std::cout << root << std::endl;
return EXIT_SUCCESS;
}

View File

@ -1,6 +0,0 @@
// comment head
{
// comment before
"key" : "value"
// comment after
}// comment tail

View File

@ -1,38 +0,0 @@
#include "json/json.h"
#include <iostream>
#include <memory>
/**
* \brief Parse a raw string into Value object using the CharReaderBuilder
* class, or the legacy Reader class.
* Example Usage:
* $g++ readFromString.cpp -ljsoncpp -std=c++11 -o readFromString
* $./readFromString
* colin
* 20
*/
int main() {
const std::string rawJson = R"({"Age": 20, "Name": "colin"})";
const auto rawJsonLength = static_cast<int>(rawJson.length());
constexpr bool shouldUseOldWay = false;
JSONCPP_STRING err;
Json::Value root;
if (shouldUseOldWay) {
Json::Reader reader;
reader.parse(rawJson, root);
} else {
Json::CharReaderBuilder builder;
const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
if (!reader->parse(rawJson.c_str(), rawJson.c_str() + rawJsonLength, &root,
&err)) {
std::cout << "error: " << err << std::endl;
return EXIT_FAILURE;
}
}
const std::string name = root["Name"].asString();
const int age = root["Age"].asInt();
std::cout << name << std::endl;
std::cout << age << std::endl;
return EXIT_SUCCESS;
}

View File

@ -1,23 +0,0 @@
#include "json/json.h"
#include <iostream>
#include <memory>
/** \brief Write the Value object to a stream.
* Example Usage:
* $g++ streamWrite.cpp -ljsoncpp -std=c++11 -o streamWrite
* $./streamWrite
* {
* "Age" : 20,
* "Name" : "robin"
* }
*/
int main() {
Json::Value root;
Json::StreamWriterBuilder builder;
const std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
root["Name"] = "robin";
root["Age"] = 20;
writer->write(root, &std::cout);
return EXIT_SUCCESS;
}

View File

@ -1,33 +0,0 @@
#include "json/json.h"
#include <iostream>
/** \brief Write a Value object to a string.
* Example Usage:
* $g++ stringWrite.cpp -ljsoncpp -std=c++11 -o stringWrite
* $./stringWrite
* {
* "action" : "run",
* "data" :
* {
* "number" : 1
* }
* }
*/
int main() {
Json::Value root;
Json::Value data;
constexpr bool shouldUseOldWay = false;
root["action"] = "run";
data["number"] = 1;
root["data"] = data;
if (shouldUseOldWay) {
Json::FastWriter writer;
const std::string json_file = writer.write(root);
std::cout << json_file << std::endl;
} else {
Json::StreamWriterBuilder builder;
const std::string json_file = Json::writeString(builder, root);
std::cout << json_file << std::endl;
}
return EXIT_SUCCESS;
}

View File

@ -1,5 +0,0 @@
while (<>) {
if (/version : '(.+)',/) {
print "$1";
}
}

View File

@ -1,5 +1,2 @@
file(GLOB INCLUDE_FILES "json/*.h") FILE(GLOB INCLUDE_FILES "json/*.h")
install(FILES INSTALL(FILES ${INCLUDE_FILES} DESTINATION ${INCLUDE_INSTALL_DIR}/json)
${INCLUDE_FILES}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/json)

View File

@ -1,9 +0,0 @@
string(TOLOWER "${CMAKE_INSTALL_PREFIX}" _PREFIX)
string(TOLOWER "${ITK_BINARY_DIR}" _BUILD)
if("${_PREFIX}" STREQUAL "${_BUILD}")
message(FATAL_ERROR
"The current CMAKE_INSTALL_PREFIX points at the build tree:\n"
" ${CMAKE_INSTALL_PREFIX}\n"
"This is not supported."
)
endif()

View File

@ -1,45 +0,0 @@
#
# This function will prevent in-source builds
function(AssureOutOfSourceBuilds)
# make sure the user doesn't play dirty with symlinks
get_filename_component(srcdir "${CMAKE_CURRENT_SOURCE_DIR}" REALPATH)
get_filename_component(bindir "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
# disallow in-source builds
if("${srcdir}" STREQUAL "${bindir}")
message("######################################################")
message("# jsoncpp should not be configured & built in the jsoncpp source directory")
message("# You must run cmake in a build directory.")
message("# For example:")
message("# mkdir jsoncpp-Sandbox ; cd jsoncpp-sandbox")
message("# git clone https://github.com/open-source-parsers/jsoncpp.git # or download & unpack the source tarball")
message("# mkdir jsoncpp-build")
message("# this will create the following directory structure")
message("#")
message("# jsoncpp-Sandbox")
message("# +--jsoncpp")
message("# +--jsoncpp-build")
message("#")
message("# Then you can proceed to configure and build")
message("# by using the following commands")
message("#")
message("# cd jsoncpp-build")
message("# cmake ../jsoncpp # or ccmake, or cmake-gui ")
message("# make")
message("#")
message("# NOTE: Given that you already tried to make an in-source build")
message("# CMake have already created several files & directories")
message("# in your source tree. run 'git status' to find them and")
message("# remove them by doing:")
message("#")
message("# cd jsoncpp-Sandbox/jsoncpp")
message("# git clean -n -d")
message("# git clean -f -d")
message("# git checkout --")
message("#")
message("######################################################")
message(FATAL_ERROR "Quitting configuration")
endif()
endfunction()
AssureOutOfSourceBuilds()

View File

@ -1,21 +1,18 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_ALLOCATOR_H_INCLUDED #ifndef CPPTL_JSON_ALLOCATOR_H_INCLUDED
#define JSON_ALLOCATOR_H_INCLUDED #define CPPTL_JSON_ALLOCATOR_H_INCLUDED
#include <algorithm>
#include <cstring> #include <cstring>
#include <memory> #include <memory>
#pragma pack(push)
#pragma pack()
namespace Json { namespace Json {
template <typename T> class SecureAllocator { template<typename T>
public: class SecureAllocator {
public:
// Type definitions // Type definitions
using value_type = T; using value_type = T;
using pointer = T*; using pointer = T*;
@ -37,18 +34,11 @@ public:
* Release memory which was allocated for N items at pointer P. * Release memory which was allocated for N items at pointer P.
* *
* The memory block is filled with zeroes before being released. * The memory block is filled with zeroes before being released.
* The pointer argument is tagged as "volatile" to prevent the
* compiler optimizing out this critical step.
*/ */
void deallocate(pointer p, size_type n) { void deallocate(volatile pointer p, size_type n) {
// These constructs will not be removed by the compiler during optimization, std::memset(p, 0, n * sizeof(T));
// unlike memset.
#if defined(HAVE_MEMSET_S)
memset_s(p, n * sizeof(T), 0, n * sizeof(T));
#elif defined(_WIN32)
RtlSecureZeroMemory(p, n * sizeof(T));
#else
std::fill_n(reinterpret_cast<volatile unsigned char*>(p), n, 0);
#endif
// free using "global operator delete" // free using "global operator delete"
::operator delete(p); ::operator delete(p);
} }
@ -56,16 +46,23 @@ public:
/** /**
* Construct an item in-place at pointer P. * Construct an item in-place at pointer P.
*/ */
template <typename... Args> void construct(pointer p, Args&&... args) { template<typename... Args>
void construct(pointer p, Args&&... args) {
// construct using "placement new" and "perfect forwarding" // construct using "placement new" and "perfect forwarding"
::new (static_cast<void*>(p)) T(std::forward<Args>(args)...); ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
} }
size_type max_size() const { return size_t(-1) / sizeof(T); } size_type max_size() const {
return size_t(-1) / sizeof(T);
}
pointer address(reference x) const { return std::addressof(x); } pointer address( reference x ) const {
return std::addressof(x);
}
const_pointer address(const_reference x) const { return std::addressof(x); } const_pointer address( const_reference x ) const {
return std::addressof(x);
}
/** /**
* Destroy an item in-place at pointer P. * Destroy an item in-place at pointer P.
@ -77,24 +74,21 @@ public:
// Boilerplate // Boilerplate
SecureAllocator() {} SecureAllocator() {}
template <typename U> SecureAllocator(const SecureAllocator<U>&) {} template<typename U> SecureAllocator(const SecureAllocator<U>&) {}
template <typename U> struct rebind { template<typename U> struct rebind { using other = SecureAllocator<U>; };
using other = SecureAllocator<U>;
};
}; };
template <typename T, typename U>
template<typename T, typename U>
bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) { bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return true; return true;
} }
template <typename T, typename U> template<typename T, typename U>
bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) { bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return false; return false;
} }
} // namespace Json } //namespace Json
#pragma pack(pop) #endif // CPPTL_JSON_ALLOCATOR_H_INCLUDED
#endif // JSON_ALLOCATOR_H_INCLUDED

View File

@ -1,12 +1,12 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_ASSERTIONS_H_INCLUDED #ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED
#define JSON_ASSERTIONS_H_INCLUDED #define CPPTL_JSON_ASSERTIONS_H_INCLUDED
#include <cstdlib> #include <stdlib.h>
#include <sstream> #include <sstream>
#if !defined(JSON_IS_AMALGAMATION) #if !defined(JSON_IS_AMALGAMATION)
@ -20,42 +20,35 @@
#if JSON_USE_EXCEPTION #if JSON_USE_EXCEPTION
// @todo <= add detail about condition in exception // @todo <= add detail about condition in exception
#define JSON_ASSERT(condition) \ # define JSON_ASSERT(condition) \
do { \ {if (!(condition)) {Json::throwLogicError( "assert json failed" );}}
if (!(condition)) { \
Json::throwLogicError("assert json failed"); \
} \
} while (0)
#define JSON_FAIL_MESSAGE(message) \ # define JSON_FAIL_MESSAGE(message) \
do { \ { \
OStringStream oss; \ JSONCPP_OSTRINGSTREAM oss; oss << message; \
oss << message; \
Json::throwLogicError(oss.str()); \ Json::throwLogicError(oss.str()); \
abort(); \ abort(); \
} while (0) }
#else // JSON_USE_EXCEPTION #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 // The call to assert() will show the failure message in debug builds. In
// release builds we abort, for a core-dump or debugger. // release builds we abort, for a core-dump or debugger.
#define JSON_FAIL_MESSAGE(message) \ # define JSON_FAIL_MESSAGE(message) \
{ \ { \
OStringStream oss; \ JSONCPP_OSTRINGSTREAM oss; oss << message; \
oss << message; \
assert(false && oss.str().c_str()); \ assert(false && oss.str().c_str()); \
abort(); \ abort(); \
} }
#endif #endif
#define JSON_ASSERT_MESSAGE(condition, message) \ #define JSON_ASSERT_MESSAGE(condition, message) \
do { \
if (!(condition)) { \ if (!(condition)) { \
JSON_FAIL_MESSAGE(message); \ JSON_FAIL_MESSAGE(message); \
} \ }
} while (0)
#endif // JSON_ASSERTIONS_H_INCLUDED #endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED

25
include/json/autolink.h Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2007-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
#ifndef JSON_AUTOLINK_H_INCLUDED
#define JSON_AUTOLINK_H_INCLUDED
#include "config.h"
#ifdef JSON_IN_CPPTL
#include <cpptl/cpptl_autolink.h>
#endif
#if !defined(JSON_NO_AUTOLINK) && !defined(JSON_DLL_BUILD) && \
!defined(JSON_IN_CPPTL)
#define CPPTL_AUTOLINK_NAME "json"
#undef CPPTL_AUTOLINK_DLL
#ifdef JSON_DLL
#define CPPTL_AUTOLINK_DLL
#endif
#include "autolink.h"
#endif
#endif // JSON_AUTOLINK_H_INCLUDED

View File

@ -1,18 +1,23 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_CONFIG_H_INCLUDED #ifndef JSON_CONFIG_H_INCLUDED
#define JSON_CONFIG_H_INCLUDED #define JSON_CONFIG_H_INCLUDED
#include <cstddef> #include <stddef.h>
#include <cstdint> #include <string> //typedef String
#include <istream> #include <stdint.h> //typedef int64_t, uint64_t
#include <memory>
#include <ostream> /// If defined, indicates that json library is embedded in CppTL library.
#include <sstream> //# define JSON_IN_CPPTL 1
#include <string>
#include <type_traits> /// If defined, indicates that json may leverage CppTL library
//# define JSON_USE_CPPTL 1
/// If defined, indicates that cpptl vector based map should be used instead of
/// std::map
/// as Value container.
//# define JSON_USE_CPPTL_SMALLMAP 1
// If non-zero, the library uses exceptions to report bad input instead of C // If non-zero, the library uses exceptions to report bad input instead of C
// assertion macros. The default is to use exceptions. // assertion macros. The default is to use exceptions.
@ -20,131 +25,154 @@
#define JSON_USE_EXCEPTION 1 #define JSON_USE_EXCEPTION 1
#endif #endif
// Temporary, tracked for removal with issue #982. /// If defined, indicates that the source file is amalgated
#ifndef JSON_USE_NULLREF
#define JSON_USE_NULLREF 1
#endif
/// If defined, indicates that the source file is amalgamated
/// to prevent private header inclusion. /// to prevent private header inclusion.
/// Remarks: it is automatically defined in the generated amalgamated header. /// Remarks: it is automatically defined in the generated amalgated header.
// #define JSON_IS_AMALGAMATION // #define JSON_IS_AMALGAMATION
// Export macros for DLL visibility #ifdef JSON_IN_CPPTL
#if defined(JSON_DLL_BUILD) #include <cpptl/config.h>
#ifndef JSON_USE_CPPTL
#define JSON_USE_CPPTL 1
#endif
#endif
#ifdef JSON_IN_CPPTL
#define JSON_API CPPTL_API
#elif defined(JSON_DLL_BUILD)
#if defined(_MSC_VER) || defined(__MINGW32__) #if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllexport) #define JSON_API __declspec(dllexport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#elif defined(__GNUC__) || defined(__clang__)
#define JSON_API __attribute__((visibility("default")))
#endif // if defined(_MSC_VER) #endif // if defined(_MSC_VER)
#elif defined(JSON_DLL) #elif defined(JSON_DLL)
#if defined(_MSC_VER) || defined(__MINGW32__) #if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllimport) #define JSON_API __declspec(dllimport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#endif // if defined(_MSC_VER) #endif // if defined(_MSC_VER)
#endif // ifdef JSON_DLL_BUILD #endif // ifdef JSON_IN_CPPTL
#if !defined(JSON_API) #if !defined(JSON_API)
#define JSON_API #define JSON_API
#endif #endif
#if defined(_MSC_VER) && _MSC_VER < 1800
#error \
"ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities"
#endif
#if defined(_MSC_VER) && _MSC_VER < 1900
// As recommended at
// https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size,
const char* format, ...);
#define jsoncpp_snprintf msvc_pre1900_c99_snprintf
#else
#define jsoncpp_snprintf std::snprintf
#endif
// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
// integer // integer
// Storages, and 64 bits integer support is disabled. // Storages, and 64 bits integer support is disabled.
// #define JSON_NO_INT64 1 // #define JSON_NO_INT64 1
// JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools. #if defined(_MSC_VER) // MSVC
// C++11 should be used directly in JSONCPP. # if _MSC_VER <= 1200 // MSVC 6
#define JSONCPP_OVERRIDE override // Microsoft Visual Studio 6 only support conversion from __int64 to double
// (no conversion from unsigned __int64).
# define JSON_USE_INT64_DOUBLE_CONVERSION 1
// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
// characters in the debug information)
// All projects I've ever seen with VS6 were using this globally (not bothering
// with pragma push/pop).
# pragma warning(disable : 4786)
# endif // MSVC 6
# if _MSC_VER >= 1500 // MSVC 2008
/// Indicates that the following function is deprecated.
# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
# endif
#endif // defined(_MSC_VER)
// In c++11 the override keyword allows you to explicity define that a function
// is intended to override the base-class version. This makes the code more
// managable and fixes a set of common hard-to-find bugs.
#if __cplusplus >= 201103L
# define JSONCPP_OVERRIDE override
#elif defined(_MSC_VER) && _MSC_VER > 1600
# define JSONCPP_OVERRIDE override
#else
# define JSONCPP_OVERRIDE
#endif
#ifndef JSON_HAS_RVALUE_REFERENCES
#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
#define JSON_HAS_RVALUE_REFERENCES 1
#endif // MSVC >= 2010
#ifdef __clang__ #ifdef __clang__
#if __has_extension(attribute_deprecated_with_message) #if __has_feature(cxx_rvalue_references)
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) #define JSON_HAS_RVALUE_REFERENCES 1
#endif // has_feature
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
#define JSON_HAS_RVALUE_REFERENCES 1
#endif // GXX_EXPERIMENTAL
#endif // __clang__ || __GNUC__
#endif // not defined JSON_HAS_RVALUE_REFERENCES
#ifndef JSON_HAS_RVALUE_REFERENCES
#define JSON_HAS_RVALUE_REFERENCES 0
#endif #endif
#elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc)
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) #ifdef __clang__
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) # define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
#endif // GNUC version # elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates # define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
// MSVC) # endif // GNUC version
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) #endif // __clang__ || __GNUC__
#endif // __clang__ || __GNUC__ || _MSC_VER
#if !defined(JSONCPP_DEPRECATED) #if !defined(JSONCPP_DEPRECATED)
#define JSONCPP_DEPRECATED(message) #define JSONCPP_DEPRECATED(message)
#endif // if !defined(JSONCPP_DEPRECATED) #endif // if !defined(JSONCPP_DEPRECATED)
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6)) #if __GNUC__ >= 6
#define JSON_USE_INT64_DOUBLE_CONVERSION 1 # define JSON_USE_INT64_DOUBLE_CONVERSION 1
#endif #endif
#if !defined(JSON_IS_AMALGAMATION) #if !defined(JSON_IS_AMALGAMATION)
#include "allocator.h" # include "version.h"
#include "version.h"
# if JSONCPP_USING_SECURE_MEMORY
# include "allocator.h" //typedef Allocator
# endif
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
namespace Json { namespace Json {
using Int = int; typedef int Int;
using UInt = unsigned int; typedef unsigned int UInt;
#if defined(JSON_NO_INT64) #if defined(JSON_NO_INT64)
using LargestInt = int; typedef int LargestInt;
using LargestUInt = unsigned int; typedef unsigned int LargestUInt;
#undef JSON_HAS_INT64 #undef JSON_HAS_INT64
#else // if defined(JSON_NO_INT64) #else // if defined(JSON_NO_INT64)
// For Microsoft Visual use specific types as long long is not supported // For Microsoft Visual use specific types as long long is not supported
#if defined(_MSC_VER) // Microsoft Visual Studio #if defined(_MSC_VER) // Microsoft Visual Studio
using Int64 = __int64; typedef __int64 Int64;
using UInt64 = unsigned __int64; typedef unsigned __int64 UInt64;
#else // if defined(_MSC_VER) // Other platforms, use long long #else // if defined(_MSC_VER) // Other platforms, use long long
using Int64 = int64_t; typedef int64_t Int64;
using UInt64 = uint64_t; typedef uint64_t UInt64;
#endif // if defined(_MSC_VER) #endif // if defined(_MSC_VER)
using LargestInt = Int64; typedef Int64 LargestInt;
using LargestUInt = UInt64; typedef UInt64 LargestUInt;
#define JSON_HAS_INT64 #define JSON_HAS_INT64
#endif // if defined(JSON_NO_INT64) #endif // if defined(JSON_NO_INT64)
#if JSONCPP_USING_SECURE_MEMORY
template <typename T> #define JSONCPP_STRING std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
using Allocator = #define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
typename std::conditional<JSONCPP_USE_SECURE_MEMORY, SecureAllocator<T>, #define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char>>
std::allocator<T>>::type; #define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>; #define JSONCPP_ISTREAM std::istream
using IStringStream = #else
std::basic_istringstream<String::value_type, String::traits_type, #define JSONCPP_STRING std::string
String::allocator_type>; #define JSONCPP_OSTRINGSTREAM std::ostringstream
using OStringStream = #define JSONCPP_OSTREAM std::ostream
std::basic_ostringstream<String::value_type, String::traits_type, #define JSONCPP_ISTRINGSTREAM std::istringstream
String::allocator_type>; #define JSONCPP_ISTREAM std::istream
using IStream = std::istream; #endif // if JSONCPP_USING_SECURE_MEMORY
using OStream = std::ostream; } // end namespace Json
} // namespace Json
// Legacy names (formerly macros).
using JSONCPP_STRING = Json::String;
using JSONCPP_ISTRINGSTREAM = Json::IStringStream;
using JSONCPP_OSTRINGSTREAM = Json::OStringStream;
using JSONCPP_ISTREAM = Json::IStream;
using JSONCPP_OSTREAM = Json::OStream;
#endif // JSON_CONFIG_H_INCLUDED #endif // JSON_CONFIG_H_INCLUDED

View File

@ -1,18 +1,15 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_FEATURES_H_INCLUDED #ifndef CPPTL_JSON_FEATURES_H_INCLUDED
#define JSON_FEATURES_H_INCLUDED #define CPPTL_JSON_FEATURES_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION) #if !defined(JSON_IS_AMALGAMATION)
#include "forwards.h" #include "forwards.h"
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
#pragma pack(push)
#pragma pack()
namespace Json { namespace Json {
/** \brief Configuration passed to reader and writer. /** \brief Configuration passed to reader and writer.
@ -42,21 +39,19 @@ public:
Features(); Features();
/// \c true if comments are allowed. Default: \c true. /// \c true if comments are allowed. Default: \c true.
bool allowComments_{true}; bool allowComments_;
/// \c true if root must be either an array or an object value. Default: \c /// \c true if root must be either an array or an object value. Default: \c
/// false. /// false.
bool strictRoot_{false}; bool strictRoot_;
/// \c true if dropped null placeholders are allowed. Default: \c false. /// \c true if dropped null placeholders are allowed. Default: \c false.
bool allowDroppedNullPlaceholders_{false}; bool allowDroppedNullPlaceholders_;
/// \c true if numeric object key are allowed. Default: \c false. /// \c true if numeric object key are allowed. Default: \c false.
bool allowNumericKeys_{false}; bool allowNumericKeys_;
}; };
} // namespace Json } // namespace Json
#pragma pack(pop) #endif // CPPTL_JSON_FEATURES_H_INCLUDED
#endif // JSON_FEATURES_H_INCLUDED

View File

@ -1,4 +1,4 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@ -13,23 +13,17 @@
namespace Json { namespace Json {
// writer.h // writer.h
class StreamWriter;
class StreamWriterBuilder;
class Writer;
class FastWriter; class FastWriter;
class StyledWriter; class StyledWriter;
class StyledStreamWriter;
// reader.h // reader.h
class Reader; class Reader;
class CharReader;
class CharReaderBuilder;
// json_features.h // features.h
class Features; class Features;
// value.h // value.h
using ArrayIndex = unsigned int; typedef unsigned int ArrayIndex;
class StaticString; class StaticString;
class Path; class Path;
class PathArgument; class PathArgument;

View File

@ -1,4 +1,4 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@ -6,10 +6,10 @@
#ifndef JSON_JSON_H_INCLUDED #ifndef JSON_JSON_H_INCLUDED
#define JSON_JSON_H_INCLUDED #define JSON_JSON_H_INCLUDED
#include "config.h" #include "autolink.h"
#include "json_features.h"
#include "reader.h"
#include "value.h" #include "value.h"
#include "reader.h"
#include "writer.h" #include "writer.h"
#include "features.h"
#endif // JSON_JSON_H_INCLUDED #endif // JSON_JSON_H_INCLUDED

View File

@ -1,20 +1,20 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_READER_H_INCLUDED #ifndef CPPTL_JSON_READER_H_INCLUDED
#define JSON_READER_H_INCLUDED #define CPPTL_JSON_READER_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION) #if !defined(JSON_IS_AMALGAMATION)
#include "json_features.h" #include "features.h"
#include "value.h" #include "value.h"
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
#include <deque> #include <deque>
#include <iosfwd> #include <iosfwd>
#include <istream>
#include <stack> #include <stack>
#include <string> #include <string>
#include <istream>
// Disable warning C4251: <data member>: <type> needs to have dll-interface to // Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by... // be used by...
@ -23,135 +23,135 @@
#pragma warning(disable : 4251) #pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma pack(push)
#pragma pack()
namespace Json { namespace Json {
/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
* Value. *Value.
* *
* \deprecated Use CharReader and CharReaderBuilder. * \deprecated Use CharReader and CharReaderBuilder.
*/ */
class JSON_API Reader { class JSON_API Reader {
public: public:
using Char = char; typedef char Char;
using Location = const Char*; typedef const Char* Location;
/** \brief An error tagged with where in the JSON text it was encountered. /** \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 * The offsets give the [start, limit) range of bytes within the text. Note
* that this is bytes, not codepoints. * that this is bytes, not codepoints.
*
*/ */
struct StructuredError { struct StructuredError {
ptrdiff_t offset_start; ptrdiff_t offset_start;
ptrdiff_t offset_limit; ptrdiff_t offset_limit;
String message; JSONCPP_STRING message;
}; };
/** \brief Constructs a Reader allowing all features for parsing. /** \brief Constructs a Reader allowing all features
* \deprecated Use CharReader and CharReaderBuilder. * for parsing.
*/ */
Reader(); Reader();
/** \brief Constructs a Reader allowing the specified feature set for parsing. /** \brief Constructs a Reader allowing the specified feature set
* \deprecated Use CharReader and CharReaderBuilder. * for parsing.
*/ */
Reader(const Features& features); Reader(const Features& features);
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
* document. * document.
* * \param document UTF-8 encoded string containing the document to read.
* \param document UTF-8 encoded string containing the document * \param root [out] Contains the root value of the document if it was
* to read. * successfully parsed.
* \param[out] root Contains the root value of the document if it * \param collectComments \c true to collect comment and allow writing them
* was successfully parsed. * back during
* \param collectComments \c true to collect comment and allow writing * serialization, \c false to discard comments.
* them back during serialization, \c false to * This parameter is ignored if
* discard comments. This parameter is ignored * Features::allowComments_
* if Features::allowComments_ is \c false. * is \c false.
* \return \c true if the document was successfully parsed, \c false if an * \return \c true if the document was successfully parsed, \c false if an
* error occurred. * error occurred.
*/ */
bool parse(const std::string& document, Value& root, bool
bool collectComments = true); parse(const std::string& document, Value& root, bool collectComments = true);
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
* document. document.
* * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
* \param beginDoc Pointer on the beginning of the UTF-8 encoded document to read.
* string of the document to read. * \param endDoc Pointer on the end of the UTF-8 encoded string of the
* \param endDoc Pointer on the end of the UTF-8 encoded string document to read.
* of the document to read. Must be >= beginDoc. * Must be >= beginDoc.
* \param[out] root Contains the root value of the document if it * \param root [out] Contains the root value of the document if it was
* was successfully parsed. * successfully parsed.
* \param collectComments \c true to collect comment and allow writing * \param collectComments \c true to collect comment and allow writing them
* them back during serialization, \c false to back during
* discard comments. This parameter is ignored * serialization, \c false to discard comments.
* if Features::allowComments_ is \c false. * This parameter is ignored if
Features::allowComments_
* is \c false.
* \return \c true if the document was successfully parsed, \c false if an * \return \c true if the document was successfully parsed, \c false if an
* error occurred. error occurred.
*/ */
bool parse(const char* beginDoc, const char* endDoc, Value& root, bool parse(const char* beginDoc,
const char* endDoc,
Value& root,
bool collectComments = true); bool collectComments = true);
/// \brief Parse from input stream. /// \brief Parse from input stream.
/// \see Json::operator>>(std::istream&, Json::Value&). /// \see Json::operator>>(std::istream&, Json::Value&).
bool parse(IStream& is, Value& root, bool collectComments = true); bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true);
/** \brief Returns a user friendly string that list errors in the parsed /** \brief Returns a user friendly string that list errors in the parsed
* document. * document.
* * \return Formatted error message with the list of errors with their location
* \return Formatted error message with the list of errors with their * in
* location in the parsed document. An empty string is returned if no error * the parsed document. An empty string is returned if no error
* occurred during parsing. * occurred
* during parsing.
* \deprecated Use getFormattedErrorMessages() instead (typo fix). * \deprecated Use getFormattedErrorMessages() instead (typo fix).
*/ */
JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
String getFormatedErrorMessages() const; JSONCPP_STRING getFormatedErrorMessages() const;
/** \brief Returns a user friendly string that list errors in the parsed /** \brief Returns a user friendly string that list errors in the parsed
* document. * document.
* * \return Formatted error message with the list of errors with their location
* \return Formatted error message with the list of errors with their * in
* location in the parsed document. An empty string is returned if no error * the parsed document. An empty string is returned if no error
* occurred during parsing. * occurred
* during parsing.
*/ */
String getFormattedErrorMessages() const; JSONCPP_STRING getFormattedErrorMessages() const;
/** \brief Returns a vector of structured errors encountered while parsing. /** \brief Returns a vector of structured erros encounted while parsing.
*
* \return A (possibly empty) vector of StructuredError objects. Currently * \return A (possibly empty) vector of StructuredError objects. Currently
* only one error can be returned, but the caller should tolerate multiple * only one error can be returned, but the caller should tolerate
* errors. This can occur if the parser recovers from a non-fatal parse * multiple
* error and then encounters additional errors. * errors. This can occur if the parser recovers from a non-fatal
* parse error and then encounters additional errors.
*/ */
std::vector<StructuredError> getStructuredErrors() const; std::vector<StructuredError> getStructuredErrors() const;
/** \brief Add a semantic error message. /** \brief Add a semantic error message.
*
* \param value JSON Value location associated with the error * \param value JSON Value location associated with the error
* \param message The error message. * \param message The error message.
* \return \c true if the error was successfully added, \c false if the Value * \return \c true if the error was successfully added, \c false if the
* offset exceeds the document size. * Value offset exceeds the document size.
*/ */
bool pushError(const Value& value, const String& message); bool pushError(const Value& value, const JSONCPP_STRING& message);
/** \brief Add a semantic error message with extra context. /** \brief Add a semantic error message with extra context.
*
* \param value JSON Value location associated with the error * \param value JSON Value location associated with the error
* \param message The error message. * \param message The error message.
* \param extra Additional JSON Value location to contextualize the error * \param extra Additional JSON Value location to contextualize the error
* \return \c true if the error was successfully added, \c false if either * \return \c true if the error was successfully added, \c false if either
* Value offset exceeds the document size. * Value offset exceeds the document size.
*/ */
bool pushError(const Value& value, const String& message, const Value& extra); bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra);
/** \brief Return whether there are any errors. /** \brief Return whether there are any errors.
* * \return \c true if there are no errors to report \c false if
* \return \c true if there are no errors to report \c false if errors have * errors have occurred.
* occurred.
*/ */
bool good() const; bool good() const;
@ -183,16 +183,15 @@ private:
class ErrorInfo { class ErrorInfo {
public: public:
Token token_; Token token_;
String message_; JSONCPP_STRING message_;
Location extra_; Location extra_;
}; };
using Errors = std::deque<ErrorInfo>; typedef std::deque<ErrorInfo> Errors;
bool readToken(Token& token); bool readToken(Token& token);
bool readTokenSkippingComments(Token& token);
void skipSpaces(); void skipSpaces();
bool match(const Char* pattern, int patternLength); bool match(Location pattern, int patternLength);
bool readComment(); bool readComment();
bool readCStyleComment(); bool readCStyleComment();
bool readCppStyleComment(); bool readCppStyleComment();
@ -204,165 +203,139 @@ private:
bool decodeNumber(Token& token); bool decodeNumber(Token& token);
bool decodeNumber(Token& token, Value& decoded); bool decodeNumber(Token& token, Value& decoded);
bool decodeString(Token& token); bool decodeString(Token& token);
bool decodeString(Token& token, String& decoded); bool decodeString(Token& token, JSONCPP_STRING& decoded);
bool decodeDouble(Token& token); bool decodeDouble(Token& token);
bool decodeDouble(Token& token, Value& decoded); bool decodeDouble(Token& token, Value& decoded);
bool decodeUnicodeCodePoint(Token& token, Location& current, Location end, bool decodeUnicodeCodePoint(Token& token,
Location& current,
Location end,
unsigned int& unicode); unsigned int& unicode);
bool decodeUnicodeEscapeSequence(Token& token, Location& current, bool decodeUnicodeEscapeSequence(Token& token,
Location end, unsigned int& unicode); Location& current,
bool addError(const String& message, Token& token, Location extra = nullptr); Location end,
unsigned int& unicode);
bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
bool recoverFromError(TokenType skipUntilToken); bool recoverFromError(TokenType skipUntilToken);
bool addErrorAndRecover(const String& message, Token& token, bool addErrorAndRecover(const JSONCPP_STRING& message,
Token& token,
TokenType skipUntilToken); TokenType skipUntilToken);
void skipUntilSpace(); void skipUntilSpace();
Value& currentValue(); Value& currentValue();
Char getNextChar(); Char getNextChar();
void getLocationLineAndColumn(Location location, int& line, void
int& column) const; getLocationLineAndColumn(Location location, int& line, int& column) const;
String getLocationLineAndColumn(Location location) const; JSONCPP_STRING getLocationLineAndColumn(Location location) const;
void addComment(Location begin, Location end, CommentPlacement placement); void addComment(Location begin, Location end, CommentPlacement placement);
void skipCommentTokens(Token& token);
static bool containsNewLine(Location begin, Location end); typedef std::stack<Value*> Nodes;
static String normalizeEOL(Location begin, Location end);
using Nodes = std::stack<Value*>;
Nodes nodes_; Nodes nodes_;
Errors errors_; Errors errors_;
String document_; JSONCPP_STRING document_;
Location begin_{}; Location begin_;
Location end_{}; Location end_;
Location current_{}; Location current_;
Location lastValueEnd_{}; Location lastValueEnd_;
Value* lastValue_{}; Value* lastValue_;
String commentsBefore_; JSONCPP_STRING commentsBefore_;
Features features_; Features features_;
bool collectComments_{}; bool collectComments_;
}; // Reader }; // Reader
/** Interface for reading JSON from a char array. /** Interface for reading JSON from a char array.
*/ */
class JSON_API CharReader { class JSON_API CharReader {
public: public:
struct JSON_API StructuredError { virtual ~CharReader() {}
ptrdiff_t offset_start;
ptrdiff_t offset_limit;
String message;
};
virtual ~CharReader() = default;
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
* document. The document must be a UTF-8 encoded string containing the document.
* document to read. * The document must be a UTF-8 encoded string containing the document to read.
* *
* \param beginDoc Pointer on the beginning of the UTF-8 encoded string * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
* of the document to read. document to read.
* \param endDoc Pointer on the end of the UTF-8 encoded string of the * \param endDoc Pointer on the end of the UTF-8 encoded string of the
* document to read. Must be >= beginDoc. document to read.
* \param[out] root Contains the root value of the document if it was * Must be >= beginDoc.
* \param root [out] Contains the root value of the document if it was
* successfully parsed. * successfully parsed.
* \param[out] errs Formatted error messages (if not NULL) a user * \param errs [out] Formatted error messages (if not NULL)
* friendly string that lists errors in the parsed * a user friendly string that lists errors in the parsed
* document. * document.
* \return \c true if the document was successfully parsed, \c false if an * \return \c true if the document was successfully parsed, \c false if an
* error occurred. error occurred.
*/ */
virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, virtual bool parse(
String* errs); char const* beginDoc, char const* endDoc,
Value* root, JSONCPP_STRING* errs) = 0;
/** \brief Returns a vector of structured errors encountered while parsing.
* Each parse call resets the stored list of errors.
*/
std::vector<StructuredError> getStructuredErrors() const;
class JSON_API Factory { class JSON_API Factory {
public: public:
virtual ~Factory() = default; virtual ~Factory() {}
/** \brief Allocate a CharReader via operator new(). /** \brief Allocate a CharReader via operator new().
* \throw std::exception if something goes wrong (e.g. invalid settings) * \throw std::exception if something goes wrong (e.g. invalid settings)
*/ */
virtual CharReader* newCharReader() const = 0; virtual CharReader* newCharReader() const = 0;
}; // Factory }; // Factory
protected:
class Impl {
public:
virtual ~Impl() = default;
virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
String* errs) = 0;
virtual std::vector<StructuredError> getStructuredErrors() const = 0;
};
explicit CharReader(std::unique_ptr<Impl> impl) : _impl(std::move(impl)) {}
private:
std::unique_ptr<Impl> _impl;
}; // CharReader }; // CharReader
/** \brief Build a CharReader implementation. /** \brief Build a CharReader implementation.
*
* Usage: Usage:
* \code \code
* using namespace Json; using namespace Json;
* CharReaderBuilder builder; CharReaderBuilder builder;
* builder["collectComments"] = false; builder["collectComments"] = false;
* Value value; Value value;
* String errs; JSONCPP_STRING errs;
* bool ok = parseFromStream(builder, std::cin, &value, &errs); bool ok = parseFromStream(builder, std::cin, &value, &errs);
* \endcode \endcode
*/ */
class JSON_API CharReaderBuilder : public CharReader::Factory { class JSON_API CharReaderBuilder : public CharReader::Factory {
public: public:
// Note: We use a Json::Value so that we can add data-members to this class // Note: We use a Json::Value so that we can add data-members to this class
// without a major version bump. // without a major version bump.
/** Configuration of this builder. /** Configuration of this builder.
* These are case-sensitive. These are case-sensitive.
* Available settings (case-sensitive): Available settings (case-sensitive):
* - `"collectComments": false or true` - `"collectComments": false or true`
* - true to collect comment and allow writing them back during - true to collect comment and allow writing them
* serialization, false to discard comments. This parameter is ignored back during serialization, false to discard comments.
* if allowComments is false. This parameter is ignored if allowComments is false.
* - `"allowComments": false or true` - `"allowComments": false or true`
* - true if comments are allowed. - true if comments are allowed.
* - `"allowTrailingCommas": false or true` - `"strictRoot": false or true`
* - true if trailing commas in objects and arrays are allowed. - true if root must be either an array or an object value
* - `"strictRoot": false or true` - `"allowDroppedNullPlaceholders": false or true`
* - true if root must be either an array or an object value - true if dropped null placeholders are allowed. (See StreamWriterBuilder.)
* - `"allowDroppedNullPlaceholders": false or true` - `"allowNumericKeys": false or true`
* - true if dropped null placeholders are allowed. (See - true if numeric object keys are allowed.
* StreamWriterBuilder.) - `"allowSingleQuotes": false or true`
* - `"allowNumericKeys": false or true` - true if '' are allowed for strings (both keys and values)
* - true if numeric object keys are allowed. - `"stackLimit": integer`
* - `"allowSingleQuotes": false or true` - Exceeding stackLimit (recursive depth of `readValue()`) will
* - true if '' are allowed for strings (both keys and values) cause an exception.
* - `"stackLimit": integer` - This is a security issue (seg-faults caused by deeply nested JSON),
* - Exceeding stackLimit (recursive depth of `readValue()`) will cause an so the default is low.
* exception. - `"failIfExtra": false or true`
* - This is a security issue (seg-faults caused by deeply nested JSON), so - If true, `parse()` returns false when extra non-whitespace trails
* the default is low. the JSON value in the input string.
* - `"failIfExtra": false or true` - `"rejectDupKeys": false or true`
* - If true, `parse()` returns false when extra non-whitespace trails the - If true, `parse()` returns false when a key is duplicated within an object.
* JSON value in the input string. - `"allowSpecialFloats": false or true`
* - `"rejectDupKeys": false or true` - If true, special float values (NaNs and infinities) are allowed
* - If true, `parse()` returns false when a key is duplicated within an and their values are lossfree restorable.
* object.
* - `"allowSpecialFloats": false or true` You can examine 'settings_` yourself
* - If true, special float values (NaNs and infinities) are allowed and to see the defaults. You can also write and read them just like any
* their values are lossfree restorable. JSON Value.
* - `"skipBom": false or true` \sa setDefaults()
* - If true, if the input starts with the Unicode byte order mark (BOM),
* it is skipped.
*
* You can examine 'settings_` yourself to see the defaults. You can also
* write and read them just like any JSON Value.
* \sa setDefaults()
*/ */
Json::Value settings_; Json::Value settings_;
CharReaderBuilder(); CharReaderBuilder();
~CharReaderBuilder() override; ~CharReaderBuilder() JSONCPP_OVERRIDE;
CharReader* newCharReader() const override; CharReader* newCharReader() const JSONCPP_OVERRIDE;
/** \return true if 'settings' are legal and consistent; /** \return true if 'settings' are legal and consistent;
* otherwise, indicate bad settings via 'invalid'. * otherwise, indicate bad settings via 'invalid'.
@ -371,7 +344,7 @@ public:
/** A simple way to update a specific setting. /** A simple way to update a specific setting.
*/ */
Value& operator[](const String& key); Value& operator[](JSONCPP_STRING key);
/** Called by ctor, but you can use this to reset settings_. /** Called by ctor, but you can use this to reset settings_.
* \pre 'settings' != NULL (but Json::null is fine) * \pre 'settings' != NULL (but Json::null is fine)
@ -385,53 +358,47 @@ public:
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
*/ */
static void strictMode(Json::Value* settings); static void strictMode(Json::Value* settings);
/** ECMA-404 mode.
* \pre 'settings' != NULL (but Json::null is fine)
* \remark Defaults:
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderECMA404Mode
*/
static void ecma404Mode(Json::Value* settings);
}; };
/** Consume entire stream and use its begin/end. /** Consume entire stream and use its begin/end.
* Someday we might have a real StreamReader, but for now this * Someday we might have a real StreamReader, but for now this
* is convenient. * is convenient.
*/ */
bool JSON_API parseFromStream(CharReader::Factory const&, IStream&, Value* root, bool JSON_API parseFromStream(
String* errs); CharReader::Factory const&,
JSONCPP_ISTREAM&,
Value* root, std::string* errs);
/** \brief Read from 'sin' into 'root'. /** \brief Read from 'sin' into 'root'.
*
* Always keep comments from the input JSON. Always keep comments from the input JSON.
*
* This can be used to read a file into a particular sub-object. This can be used to read a file into a particular sub-object.
* For example: For example:
* \code \code
* Json::Value root; Json::Value root;
* cin >> root["dir"]["file"]; cin >> root["dir"]["file"];
* cout << root; cout << root;
* \endcode \endcode
* Result: Result:
* \verbatim \verbatim
* { {
* "dir": { "dir": {
* "file": { "file": {
* // The input stream JSON would be nested here. // The input stream JSON would be nested here.
* } }
* } }
* } }
* \endverbatim \endverbatim
* \throw std::exception on parse error. \throw std::exception on parse error.
* \see Json::operator<<() \see Json::operator<<()
*/ */
JSON_API IStream& operator>>(IStream&, Value&); JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
} // namespace Json } // namespace Json
#pragma pack(pop)
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(pop) #pragma warning(pop)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#endif // JSON_READER_H_INCLUDED #endif // CPPTL_JSON_READER_H_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +1,19 @@
// DO NOT EDIT. This file (and "version") is generated by CMake.
// Run CMake configure step to update it.
#ifndef JSON_VERSION_H_INCLUDED #ifndef JSON_VERSION_H_INCLUDED
#define JSON_VERSION_H_INCLUDED # define JSON_VERSION_H_INCLUDED
// Note: version must be updated in four places when doing a release. This # define JSONCPP_VERSION_STRING "1.7.7"
// annoying process ensures that amalgamate, CMake, and meson all report the # define JSONCPP_VERSION_MAJOR 1
// correct version. # define JSONCPP_VERSION_MINOR 7
// 1. /meson.build # define JSONCPP_VERSION_PATCH 7
// 2. /include/json/version.h # define JSONCPP_VERSION_QUALIFIER
// 3. /CMakeLists.txt # define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
// 4. /MODULE.bazel
// IMPORTANT: also update the SOVERSION!!
#define JSONCPP_VERSION_STRING "1.9.7" #ifdef JSONCPP_USING_SECURE_MEMORY
#define JSONCPP_VERSION_MAJOR 1 #undef JSONCPP_USING_SECURE_MEMORY
#define JSONCPP_VERSION_MINOR 9
#define JSONCPP_VERSION_PATCH 7
#define JSONCPP_VERSION_QUALIFIER
#define JSONCPP_VERSION_HEXA \
((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \
(JSONCPP_VERSION_PATCH << 8))
#if !defined(JSONCPP_USE_SECURE_MEMORY)
#define JSONCPP_USE_SECURE_MEMORY 0
#endif #endif
#define JSONCPP_USING_SECURE_MEMORY 0
// If non-zero, the library zeroes any memory that it has allocated before // If non-zero, the library zeroes any memory that it has allocated before
// it frees its memory. // it frees its memory.

View File

@ -1,4 +1,4 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@ -9,50 +9,47 @@
#if !defined(JSON_IS_AMALGAMATION) #if !defined(JSON_IS_AMALGAMATION)
#include "value.h" #include "value.h"
#endif // if !defined(JSON_IS_AMALGAMATION) #endif // if !defined(JSON_IS_AMALGAMATION)
#include <ostream>
#include <string>
#include <vector> #include <vector>
#include <string>
#include <ostream>
// Disable warning C4251: <data member>: <type> needs to have dll-interface to // Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by... // be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) && defined(_MSC_VER) #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4251) #pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma pack(push)
#pragma pack()
namespace Json { namespace Json {
class Value; class Value;
/** /**
*
* Usage: Usage:
* \code \code
* using namespace Json; using namespace Json;
* void writeToStdout(StreamWriter::Factory const& factory, Value const& value) void writeToStdout(StreamWriter::Factory const& factory, Value const& value) {
* { std::unique_ptr<StreamWriter> const writer( factory.newStreamWriter()); std::unique_ptr<StreamWriter> const writer(
* writer->write(value, &std::cout); factory.newStreamWriter());
* std::cout << std::endl; // add lf and flush writer->write(value, &std::cout);
* } std::cout << std::endl; // add lf and flush
* \endcode }
*/ \endcode
*/
class JSON_API StreamWriter { class JSON_API StreamWriter {
protected: protected:
OStream* sout_; // not owned; will not delete JSONCPP_OSTREAM* sout_; // not owned; will not delete
public: public:
StreamWriter(); StreamWriter();
virtual ~StreamWriter(); virtual ~StreamWriter();
/** Write Value into document as configured in sub-class. /** Write Value into document as configured in sub-class.
* Do not take ownership of sout, but maintain a reference during function. Do not take ownership of sout, but maintain a reference during function.
* \pre sout != NULL \pre sout != NULL
* \return zero on success (For now, we always return zero, so check the \return zero on success (For now, we always return zero, so check the stream instead.)
* stream instead.) \throw std::exception possibly, depending on \throw std::exception possibly, depending on configuration
* configuration
*/ */
virtual int write(Value const& root, OStream* sout) = 0; virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0;
/** \brief A simple abstract factory. /** \brief A simple abstract factory.
*/ */
@ -69,65 +66,58 @@ public:
/** \brief Write into stringstream, then return string, for convenience. /** \brief Write into stringstream, then return string, for convenience.
* A StreamWriter will be created from the factory, used, and then deleted. * A StreamWriter will be created from the factory, used, and then deleted.
*/ */
String JSON_API writeString(StreamWriter::Factory const& factory, JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root);
Value const& root);
/** \brief Build a StreamWriter implementation. /** \brief Build a StreamWriter implementation.
* Usage: Usage:
* \code \code
* using namespace Json; using namespace Json;
* Value value = ...; Value value = ...;
* StreamWriterBuilder builder; StreamWriterBuilder builder;
* builder["commentStyle"] = "None"; builder["commentStyle"] = "None";
* builder["indentation"] = " "; // or whatever you like builder["indentation"] = " "; // or whatever you like
* std::unique_ptr<Json::StreamWriter> writer( std::unique_ptr<Json::StreamWriter> writer(
* builder.newStreamWriter()); builder.newStreamWriter());
* writer->write(value, &std::cout); writer->write(value, &std::cout);
* std::cout << std::endl; // add lf and flush std::cout << std::endl; // add lf and flush
* \endcode \endcode
*/ */
class JSON_API StreamWriterBuilder : public StreamWriter::Factory { class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
public: public:
// Note: We use a Json::Value so that we can add data-members to this class // Note: We use a Json::Value so that we can add data-members to this class
// without a major version bump. // without a major version bump.
/** Configuration of this builder. /** Configuration of this builder.
* Available settings (case-sensitive): Available settings (case-sensitive):
* - "commentStyle": "None" or "All" - "commentStyle": "None" or "All"
* - "indentation": "<anything>". - "indentation": "<anything>"
* - Setting this to an empty string also omits newline characters. - "enableYAMLCompatibility": false or true
* - "enableYAMLCompatibility": false or true - slightly change the whitespace around colons
* - slightly change the whitespace around colons - "dropNullPlaceholders": false or true
* - "dropNullPlaceholders": false or true - Drop the "null" string from the writer's output for nullValues.
* - Drop the "null" string from the writer's output for nullValues. Strictly speaking, this is not valid JSON. But when the output is being
* 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
* fed to a browser's JavaScript, it makes for smaller output and the browser can handle the output just fine.
* browser can handle the output just fine. - "useSpecialFloats": false or true
* - "useSpecialFloats": false or true - If true, outputs non-finite floating point values in the following way:
* - If true, outputs non-finite floating point values in the following way: NaN values as "NaN", positive infinity as "Infinity", and negative infinity
* NaN values as "NaN", positive infinity as "Infinity", and negative as "-Infinity".
* infinity as "-Infinity".
* - "precision": int
* - Number of precision digits for formatting of real values.
* - "precisionType": "significant"(default) or "decimal"
* - Type of precision for formatting of real values.
* - "emitUTF8": false or true
* - If true, outputs raw UTF8 strings instead of escaping them.
* You can examine 'settings_` yourself You can examine 'settings_` yourself
* to see the defaults. You can also write and read them just like any to see the defaults. You can also write and read them just like any
* JSON Value. JSON Value.
* \sa setDefaults() \sa setDefaults()
*/ */
Json::Value settings_; Json::Value settings_;
StreamWriterBuilder(); StreamWriterBuilder();
~StreamWriterBuilder() override; ~StreamWriterBuilder() JSONCPP_OVERRIDE;
/** /**
* \throw std::exception if something goes wrong (e.g. invalid settings) * \throw std::exception if something goes wrong (e.g. invalid settings)
*/ */
StreamWriter* newStreamWriter() const override; StreamWriter* newStreamWriter() const JSONCPP_OVERRIDE;
/** \return true if 'settings' are legal and consistent; /** \return true if 'settings' are legal and consistent;
* otherwise, indicate bad settings via 'invalid'. * otherwise, indicate bad settings via 'invalid'.
@ -135,7 +125,7 @@ public:
bool validate(Json::Value* invalid) const; bool validate(Json::Value* invalid) const;
/** A simple way to update a specific setting. /** A simple way to update a specific setting.
*/ */
Value& operator[](const String& key); Value& operator[](JSONCPP_STRING key);
/** Called by ctor, but you can use this to reset settings_. /** Called by ctor, but you can use this to reset settings_.
* \pre 'settings' != NULL (but Json::null is fine) * \pre 'settings' != NULL (but Json::null is fine)
@ -152,7 +142,7 @@ class JSON_API Writer {
public: public:
virtual ~Writer(); virtual ~Writer();
virtual String write(const Value& root) = 0; virtual JSONCPP_STRING write(const Value& root) = 0;
}; };
/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format /** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
@ -160,24 +150,21 @@ public:
* *
* The JSON document is written in a single line. It is not intended for 'human' * The JSON document is written in a single line. It is not intended for 'human'
*consumption, *consumption,
* but may be useful to support feature such as RPC where bandwidth is limited. * but may be usefull to support feature such as RPC where bandwith is limited.
* \sa Reader, Value * \sa Reader, Value
* \deprecated Use StreamWriterBuilder. * \deprecated Use StreamWriterBuilder.
*/ */
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4996) // Deriving from deprecated class
#endif
class JSON_API FastWriter : public Writer { class JSON_API FastWriter : public Writer {
public: public:
FastWriter(); FastWriter();
~FastWriter() override = default; ~FastWriter() JSONCPP_OVERRIDE {}
void enableYAMLCompatibility(); void enableYAMLCompatibility();
/** \brief Drop the "null" string from the writer's output for nullValues. /** \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 * 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 * fed to a browser's Javascript, it makes for smaller output and the
* browser can handle the output just fine. * browser can handle the output just fine.
*/ */
void dropNullPlaceholders(); void dropNullPlaceholders();
@ -185,19 +172,16 @@ public:
void omitEndingLineFeed(); void omitEndingLineFeed();
public: // overridden from Writer public: // overridden from Writer
String write(const Value& root) override; JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE;
private: private:
void writeValue(const Value& value); void writeValue(const Value& value);
String document_; JSONCPP_STRING document_;
bool yamlCompatibilityEnabled_{false}; bool yamlCompatiblityEnabled_;
bool dropNullPlaceholders_{false}; bool dropNullPlaceholders_;
bool omitEndingLineFeed_{false}; bool omitEndingLineFeed_;
}; };
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a /** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
*human friendly way. *human friendly way.
@ -217,54 +201,47 @@ private:
* - otherwise, it the values do not fit on one line, or the array contains * - otherwise, it the values do not fit on one line, or the array contains
* object or non empty array, then print one value per line. * object or non empty array, then print one value per line.
* *
* If the Value have comments then they are outputted according to their * If the Value have comments then they are outputed according to their
*#CommentPlacement. *#CommentPlacement.
* *
* \sa Reader, Value, Value::setComment() * \sa Reader, Value, Value::setComment()
* \deprecated Use StreamWriterBuilder. * \deprecated Use StreamWriterBuilder.
*/ */
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4996) // Deriving from deprecated class
#endif
class JSON_API StyledWriter : public Writer { class JSON_API StyledWriter : public Writer {
public: public:
StyledWriter(); StyledWriter();
~StyledWriter() override = default; ~StyledWriter() JSONCPP_OVERRIDE {}
public: // overridden from Writer public: // overridden from Writer
/** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format. /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
* \param root Value to serialize. * \param root Value to serialize.
* \return String containing the JSON document that represents the root value. * \return String containing the JSON document that represents the root value.
*/ */
String write(const Value& root) override; JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE;
private: private:
void writeValue(const Value& value); void writeValue(const Value& value);
void writeArrayValue(const Value& value); void writeArrayValue(const Value& value);
bool isMultilineArray(const Value& value); bool isMultineArray(const Value& value);
void pushValue(const String& value); void pushValue(const JSONCPP_STRING& value);
void writeIndent(); void writeIndent();
void writeWithIndent(const String& value); void writeWithIndent(const JSONCPP_STRING& value);
void indent(); void indent();
void unindent(); void unindent();
void writeCommentBeforeValue(const Value& root); void writeCommentBeforeValue(const Value& root);
void writeCommentAfterValueOnSameLine(const Value& root); void writeCommentAfterValueOnSameLine(const Value& root);
static bool hasCommentForValue(const Value& value); bool hasCommentForValue(const Value& value);
static String normalizeEOL(const String& text); static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
using ChildValues = std::vector<String>; typedef std::vector<JSONCPP_STRING> ChildValues;
ChildValues childValues_; ChildValues childValues_;
String document_; JSONCPP_STRING document_;
String indentString_; JSONCPP_STRING indentString_;
unsigned int rightMargin_{74}; unsigned int rightMargin_;
unsigned int indentSize_{3}; unsigned int indentSize_;
bool addChildValues_{false}; bool addChildValues_;
}; };
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a /** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
human friendly way, human friendly way,
@ -285,23 +262,17 @@ private:
* - otherwise, it the values do not fit on one line, or the array contains * - otherwise, it the values do not fit on one line, or the array contains
* object or non empty array, then print one value per line. * object or non empty array, then print one value per line.
* *
* If the Value have comments then they are outputted according to their * If the Value have comments then they are outputed according to their
#CommentPlacement. #CommentPlacement.
* *
* \param indentation Each level will be indented by this amount extra.
* \sa Reader, Value, Value::setComment() * \sa Reader, Value, Value::setComment()
* \deprecated Use StreamWriterBuilder. * \deprecated Use StreamWriterBuilder.
*/ */
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4996) // Deriving from deprecated class
#endif
class JSON_API StyledStreamWriter { class JSON_API StyledStreamWriter {
public: public:
/** StyledStreamWriter(JSONCPP_STRING indentation = "\t");
* \param indentation Each level will be indented by this amount extra. ~StyledStreamWriter() {}
*/
StyledStreamWriter(String indentation = "\t");
~StyledStreamWriter() = default;
public: public:
/** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format. /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
@ -310,57 +281,49 @@ public:
* \note There is no point in deriving from Writer, since write() should not * \note There is no point in deriving from Writer, since write() should not
* return a value. * return a value.
*/ */
void write(OStream& out, const Value& root); void write(JSONCPP_OSTREAM& out, const Value& root);
private: private:
void writeValue(const Value& value); void writeValue(const Value& value);
void writeArrayValue(const Value& value); void writeArrayValue(const Value& value);
bool isMultilineArray(const Value& value); bool isMultineArray(const Value& value);
void pushValue(const String& value); void pushValue(const JSONCPP_STRING& value);
void writeIndent(); void writeIndent();
void writeWithIndent(const String& value); void writeWithIndent(const JSONCPP_STRING& value);
void indent(); void indent();
void unindent(); void unindent();
void writeCommentBeforeValue(const Value& root); void writeCommentBeforeValue(const Value& root);
void writeCommentAfterValueOnSameLine(const Value& root); void writeCommentAfterValueOnSameLine(const Value& root);
static bool hasCommentForValue(const Value& value); bool hasCommentForValue(const Value& value);
static String normalizeEOL(const String& text); static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
using ChildValues = std::vector<String>; typedef std::vector<JSONCPP_STRING> ChildValues;
ChildValues childValues_; ChildValues childValues_;
OStream* document_; JSONCPP_OSTREAM* document_;
String indentString_; JSONCPP_STRING indentString_;
unsigned int rightMargin_{74}; unsigned int rightMargin_;
String indentation_; JSONCPP_STRING indentation_;
bool addChildValues_ : 1; bool addChildValues_ : 1;
bool indented_ : 1; bool indented_ : 1;
}; };
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#if defined(JSON_HAS_INT64) #if defined(JSON_HAS_INT64)
String JSON_API valueToString(Int value); JSONCPP_STRING JSON_API valueToString(Int value);
String JSON_API valueToString(UInt value); JSONCPP_STRING JSON_API valueToString(UInt value);
#endif // if defined(JSON_HAS_INT64) #endif // if defined(JSON_HAS_INT64)
String JSON_API valueToString(LargestInt value); JSONCPP_STRING JSON_API valueToString(LargestInt value);
String JSON_API valueToString(LargestUInt value); JSONCPP_STRING JSON_API valueToString(LargestUInt value);
String JSON_API valueToString( JSONCPP_STRING JSON_API valueToString(double value);
double value, unsigned int precision = Value::defaultRealPrecision, JSONCPP_STRING JSON_API valueToString(bool value);
PrecisionType precisionType = PrecisionType::significantDigits); JSONCPP_STRING JSON_API valueToQuotedString(const char* value);
String JSON_API valueToString(bool value);
String JSON_API valueToQuotedString(const char* value);
String JSON_API valueToQuotedString(const char* value, size_t length);
/// \brief Output using the StyledStreamWriter. /// \brief Output using the StyledStreamWriter.
/// \see Json::operator>>() /// \see Json::operator>>()
JSON_API OStream& operator<<(OStream&, const Value& root); JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root);
} // namespace Json } // namespace Json
#pragma pack(pop)
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(pop) #pragma warning(pop)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)

View File

@ -1,9 +0,0 @@
if (NOT TARGET JsonCpp::JsonCpp)
if (TARGET jsoncpp_static)
add_library(JsonCpp::JsonCpp INTERFACE IMPORTED)
set_target_properties(JsonCpp::JsonCpp PROPERTIES INTERFACE_LINK_LIBRARIES "jsoncpp_static")
elseif (TARGET jsoncpp_lib)
add_library(JsonCpp::JsonCpp INTERFACE IMPORTED)
set_target_properties(JsonCpp::JsonCpp PROPERTIES INTERFACE_LINK_LIBRARIES "jsoncpp_lib")
endif ()
endif ()

View File

@ -1,11 +0,0 @@
cmake_policy(PUSH)
cmake_policy(VERSION 3.0...3.26)
@PACKAGE_INIT@
include ( "${CMAKE_CURRENT_LIST_DIR}/jsoncpp-targets.cmake" )
include ( "${CMAKE_CURRENT_LIST_DIR}/jsoncpp-namespaced-targets.cmake" )
check_required_components(JsonCpp)
cmake_policy(POP)

View File

@ -1,6 +0,0 @@
@PACKAGE_INIT@
@MESON_SHARED_TARGET@
@MESON_STATIC_TARGET@
include ( "${CMAKE_CURRENT_LIST_DIR}/jsoncpp-namespaced-targets.cmake" )

View File

@ -0,0 +1,42 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_json", "lib_json.vcxproj", "{1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsontest", "jsontest.vcxproj", "{25AF2DD2-D396-4668-B188-488C33B8E620}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib_json", "test_lib_json.vcxproj", "{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Debug|Win32.ActiveCfg = Debug|Win32
{1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Debug|Win32.Build.0 = Debug|Win32
{1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Debug|x64.ActiveCfg = Debug|x64
{1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Debug|x64.Build.0 = Debug|x64
{1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Release|Win32.ActiveCfg = Release|Win32
{1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Release|Win32.Build.0 = Release|Win32
{1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Release|x64.ActiveCfg = Release|x64
{1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Release|x64.Build.0 = Release|x64
{25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|Win32.ActiveCfg = Debug|Win32
{25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|Win32.Build.0 = Debug|Win32
{25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|x64.ActiveCfg = Debug|Win32
{25AF2DD2-D396-4668-B188-488C33B8E620}.Release|Win32.ActiveCfg = Release|Win32
{25AF2DD2-D396-4668-B188-488C33B8E620}.Release|Win32.Build.0 = Release|Win32
{25AF2DD2-D396-4668-B188-488C33B8E620}.Release|x64.ActiveCfg = Release|Win32
{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|Win32.ActiveCfg = Debug|Win32
{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|Win32.Build.0 = Debug|Win32
{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|x64.ActiveCfg = Debug|Win32
{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|Win32.ActiveCfg = Release|Win32
{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|Win32.Build.0 = Release|Win32
{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{25AF2DD2-D396-4668-B188-488C33B8E620}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../build/vs71/debug/jsontest\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../build/vs71/debug/jsontest\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../build/vs71/release/jsontest\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../build/vs71/release/jsontest\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)jsontest.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)jsontest.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)jsontest.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\jsontestrunner\main.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="lib_json.vcxproj">
<Project>{1e6c2c1c-6453-4129-ae3f-0ee8e6599c89}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{903591b3-ade3-4ce4-b1f9-1e175e62b014}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\jsontestrunner\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\lib_json\json_reader.cpp" />
<ClCompile Include="..\..\src\lib_json\json_value.cpp" />
<ClCompile Include="..\..\src\lib_json\json_writer.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\json\reader.h" />
<ClInclude Include="..\..\include\json\value.h" />
<ClInclude Include="..\..\include\json\writer.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>jsoncpp</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{c110bc57-c46e-476c-97ea-84d8014f431c}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{ed718592-5acf-47b5-8f2b-b8224590da6a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\lib_json\json_reader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lib_json\json_value.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lib_json\json_writer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\json\reader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\json\value.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\json\writer.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}</ProjectGuid>
<RootNamespace>test_lib_json</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../build/vs71/debug/test_lib_json\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../build/vs71/debug/test_lib_json\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../build/vs71/release/test_lib_json\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../build/vs71/release/test_lib_json\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)test_lib_json.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)test_lib_json.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Message>Running all unit tests</Message>
<Command>$(TargetPath)</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)test_lib_json.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Message>Running all unit tests</Message>
<Command>$(TargetPath)</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\test_lib_json\jsontest.cpp" />
<ClCompile Include="..\..\src\test_lib_json\main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\test_lib_json\jsontest.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="lib_json.vcxproj">
<Project>{1e6c2c1c-6453-4129-ae3f-0ee8e6599c89}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\..\src\test_lib_json\jsontest.cpp">
<Filter>Source Filter</Filter>
</ClCompile>
<ClCompile Include="..\..\src\test_lib_json\main.cpp">
<Filter>Source Filter</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="Source Filter">
<UniqueIdentifier>{bf40cbfc-8e98-40b4-b9f3-7e8d579cbae2}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{5fd39074-89e6-4939-aa3f-694fefd296b1}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\test_lib_json\jsontest.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,46 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_json", "lib_json.vcproj", "{B84F7231-16CE-41D8-8C08-7B523FF4225B}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsontest", "jsontest.vcproj", "{25AF2DD2-D396-4668-B188-488C33B8E620}"
ProjectSection(ProjectDependencies) = postProject
{B84F7231-16CE-41D8-8C08-7B523FF4225B} = {B84F7231-16CE-41D8-8C08-7B523FF4225B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib_json", "test_lib_json.vcproj", "{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}"
ProjectSection(ProjectDependencies) = postProject
{B84F7231-16CE-41D8-8C08-7B523FF4225B} = {B84F7231-16CE-41D8-8C08-7B523FF4225B}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
dummy = dummy
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug.ActiveCfg = Debug|Win32
{B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug.Build.0 = Debug|Win32
{B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy.ActiveCfg = dummy|Win32
{B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy.Build.0 = dummy|Win32
{B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release.ActiveCfg = Release|Win32
{B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release.Build.0 = Release|Win32
{25AF2DD2-D396-4668-B188-488C33B8E620}.Debug.ActiveCfg = Debug|Win32
{25AF2DD2-D396-4668-B188-488C33B8E620}.Debug.Build.0 = Debug|Win32
{25AF2DD2-D396-4668-B188-488C33B8E620}.dummy.ActiveCfg = Debug|Win32
{25AF2DD2-D396-4668-B188-488C33B8E620}.dummy.Build.0 = Debug|Win32
{25AF2DD2-D396-4668-B188-488C33B8E620}.Release.ActiveCfg = Release|Win32
{25AF2DD2-D396-4668-B188-488C33B8E620}.Release.Build.0 = Release|Win32
{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug.ActiveCfg = Debug|Win32
{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug.Build.0 = Debug|Win32
{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy.ActiveCfg = Debug|Win32
{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy.Build.0 = Debug|Win32
{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release.ActiveCfg = Release|Win32
{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="jsontest"
ProjectGUID="{25AF2DD2-D396-4668-B188-488C33B8E620}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../build/vs71/debug/jsontest"
IntermediateDirectory="../../build/vs71/debug/jsontest"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/jsontest.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/jsontest.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../build/vs71/release/jsontest"
IntermediateDirectory="../../build/vs71/release/jsontest"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/jsontest.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\..\src\jsontestrunner\main.cpp">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,205 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="lib_json"
ProjectGUID="{B84F7231-16CE-41D8-8C08-7B523FF4225B}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../build/vs71/debug/lib_json"
IntermediateDirectory="../../build/vs71/debug/lib_json"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
StringPooling="TRUE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
EnableFunctionLevelLinking="TRUE"
DisableLanguageExtensions="TRUE"
ForceConformanceInForLoopScope="FALSE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/json_vc71_libmtd.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../build/vs71/release/lib_json"
IntermediateDirectory="../../build/vs71/release/lib_json"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="TRUE">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
EnableIntrinsicFunctions="TRUE"
AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
DisableLanguageExtensions="TRUE"
ForceConformanceInForLoopScope="FALSE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
AssemblerOutput="4"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/json_vc71_libmt.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="dummy|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="TRUE">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
EnableIntrinsicFunctions="TRUE"
AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
DisableLanguageExtensions="TRUE"
ForceConformanceInForLoopScope="FALSE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
AssemblerOutput="4"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
GenerateDebugInformation="TRUE"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\..\include\json\autolink.h">
</File>
<File
RelativePath="..\..\include\json\config.h">
</File>
<File
RelativePath="..\..\include\json\features.h">
</File>
<File
RelativePath="..\..\include\json\forwards.h">
</File>
<File
RelativePath="..\..\include\json\json.h">
</File>
<File
RelativePath="..\..\src\lib_json\json_reader.cpp">
</File>
<File
RelativePath="..\..\src\lib_json\json_value.cpp">
</File>
<File
RelativePath="..\..\src\lib_json\json_valueiterator.inl">
</File>
<File
RelativePath="..\..\src\lib_json\json_writer.cpp">
</File>
<File
RelativePath="..\..\include\json\reader.h">
</File>
<File
RelativePath="..\..\include\json\value.h">
</File>
<File
RelativePath="..\..\include\json\writer.h">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="test_lib_json"
ProjectGUID="{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}"
RootNamespace="test_lib_json"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../build/vs71/debug/test_lib_json"
IntermediateDirectory="../../build/vs71/debug/test_lib_json"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/test_lib_json.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/test_lib_json.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"
Description="Running all unit tests"
CommandLine="$(TargetPath)"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../build/vs71/release/test_lib_json"
IntermediateDirectory="../../build/vs71/release/test_lib_json"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/test_lib_json.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"
Description="Running all unit tests"
CommandLine="$(TargetPath)"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\..\src\test_lib_json\jsontest.cpp">
</File>
<File
RelativePath="..\..\src\test_lib_json\jsontest.h">
</File>
<File
RelativePath="..\..\src\test_lib_json\main.cpp">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

390
makerelease.py Normal file
View File

@ -0,0 +1,390 @@
# 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
Example of invocation (use to test the script):
python makerelease.py --platform=msvc6,msvc71,msvc80,msvc90,mingw -ublep 0.6.0 0.7.0-dev
When testing this script:
python makerelease.py --force --retag --platform=msvc6,msvc71,msvc80,mingw -ublep test-0.6.0 test-0.6.1-dev
Example of invocation when doing a release:
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
import sys
import doxybuild
import subprocess
import xml.etree.ElementTree as ElementTree
import shutil
import urllib2
import tempfile
import os
import time
from devtools import antglob, fixeol, tarball
import amalgamate
SVN_ROOT = 'https://jsoncpp.svn.sourceforge.net/svnroot/jsoncpp/'
SVN_TAG_ROOT = SVN_ROOT + 'tags/jsoncpp'
SCONS_LOCAL_URL = 'http://sourceforge.net/projects/scons/files/scons-local/1.2.0/scons-local-1.2.0.tar.gz/download'
SOURCEFORGE_PROJECT = 'jsoncpp'
def set_version(version):
with open('version','wb') as f:
f.write(version.strip())
def rmdir_if_exist(dir_path):
if os.path.isdir(dir_path):
shutil.rmtree(dir_path)
class SVNError(Exception):
pass
def svn_command(command, *args):
cmd = ['svn', '--non-interactive', command] + list(args)
print('Running:', ' '.join(cmd))
process = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout = process.communicate()[0]
if process.returncode:
error = SVNError('SVN command failed:\n' + stdout)
error.returncode = process.returncode
raise error
return stdout
def check_no_pending_commit():
"""Checks that there is no pending commit in the sandbox."""
stdout = svn_command('status', '--xml')
etree = ElementTree.fromstring(stdout)
msg = []
for entry in etree.getiterator('entry'):
path = entry.get('path')
status = entry.find('wc-status').get('item')
if status != 'unversioned' and path != 'version':
msg.append('File "%s" has pending change (status="%s")' % (path, status))
if msg:
msg.insert(0, 'Pending change to commit found in sandbox. Commit them first!')
return '\n'.join(msg)
def svn_join_url(base_url, suffix):
if not base_url.endswith('/'):
base_url += '/'
if suffix.startswith('/'):
suffix = suffix[1:]
return base_url + suffix
def svn_check_if_tag_exist(tag_url):
"""Checks if a tag exist.
Returns: True if the tag exist, False otherwise.
"""
try:
list_stdout = svn_command('list', tag_url)
except SVNError as e:
if e.returncode != 1 or not str(e).find('tag_url'):
raise e
# otherwise ignore error, meaning tag does not exist
return False
return True
def svn_commit(message):
"""Commit the sandbox, providing the specified comment.
"""
svn_command('ci', '-m', message)
def svn_tag_sandbox(tag_url, message):
"""Makes a tag based on the sandbox revisions.
"""
svn_command('copy', '-m', message, '.', tag_url)
def svn_remove_tag(tag_url, message):
"""Removes an existing tag.
"""
svn_command('delete', '-m', message, tag_url)
def svn_export(tag_url, export_dir):
"""Exports the tag_url revision to export_dir.
Target directory, including its parent is created if it does not exist.
If the directory export_dir exist, it is deleted before export proceed.
"""
rmdir_if_exist(export_dir)
svn_command('export', tag_url, export_dir)
def fix_sources_eol(dist_dir):
"""Set file EOL for tarball distribution.
"""
print('Preparing exported source file EOL for distribution...')
prune_dirs = antglob.prune_dirs + 'scons-local* ./build* ./libs ./dist'
win_sources = antglob.glob(dist_dir,
includes = '**/*.sln **/*.vcproj',
prune_dirs = prune_dirs)
unix_sources = antglob.glob(dist_dir,
includes = '''**/*.h **/*.cpp **/*.inl **/*.txt **/*.dox **/*.py **/*.html **/*.in
sconscript *.json *.expected AUTHORS LICENSE''',
excludes = antglob.default_excludes + 'scons.py sconsign.py scons-*',
prune_dirs = prune_dirs)
for path in win_sources:
fixeol.fix_source_eol(path, is_dry_run = False, verbose = True, eol = '\r\n')
for path in unix_sources:
fixeol.fix_source_eol(path, is_dry_run = False, verbose = True, eol = '\n')
def download(url, target_path):
"""Download file represented by url to target_path.
"""
f = urllib2.urlopen(url)
try:
data = f.read()
finally:
f.close()
fout = open(target_path, 'wb')
try:
fout.write(data)
finally:
fout.close()
def check_compile(distcheck_top_dir, platform):
cmd = [sys.executable, 'scons.py', 'platform=%s' % platform, 'check']
print('Running:', ' '.join(cmd))
log_path = os.path.join(distcheck_top_dir, 'build-%s.log' % platform)
flog = open(log_path, 'wb')
try:
process = subprocess.Popen(cmd,
stdout=flog,
stderr=subprocess.STDOUT,
cwd=distcheck_top_dir)
stdout = process.communicate()[0]
status = (process.returncode == 0)
finally:
flog.close()
return (status, log_path)
def write_tempfile(content, **kwargs):
fd, path = tempfile.mkstemp(**kwargs)
f = os.fdopen(fd, 'wt')
try:
f.write(content)
finally:
f.close()
return path
class SFTPError(Exception):
pass
def run_sftp_batch(userhost, sftp, batch, retry=0):
path = write_tempfile(batch, suffix='.sftp', text=True)
# psftp -agent -C blep,jsoncpp@web.sourceforge.net -batch -b batch.sftp -bc
cmd = [sftp, '-agent', '-C', '-batch', '-b', path, '-bc', userhost]
error = None
for retry_index in range(0, max(1,retry)):
heading = retry_index == 0 and 'Running:' or 'Retrying:'
print(heading, ' '.join(cmd))
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout = process.communicate()[0]
if process.returncode != 0:
error = SFTPError('SFTP batch failed:\n' + stdout)
else:
break
if error:
raise error
return stdout
def sourceforge_web_synchro(sourceforge_project, doc_dir,
user=None, sftp='sftp'):
"""Notes: does not synchronize sub-directory of doc-dir.
"""
userhost = '%s,%s@web.sourceforge.net' % (user, sourceforge_project)
stdout = run_sftp_batch(userhost, sftp, """
cd htdocs
dir
exit
""")
existing_paths = set()
collect = 0
for line in stdout.split('\n'):
line = line.strip()
if not collect and line.endswith('> dir'):
collect = True
elif collect and line.endswith('> exit'):
break
elif collect == 1:
collect = 2
elif collect == 2:
path = line.strip().split()[-1:]
if path and path[0] not in ('.', '..'):
existing_paths.add(path[0])
upload_paths = set([os.path.basename(p) for p in antglob.glob(doc_dir)])
paths_to_remove = existing_paths - upload_paths
if paths_to_remove:
print('Removing the following file from web:')
print('\n'.join(paths_to_remove))
stdout = run_sftp_batch(userhost, sftp, """cd htdocs
rm %s
exit""" % ' '.join(paths_to_remove))
print('Uploading %d files:' % len(upload_paths))
batch_size = 10
upload_paths = list(upload_paths)
start_time = time.time()
for index in range(0,len(upload_paths),batch_size):
paths = upload_paths[index:index+batch_size]
file_per_sec = (time.time() - start_time) / (index+1)
remaining_files = len(upload_paths) - index
remaining_sec = file_per_sec * remaining_files
print('%d/%d, ETA=%.1fs' % (index+1, len(upload_paths), remaining_sec))
run_sftp_batch(userhost, sftp, """cd htdocs
lcd %s
mput %s
exit""" % (doc_dir, ' '.join(paths)), retry=3)
def sourceforge_release_tarball(sourceforge_project, paths, user=None, sftp='sftp'):
userhost = '%s,%s@frs.sourceforge.net' % (user, sourceforge_project)
run_sftp_batch(userhost, sftp, """
mput %s
exit
""" % (' '.join(paths),))
def main():
usage = """%prog release_version next_dev_version
Update 'version' file to release_version and commit.
Generates the document tarball.
Tags the sandbox revision with release_version.
Update 'version' file to next_dev_version and commit.
Performs an svn export of tag release version, and build a source tarball.
Must be started in the project top directory.
Warning: --force should only be used when developping/testing the release script.
"""
from optparse import OptionParser
parser = OptionParser(usage=usage)
parser.allow_interspersed_args = False
parser.add_option('--dot', dest="dot_path", action='store', default=doxybuild.find_program('dot'),
help="""Path to GraphViz dot tool. Must be full qualified path. [Default: %default]""")
parser.add_option('--doxygen', dest="doxygen_path", action='store', default=doxybuild.find_program('doxygen'),
help="""Path to Doxygen tool. [Default: %default]""")
parser.add_option('--force', dest="ignore_pending_commit", action='store_true', default=False,
help="""Ignore pending commit. [Default: %default]""")
parser.add_option('--retag', dest="retag_release", action='store_true', default=False,
help="""Overwrite release existing tag if it exist. [Default: %default]""")
parser.add_option('-p', '--platforms', dest="platforms", action='store', default='',
help="""Comma separated list of platform passed to scons for build check.""")
parser.add_option('--no-test', dest="no_test", action='store_true', default=False,
help="""Skips build check.""")
parser.add_option('--no-web', dest="no_web", action='store_true', default=False,
help="""Do not update web site.""")
parser.add_option('-u', '--upload-user', dest="user", action='store',
help="""Sourceforge user for SFTP documentation upload.""")
parser.add_option('--sftp', dest='sftp', action='store', default=doxybuild.find_program('psftp', 'sftp'),
help="""Path of the SFTP compatible binary used to upload the documentation.""")
parser.enable_interspersed_args()
options, args = parser.parse_args()
if len(args) != 2:
parser.error('release_version missing on command-line.')
release_version = args[0]
next_version = args[1]
if not options.platforms and not options.no_test:
parser.error('You must specify either --platform or --no-test option.')
if options.ignore_pending_commit:
msg = ''
else:
msg = check_no_pending_commit()
if not msg:
print('Setting version to', release_version)
set_version(release_version)
svn_commit('Release ' + release_version)
tag_url = svn_join_url(SVN_TAG_ROOT, release_version)
if svn_check_if_tag_exist(tag_url):
if options.retag_release:
svn_remove_tag(tag_url, 'Overwriting previous tag')
else:
print('Aborting, tag %s already exist. Use --retag to overwrite it!' % tag_url)
sys.exit(1)
svn_tag_sandbox(tag_url, 'Release ' + release_version)
print('Generated doxygen document...')
## doc_dirname = r'jsoncpp-api-html-0.5.0'
## doc_tarball_path = r'e:\prg\vc\Lib\jsoncpp-trunk\dist\jsoncpp-api-html-0.5.0.tar.gz'
doc_tarball_path, doc_dirname = doxybuild.build_doc(options, make_release=True)
doc_distcheck_dir = 'dist/doccheck'
tarball.decompress(doc_tarball_path, doc_distcheck_dir)
doc_distcheck_top_dir = os.path.join(doc_distcheck_dir, doc_dirname)
export_dir = 'dist/export'
svn_export(tag_url, export_dir)
fix_sources_eol(export_dir)
source_dir = 'jsoncpp-src-' + release_version
source_tarball_path = 'dist/%s.tar.gz' % source_dir
print('Generating source tarball to', source_tarball_path)
tarball.make_tarball(source_tarball_path, [export_dir], export_dir, prefix_dir=source_dir)
amalgamation_tarball_path = 'dist/%s-amalgamation.tar.gz' % source_dir
print('Generating amalgamation source tarball to', amalgamation_tarball_path)
amalgamation_dir = 'dist/amalgamation'
amalgamate.amalgamate_source(export_dir, '%s/jsoncpp.cpp' % amalgamation_dir, 'json/json.h')
amalgamation_source_dir = 'jsoncpp-src-amalgamation' + release_version
tarball.make_tarball(amalgamation_tarball_path, [amalgamation_dir],
amalgamation_dir, prefix_dir=amalgamation_source_dir)
# Decompress source tarball, download and install scons-local
distcheck_dir = 'dist/distcheck'
distcheck_top_dir = distcheck_dir + '/' + source_dir
print('Decompressing source tarball to', distcheck_dir)
rmdir_if_exist(distcheck_dir)
tarball.decompress(source_tarball_path, distcheck_dir)
scons_local_path = 'dist/scons-local.tar.gz'
print('Downloading scons-local to', scons_local_path)
download(SCONS_LOCAL_URL, scons_local_path)
print('Decompressing scons-local to', distcheck_top_dir)
tarball.decompress(scons_local_path, distcheck_top_dir)
# Run compilation
print('Compiling decompressed tarball')
all_build_status = True
for platform in options.platforms.split(','):
print('Testing platform:', platform)
build_status, log_path = check_compile(distcheck_top_dir, platform)
print('see build log:', log_path)
print(build_status and '=> ok' or '=> FAILED')
all_build_status = all_build_status and build_status
if not build_status:
print('Testing failed on at least one platform, aborting...')
svn_remove_tag(tag_url, 'Removing tag due to failed testing')
sys.exit(1)
if options.user:
if not options.no_web:
print('Uploading documentation using user', options.user)
sourceforge_web_synchro(SOURCEFORGE_PROJECT, doc_distcheck_top_dir, user=options.user, sftp=options.sftp)
print('Completed documentation upload')
print('Uploading source and documentation tarballs for release using user', options.user)
sourceforge_release_tarball(SOURCEFORGE_PROJECT,
[source_tarball_path, doc_tarball_path],
user=options.user, sftp=options.sftp)
print('Source and doc release tarballs uploaded')
else:
print('No upload user specified. Web site and download tarbal were not uploaded.')
print('Tarball can be found at:', doc_tarball_path)
# Set next version number and commit
set_version(next_version)
svn_commit('Released ' + release_version)
else:
sys.stderr.write(msg + '\n')
if __name__ == '__main__':
main()

View File

@ -1,157 +0,0 @@
project(
'jsoncpp',
'cpp',
# Note: version must be updated in four places when doing a release. This
# annoying process ensures that amalgamate, CMake, and meson all report the
# correct version.
# 1. /meson.build
# 2. /include/json/version.h
# 3. /CMakeLists.txt
# 4. /MODULE.bazel
# IMPORTANT: also update the SOVERSION!!
version : '1.9.7',
default_options : [
'buildtype=release',
'cpp_std=c++11',
'warning_level=1'],
license : 'Public Domain',
meson_version : '>= 0.54.0')
jsoncpp_headers = files([
'include/json/allocator.h',
'include/json/assertions.h',
'include/json/config.h',
'include/json/json_features.h',
'include/json/forwards.h',
'include/json/json.h',
'include/json/reader.h',
'include/json/value.h',
'include/json/version.h',
'include/json/writer.h',
])
jsoncpp_include_directories = include_directories('include')
install_headers(
jsoncpp_headers,
subdir : 'json')
if get_option('default_library') == 'shared' and meson.get_compiler('cpp').get_id() == 'msvc'
dll_export_flag = '-DJSON_DLL_BUILD'
dll_import_flag = '-DJSON_DLL'
else
dll_export_flag = []
dll_import_flag = []
endif
jsoncpp_lib = library(
'jsoncpp', files([
'src/lib_json/json_reader.cpp',
'src/lib_json/json_value.cpp',
'src/lib_json/json_writer.cpp',
]),
soversion : 27,
install : true,
include_directories : jsoncpp_include_directories,
cpp_args: dll_export_flag)
import('pkgconfig').generate(
libraries : jsoncpp_lib,
version : meson.project_version(),
name : 'jsoncpp',
filebase : 'jsoncpp',
description : 'A C++ library for interacting with JSON')
cmakeconf = configuration_data()
cmakeconf.set('MESON_LIB_DIR', get_option('libdir'))
cmakeconf.set('MESON_INCLUDE_DIR', get_option('includedir'))
fs = import('fs')
if get_option('default_library') == 'shared'
shared_name = fs.name(jsoncpp_lib.full_path())
endif
if get_option('default_library') == 'static'
static_name = fs.name(jsoncpp_lib.full_path())
endif
if get_option('default_library') == 'both'
shared_name = fs.name(jsoncpp_lib.get_shared_lib().full_path())
static_name = fs.name(jsoncpp_lib.get_static_lib().full_path())
endif
if get_option('default_library') == 'shared' or get_option('default_library') == 'both'
cmakeconf.set('MESON_SHARED_TARGET', '''
add_library(jsoncpp_lib IMPORTED SHARED)
set_target_properties(jsoncpp_lib PROPERTIES
IMPORTED_LOCATION "''' + join_paths('${PACKAGE_PREFIX_DIR}', get_option('libdir'), shared_name) + '''"
INTERFACE_INCLUDE_DIRECTORIES "''' + join_paths('${PACKAGE_PREFIX_DIR}', get_option('includedir')) + '")')
endif
if get_option('default_library') == 'static' or get_option('default_library') == 'both'
cmakeconf.set('MESON_STATIC_TARGET', '''
add_library(jsoncpp_static IMPORTED STATIC)
set_target_properties(jsoncpp_static PROPERTIES
IMPORTED_LOCATION "''' + join_paths('${PACKAGE_PREFIX_DIR}', get_option('libdir'), static_name) + '''"
INTERFACE_INCLUDE_DIRECTORIES "''' + join_paths('${PACKAGE_PREFIX_DIR}', get_option('includedir')) + '")')
endif
import('cmake').configure_package_config_file(
name: 'jsoncpp',
input: 'jsoncppConfig.cmake.meson.in',
configuration: cmakeconf)
install_data('jsoncpp-namespaced-targets.cmake', install_dir : join_paths(get_option('libdir'), 'cmake', jsoncpp_lib.name()))
# for libraries bundling jsoncpp
jsoncpp_dep = declare_dependency(
include_directories : jsoncpp_include_directories,
link_with : jsoncpp_lib,
version : meson.project_version())
# tests
if meson.is_subproject() or not get_option('tests')
subdir_done()
endif
python = find_program('python3')
jsoncpp_test = executable(
'jsoncpp_test', files([
'src/test_lib_json/jsontest.cpp',
'src/test_lib_json/main.cpp',
'src/test_lib_json/fuzz.cpp',
]),
include_directories : jsoncpp_include_directories,
link_with : jsoncpp_lib,
install : false,
cpp_args: dll_import_flag)
test(
'unittest_jsoncpp_test',
jsoncpp_test)
jsontestrunner = executable(
'jsontestrunner',
'src/jsontestrunner/main.cpp',
include_directories : jsoncpp_include_directories,
link_with : jsoncpp_lib,
install : false,
cpp_args: dll_import_flag)
test(
'unittest_jsontestrunner',
python,
args : [
'-B',
join_paths(meson.current_source_dir(), 'test/runjsontests.py'),
jsontestrunner,
join_paths(meson.current_source_dir(), 'test/data')],
)
test(
'jsonchecker_jsontestrunner',
python,
is_parallel : false,
args : [
'-B',
join_paths(meson.current_source_dir(), 'test/runjsontests.py'),
'--with-json-checker',
jsontestrunner,
join_paths(meson.current_source_dir(), 'test/data')],
workdir : join_paths(meson.current_source_dir(), 'test/data'),
)

View File

@ -1,5 +0,0 @@
option(
'tests',
type : 'boolean',
value : true,
description : 'Enable building tests')

View File

@ -1,11 +1,11 @@
prefix=@CMAKE_INSTALL_PREFIX@ prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix}
libdir=@libdir_for_pc_file@ libdir=${exec_prefix}/@LIBRARY_INSTALL_DIR@
includedir=@includedir_for_pc_file@ includedir=${prefix}/@INCLUDE_INSTALL_DIR@
Name: jsoncpp Name: jsoncpp
Description: A C++ library for interacting with JSON Description: A C++ library for interacting with JSON
Version: @PROJECT_VERSION@ Version: @JSONCPP_VERSION@
URL: https://github.com/open-source-parsers/jsoncpp URL: https://github.com/open-source-parsers/jsoncpp
Libs: -L${libdir} -ljsoncpp Libs: -L${libdir} -ljsoncpp
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -1 +0,0 @@
find src -name '*.cpp' -or -name '*.h' | xargs clang-format -i

58
scons-tools/globtool.py Normal file
View File

@ -0,0 +1,58 @@
# 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
def generate(env):
def Glob(env, includes = None, excludes = None, dir = '.'):
"""Adds Glob(includes = Split('*'), excludes = None, dir = '.')
helper function to environment.
Glob both the file-system files.
includes: list of file name pattern included in the return list when matched.
excludes: list of file name pattern exluced from the return list.
Example:
sources = env.Glob(("*.cpp", '*.h'), "~*.cpp", "#src")
"""
def filterFilename(path):
abs_path = os.path.join(dir, path)
if not os.path.isfile(abs_path):
return 0
fn = os.path.basename(path)
match = 0
for include in includes:
if fnmatch.fnmatchcase(fn, include):
match = 1
break
if match == 1 and not excludes is None:
for exclude in excludes:
if fnmatch.fnmatchcase(fn, exclude):
match = 0
break
return match
if includes is None:
includes = ('*',)
elif type(includes) in (type(''), type(u'')):
includes = (includes,)
if type(excludes) in (type(''), type(u'')):
excludes = (excludes,)
dir = env.Dir(dir).abspath
paths = os.listdir(dir)
def makeAbsFileNode(path):
return env.File(os.path.join(dir, path))
nodes = filter(filterFilename, paths)
return map(makeAbsFileNode, nodes)
from SCons.Script import Environment
Environment.Glob = Glob
def exists(env):
"""
Tool always exists.
"""
return True

183
scons-tools/srcdist.py Normal file
View File

@ -0,0 +1,183 @@
# 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
import targz
##def DoxyfileParse(file_contents):
## """
## Parse a Doxygen source file and return a dictionary of all the values.
## Values will be strings and lists of strings.
## """
## data = {}
##
## import shlex
## lex = shlex.shlex(instream = file_contents, posix = True)
## lex.wordchars += "*+./-:"
## lex.whitespace = lex.whitespace.replace("\n", "")
## lex.escape = ""
##
## lineno = lex.lineno
## last_backslash_lineno = lineno
## token = lex.get_token()
## key = token # the first token should be a key
## last_token = ""
## key_token = False
## next_key = False
## new_data = True
##
## def append_data(data, key, new_data, token):
## if new_data or len(data[key]) == 0:
## data[key].append(token)
## else:
## data[key][-1] += token
##
## while token:
## if token in ['\n']:
## if last_token not in ['\\']:
## key_token = True
## elif token in ['\\']:
## pass
## elif key_token:
## key = token
## key_token = False
## else:
## if token == "+=":
## if not data.has_key(key):
## data[key] = list()
## elif token == "=":
## data[key] = list()
## else:
## append_data(data, key, new_data, token)
## new_data = True
##
## last_token = token
## token = lex.get_token()
##
## if last_token == '\\' and token != '\n':
## new_data = False
## append_data(data, key, new_data, '\\')
##
## # compress lists of len 1 into single strings
## for (k, v) in data.items():
## if len(v) == 0:
## data.pop(k)
##
## # items in the following list will be kept as lists and not converted to strings
## if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS"]:
## continue
##
## if len(v) == 1:
## data[k] = v[0]
##
## return data
##
##def DoxySourceScan(node, env, path):
## """
## Doxygen Doxyfile source scanner. This should scan the Doxygen file and add
## any files used to generate docs to the list of source files.
## """
## default_file_patterns = [
## '*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx',
## '*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++',
## '*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm',
## '*.py',
## ]
##
## default_exclude_patterns = [
## '*~',
## ]
##
## sources = []
##
## data = DoxyfileParse(node.get_contents())
##
## if data.get("RECURSIVE", "NO") == "YES":
## recursive = True
## else:
## recursive = False
##
## file_patterns = data.get("FILE_PATTERNS", default_file_patterns)
## exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns)
##
## for node in data.get("INPUT", []):
## if os.path.isfile(node):
## sources.add(node)
## elif os.path.isdir(node):
## if recursive:
## for root, dirs, files in os.walk(node):
## for f in files:
## filename = os.path.join(root, f)
##
## pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False)
## exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True)
##
## if pattern_check and not exclude_check:
## sources.append(filename)
## else:
## for pattern in file_patterns:
## sources.extend(glob.glob("/".join([node, pattern])))
## sources = map(lambda path: env.File(path), sources)
## return sources
##
##
##def DoxySourceScanCheck(node, env):
## """Check if we should scan this file"""
## return os.path.isfile(node.path)
def srcDistEmitter(source, target, env):
## """Doxygen Doxyfile emitter"""
## # possible output formats and their default values and output locations
## output_formats = {
## "HTML": ("YES", "html"),
## "LATEX": ("YES", "latex"),
## "RTF": ("NO", "rtf"),
## "MAN": ("YES", "man"),
## "XML": ("NO", "xml"),
## }
##
## data = DoxyfileParse(source[0].get_contents())
##
## targets = []
## out_dir = data.get("OUTPUT_DIRECTORY", ".")
##
## # add our output locations
## for (k, v) in output_formats.items():
## if data.get("GENERATE_" + k, v[0]) == "YES":
## targets.append(env.Dir(os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))))
##
## # don't clobber targets
## for node in targets:
## env.Precious(node)
##
## # set up cleaning stuff
## for node in targets:
## env.Clean(node, node)
##
## return (targets, source)
return (target,source)
def generate(env):
"""
Add builders and construction variables for the
SrcDist tool.
"""
## doxyfile_scanner = env.Scanner(## DoxySourceScan,
## "DoxySourceScan",
## scan_check = DoxySourceScanCheck,
##)
if targz.exists(env):
srcdist_builder = targz.makeBuilder(srcDistEmitter)
env['BUILDERS']['SrcDist'] = srcdist_builder
def exists(env):
"""
Make sure srcdist exists.
"""
return targz.exists(env)

View File

@ -0,0 +1,85 @@
# 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
def generate(env):
"""
Add builders and construction variables for the
SubstInFile tool.
Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
from the source to the target.
The values of SUBST_DICT first have any construction variables expanded
(its keys are not expanded).
If a value of SUBST_DICT is a python callable function, it is called and
the result is expanded as the value.
If there's more than one source and more than one target, each target gets
substituted from the corresponding source.
"""
def do_subst_in_file(targetfile, sourcefile, dict):
"""Replace all instances of the keys of dict with their values.
For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
"""
try:
f = open(sourcefile, 'rb')
contents = f.read()
f.close()
except:
raise SCons.Errors.UserError("Can't read source file %s"%sourcefile)
for (k,v) in list(dict.items()):
contents = re.sub(k, v, contents)
try:
f = open(targetfile, 'wb')
f.write(contents)
f.close()
except:
raise SCons.Errors.UserError("Can't write target file %s"%targetfile)
return 0 # success
def subst_in_file(target, source, env):
if 'SUBST_DICT' not in env:
raise SCons.Errors.UserError("SubstInFile requires SUBST_DICT to be set.")
d = dict(env['SUBST_DICT']) # copy it
for (k,v) in list(d.items()):
if isinstance(v, collections.Callable):
d[k] = env.subst(v()).replace('\\','\\\\')
elif SCons.Util.is_String(v):
d[k] = env.subst(v).replace('\\','\\\\')
else:
raise SCons.Errors.UserError("SubstInFile: key %s: %s must be a string or callable"%(k, repr(v)))
for (t,s) in zip(target, source):
return do_subst_in_file(str(t), str(s), d)
def subst_in_file_string(target, source, env):
"""This is what gets printed on the console."""
return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
for (t,s) in zip(target, source)])
def subst_emitter(target, source, env):
"""Add dependency from substituted SUBST_DICT to target.
Returns original target, source tuple unchanged.
"""
d = env['SUBST_DICT'].copy() # copy it
for (k,v) in list(d.items()):
if isinstance(v, collections.Callable):
d[k] = env.subst(v())
elif SCons.Util.is_String(v):
d[k]=env.subst(v)
Depends(target, SCons.Node.Python.Value(d))
return target, source
## env.Append(TOOLS = 'substinfile') # this should be automaticaly done by Scons ?!?
subst_action = SCons.Action.Action(subst_in_file, subst_in_file_string)
env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
def exists(env):
"""
Make sure tool exists.
"""
return True

87
scons-tools/targz.py Normal file
View File

@ -0,0 +1,87 @@
# 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.
"""
## Commands to tackle a command based implementation:
##to unpack on the fly...
##gunzip < FILE.tar.gz | tar xvf -
##to pack on the fly...
##tar cvf - FILE-LIST | gzip -c > FILE.tar.gz
import os.path
import SCons.Builder
import SCons.Node.FS
import SCons.Util
try:
import gzip
import tarfile
internal_targz = 1
except ImportError:
internal_targz = 0
TARGZ_DEFAULT_COMPRESSION_LEVEL = 9
if internal_targz:
def targz(target, source, env):
def archive_name(path):
path = os.path.normpath(os.path.abspath(path))
common_path = os.path.commonprefix((base_dir, path))
archive_name = path[len(common_path):]
return archive_name
def visit(tar, dirname, names):
for name in names:
path = os.path.join(dirname, name)
if os.path.isfile(path):
tar.add(path, archive_name(path))
compression = env.get('TARGZ_COMPRESSION_LEVEL',TARGZ_DEFAULT_COMPRESSION_LEVEL)
base_dir = os.path.normpath(env.get('TARGZ_BASEDIR', env.Dir('.')).abspath)
target_path = str(target[0])
fileobj = gzip.GzipFile(target_path, 'wb', compression)
tar = tarfile.TarFile(os.path.splitext(target_path)[0], 'w', fileobj)
for source in source:
source_path = str(source)
if source.isdir():
os.path.walk(source_path, visit, tar)
else:
tar.add(source_path, archive_name(source_path)) # filename, arcname
tar.close()
targzAction = SCons.Action.Action(targz, varlist=['TARGZ_COMPRESSION_LEVEL','TARGZ_BASEDIR'])
def makeBuilder(emitter = None):
return SCons.Builder.Builder(action = SCons.Action.Action('$TARGZ_COM', '$TARGZ_COMSTR'),
source_factory = SCons.Node.FS.Entry,
source_scanner = SCons.Defaults.DirScanner,
suffix = '$TARGZ_SUFFIX',
multi = 1)
TarGzBuilder = makeBuilder()
def generate(env):
"""Add Builders and construction variables for zip to an Environment.
The following environnement variables may be set:
TARGZ_COMPRESSION_LEVEL: integer, [0-9]. 0: no compression, 9: best compression (same as gzip compression level).
TARGZ_BASEDIR: base-directory used to determine archive name (this allow archive name to be relative
to something other than top-dir).
"""
env['BUILDERS']['TarGz'] = TarGzBuilder
env['TARGZ_COM'] = targzAction
env['TARGZ_COMPRESSION_LEVEL'] = TARGZ_DEFAULT_COMPRESSION_LEVEL # range 0-9
env['TARGZ_SUFFIX'] = '.tar.gz'
env['TARGZ_BASEDIR'] = env.Dir('.') # Sources archive name are made relative to that directory.
else:
def generate(env):
pass
def exists(env):
return internal_targz

View File

@ -1,5 +1,5 @@
add_subdirectory(lib_json) ADD_SUBDIRECTORY(lib_json)
if(JSONCPP_WITH_TESTS) IF(JSONCPP_WITH_TESTS)
add_subdirectory(jsontestrunner) ADD_SUBDIRECTORY(jsontestrunner)
add_subdirectory(test_lib_json) ADD_SUBDIRECTORY(test_lib_json)
endif() ENDIF()

View File

@ -1,51 +1,25 @@
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) FIND_PACKAGE(PythonInterp 2.6)
# The new Python3 module is much more robust than the previous PythonInterp
find_package(Python3 COMPONENTS Interpreter)
# Set variables for backwards compatibility with cmake < 3.12.0
set(PYTHONINTERP_FOUND ${Python3_Interpreter_FOUND})
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
else()
set(Python_ADDITIONAL_VERSIONS 3.8)
find_package(PythonInterp 3)
endif()
add_executable(jsontestrunner_exe ADD_EXECUTABLE(jsontestrunner_exe
main.cpp main.cpp
) )
if(BUILD_SHARED_LIBS) IF(BUILD_SHARED_LIBS)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) ADD_DEFINITIONS( -DJSON_DLL )
add_compile_definitions( JSON_DLL ) TARGET_LINK_LIBRARIES(jsontestrunner_exe jsoncpp_lib)
else() ELSE(BUILD_SHARED_LIBS)
add_definitions(-DJSON_DLL) TARGET_LINK_LIBRARIES(jsontestrunner_exe jsoncpp_lib_static)
endif() ENDIF()
target_link_libraries(jsontestrunner_exe jsoncpp_lib)
else()
target_link_libraries(jsontestrunner_exe jsoncpp_static)
endif()
set_target_properties(jsontestrunner_exe PROPERTIES OUTPUT_NAME jsontestrunner_exe) SET_TARGET_PROPERTIES(jsontestrunner_exe PROPERTIES OUTPUT_NAME jsontestrunner_exe)
if(PYTHONINTERP_FOUND) IF(PYTHONINTERP_FOUND)
# Run end to end parser/writer tests # Run end to end parser/writer tests
set(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../test) SET(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../test)
set(RUNJSONTESTS_PATH ${TEST_DIR}/runjsontests.py) SET(RUNJSONTESTS_PATH ${TEST_DIR}/runjsontests.py)
ADD_CUSTOM_TARGET(jsoncpp_readerwriter_tests
# Run unit tests in post-build
# (default cmake workflow hides away the test result into a file, resulting in poor dev workflow?!?)
add_custom_target(jsoncpp_readerwriter_tests
"${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $<TARGET_FILE:jsontestrunner_exe> "${TEST_DIR}/data" "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $<TARGET_FILE:jsontestrunner_exe> "${TEST_DIR}/data"
DEPENDS jsontestrunner_exe jsoncpp_test DEPENDS jsontestrunner_exe jsoncpp_test
) )
add_custom_target(jsoncpp_check DEPENDS jsoncpp_readerwriter_tests) ADD_CUSTOM_TARGET(jsoncpp_check DEPENDS jsoncpp_readerwriter_tests)
ENDIF()
## Create tests for dashboard submission, allows easy review of CI results https://my.cdash.org/index.php?project=jsoncpp
add_test(NAME jsoncpp_readerwriter
COMMAND "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $<TARGET_FILE:jsontestrunner_exe> "${TEST_DIR}/data"
WORKING_DIRECTORY "${TEST_DIR}/data"
)
add_test(NAME jsoncpp_readerwriter_json_checker
COMMAND "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" --with-json-checker $<TARGET_FILE:jsontestrunner_exe> "${TEST_DIR}/data"
WORKING_DIRECTORY "${TEST_DIR}/data"
)
endif()

View File

@ -1,49 +1,49 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(_MSC_VER)
#pragma warning(disable : 4996)
#endif
/* This executable is used for testing parser/writer using real JSON files. /* This executable is used for testing parser/writer using real JSON files.
*/ */
#include <algorithm> // sort
#include <cstdio>
#include <iostream>
#include <json/json.h> #include <json/json.h>
#include <memory> #include <algorithm> // sort
#include <sstream> #include <sstream>
#include <stdio.h>
struct Options { #if defined(_MSC_VER) && _MSC_VER >= 1310
Json::String path; #pragma warning(disable : 4996) // disable fopen deprecation warning
#endif
struct Options
{
JSONCPP_STRING path;
Json::Features features; Json::Features features;
bool parseOnly; bool parseOnly;
using writeFuncType = Json::String (*)(Json::Value const&); typedef JSONCPP_STRING (*writeFuncType)(Json::Value const&);
writeFuncType write; writeFuncType write;
}; };
static Json::String normalizeFloatingPointStr(double value) { static JSONCPP_STRING normalizeFloatingPointStr(double value) {
char buffer[32]; char buffer[32];
jsoncpp_snprintf(buffer, sizeof(buffer), "%.16g", value); #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
sprintf_s(buffer, sizeof(buffer), "%.16g", value);
#else
snprintf(buffer, sizeof(buffer), "%.16g", value);
#endif
buffer[sizeof(buffer) - 1] = 0; buffer[sizeof(buffer) - 1] = 0;
Json::String s(buffer); JSONCPP_STRING s(buffer);
Json::String::size_type index = s.find_last_of("eE"); JSONCPP_STRING::size_type index = s.find_last_of("eE");
if (index != Json::String::npos) { if (index != JSONCPP_STRING::npos) {
Json::String::size_type hasSign = JSONCPP_STRING::size_type hasSign =
(s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0;
Json::String::size_type exponentStartIndex = index + 1 + hasSign; JSONCPP_STRING::size_type exponentStartIndex = index + 1 + hasSign;
Json::String normalized = s.substr(0, exponentStartIndex); JSONCPP_STRING normalized = s.substr(0, exponentStartIndex);
Json::String::size_type indexDigit = JSONCPP_STRING::size_type indexDigit =
s.find_first_not_of('0', exponentStartIndex); s.find_first_not_of('0', exponentStartIndex);
Json::String exponent = "0"; JSONCPP_STRING exponent = "0";
if (indexDigit != Json::String::npos) // There is an exponent different if (indexDigit !=
// from 0 JSONCPP_STRING::npos) // There is an exponent different from 0
{ {
exponent = s.substr(indexDigit); exponent = s.substr(indexDigit);
} }
@ -52,17 +52,17 @@ static Json::String normalizeFloatingPointStr(double value) {
return s; return s;
} }
static Json::String readInputTestFile(const char* path) { static JSONCPP_STRING readInputTestFile(const char* path) {
FILE* file = fopen(path, "rb"); FILE* file = fopen(path, "rb");
if (!file) if (!file)
return ""; return JSONCPP_STRING("");
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
auto const size = ftell(file); long const size = ftell(file);
auto const usize = static_cast<size_t>(size); unsigned long const usize = static_cast<unsigned long>(size);
fseek(file, 0, SEEK_SET); fseek(file, 0, SEEK_SET);
auto buffer = new char[size + 1]; JSONCPP_STRING text;
char* buffer = new char[size + 1];
buffer[size] = 0; buffer[size] = 0;
Json::String text;
if (fread(buffer, 1, usize, file) == usize) if (fread(buffer, 1, usize, file) == usize)
text = buffer; text = buffer;
fclose(file); fclose(file);
@ -70,8 +70,8 @@ static Json::String readInputTestFile(const char* path) {
return text; return text;
} }
static void printValueTree(FILE* fout, Json::Value& value, static void
const Json::String& path = ".") { printValueTree(FILE* fout, Json::Value& value, const JSONCPP_STRING& path = ".") {
if (value.hasComment(Json::commentBefore)) { if (value.hasComment(Json::commentBefore)) {
fprintf(fout, "%s\n", value.getComment(Json::commentBefore).c_str()); fprintf(fout, "%s\n", value.getComment(Json::commentBefore).c_str());
} }
@ -80,15 +80,21 @@ static void printValueTree(FILE* fout, Json::Value& value,
fprintf(fout, "%s=null\n", path.c_str()); fprintf(fout, "%s=null\n", path.c_str());
break; break;
case Json::intValue: case Json::intValue:
fprintf(fout, "%s=%s\n", path.c_str(), fprintf(fout,
"%s=%s\n",
path.c_str(),
Json::valueToString(value.asLargestInt()).c_str()); Json::valueToString(value.asLargestInt()).c_str());
break; break;
case Json::uintValue: case Json::uintValue:
fprintf(fout, "%s=%s\n", path.c_str(), fprintf(fout,
"%s=%s\n",
path.c_str(),
Json::valueToString(value.asLargestUInt()).c_str()); Json::valueToString(value.asLargestUInt()).c_str());
break; break;
case Json::realValue: case Json::realValue:
fprintf(fout, "%s=%s\n", path.c_str(), fprintf(fout,
"%s=%s\n",
path.c_str(),
normalizeFloatingPointStr(value.asDouble()).c_str()); normalizeFloatingPointStr(value.asDouble()).c_str());
break; break;
case Json::stringValue: case Json::stringValue:
@ -102,7 +108,11 @@ static void printValueTree(FILE* fout, Json::Value& value,
Json::ArrayIndex size = value.size(); Json::ArrayIndex size = value.size();
for (Json::ArrayIndex index = 0; index < size; ++index) { for (Json::ArrayIndex index = 0; index < size; ++index) {
static char buffer[16]; static char buffer[16];
jsoncpp_snprintf(buffer, sizeof(buffer), "[%u]", index); #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
sprintf_s(buffer, sizeof(buffer), "[%d]", index);
#else
snprintf(buffer, sizeof(buffer), "[%d]", index);
#endif
printValueTree(fout, value[index], path + buffer); printValueTree(fout, value[index], path + buffer);
} }
} break; } break;
@ -110,8 +120,11 @@ static void printValueTree(FILE* fout, Json::Value& value,
fprintf(fout, "%s={}\n", path.c_str()); fprintf(fout, "%s={}\n", path.c_str());
Json::Value::Members members(value.getMemberNames()); Json::Value::Members members(value.getMemberNames());
std::sort(members.begin(), members.end()); std::sort(members.begin(), members.end());
Json::String suffix = *(path.end() - 1) == '.' ? "" : "."; JSONCPP_STRING suffix = *(path.end() - 1) == '.' ? "" : ".";
for (const auto& name : members) { for (Json::Value::Members::iterator it = members.begin();
it != members.end();
++it) {
const JSONCPP_STRING name = *it;
printValueTree(fout, value[name], path + suffix + name); printValueTree(fout, value[name], path + suffix + name);
} }
} break; } break;
@ -124,49 +137,25 @@ static void printValueTree(FILE* fout, Json::Value& value,
} }
} }
static int parseAndSaveValueTree(const Json::String& input, static int parseAndSaveValueTree(const JSONCPP_STRING& input,
const Json::String& actual, const JSONCPP_STRING& actual,
const Json::String& kind, const JSONCPP_STRING& kind,
const Json::Features& features, bool parseOnly, const Json::Features& features,
Json::Value* root, bool use_legacy) { bool parseOnly,
if (!use_legacy) { Json::Value* root)
Json::CharReaderBuilder builder; {
builder.settings_["allowComments"] = features.allowComments_;
builder.settings_["strictRoot"] = features.strictRoot_;
builder.settings_["allowDroppedNullPlaceholders"] =
features.allowDroppedNullPlaceholders_;
builder.settings_["allowNumericKeys"] = features.allowNumericKeys_;
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
Json::String errors;
const bool parsingSuccessful =
reader->parse(input.data(), input.data() + input.size(), root, &errors);
if (!parsingSuccessful) {
std::cerr << "Failed to parse " << kind << " file: " << std::endl
<< errors << std::endl;
return 1;
}
// We may instead check the legacy implementation (to ensure it doesn't
// randomly get broken).
} else {
Json::Reader reader(features); Json::Reader reader(features);
const bool parsingSuccessful = bool parsingSuccessful = reader.parse(input.data(), input.data() + input.size(), *root);
reader.parse(input.data(), input.data() + input.size(), *root);
if (!parsingSuccessful) { if (!parsingSuccessful) {
std::cerr << "Failed to parse " << kind << " file: " << std::endl printf("Failed to parse %s file: \n%s\n",
<< reader.getFormatedErrorMessages() << std::endl; kind.c_str(),
reader.getFormattedErrorMessages().c_str());
return 1; return 1;
} }
}
if (!parseOnly) { if (!parseOnly) {
FILE* factual = fopen(actual.c_str(), "wt"); FILE* factual = fopen(actual.c_str(), "wt");
if (!factual) { if (!factual) {
std::cerr << "Failed to create '" << kind << "' actual file." printf("Failed to create %s actual file.\n", kind.c_str());
<< std::endl;
return 2; return 2;
} }
printValueTree(factual, *root); printValueTree(factual, *root);
@ -174,33 +163,41 @@ static int parseAndSaveValueTree(const Json::String& input,
} }
return 0; return 0;
} }
// static Json::String useFastWriter(Json::Value const& root) { // static JSONCPP_STRING useFastWriter(Json::Value const& root) {
// Json::FastWriter writer; // Json::FastWriter writer;
// writer.enableYAMLCompatibility(); // writer.enableYAMLCompatibility();
// return writer.write(root); // return writer.write(root);
// } // }
static Json::String useStyledWriter(Json::Value const& root) { static JSONCPP_STRING useStyledWriter(
Json::Value const& root)
{
Json::StyledWriter writer; Json::StyledWriter writer;
return writer.write(root); return writer.write(root);
} }
static Json::String useStyledStreamWriter(Json::Value const& root) { static JSONCPP_STRING useStyledStreamWriter(
Json::Value const& root)
{
Json::StyledStreamWriter writer; Json::StyledStreamWriter writer;
Json::OStringStream sout; JSONCPP_OSTRINGSTREAM sout;
writer.write(sout, root); writer.write(sout, root);
return sout.str(); return sout.str();
} }
static Json::String useBuiltStyledStreamWriter(Json::Value const& root) { static JSONCPP_STRING useBuiltStyledStreamWriter(
Json::Value const& root)
{
Json::StreamWriterBuilder builder; Json::StreamWriterBuilder builder;
return Json::writeString(builder, root); return Json::writeString(builder, root);
} }
static int rewriteValueTree(const Json::String& rewritePath, static int rewriteValueTree(
const JSONCPP_STRING& rewritePath,
const Json::Value& root, const Json::Value& root,
Options::writeFuncType write, Options::writeFuncType write,
Json::String* rewrite) { JSONCPP_STRING* rewrite)
{
*rewrite = write(root); *rewrite = write(root);
FILE* fout = fopen(rewritePath.c_str(), "wt"); FILE* fout = fopen(rewritePath.c_str(), "wt");
if (!fout) { if (!fout) {
std::cerr << "Failed to create rewrite file: " << rewritePath << std::endl; printf("Failed to create rewrite file: %s\n", rewritePath.c_str());
return 2; return 2;
} }
fprintf(fout, "%s\n", rewrite->c_str()); fprintf(fout, "%s\n", rewrite->c_str());
@ -208,53 +205,51 @@ static int rewriteValueTree(const Json::String& rewritePath,
return 0; return 0;
} }
static Json::String removeSuffix(const Json::String& path, static JSONCPP_STRING removeSuffix(const JSONCPP_STRING& path,
const Json::String& extension) { const JSONCPP_STRING& extension) {
if (extension.length() >= path.length()) if (extension.length() >= path.length())
return Json::String(""); return JSONCPP_STRING("");
Json::String suffix = path.substr(path.length() - extension.length()); JSONCPP_STRING suffix = path.substr(path.length() - extension.length());
if (suffix != extension) if (suffix != extension)
return Json::String(""); return JSONCPP_STRING("");
return path.substr(0, path.length() - extension.length()); return path.substr(0, path.length() - extension.length());
} }
static void printConfig() { static void printConfig() {
// Print the configuration used to compile JsonCpp // Print the configuration used to compile JsonCpp
#if defined(JSON_NO_INT64) #if defined(JSON_NO_INT64)
std::cout << "JSON_NO_INT64=1" << std::endl; printf("JSON_NO_INT64=1\n");
#else #else
std::cout << "JSON_NO_INT64=0" << std::endl; printf("JSON_NO_INT64=0\n");
#endif #endif
} }
static int printUsage(const char* argv[]) { static int printUsage(const char* argv[]) {
std::cout << "Usage: " << argv[0] << " [--strict] input-json-file" printf("Usage: %s [--strict] input-json-file", argv[0]);
<< std::endl;
return 3; return 3;
} }
static int parseCommandLine(int argc, const char* argv[], Options* opts) { static int parseCommandLine(
int argc, const char* argv[], Options* opts)
{
opts->parseOnly = false; opts->parseOnly = false;
opts->write = &useStyledWriter; opts->write = &useStyledWriter;
if (argc < 2) { if (argc < 2) {
return printUsage(argv); return printUsage(argv);
} }
int index = 1; int index = 1;
if (Json::String(argv[index]) == "--parse-only") { if (JSONCPP_STRING(argv[index]) == "--json-checker") {
opts->features = Json::Features::strictMode();
opts->parseOnly = true; opts->parseOnly = true;
++index; ++index;
} }
if (Json::String(argv[index]) == "--strict") { if (JSONCPP_STRING(argv[index]) == "--json-config") {
opts->features = Json::Features::strictMode();
++index;
}
if (Json::String(argv[index]) == "--json-config") {
printConfig(); printConfig();
return 3; return 3;
} }
if (Json::String(argv[index]) == "--json-writer") { if (JSONCPP_STRING(argv[index]) == "--json-writer") {
++index; ++index;
Json::String const writerName(argv[index++]); JSONCPP_STRING const writerName(argv[index++]);
if (writerName == "StyledWriter") { if (writerName == "StyledWriter") {
opts->write = &useStyledWriter; opts->write = &useStyledWriter;
} else if (writerName == "StyledStreamWriter") { } else if (writerName == "StyledStreamWriter") {
@ -262,7 +257,7 @@ static int parseCommandLine(int argc, const char* argv[], Options* opts) {
} else if (writerName == "BuiltStyledStreamWriter") { } else if (writerName == "BuiltStyledStreamWriter") {
opts->write = &useBuiltStyledStreamWriter; opts->write = &useBuiltStyledStreamWriter;
} else { } else {
std::cerr << "Unknown '--json-writer' " << writerName << std::endl; printf("Unknown '--json-writer %s'\n", writerName.c_str());
return 4; return 4;
} }
} }
@ -272,75 +267,60 @@ static int parseCommandLine(int argc, const char* argv[], Options* opts) {
opts->path = argv[index]; opts->path = argv[index];
return 0; return 0;
} }
static int runTest(Options const& opts)
static int runTest(Options const& opts, bool use_legacy) { {
int exitCode = 0; int exitCode = 0;
Json::String input = readInputTestFile(opts.path.c_str()); JSONCPP_STRING input = readInputTestFile(opts.path.c_str());
if (input.empty()) { if (input.empty()) {
std::cerr << "Invalid input file: " << opts.path << std::endl; printf("Failed to read input or empty input: %s\n", opts.path.c_str());
return 3; return 3;
} }
Json::String basePath = removeSuffix(opts.path, ".json"); JSONCPP_STRING basePath = removeSuffix(opts.path, ".json");
if (!opts.parseOnly && basePath.empty()) { if (!opts.parseOnly && basePath.empty()) {
std::cerr << "Bad input path '" << opts.path printf("Bad input path. Path does not end with '.expected':\n%s\n",
<< "'. Must end with '.expected'" << std::endl; opts.path.c_str());
return 3; return 3;
} }
Json::String const actualPath = basePath + ".actual"; JSONCPP_STRING const actualPath = basePath + ".actual";
Json::String const rewritePath = basePath + ".rewrite"; JSONCPP_STRING const rewritePath = basePath + ".rewrite";
Json::String const rewriteActualPath = basePath + ".actual-rewrite"; JSONCPP_STRING const rewriteActualPath = basePath + ".actual-rewrite";
Json::Value root; Json::Value root;
exitCode = parseAndSaveValueTree(input, actualPath, "input", opts.features, exitCode = parseAndSaveValueTree(
opts.parseOnly, &root, use_legacy); input, actualPath, "input",
opts.features, opts.parseOnly, &root);
if (exitCode || opts.parseOnly) { if (exitCode || opts.parseOnly) {
return exitCode; return exitCode;
} }
JSONCPP_STRING rewrite;
Json::String rewrite;
exitCode = rewriteValueTree(rewritePath, root, opts.write, &rewrite); exitCode = rewriteValueTree(rewritePath, root, opts.write, &rewrite);
if (exitCode) { if (exitCode) {
return exitCode; return exitCode;
} }
Json::Value rewriteRoot; Json::Value rewriteRoot;
exitCode = parseAndSaveValueTree(rewrite, rewriteActualPath, "rewrite", exitCode = parseAndSaveValueTree(
opts.features, opts.parseOnly, &rewriteRoot, rewrite, rewriteActualPath, "rewrite",
use_legacy); opts.features, opts.parseOnly, &rewriteRoot);
if (exitCode) {
return exitCode; return exitCode;
}
return 0;
} }
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
Options opts; Options opts;
try { try {
int exitCode = parseCommandLine(argc, argv, &opts); int exitCode = parseCommandLine(argc, argv, &opts);
if (exitCode != 0) { if (exitCode != 0) {
std::cerr << "Failed to parse command-line." << std::endl; printf("Failed to parse command-line.");
return exitCode; return exitCode;
} }
return runTest(opts);
const int modern_return_code = runTest(opts, false);
if (modern_return_code) {
return modern_return_code;
} }
catch (const std::exception& e) {
const std::string filename = printf("Unhandled exception:\n%s\n", e.what());
opts.path.substr(opts.path.find_last_of("\\/") + 1);
const bool should_run_legacy = (filename.rfind("legacy_", 0) == 0);
if (should_run_legacy) {
return runTest(opts, true);
}
} catch (const std::exception& e) {
std::cerr << "Unhandled exception:" << std::endl << e.what() << std::endl;
return 1; return 1;
} }
return 0;
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

View File

@ -0,0 +1,9 @@
Import( 'env_testing buildJSONTests' )
buildJSONTests( env_testing, Split( """
main.cpp
""" ),
'jsontestrunner' )
# For 'check' to work, 'libs' must be built first.
env_testing.Depends('jsontestrunner', '#libs')

View File

@ -1,205 +1,85 @@
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.1.2) if( CMAKE_COMPILER_IS_GNUCXX )
#Get compiler version.
execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion
OUTPUT_VARIABLE GNUCXX_VERSION )
#-Werror=* was introduced -after- GCC 4.1.2 #-Werror=* was introduced -after- GCC 4.1.2
add_compile_options("-Werror=strict-aliasing") if( GNUCXX_VERSION VERSION_GREATER 4.1.2 )
endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=strict-aliasing")
include(CheckIncludeFileCXX)
include(CheckTypeSize)
include(CheckStructHasMember)
include(CheckCXXSymbolExists)
check_include_file_cxx(clocale HAVE_CLOCALE)
check_cxx_symbol_exists(localeconv clocale HAVE_LOCALECONV)
set(CMAKE_EXTRA_INCLUDE_FILES clocale)
check_type_size(lconv LCONV_SIZE LANGUAGE CXX)
unset(CMAKE_EXTRA_INCLUDE_FILES)
check_struct_has_member(lconv decimal_point clocale HAVE_DECIMAL_POINT LANGUAGE CXX)
if(NOT (HAVE_CLOCALE AND HAVE_LCONV_SIZE AND HAVE_DECIMAL_POINT AND HAVE_LOCALECONV))
message(WARNING "Locale functionality is not supported")
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0)
add_compile_definitions(JSONCPP_NO_LOCALE_SUPPORT)
else()
add_definitions(-DJSONCPP_NO_LOCALE_SUPPORT)
endif() endif()
endif() endif( CMAKE_COMPILER_IS_GNUCXX )
set(JSONCPP_INCLUDE_DIR ../../include) SET( JSONCPP_INCLUDE_DIR ../../include )
set(PUBLIC_HEADERS SET( PUBLIC_HEADERS
${JSONCPP_INCLUDE_DIR}/json/config.h ${JSONCPP_INCLUDE_DIR}/json/config.h
${JSONCPP_INCLUDE_DIR}/json/forwards.h ${JSONCPP_INCLUDE_DIR}/json/forwards.h
${JSONCPP_INCLUDE_DIR}/json/json_features.h ${JSONCPP_INCLUDE_DIR}/json/features.h
${JSONCPP_INCLUDE_DIR}/json/value.h ${JSONCPP_INCLUDE_DIR}/json/value.h
${JSONCPP_INCLUDE_DIR}/json/reader.h ${JSONCPP_INCLUDE_DIR}/json/reader.h
${JSONCPP_INCLUDE_DIR}/json/version.h
${JSONCPP_INCLUDE_DIR}/json/writer.h ${JSONCPP_INCLUDE_DIR}/json/writer.h
${JSONCPP_INCLUDE_DIR}/json/assertions.h ${JSONCPP_INCLUDE_DIR}/json/assertions.h
) ${JSONCPP_INCLUDE_DIR}/json/version.h
)
source_group("Public API" FILES ${PUBLIC_HEADERS}) SOURCE_GROUP( "Public API" FILES ${PUBLIC_HEADERS} )
set(JSONCPP_SOURCES SET(jsoncpp_sources
json_tool.h json_tool.h
json_reader.cpp json_reader.cpp
json_valueiterator.inl json_valueiterator.inl
json_value.cpp json_value.cpp
json_writer.cpp json_writer.cpp
) version.h.in)
# Install instructions for this target # Install instructions for this target
if(JSONCPP_WITH_CMAKE_PACKAGE) IF(JSONCPP_WITH_CMAKE_PACKAGE)
set(INSTALL_EXPORT EXPORT jsoncpp) SET(INSTALL_EXPORT EXPORT jsoncpp)
else() ELSE(JSONCPP_WITH_CMAKE_PACKAGE)
set(INSTALL_EXPORT) SET(INSTALL_EXPORT)
endif() ENDIF()
# Specify compiler features required when compiling a given target. IF(BUILD_SHARED_LIBS)
# See https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html#prop_gbl:CMAKE_CXX_KNOWN_FEATURES ADD_DEFINITIONS( -DJSON_DLL_BUILD )
# for complete list of features available ADD_LIBRARY(jsoncpp_lib SHARED ${PUBLIC_HEADERS} ${jsoncpp_sources})
list(APPEND REQUIRED_FEATURES SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_SOVERSION})
cxx_std_11 # Compiler mode is aware of C++ 11. SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES OUTPUT_NAME jsoncpp
#MSVC 1900 cxx_alignas # Alignment control alignas, as defined in N2341. DEBUG_OUTPUT_NAME jsoncpp${DEBUG_LIBNAME_SUFFIX} )
#MSVC 1900 cxx_alignof # Alignment control alignof, as defined in N2341.
#MSVC 1900 cxx_attributes # Generic attributes, as defined in N2761.
cxx_auto_type # Automatic type deduction, as defined in N1984.
#MSVC 1900 cxx_constexpr # Constant expressions, as defined in N2235.
cxx_decltype # Decltype, as defined in N2343.
cxx_default_function_template_args # Default template arguments for function templates, as defined in DR226
cxx_defaulted_functions # Defaulted functions, as defined in N2346.
#MSVC 1900 cxx_defaulted_move_initializers # Defaulted move initializers, as defined in N3053.
cxx_delegating_constructors # Delegating constructors, as defined in N1986.
#MSVC 1900 cxx_deleted_functions # Deleted functions, as defined in N2346.
cxx_enum_forward_declarations # Enum forward declarations, as defined in N2764.
cxx_explicit_conversions # Explicit conversion operators, as defined in N2437.
cxx_extended_friend_declarations # Extended friend declarations, as defined in N1791.
cxx_extern_templates # Extern templates, as defined in N1987.
cxx_final # Override control final keyword, as defined in N2928, N3206 and N3272.
#MSVC 1900 cxx_func_identifier # Predefined __func__ identifier, as defined in N2340.
#MSVC 1900 cxx_generalized_initializers # Initializer lists, as defined in N2672.
#MSVC 1900 cxx_inheriting_constructors # Inheriting constructors, as defined in N2540.
#MSVC 1900 cxx_inline_namespaces # Inline namespaces, as defined in N2535.
cxx_lambdas # Lambda functions, as defined in N2927.
#MSVC 1900 cxx_local_type_template_args # Local and unnamed types as template arguments, as defined in N2657.
cxx_long_long_type # long long type, as defined in N1811.
#MSVC 1900 cxx_noexcept # Exception specifications, as defined in N3050.
#MSVC 1900 cxx_nonstatic_member_init # Non-static data member initialization, as defined in N2756.
cxx_nullptr # Null pointer, as defined in N2431.
cxx_override # Override control override keyword, as defined in N2928, N3206 and N3272.
cxx_range_for # Range-based for, as defined in N2930.
cxx_raw_string_literals # Raw string literals, as defined in N2442.
#MSVC 1900 cxx_reference_qualified_functions # Reference qualified functions, as defined in N2439.
cxx_right_angle_brackets # Right angle bracket parsing, as defined in N1757.
cxx_rvalue_references # R-value references, as defined in N2118.
#MSVC 1900 cxx_sizeof_member # Size of non-static data members, as defined in N2253.
cxx_static_assert # Static assert, as defined in N1720.
cxx_strong_enums # Strongly typed enums, as defined in N2347.
#MSVC 1900 cxx_thread_local # Thread-local variables, as defined in N2659.
cxx_trailing_return_types # Automatic function return type, as defined in N2541.
#MSVC 1900 cxx_unicode_literals # Unicode string literals, as defined in N2442.
cxx_uniform_initialization # Uniform initialization, as defined in N2640.
#MSVC 1900 cxx_unrestricted_unions # Unrestricted unions, as defined in N2544.
#MSVC 1900 cxx_user_literals # User-defined literals, as defined in N2765.
cxx_variadic_macros # Variadic macros, as defined in N1653.
cxx_variadic_templates # Variadic templates, as defined in N2242.
)
if(BUILD_SHARED_LIBS)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0)
add_compile_definitions(JSON_DLL_BUILD)
else()
add_definitions(-DJSON_DLL_BUILD)
endif()
set(SHARED_LIB ${PROJECT_NAME}_lib)
add_library(${SHARED_LIB} SHARED ${PUBLIC_HEADERS} ${JSONCPP_SOURCES})
set_target_properties(${SHARED_LIB} PROPERTIES
OUTPUT_NAME jsoncpp
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_SOVERSION}
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
# Set library's runtime search path on OSX # Set library's runtime search path on OSX
if(APPLE) IF(APPLE)
set_target_properties(${SHARED_LIB} PROPERTIES INSTALL_RPATH "@loader_path/.") SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES INSTALL_RPATH "@loader_path/." )
endif() ENDIF()
target_compile_features(${SHARED_LIB} PUBLIC ${REQUIRED_FEATURES}) INSTALL( TARGETS jsoncpp_lib ${INSTALL_EXPORT}
RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR}
LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR}
ARCHIVE DESTINATION ${ARCHIVE_INSTALL_DIR})
target_include_directories(${SHARED_LIB} PUBLIC IF(NOT CMAKE_VERSION VERSION_LESS 2.8.11)
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> TARGET_INCLUDE_DIRECTORIES( jsoncpp_lib PUBLIC
$<INSTALL_INTERFACE:${INCLUDE_INSTALL_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}>)
ENDIF()
ENDIF()
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_SOVERSION})
SET_TARGET_PROPERTIES( jsoncpp_lib_static PROPERTIES OUTPUT_NAME jsoncpp
DEBUG_OUTPUT_NAME jsoncpp${DEBUG_LIBNAME_SUFFIX} )
INSTALL( TARGETS jsoncpp_lib_static ${INSTALL_EXPORT}
RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR}
LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR}
ARCHIVE DESTINATION ${ARCHIVE_INSTALL_DIR})
IF(NOT CMAKE_VERSION VERSION_LESS 2.8.11)
TARGET_INCLUDE_DIRECTORIES( jsoncpp_lib_static PUBLIC
$<INSTALL_INTERFACE:${INCLUDE_INSTALL_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}>
) )
ENDIF()
list(APPEND CMAKE_TARGETS ${SHARED_LIB}) ENDIF()
endif()
if(BUILD_STATIC_LIBS)
set(STATIC_LIB ${PROJECT_NAME}_static)
add_library(${STATIC_LIB} STATIC ${PUBLIC_HEADERS} ${JSONCPP_SOURCES})
# avoid name clashes on windows as the shared import lib is also named jsoncpp.lib
if(NOT DEFINED STATIC_SUFFIX AND BUILD_SHARED_LIBS)
if (MSVC OR ("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC"))
set(STATIC_SUFFIX "_static")
else()
set(STATIC_SUFFIX "")
endif()
endif()
set_target_properties(${STATIC_LIB} PROPERTIES
OUTPUT_NAME jsoncpp${STATIC_SUFFIX}
VERSION ${PROJECT_VERSION}
)
# Set library's runtime search path on OSX
if(APPLE)
set_target_properties(${STATIC_LIB} PROPERTIES INSTALL_RPATH "@loader_path/.")
endif()
target_compile_features(${STATIC_LIB} PUBLIC ${REQUIRED_FEATURES})
target_include_directories(${STATIC_LIB} PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}>
)
list(APPEND CMAKE_TARGETS ${STATIC_LIB})
endif()
if(BUILD_OBJECT_LIBS)
set(OBJECT_LIB ${PROJECT_NAME}_object)
add_library(${OBJECT_LIB} OBJECT ${PUBLIC_HEADERS} ${JSONCPP_SOURCES})
set_target_properties(${OBJECT_LIB} PROPERTIES
OUTPUT_NAME jsoncpp
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_SOVERSION}
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
# Set library's runtime search path on OSX
if(APPLE)
set_target_properties(${OBJECT_LIB} PROPERTIES INSTALL_RPATH "@loader_path/.")
endif()
target_compile_features(${OBJECT_LIB} PUBLIC ${REQUIRED_FEATURES})
target_include_directories(${OBJECT_LIB} PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/${JSONCPP_INCLUDE_DIR}>
)
list(APPEND CMAKE_TARGETS ${OBJECT_LIB})
endif()
install(TARGETS ${CMAKE_TARGETS} ${INSTALL_EXPORT}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
OBJECTS DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@ -6,16 +6,7 @@
#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED #ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED #define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION) #ifndef NO_LOCALE_SUPPORT
#include <json/config.h>
#endif
// Also support old flag NO_LOCALE_SUPPORT
#ifdef NO_LOCALE_SUPPORT
#define JSONCPP_NO_LOCALE_SUPPORT
#endif
#ifndef JSONCPP_NO_LOCALE_SUPPORT
#include <clocale> #include <clocale>
#endif #endif
@ -26,8 +17,8 @@
*/ */
namespace Json { namespace Json {
static inline char getDecimalPoint() { static char getDecimalPoint() {
#ifdef JSONCPP_NO_LOCALE_SUPPORT #ifdef NO_LOCALE_SUPPORT
return '\0'; return '\0';
#else #else
struct lconv* lc = localeconv(); struct lconv* lc = localeconv();
@ -36,8 +27,8 @@ static inline char getDecimalPoint() {
} }
/// Converts a unicode code-point to UTF-8. /// Converts a unicode code-point to UTF-8.
static inline String codePointToUTF8(unsigned int cp) { static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) {
String result; JSONCPP_STRING result;
// based on description from http://en.wikipedia.org/wiki/UTF-8 // based on description from http://en.wikipedia.org/wiki/UTF-8
@ -64,6 +55,9 @@ static inline String codePointToUTF8(unsigned int cp) {
return result; return result;
} }
/// Returns true if ch is a control character (in range [1,31]).
static inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; }
enum { enum {
/// Constant that specify the size of the buffer that must be passed to /// Constant that specify the size of the buffer that must be passed to
/// uintToString. /// uintToString.
@ -71,10 +65,10 @@ enum {
}; };
// Defines a char buffer for use with uintToString(). // Defines a char buffer for use with uintToString().
using UIntToStringBuffer = char[uintToStringBufferSize]; typedef char UIntToStringBuffer[uintToStringBufferSize];
/** Converts an unsigned integer to string. /** Converts an unsigned integer to string.
* @param value Unsigned integer to convert to string * @param value Unsigned interger to convert to string
* @param current Input/Output string buffer. * @param current Input/Output string buffer.
* Must have at least uintToStringBufferSize chars free. * Must have at least uintToStringBufferSize chars free.
*/ */
@ -91,48 +85,27 @@ static inline void uintToString(LargestUInt value, char*& current) {
* We had a sophisticated way, but it did not work in WinCE. * We had a sophisticated way, but it did not work in WinCE.
* @see https://github.com/open-source-parsers/jsoncpp/pull/9 * @see https://github.com/open-source-parsers/jsoncpp/pull/9
*/ */
template <typename Iter> Iter fixNumericLocale(Iter begin, Iter end) { static inline void fixNumericLocale(char* begin, char* end) {
for (; begin != end; ++begin) { while (begin < end) {
if (*begin == ',') { if (*begin == ',') {
*begin = '.'; *begin = '.';
} }
++begin;
} }
return begin;
} }
template <typename Iter> void fixNumericLocaleInput(Iter begin, Iter end) { static inline void fixNumericLocaleInput(char* begin, char* end) {
char decimalPoint = getDecimalPoint(); char decimalPoint = getDecimalPoint();
if (decimalPoint == '\0' || decimalPoint == '.') { if (decimalPoint != '\0' && decimalPoint != '.') {
return; while (begin < end) {
}
for (; begin != end; ++begin) {
if (*begin == '.') { if (*begin == '.') {
*begin = decimalPoint; *begin = decimalPoint;
} }
++begin;
}
} }
} }
/** } // namespace Json {
* Return iterator that would be the new end of the range [begin,end), if we
* were to delete zeros in the end of string, but not the last zero before '.'.
*/
template <typename Iter>
Iter fixZerosInTheEnd(Iter begin, Iter end, unsigned int precision) {
for (; begin != end; --end) {
if (*(end - 1) != '0') {
return end;
}
// Don't delete the last zero before the decimal point.
if (begin != (end - 1) && begin != (end - 2) && *(end - 2) == '.') {
if (precision) {
return end;
}
return end - 2;
}
}
return end;
}
} // namespace Json
#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED #endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@ -15,21 +15,31 @@ namespace Json {
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
ValueIteratorBase::ValueIteratorBase() : current_() {} ValueIteratorBase::ValueIteratorBase()
: current_(), isNull_(true) {
}
ValueIteratorBase::ValueIteratorBase( ValueIteratorBase::ValueIteratorBase(
const Value::ObjectValues::iterator& current) const Value::ObjectValues::iterator& current)
: current_(current), isNull_(false) {} : current_(current), isNull_(false) {}
Value& ValueIteratorBase::deref() { return current_->second; } Value& ValueIteratorBase::deref() const {
const Value& ValueIteratorBase::deref() const { return current_->second; } return current_->second;
}
void ValueIteratorBase::increment() { ++current_; } void ValueIteratorBase::increment() {
++current_;
}
void ValueIteratorBase::decrement() { --current_; } void ValueIteratorBase::decrement() {
--current_;
}
ValueIteratorBase::difference_type ValueIteratorBase::difference_type
ValueIteratorBase::computeDistance(const SelfType& other) const { ValueIteratorBase::computeDistance(const SelfType& other) const {
#ifdef JSON_USE_CPPTL_SMALLMAP
return other.current_ - current_;
#else
// Iterator for null value are initialized using the default // Iterator for null value are initialized using the default
// constructor, which initialize current_ to the default // constructor, which initialize current_ to the default
// std::map::iterator. As begin() and end() are two instance // std::map::iterator. As begin() and end() are two instance
@ -50,6 +60,7 @@ ValueIteratorBase::computeDistance(const SelfType& other) const {
++myDistance; ++myDistance;
} }
return myDistance; return myDistance;
#endif
} }
bool ValueIteratorBase::isEqual(const SelfType& other) const { bool ValueIteratorBase::isEqual(const SelfType& other) const {
@ -81,13 +92,12 @@ UInt ValueIteratorBase::index() const {
return Value::UInt(-1); return Value::UInt(-1);
} }
String ValueIteratorBase::name() const { JSONCPP_STRING ValueIteratorBase::name() const {
char const* keey; char const* keey;
char const* end; char const* end;
keey = memberName(&end); keey = memberName(&end);
if (!keey) if (!keey) return JSONCPP_STRING();
return String(); return JSONCPP_STRING(keey, end);
return String(keey, end);
} }
char const* ValueIteratorBase::memberName() const { char const* ValueIteratorBase::memberName() const {
@ -98,8 +108,8 @@ char const* ValueIteratorBase::memberName() const {
char const* ValueIteratorBase::memberName(char const** end) const { char const* ValueIteratorBase::memberName(char const** end) const {
const char* cname = (*current_).first.data(); const char* cname = (*current_).first.data();
if (!cname) { if (!cname) {
*end = nullptr; *end = NULL;
return nullptr; return NULL;
} }
*end = cname + (*current_).first.length(); *end = cname + (*current_).first.length();
return cname; return cname;
@ -113,7 +123,7 @@ char const* ValueIteratorBase::memberName(char const** end) const {
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
ValueConstIterator::ValueConstIterator() = default; ValueConstIterator::ValueConstIterator() {}
ValueConstIterator::ValueConstIterator( ValueConstIterator::ValueConstIterator(
const Value::ObjectValues::iterator& current) const Value::ObjectValues::iterator& current)
@ -136,7 +146,7 @@ operator=(const ValueIteratorBase& other) {
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
ValueIterator::ValueIterator() = default; ValueIterator::ValueIterator() {}
ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current) ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
: ValueIteratorBase(current) {} : ValueIteratorBase(current) {}
@ -146,7 +156,8 @@ ValueIterator::ValueIterator(const ValueConstIterator& other)
throwRuntimeError("ConstIterator to Iterator should never be allowed."); throwRuntimeError("ConstIterator to Iterator should never be allowed.");
} }
ValueIterator::ValueIterator(const ValueIterator& other) = default; ValueIterator::ValueIterator(const ValueIterator& other)
: ValueIteratorBase(other) {}
ValueIterator& ValueIterator::operator=(const SelfType& other) { ValueIterator& ValueIterator::operator=(const SelfType& other) {
copy(other); copy(other);

File diff suppressed because it is too large Load Diff

8
src/lib_json/sconscript Normal file
View File

@ -0,0 +1,8 @@
Import( 'env buildLibrary' )
buildLibrary( env, Split( """
json_reader.cpp
json_value.cpp
json_writer.cpp
""" ),
'json' )

20
src/lib_json/version.h.in Normal file
View File

@ -0,0 +1,20 @@
// DO NOT EDIT. This file (and "version") is generated by CMake.
// Run CMake configure step to update it.
#ifndef JSON_VERSION_H_INCLUDED
# define JSON_VERSION_H_INCLUDED
# define JSONCPP_VERSION_STRING "@JSONCPP_VERSION@"
# define JSONCPP_VERSION_MAJOR @JSONCPP_VERSION_MAJOR@
# define JSONCPP_VERSION_MINOR @JSONCPP_VERSION_MINOR@
# define JSONCPP_VERSION_PATCH @JSONCPP_VERSION_PATCH@
# define JSONCPP_VERSION_QUALIFIER
# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
#ifdef JSONCPP_USING_SECURE_MEMORY
#undef JSONCPP_USING_SECURE_MEMORY
#endif
#define JSONCPP_USING_SECURE_MEMORY @JSONCPP_USE_SECURE_MEMORY@
// If non-zero, the library zeroes any memory that it has allocated before
// it frees its memory.
#endif // JSON_VERSION_H_INCLUDED

View File

@ -1,39 +1,38 @@
# vim: et ts=4 sts=4 sw=4 tw=0 # vim: et ts=4 sts=4 sw=4 tw=0
add_executable(jsoncpp_test ADD_EXECUTABLE( jsoncpp_test
jsontest.cpp jsontest.cpp
jsontest.h jsontest.h
fuzz.cpp
fuzz.h
main.cpp main.cpp
) )
if(BUILD_SHARED_LIBS) IF(BUILD_SHARED_LIBS)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) ADD_DEFINITIONS( -DJSON_DLL )
add_compile_definitions( JSON_DLL ) TARGET_LINK_LIBRARIES(jsoncpp_test jsoncpp_lib)
else() ELSE(BUILD_SHARED_LIBS)
add_definitions( -DJSON_DLL ) TARGET_LINK_LIBRARIES(jsoncpp_test jsoncpp_lib_static)
endif() ENDIF()
target_link_libraries(jsoncpp_test jsoncpp_lib)
else()
target_link_libraries(jsoncpp_test jsoncpp_static)
endif()
# another way to solve issue #90 # another way to solve issue #90
#set_target_properties(jsoncpp_test PROPERTIES COMPILE_FLAGS -ffloat-store) #set_target_properties(jsoncpp_test PROPERTIES COMPILE_FLAGS -ffloat-store)
## Create tests for dashboard submission, allows easy review of CI results https://my.cdash.org/index.php?project=jsoncpp
add_test(NAME jsoncpp_test
COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:jsoncpp_test>
)
set_target_properties(jsoncpp_test PROPERTIES OUTPUT_NAME jsoncpp_test)
# Run unit tests in post-build # Run unit tests in post-build
# (default cmake workflow hides away the test result into a file, resulting in poor dev workflow?!?) # (default cmake workflow hides away the test result into a file, resulting in poor dev workflow?!?)
if(JSONCPP_WITH_POST_BUILD_UNITTEST) IF(JSONCPP_WITH_POST_BUILD_UNITTEST)
add_custom_command(TARGET jsoncpp_test IF(BUILD_SHARED_LIBS)
# First, copy the shared lib, for Microsoft.
# Then, run the test executable.
ADD_CUSTOM_COMMAND( TARGET jsoncpp_test
POST_BUILD POST_BUILD
COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:jsoncpp_test> COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:jsoncpp_lib> $<TARGET_FILE_DIR:jsoncpp_test>
) COMMAND $<TARGET_FILE:jsoncpp_test>)
endif() ELSE(BUILD_SHARED_LIBS)
# Just run the test executable.
ADD_CUSTOM_COMMAND( TARGET jsoncpp_test
POST_BUILD
COMMAND $<TARGET_FILE:jsoncpp_test>)
ENDIF()
ENDIF()
SET_TARGET_PROPERTIES(jsoncpp_test PROPERTIES OUTPUT_NAME jsoncpp_test)

View File

@ -1,54 +0,0 @@
// Copyright 2007-2019 The JsonCpp Authors
// 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
#include "fuzz.h"
#include <cstdint>
#include <json/config.h>
#include <json/json.h>
#include <memory>
#include <string>
namespace Json {
class Exception;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
Json::CharReaderBuilder builder;
if (size < sizeof(uint32_t)) {
return 0;
}
const uint32_t hash_settings = static_cast<uint32_t>(data[0]) |
(static_cast<uint32_t>(data[1]) << 8) |
(static_cast<uint32_t>(data[2]) << 16) |
(static_cast<uint32_t>(data[3]) << 24);
data += sizeof(uint32_t);
size -= sizeof(uint32_t);
builder.settings_["failIfExtra"] = hash_settings & (1 << 0);
builder.settings_["allowComments_"] = hash_settings & (1 << 1);
builder.settings_["strictRoot_"] = hash_settings & (1 << 2);
builder.settings_["allowDroppedNullPlaceholders_"] = hash_settings & (1 << 3);
builder.settings_["allowNumericKeys_"] = hash_settings & (1 << 4);
builder.settings_["allowSingleQuotes_"] = hash_settings & (1 << 5);
builder.settings_["failIfExtra_"] = hash_settings & (1 << 6);
builder.settings_["rejectDupKeys_"] = hash_settings & (1 << 7);
builder.settings_["allowSpecialFloats_"] = hash_settings & (1 << 8);
builder.settings_["collectComments"] = hash_settings & (1 << 9);
builder.settings_["allowTrailingCommas_"] = hash_settings & (1 << 10);
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
Json::Value root;
const auto data_str = reinterpret_cast<const char*>(data);
try {
reader->parse(data_str, data_str + size, &root, nullptr);
} catch (Json::Exception const&) {
}
// Whether it succeeded or not doesn't matter.
return 0;
}

View File

@ -1,54 +0,0 @@
#
# AFL dictionary for JSON
# -----------------------
#
# Just the very basics.
#
# Inspired by a dictionary by Jakub Wilk <jwilk@jwilk.net>
#
# https://github.com/rc0r/afl-fuzz/blob/master/dictionaries/json.dict
#
"0"
",0"
":0"
"0:"
"-1.2e+3"
"true"
"false"
"null"
"\"\""
",\"\""
":\"\""
"\"\":"
"{}"
",{}"
":{}"
"{\"\":0}"
"{{}}"
"[]"
",[]"
":[]"
"[0]"
"[[]]"
"''"
"\\"
"\\b"
"\\f"
"\\n"
"\\r"
"\\t"
"\\u0000"
"\\x00"
"\\0"
"\\uD800\\uDC00"
"\\uDBFF\\uDFFF"
"\"\":0"
"//"
"/**/"

View File

@ -1,14 +0,0 @@
// Copyright 2007-2010 The JsonCpp Authors
// 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
#ifndef FUZZ_H_INCLUDED
#define FUZZ_H_INCLUDED
#include <cstddef>
#include <stdint.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
#endif // ifndef FUZZ_H_INCLUDED

View File

@ -1,11 +1,11 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#define _CRT_SECURE_NO_WARNINGS 1 // Prevents deprecation warning with MSVC #define _CRT_SECURE_NO_WARNINGS 1 // Prevents deprecation warning with MSVC
#include "jsontest.h" #include "jsontest.h"
#include <cstdio> #include <stdio.h>
#include <string> #include <string>
#if defined(_MSC_VER) #if defined(_MSC_VER)
@ -73,27 +73,28 @@ namespace JsonTest {
// class TestResult // class TestResult
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
TestResult::TestResult() { TestResult::TestResult()
: predicateId_(1), lastUsedPredicateId_(0), messageTarget_(0) {
// The root predicate has id 0 // The root predicate has id 0
rootPredicateNode_.id_ = 0; rootPredicateNode_.id_ = 0;
rootPredicateNode_.next_ = nullptr; rootPredicateNode_.next_ = 0;
predicateStackTail_ = &rootPredicateNode_; predicateStackTail_ = &rootPredicateNode_;
} }
void TestResult::setTestName(const Json::String& name) { name_ = name; } void TestResult::setTestName(const JSONCPP_STRING& name) { name_ = name; }
TestResult& TestResult::addFailure(const char* file, unsigned int line, TestResult&
const char* expr) { TestResult::addFailure(const char* file, unsigned int line, const char* expr) {
/// Walks the PredicateContext stack adding them to failures_ if not already /// Walks the PredicateContext stack adding them to failures_ if not already
/// added. /// added.
unsigned int nestingLevel = 0; unsigned int nestingLevel = 0;
PredicateContext* lastNode = rootPredicateNode_.next_; PredicateContext* lastNode = rootPredicateNode_.next_;
for (; lastNode != nullptr; lastNode = lastNode->next_) { for (; lastNode != 0; lastNode = lastNode->next_) {
if (lastNode->id_ > lastUsedPredicateId_) // new PredicateContext if (lastNode->id_ > lastUsedPredicateId_) // new PredicateContext
{ {
lastUsedPredicateId_ = lastNode->id_; lastUsedPredicateId_ = lastNode->id_;
addFailureInfo(lastNode->file_, lastNode->line_, lastNode->expr_, addFailureInfo(
nestingLevel); lastNode->file_, lastNode->line_, lastNode->expr_, nestingLevel);
// Link the PredicateContext to the failure for message target when // Link the PredicateContext to the failure for message target when
// popping the PredicateContext. // popping the PredicateContext.
lastNode->failure_ = &(failures_.back()); lastNode->failure_ = &(failures_.back());
@ -107,8 +108,10 @@ TestResult& TestResult::addFailure(const char* file, unsigned int line,
return *this; return *this;
} }
void TestResult::addFailureInfo(const char* file, unsigned int line, void TestResult::addFailureInfo(const char* file,
const char* expr, unsigned int nestingLevel) { unsigned int line,
const char* expr,
unsigned int nestingLevel) {
Failure failure; Failure failure;
failure.file_ = file; failure.file_ = file;
failure.line_ = line; failure.line_ = line;
@ -121,22 +124,32 @@ void TestResult::addFailureInfo(const char* file, unsigned int line,
TestResult& TestResult::popPredicateContext() { TestResult& TestResult::popPredicateContext() {
PredicateContext* lastNode = &rootPredicateNode_; PredicateContext* lastNode = &rootPredicateNode_;
while (lastNode->next_ != nullptr && lastNode->next_->next_ != nullptr) { while (lastNode->next_ != 0 && lastNode->next_->next_ != 0) {
lastNode = lastNode->next_; lastNode = lastNode->next_;
} }
// Set message target to popped failure // Set message target to popped failure
PredicateContext* tail = lastNode->next_; PredicateContext* tail = lastNode->next_;
if (tail != nullptr && tail->failure_ != nullptr) { if (tail != 0 && tail->failure_ != 0) {
messageTarget_ = tail->failure_; messageTarget_ = tail->failure_;
} }
// Remove tail from list // Remove tail from list
predicateStackTail_ = lastNode; predicateStackTail_ = lastNode;
lastNode->next_ = nullptr; lastNode->next_ = 0;
return *this; return *this;
} }
bool TestResult::failed() const { return !failures_.empty(); } bool TestResult::failed() const { return !failures_.empty(); }
unsigned int TestResult::getAssertionNestingLevel() const {
unsigned int level = 0;
const PredicateContext* lastNode = &rootPredicateNode_;
while (lastNode->next_ != 0) {
lastNode = lastNode->next_;
++level;
}
return level;
}
void TestResult::printFailure(bool printTestName) const { void TestResult::printFailure(bool printTestName) const {
if (failures_.empty()) { if (failures_.empty()) {
return; return;
@ -147,10 +160,12 @@ void TestResult::printFailure(bool printTestName) const {
} }
// Print in reverse to display the callstack in the right order // Print in reverse to display the callstack in the right order
for (const auto& failure : failures_) { Failures::const_iterator itEnd = failures_.end();
Json::String indent(failure.nestingLevel_ * 2, ' '); for (Failures::const_iterator it = failures_.begin(); it != itEnd; ++it) {
const Failure& failure = *it;
JSONCPP_STRING indent(failure.nestingLevel_ * 2, ' ');
if (failure.file_) { if (failure.file_) {
printf("%s%s(%u): ", indent.c_str(), failure.file_, failure.line_); printf("%s%s(%d): ", indent.c_str(), failure.file_, failure.line_);
} }
if (!failure.expr_.empty()) { if (!failure.expr_.empty()) {
printf("%s\n", failure.expr_.c_str()); printf("%s\n", failure.expr_.c_str());
@ -158,19 +173,19 @@ void TestResult::printFailure(bool printTestName) const {
printf("\n"); printf("\n");
} }
if (!failure.message_.empty()) { if (!failure.message_.empty()) {
Json::String reindented = indentText(failure.message_, indent + " "); JSONCPP_STRING reindented = indentText(failure.message_, indent + " ");
printf("%s\n", reindented.c_str()); printf("%s\n", reindented.c_str());
} }
} }
} }
Json::String TestResult::indentText(const Json::String& text, JSONCPP_STRING TestResult::indentText(const JSONCPP_STRING& text,
const Json::String& indent) { const JSONCPP_STRING& indent) {
Json::String reindented; JSONCPP_STRING reindented;
Json::String::size_type lastIndex = 0; JSONCPP_STRING::size_type lastIndex = 0;
while (lastIndex < text.size()) { while (lastIndex < text.size()) {
Json::String::size_type nextIndex = text.find('\n', lastIndex); JSONCPP_STRING::size_type nextIndex = text.find('\n', lastIndex);
if (nextIndex == Json::String::npos) { if (nextIndex == JSONCPP_STRING::npos) {
nextIndex = text.size() - 1; nextIndex = text.size() - 1;
} }
reindented += indent; reindented += indent;
@ -180,8 +195,8 @@ Json::String TestResult::indentText(const Json::String& text,
return reindented; return reindented;
} }
TestResult& TestResult::addToLastFailure(const Json::String& message) { TestResult& TestResult::addToLastFailure(const JSONCPP_STRING& message) {
if (messageTarget_ != nullptr) { if (messageTarget_ != 0) {
messageTarget_->message_ += message; messageTarget_->message_ += message;
} }
return *this; return *this;
@ -202,9 +217,9 @@ TestResult& TestResult::operator<<(bool value) {
// class TestCase // class TestCase
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
TestCase::TestCase() = default; TestCase::TestCase() : result_(0) {}
TestCase::~TestCase() = default; TestCase::~TestCase() {}
void TestCase::run(TestResult& result) { void TestCase::run(TestResult& result) {
result_ = &result; result_ = &result;
@ -214,23 +229,25 @@ void TestCase::run(TestResult& result) {
// class Runner // class Runner
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
Runner::Runner() = default; Runner::Runner() {}
Runner& Runner::add(TestCaseFactory factory) { Runner& Runner::add(TestCaseFactory factory) {
tests_.push_back(factory); tests_.push_back(factory);
return *this; return *this;
} }
size_t Runner::testCount() const { return tests_.size(); } unsigned int Runner::testCount() const {
return static_cast<unsigned int>(tests_.size());
}
Json::String Runner::testNameAt(size_t index) const { JSONCPP_STRING Runner::testNameAt(unsigned int index) const {
TestCase* test = tests_[index](); TestCase* test = tests_[index]();
Json::String name = test->testName(); JSONCPP_STRING name = test->testName();
delete test; delete test;
return name; return name;
} }
void Runner::runTestAt(size_t index, TestResult& result) const { void Runner::runTestAt(unsigned int index, TestResult& result) const {
TestCase* test = tests_[index](); TestCase* test = tests_[index]();
result.setTestName(test->testName()); result.setTestName(test->testName());
printf("Testing %s: ", test->testName()); printf("Testing %s: ", test->testName());
@ -240,7 +257,8 @@ void Runner::runTestAt(size_t index, TestResult& result) const {
#endif // if JSON_USE_EXCEPTION #endif // if JSON_USE_EXCEPTION
test->run(result); test->run(result);
#if JSON_USE_EXCEPTION #if JSON_USE_EXCEPTION
} catch (const std::exception& e) { }
catch (const std::exception& e) {
result.addFailure(__FILE__, __LINE__, "Unexpected exception caught:") result.addFailure(__FILE__, __LINE__, "Unexpected exception caught:")
<< e.what(); << e.what();
} }
@ -252,9 +270,9 @@ void Runner::runTestAt(size_t index, TestResult& result) const {
} }
bool Runner::runAllTest(bool printSummary) const { bool Runner::runAllTest(bool printSummary) const {
size_t const count = testCount(); unsigned int count = testCount();
std::deque<TestResult> failures; std::deque<TestResult> failures;
for (size_t index = 0; index < count; ++index) { for (unsigned int index = 0; index < count; ++index) {
TestResult result; TestResult result;
runTestAt(index, result); runTestAt(index, result);
if (result.failed()) { if (result.failed()) {
@ -264,26 +282,31 @@ bool Runner::runAllTest(bool printSummary) const {
if (failures.empty()) { if (failures.empty()) {
if (printSummary) { if (printSummary) {
printf("All %zu tests passed\n", count); printf("All %d tests passed\n", count);
} }
return true; return true;
} } else {
for (auto& result : failures) { for (unsigned int index = 0; index < failures.size(); ++index) {
TestResult& result = failures[index];
result.printFailure(count > 1); result.printFailure(count > 1);
} }
if (printSummary) { if (printSummary) {
size_t const failedCount = failures.size(); unsigned int failedCount = static_cast<unsigned int>(failures.size());
size_t const passedCount = count - failedCount; unsigned int passedCount = count - failedCount;
printf("%zu/%zu tests passed (%zu failure(s))\n", passedCount, count, printf("%d/%d tests passed (%d failure(s))\n",
passedCount,
count,
failedCount); failedCount);
} }
return false; return false;
}
} }
bool Runner::testIndex(const Json::String& testName, size_t& indexOut) const { bool Runner::testIndex(const JSONCPP_STRING& testName,
const size_t count = testCount(); unsigned int& indexOut) const {
for (size_t index = 0; index < count; ++index) { unsigned int count = testCount();
for (unsigned int index = 0; index < count; ++index) {
if (testNameAt(index) == testName) { if (testNameAt(index) == testName) {
indexOut = index; indexOut = index;
return true; return true;
@ -293,27 +316,26 @@ bool Runner::testIndex(const Json::String& testName, size_t& indexOut) const {
} }
void Runner::listTests() const { void Runner::listTests() const {
const size_t count = testCount(); unsigned int count = testCount();
for (size_t index = 0; index < count; ++index) { for (unsigned int index = 0; index < count; ++index) {
printf("%s\n", testNameAt(index).c_str()); printf("%s\n", testNameAt(index).c_str());
} }
} }
int Runner::runCommandLine(int argc, const char* argv[]) const { int Runner::runCommandLine(int argc, const char* argv[]) const {
// typedef std::deque<String> TestNames; // typedef std::deque<JSONCPP_STRING> TestNames;
Runner subrunner; Runner subrunner;
for (int index = 1; index < argc; ++index) { for (int index = 1; index < argc; ++index) {
Json::String opt = argv[index]; JSONCPP_STRING opt = argv[index];
if (opt == "--list-tests") { if (opt == "--list-tests") {
listTests(); listTests();
return 0; return 0;
} } else if (opt == "--test-auto") {
if (opt == "--test-auto") {
preventDialogOnCrash(); preventDialogOnCrash();
} else if (opt == "--test") { } else if (opt == "--test") {
++index; ++index;
if (index < argc) { if (index < argc) {
size_t testNameIndex; unsigned int testNameIndex;
if (testIndex(argv[index], testNameIndex)) { if (testIndex(argv[index], testNameIndex)) {
subrunner.add(tests_[testNameIndex]); subrunner.add(tests_[testNameIndex]);
} else { } else {
@ -340,8 +362,8 @@ int Runner::runCommandLine(int argc, const char* argv[]) const {
#if defined(_MSC_VER) && defined(_DEBUG) #if defined(_MSC_VER) && defined(_DEBUG)
// Hook MSVCRT assertions to prevent dialog from appearing // Hook MSVCRT assertions to prevent dialog from appearing
static int msvcrtSilentReportHook(int reportType, char* message, static int
int* /*returnValue*/) { msvcrtSilentReportHook(int reportType, char* message, int* /*returnValue*/) {
// The default CRT handling of error and assertion is to display // The default CRT handling of error and assertion is to display
// an error dialog to the user. // an error dialog to the user.
// Instead, when an error or an assertion occurs, we force the // Instead, when an error or an assertion occurs, we force the
@ -376,8 +398,8 @@ void Runner::preventDialogOnCrash() {
_CrtSetReportHook(&msvcrtSilentReportHook); _CrtSetReportHook(&msvcrtSilentReportHook);
#endif // if defined(_MSC_VER) #endif // if defined(_MSC_VER)
// @todo investigate this handler (for buffer overflow) // @todo investiguate this handler (for buffer overflow)
// _set_security_error_handler // _set_security_error_handler
#if defined(_WIN32) #if defined(_WIN32)
// Prevents the system from popping a dialog for debugging if the // Prevents the system from popping a dialog for debugging if the
@ -404,21 +426,26 @@ void Runner::printUsage(const char* appName) {
// Assertion functions // Assertion functions
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
Json::String ToJsonString(const char* toConvert) { JSONCPP_STRING ToJsonString(const char* toConvert) {
return Json::String(toConvert); return JSONCPP_STRING(toConvert);
} }
Json::String ToJsonString(Json::String in) { return in; } JSONCPP_STRING ToJsonString(JSONCPP_STRING in) {
return in;
}
#if JSONCPP_USE_SECURE_MEMORY #if JSONCPP_USING_SECURE_MEMORY
Json::String ToJsonString(std::string in) { JSONCPP_STRING ToJsonString(std::string in) {
return Json::String(in.data(), in.data() + in.length()); return JSONCPP_STRING(in.data(), in.data() + in.length());
} }
#endif #endif
TestResult& checkStringEqual(TestResult& result, const Json::String& expected, TestResult& checkStringEqual(TestResult& result,
const Json::String& actual, const char* file, const JSONCPP_STRING& expected,
unsigned int line, const char* expr) { const JSONCPP_STRING& actual,
const char* file,
unsigned int line,
const char* expr) {
if (expected != actual) { if (expected != actual) {
result.addFailure(file, line, expr); result.addFailure(file, line, expr);
result << "Expected: '" << expected << "'\n"; result << "Expected: '" << expected << "'\n";

View File

@ -1,4 +1,4 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and // Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction. // recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@ -6,12 +6,11 @@
#ifndef JSONTEST_H_INCLUDED #ifndef JSONTEST_H_INCLUDED
#define JSONTEST_H_INCLUDED #define JSONTEST_H_INCLUDED
#include <cstdio>
#include <deque>
#include <iomanip>
#include <json/config.h> #include <json/config.h>
#include <json/value.h> #include <json/value.h>
#include <json/writer.h> #include <json/writer.h>
#include <stdio.h>
#include <deque>
#include <sstream> #include <sstream>
#include <string> #include <string>
@ -33,8 +32,8 @@ class Failure {
public: public:
const char* file_; const char* file_;
unsigned int line_; unsigned int line_;
Json::String expr_; JSONCPP_STRING expr_;
Json::String message_; JSONCPP_STRING message_;
unsigned int nestingLevel_; unsigned int nestingLevel_;
}; };
@ -42,7 +41,7 @@ public:
/// Must be a POD to allow inline initialisation without stepping /// Must be a POD to allow inline initialisation without stepping
/// into the debugger. /// into the debugger.
struct PredicateContext { struct PredicateContext {
using Id = unsigned int; typedef unsigned int Id;
Id id_; Id id_;
const char* file_; const char* file_;
unsigned int line_; unsigned int line_;
@ -61,20 +60,20 @@ public:
/// Not encapsulated to prevent step into when debugging failed assertions /// Not encapsulated to prevent step into when debugging failed assertions
/// Incremented by one on assertion predicate entry, decreased by one /// Incremented by one on assertion predicate entry, decreased by one
/// by addPredicateContext(). /// by addPredicateContext().
PredicateContext::Id predicateId_{1}; PredicateContext::Id predicateId_;
/// \internal Implementation detail for predicate macros /// \internal Implementation detail for predicate macros
PredicateContext* predicateStackTail_; PredicateContext* predicateStackTail_;
void setTestName(const Json::String& name); void setTestName(const JSONCPP_STRING& name);
/// Adds an assertion failure. /// Adds an assertion failure.
TestResult& addFailure(const char* file, unsigned int line, TestResult&
const char* expr = nullptr); addFailure(const char* file, unsigned int line, const char* expr = 0);
/// Removes the last PredicateContext added to the predicate stack /// Removes the last PredicateContext added to the predicate stack
/// chained list. /// chained list.
/// Next messages will be targeted at the PredicateContext that was removed. /// Next messages will be targed at the PredicateContext that was removed.
TestResult& popPredicateContext(); TestResult& popPredicateContext();
bool failed() const; bool failed() const;
@ -83,8 +82,10 @@ public:
// Generic operator that will work with anything ostream can deal with. // Generic operator that will work with anything ostream can deal with.
template <typename T> TestResult& operator<<(const T& value) { template <typename T> TestResult& operator<<(const T& value) {
Json::OStringStream oss; JSONCPP_OSTRINGSTREAM oss;
oss << std::setprecision(16) << std::hexfloat << value; oss.precision(16);
oss.setf(std::ios_base::floatfield);
oss << value;
return addToLastFailure(oss.str()); return addToLastFailure(oss.str());
} }
@ -95,20 +96,23 @@ public:
TestResult& operator<<(Json::UInt64 value); TestResult& operator<<(Json::UInt64 value);
private: private:
TestResult& addToLastFailure(const Json::String& message); TestResult& addToLastFailure(const JSONCPP_STRING& message);
unsigned int getAssertionNestingLevel() const;
/// Adds a failure or a predicate context /// Adds a failure or a predicate context
void addFailureInfo(const char* file, unsigned int line, const char* expr, void addFailureInfo(const char* file,
unsigned int line,
const char* expr,
unsigned int nestingLevel); unsigned int nestingLevel);
static Json::String indentText(const Json::String& text, static JSONCPP_STRING indentText(const JSONCPP_STRING& text,
const Json::String& indent); const JSONCPP_STRING& indent);
using Failures = std::deque<Failure>; typedef std::deque<Failure> Failures;
Failures failures_; Failures failures_;
Json::String name_; JSONCPP_STRING name_;
PredicateContext rootPredicateNode_; PredicateContext rootPredicateNode_;
PredicateContext::Id lastUsedPredicateId_{0}; PredicateContext::Id lastUsedPredicateId_;
/// Failure which is the target of the messages added using operator << /// Failure which is the target of the messages added using operator <<
Failure* messageTarget_{nullptr}; Failure* messageTarget_;
}; };
class TestCase { class TestCase {
@ -122,14 +126,14 @@ public:
virtual const char* testName() const = 0; virtual const char* testName() const = 0;
protected: protected:
TestResult* result_{nullptr}; TestResult* result_;
private: private:
virtual void runTestCase() = 0; virtual void runTestCase() = 0;
}; };
/// Function pointer type for TestCase factory /// Function pointer type for TestCase factory
using TestCaseFactory = TestCase* (*)(); typedef TestCase* (*TestCaseFactory)();
class Runner { class Runner {
public: public:
@ -148,33 +152,37 @@ public:
bool runAllTest(bool printSummary) const; bool runAllTest(bool printSummary) const;
/// Returns the number of test case in the suite /// Returns the number of test case in the suite
size_t testCount() const; unsigned int testCount() const;
/// Returns the name of the test case at the specified index /// Returns the name of the test case at the specified index
Json::String testNameAt(size_t index) const; JSONCPP_STRING testNameAt(unsigned int index) const;
/// Runs the test case at the specified index using the specified TestResult /// Runs the test case at the specified index using the specified TestResult
void runTestAt(size_t index, TestResult& result) const; void runTestAt(unsigned int index, TestResult& result) const;
static void printUsage(const char* appName); static void printUsage(const char* appName);
private: // prevents copy construction and assignment private: // prevents copy construction and assignment
Runner(const Runner& other) = delete; Runner(const Runner& other);
Runner& operator=(const Runner& other) = delete; Runner& operator=(const Runner& other);
private: private:
void listTests() const; void listTests() const;
bool testIndex(const Json::String& testName, size_t& indexOut) const; bool testIndex(const JSONCPP_STRING& testName, unsigned int& index) const;
static void preventDialogOnCrash(); static void preventDialogOnCrash();
private: private:
using Factories = std::deque<TestCaseFactory>; typedef std::deque<TestCaseFactory> Factories;
Factories tests_; Factories tests_;
}; };
template <typename T, typename U> template <typename T, typename U>
TestResult& checkEqual(TestResult& result, T expected, U actual, TestResult& checkEqual(TestResult& result,
const char* file, unsigned int line, const char* expr) { T expected,
U actual,
const char* file,
unsigned int line,
const char* expr) {
if (static_cast<U>(expected) != actual) { if (static_cast<U>(expected) != actual) {
result.addFailure(file, line, expr); result.addFailure(file, line, expr);
result << "Expected: " << static_cast<U>(expected) << "\n"; result << "Expected: " << static_cast<U>(expected) << "\n";
@ -183,15 +191,18 @@ TestResult& checkEqual(TestResult& result, T expected, U actual,
return result; return result;
} }
Json::String ToJsonString(const char* toConvert); JSONCPP_STRING ToJsonString(const char* toConvert);
Json::String ToJsonString(Json::String in); JSONCPP_STRING ToJsonString(JSONCPP_STRING in);
#if JSONCPP_USE_SECURE_MEMORY #if JSONCPP_USING_SECURE_MEMORY
Json::String ToJsonString(std::string in); JSONCPP_STRING ToJsonString(std::string in);
#endif #endif
TestResult& checkStringEqual(TestResult& result, const Json::String& expected, TestResult& checkStringEqual(TestResult& result,
const Json::String& actual, const char* file, const JSONCPP_STRING& expected,
unsigned int line, const char* expr); const JSONCPP_STRING& actual,
const char* file,
unsigned int line,
const char* expr);
} // namespace JsonTest } // namespace JsonTest
@ -207,40 +218,49 @@ TestResult& checkStringEqual(TestResult& result, const Json::String& expected,
/// The predicate may do other assertions and be a member function of the /// The predicate may do other assertions and be a member function of the
/// fixture. /// fixture.
#define JSONTEST_ASSERT_PRED(expr) \ #define JSONTEST_ASSERT_PRED(expr) \
do { \ { \
JsonTest::PredicateContext _minitest_Context = { \ JsonTest::PredicateContext _minitest_Context = { \
result_->predicateId_, __FILE__, __LINE__, #expr, NULL, NULL}; \ result_->predicateId_, __FILE__, __LINE__, #expr, NULL, NULL \
}; \
result_->predicateStackTail_->next_ = &_minitest_Context; \ result_->predicateStackTail_->next_ = &_minitest_Context; \
result_->predicateId_ += 1; \ result_->predicateId_ += 1; \
result_->predicateStackTail_ = &_minitest_Context; \ result_->predicateStackTail_ = &_minitest_Context; \
(expr); \ (expr); \
result_->popPredicateContext(); \ result_->popPredicateContext(); \
} while (0) }
/// \brief Asserts that two values are equals. /// \brief Asserts that two values are equals.
#define JSONTEST_ASSERT_EQUAL(expected, actual) \ #define JSONTEST_ASSERT_EQUAL(expected, actual) \
JsonTest::checkEqual(*result_, expected, actual, __FILE__, __LINE__, \ JsonTest::checkEqual(*result_, \
expected, \
actual, \
__FILE__, \
__LINE__, \
#expected " == " #actual) #expected " == " #actual)
/// \brief Asserts that two values are equals. /// \brief Asserts that two values are equals.
#define JSONTEST_ASSERT_STRING_EQUAL(expected, actual) \ #define JSONTEST_ASSERT_STRING_EQUAL(expected, actual) \
JsonTest::checkStringEqual(*result_, JsonTest::ToJsonString(expected), \ JsonTest::checkStringEqual(*result_, \
JsonTest::ToJsonString(actual), __FILE__, \ JsonTest::ToJsonString(expected), \
__LINE__, #expected " == " #actual) JsonTest::ToJsonString(actual), \
__FILE__, \
__LINE__, \
#expected " == " #actual)
/// \brief Asserts that a given expression throws an exception /// \brief Asserts that a given expression throws an exception
#define JSONTEST_ASSERT_THROWS(expr) \ #define JSONTEST_ASSERT_THROWS(expr) \
do { \ { \
bool _threw = false; \ bool _threw = false; \
try { \ try { \
expr; \ expr; \
} catch (...) { \ } \
catch (...) { \
_threw = true; \ _threw = true; \
} \ } \
if (!_threw) \ if (!_threw) \
result_->addFailure(__FILE__, __LINE__, \ result_->addFailure( \
"expected exception thrown: " #expr); \ __FILE__, __LINE__, "expected exception thrown: " #expr); \
} while (0) }
/// \brief Begin a fixture test case. /// \brief Begin a fixture test case.
#define JSONTEST_FIXTURE(FixtureType, name) \ #define JSONTEST_FIXTURE(FixtureType, name) \
@ -250,9 +270,9 @@ TestResult& checkStringEqual(TestResult& result, const Json::String& expected,
return new Test##FixtureType##name(); \ return new Test##FixtureType##name(); \
} \ } \
\ \
public: /* overridden from TestCase */ \ public: /* overidden from TestCase */ \
const char* testName() const override { return #FixtureType "/" #name; } \ const char* testName() const JSONCPP_OVERRIDE { return #FixtureType "/" #name; } \
void runTestCase() override; \ void runTestCase() JSONCPP_OVERRIDE; \
}; \ }; \
\ \
void Test##FixtureType##name::runTestCase() void Test##FixtureType##name::runTestCase()
@ -263,26 +283,4 @@ TestResult& checkStringEqual(TestResult& result, const Json::String& expected,
#define JSONTEST_REGISTER_FIXTURE(runner, FixtureType, name) \ #define JSONTEST_REGISTER_FIXTURE(runner, FixtureType, name) \
(runner).add(JSONTEST_FIXTURE_FACTORY(FixtureType, name)) (runner).add(JSONTEST_FIXTURE_FACTORY(FixtureType, name))
/// \brief Begin a fixture test case.
#define JSONTEST_FIXTURE_V2(FixtureType, name, collections) \
class Test##FixtureType##name : public FixtureType { \
public: \
static JsonTest::TestCase* factory() { \
return new Test##FixtureType##name(); \
} \
static bool collect() { \
(collections).push_back(JSONTEST_FIXTURE_FACTORY(FixtureType, name)); \
return true; \
} \
\
public: /* overridden from TestCase */ \
const char* testName() const override { return #FixtureType "/" #name; } \
void runTestCase() override; \
}; \
\
static bool test##FixtureType##name##collect = \
Test##FixtureType##name::collect(); \
\
void Test##FixtureType##name::runTestCase()
#endif // ifndef JSONTEST_H_INCLUDED #endif // ifndef JSONTEST_H_INCLUDED

Some files were not shown because too many files have changed in this diff Show More