This commit is contained in:
Cristian Le 2023-05-10 11:48:05 +00:00 committed by GitHub
commit 449bd7f784
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 1680 additions and 1825 deletions

View File

@ -1,17 +1,66 @@
--- # Generated from CLion C/C++ Code Style settings
BasedOnStyle: LLVM BasedOnStyle: LLVM
AccessModifierOffset: -2
#AlignConsecutiveAssignments: true
#AlignConsecutiveDeclarations: true
AllowShortFunctionsOnASingleLine: Inline
BreakBeforeBraces: Linux
ColumnLimit: 0
ConstructorInitializerAllOnOneLineOrOnePerLine: true
IndentWidth: 4
IndentPPDirectives: AfterHash
ObjCBlockIndentWidth: 0
SpaceAfterCStyleCast: true
TabWidth: 4
AccessModifierOffset: -4 AccessModifierOffset: -4
UseTab: ForIndentation AlignAfterOpenBracket: Align
... AlignConsecutiveAssignments: None
AlignOperands: Align
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ColumnLimit: 0
CompactNamespaces: false
ContinuationIndentWidth: 8
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Left
ReflowComments: false
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: ForIndentation

View File

@ -1,83 +0,0 @@
name: Ubuntu
on:
push:
branches:
- develop
- master
- release/*
- main
pull_request:
jobs:
build_and_test:
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.4.0
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub."
- run: echo "🔎 Branch name is ${{ github.ref }} and repository is ${{ github.repository }}."
- name: Clone nlohmann json
uses: actions/checkout@master
with:
repository: nlohmann/json
path: nlohmann-json
ref: v3.11.2
- name: Build and install nlohmann json
run: |
cd nlohmann-json
cmake -S . -B build
cmake --build build --target install -j$(nproc)
cd ..
- name: Clone json-schema-validator
uses: actions/checkout@v2
- name: cmake
run: cmake -S . -B build
- name: build
run: cmake --build build --target all -j$(nproc)
- name: test
run: cd build && ctest
build_and_test_min_version:
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.4.0
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub."
- run: echo "🔎 Branch name is ${{ github.ref }} and repository is ${{ github.repository }}."
- name: Clone nlohmann json
uses: actions/checkout@master
with:
repository: nlohmann/json
path: nlohmann-json
ref: v3.8.0
- name: Build and install nlohmann json
run: |
cd nlohmann-json
cmake -S . -B build
cmake --build build --target install -j$(nproc)
cd ..
- name: Clone json-schema-validator
uses: actions/checkout@v2
- name: cmake
run: cmake -S . -B build
- name: build
run: cmake --build build --target all -j$(nproc)
- name: test
run: cd build && ctest
build_conan:
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.4.0
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub."
- run: echo "🔎 Branch name is ${{ github.ref }} and repository is ${{ github.repository }}."
- name: Clone json-schema-validator
uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- run: python -m pip install --upgrade conan
- run: conan config init
- run: conan profile update settings.compiler.libcxx=libstdc++11 default
- name: conan create package
run: conan create .

31
.github/workflows/release.yaml vendored Normal file
View File

@ -0,0 +1,31 @@
name: release
run-name: Release
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
- "v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+"
jobs:
tests:
uses: ./.github/workflows/test.yaml
secrets: inherit
build_conan:
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.4.0
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub."
- run: echo "🔎 Branch name is ${{ github.ref }} and repository is ${{ github.repository }}."
- name: Clone json-schema-validator
uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- run: python -m pip install --upgrade conan
- run: conan config init
- run: conan profile update settings.compiler.libcxx=libstdc++11 default
- name: conan create package
run: conan create .

61
.github/workflows/test.yaml vendored Normal file
View File

@ -0,0 +1,61 @@
name: test
run-name: Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
# Make it able to be used in other workflows
workflow_call:
jobs:
pre-commit:
name: Check pre-commit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: pre-commit/action@v3.0.0
test:
name: Run ctests
needs: [ pre-commit ]
strategy:
matrix:
toolchain: [ gcc, llvm, intel ]
json_version: [ v3.11.2, v3.8.0 ]
env:
NLOHMANN_JSON_VERSION: ${{ matrix.json_version }}
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.4.0
steps:
- name: Clone json-schema-validator
uses: actions/checkout@v3
- name: Run CMake ${{ matrix.toolchain }}-ci workflow with nlohmann/json version ${{ matrix.json_version }}
uses: lukka/run-cmake@v10.5
with:
workflowPreset: "${{ matrix.toolchain }}-ci"
coverage:
name: Run coverage tests
needs: [ test ]
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.4.0
if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }}
steps:
- uses: actions/checkout@v3
- name: Get test coverage
uses: lukka/run-cmake@v10.5
with:
workflowPreset: ci-coverage
- name: Get lcov data
uses: danielealbano/lcov-action@v3
with:
# Note lcov-action prepends and appends wild-cards *. Account for those
# https://github.com/danielealbano/lcov-action/issues/11
remove_patterns: /test/,/cmake-build*/
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
files: coverage.info
verbose: true

5
.gitignore vendored
View File

@ -1,3 +1,6 @@
build*/ build*/
*.sw? *.sw?
cmake-build-*
venv
env
compile_commands.json

32
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,32 @@
repos:
- repo: https://github.com/Takishima/cmake-pre-commit-hooks
rev: v1.8.1
hooks:
- id: clang-format
args:
- '-i'
- id: clang-tidy
args:
# TODO: Remove when upstream issue is fixed
# https://gitlab.kitware.com/cmake/cmake/-/issues/24827
# https://github.com/Takishima/cmake-pre-commit-hooks/issues/63
- '-Bcmake-build-pre-commit'
- '--preset'
- 'pre-commit'
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- repo: https://github.com/executablebooks/mdformat
rev: 0.7.16
hooks:
- id: mdformat
additional_dependencies:
- mdformat-gfm
- mdformat-tables
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.23.0
hooks:
- id: check-github-workflows

View File

@ -1,78 +0,0 @@
#########################
# project configuration #
#########################
# C++ project
language: cpp
dist: trusty
sudo: required
group: edge
matrix:
include:
- os: linux
compiler: gcc
env: COMPILER=g++-4.9
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.9', 'ninja-build']
- os: linux
compiler: gcc
env: COMPILER=g++-5
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5', 'ninja-build']
- os: linux
compiler: gcc
env: COMPILER=g++-6
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6', 'ninja-build']
- os: linux
compiler: gcc
env: COMPILER=g++-7
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-7', 'ninja-build']
script:
# get CMake and Ninja (only for systems with brew - macOS)
- |
if [[ (-x $(which brew)) ]]; then
brew update
brew install cmake ninja
brew upgrade cmake
fi
# make sure CXX is correctly set
- if [[ "${COMPILER}" != "" ]]; then export CXX=${COMPILER}; fi
# show OS/compiler version
- uname -a
- cmake --version
- $CXX --version
# put json.hpp to nlohmann
- mkdir -p nlohmann && wget https://github.com/nlohmann/json/releases/download/v3.8.0/json.hpp -O nlohmann/json.hpp
# compile and execute unit tests
- mkdir -p build && cd build
- cmake .. -Dnlohmann_json_DIR=.. ${CMAKE_OPTIONS} -GNinja && cmake --build . --config Release
- ctest -C Release -V -j
- cd ..
# Remove previous build and tests
- rm -r build
# Compile and execute with Hunter package manager instead of using local json.hpp
- mkdir -p build && cd build
- cmake .. -DHUNTER_ENABLED=ON ${CMAKE_OPTIONS} -GNinja && cmake --build . --config Release
- ctest -C Release -V -j
- cd ..

View File

@ -1,157 +1,214 @@
cmake_minimum_required(VERSION 3.2) cmake_minimum_required(VERSION 3.14)
# CMake version compatibility
# TODO: Remove when bumping cmake >= 3.25
if (POLICY CMP0140)
# Enables: return(PROPAGATE)
cmake_policy(SET CMP0140 NEW)
endif ()
option(JSON_VALIDATOR_INSTALL "Install target" ON) #[==============================================================================================[
option(JSON_VALIDATOR_HUNTER "Enable Hunter package manager support" OFF) # Basic project definition #
]==============================================================================================]
if(JSON_VALIDATOR_HUNTER) # TODO: Version 3, rename the project and namespace to something more compact
include("cmake/HunterGate.cmake")
HunterGate(
URL "https://github.com/cpp-pm/hunter/archive/v0.23.262.tar.gz"
SHA1 "eb51e633e08cdbe2153caf255e9c23968fecb29d"
)
endif()
# the project
project(nlohmann_json_schema_validator project(nlohmann_json_schema_validator
VERSION 2.2.0
DESCRIPTION "Json validator for nlohmann::json library"
HOMEPAGE_URL "https://github.com/pboettch/json-schema-validator"
LANGUAGES CXX) LANGUAGES CXX)
# TODO: Remove when bumping cmake >= 3.21
if (NOT DEFINED nlohmann_json_schema_validator_IS_TOP_LEVEL)
if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(PROJECT_IS_TOP_LEVEL ON)
else ()
set(PROJECT_IS_TOP_LEVEL OFF)
endif ()
endif ()
set(PROJECT_VERSION 2.2.0) #[==============================================================================================[
# Options #
]==============================================================================================]
if(JSON_VALIDATOR_HUNTER) option(JSON_VALIDATOR_INSTALL "JsonValidator: Install targets" ${PROJECT_IS_TOP_LEVEL})
hunter_add_package(nlohmann_json) option(JSON_VALIDATOR_BUILD_TESTS "JsonValidator: Build tests" ${PROJECT_IS_TOP_LEVEL})
endif() option(JSON_VALIDATOR_BUILD_EXAMPLES "JsonValidator: Build examples" ${PROJECT_IS_TOP_LEVEL})
option(JSON_VALIDATOR_SHARED_LIBS "JsonValidator: Build as shared library" ${PROJECT_IS_TOP_LEVEL})
option(JSON_VALIDATOR_TEST_COVERAGE "JsonValidator: Build with test coverage" OFF)
mark_as_advanced(JSON_VALIDATOR_TEST_COVERAGE)
# Get a default JSON_FETCH_VERSION from environment variables to workaround the CI
if (DEFINED ENV{NLOHMANN_JSON_VERSION})
set(JSON_FETCH_VERSION_DEFAULT $ENV{NLOHMANN_JSON_VERSION})
else ()
set(JSON_FETCH_VERSION_DEFAULT v3.11.2)
endif ()
set(JSON_FETCH_VERSION ${JSON_FETCH_VERSION_DEFAULT} CACHE STRING "Fetch nlohmann::json version")
# the library #[==============================================================================================[
add_library(nlohmann_json_schema_validator # Project configuration #
src/smtp-address-validator.cpp ]==============================================================================================]
src/json-schema-draft7.json.cpp
src/json-uri.cpp
src/json-validator.cpp
src/json-patch.cpp
src/string-format-check.cpp)
target_include_directories(nlohmann_json_schema_validator # Include cmake modules
PUBLIC include(FetchContent)
$<INSTALL_INTERFACE:include> if (JSON_VALIDATOR_INSTALL)
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>) include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
endif ()
target_compile_features(nlohmann_json_schema_validator # Default to release build
PUBLIC if (NOT CMAKE_BUILD_TYPE)
cxx_range_for) # for C++11 - flags set(CMAKE_BUILD_TYPE Release)
endif ()
set_target_properties(nlohmann_json_schema_validator # Enable cmake's BUILD_SHARED_LIBS
PROPERTIES set(BUILD_SHARED_LIBS ${nlohmann_json_schema_validator_SHARED_LIBS})
VERSION ${PROJECT_VERSION}
SOVERSION 2)
# disable tests and examples if project is not super project if (JSON_VALIDATOR_TEST_COVERAGE)
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) if (CMAKE_CXX_COMPILER_ID STREQUAL Clang)
# I am top-level project. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
set(JSON_VALIDATOR_IS_TOP_LEVEL ON) elseif (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
else ()
message(WARNING
"JsonValidator: Other toolchain coverage flags unknown.\n"
"Using --coverage as default")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
endif ()
endif ()
option(JSON_VALIDATOR_BUILD_TESTS "Build tests" ${JSON_VALIDATOR_IS_TOP_LEVEL}) #[==============================================================================================[
option(JSON_VALIDATOR_BUILD_EXAMPLES "Build examples" ${JSON_VALIDATOR_IS_TOP_LEVEL}) # External packages #
]==============================================================================================]
if(NOT TARGET nlohmann_json::nlohmann_json) set(fetch_packages "")
find_package(nlohmann_json REQUIRED) # Fetch/Find nlohmann_json
endif() # TODO: Remove when bumping cmake >= 3.24
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
FetchContent_Declare(nlohmann_json
GIT_REPOSITORY https://github.com/nlohmann/json
GIT_TAG ${JSON_FETCH_VERSION}
FIND_PACKAGE_ARGS
)
list(APPEND fetch_packages nlohmann_json)
else ()
# Try to get system installed version
find_package(nlohmann_json QUIET)
if (NOT nlohmann_json_FOUND)
# If failed fetch the desired version
FetchContent_Declare(nlohmann_json
GIT_REPOSITORY https://github.com/nlohmann/json
GIT_TAG ${JSON_FETCH_VERSION}
)
list(APPEND fetch_packages nlohmann_json)
endif ()
endif ()
target_link_libraries( # Handle configure flags
nlohmann_json_schema_validator if (JSON_VALIDATOR_INSTALL)
PUBLIC nlohmann_json::nlohmann_json) # TODO: This is not ideal, this package should not be installing nlohmann::json
# Currently required in order to satisfy cmake exporter
set(JSON_Install ON CACHE BOOL "")
endif ()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR # Get all dependencies
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") FetchContent_MakeAvailable(${fetch_packages})
target_compile_options(nlohmann_json_schema_validator if (JSON_VALIDATOR_INSTALL AND NOT nlohmann_json_FOUND AND JSON_Install)
PRIVATE # TODO: This is not ideal
-Wall -Wextra -Wshadow) message(WARNING
endif() "JsonValidator: No nlohmann::json found on the system and nlohmann_json_schema_validator will be installed\n"
"This will also install nlohmann::json in its typical installation path\n"
"This is not ideal because it might overwrite system installed")
endif ()
if(BUILD_SHARED_LIBS) #[==============================================================================================[
target_compile_definitions(nlohmann_json_schema_validator # Main definition #
PRIVATE ]==============================================================================================]
-DJSON_SCHEMA_VALIDATOR_EXPORTS)
endif()
# regex with boost if gcc < 4.9 - default is std::regex message(STATUS "JsonValidator: Configured for ${CMAKE_BUILD_TYPE}")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if (DEFINED nlohmann_json_VERSION)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9.0") message(STATUS "JsonValidator: Using nlohmann/json version: ${nlohmann_json_VERSION}")
find_package(Boost COMPONENTS regex) else ()
if(NOT Boost_FOUND) message(STATUS "JsonValidator: nlohmann_json_VERSION is not set. Possible value: ${JSON_FETCH_VERSION}")
message(STATUS "GCC less then 4.9 and boost-regex NOT found - no regex used") endif ()
target_compile_definitions(nlohmann_json_schema_validator PRIVATE -DJSON_SCHEMA_NO_REGEX)
else()
message(STATUS "GCC less then 4.9 and boost-regex FOUND - using boost::regex")
target_compile_definitions(nlohmann_json_schema_validator PRIVATE -DJSON_SCHEMA_BOOST_REGEX)
target_include_directories(nlohmann_json_schema_validator PRIVATE ${Boost_INCLUDE_DIRS})
target_link_libraries(nlohmann_json_schema_validator PRIVATE ${Boost_LIBRARIES})
endif()
endif()
endif()
if(JSON_VALIDATOR_INSTALL) ## Main targets
install(TARGETS nlohmann_json_schema_validator add_library(nlohmann_json_schema_validator)
EXPORT ${PROJECT_NAME}Targets add_library(nlohmann_json_schema_validator::validator ALIAS nlohmann_json_schema_validator)
LIBRARY DESTINATION lib set_target_properties(nlohmann_json_schema_validator PROPERTIES
ARCHIVE DESTINATION lib VERSION ${PROJECT_VERSION}
RUNTIME DESTINATION bin) SOVERSION ${PROJECT_VERSION_MAJOR}
EXPORT_NAME validator
OUTPUT_NAME nlohmann_json_validator
)
install(FILES src/nlohmann/json-schema.hpp # Main definitions in here
DESTINATION include/nlohmann) add_subdirectory(src)
endif()
if (JSON_VALIDATOR_BUILD_EXAMPLES) # Enable examples
# simple nlohmann_json_schema_validator-executable
add_executable(json-schema-validate app/json-schema-validate.cpp)
target_link_libraries(json-schema-validate nlohmann_json_schema_validator)
add_executable(readme-json-schema app/readme.cpp)
target_link_libraries(readme-json-schema nlohmann_json_schema_validator)
add_executable(format-json-schema app/format.cpp)
target_link_libraries(format-json-schema nlohmann_json_schema_validator)
install(TARGETS json-schema-validate readme-json-schema
DESTINATION bin)
endif()
# Enable testings
if (JSON_VALIDATOR_BUILD_TESTS) if (JSON_VALIDATOR_BUILD_TESTS)
# test-zone
enable_testing() enable_testing()
add_subdirectory(test) add_subdirectory(test)
endif() endif ()
# Set Up the Project Targets and Config Files for CMake if (JSON_VALIDATOR_BUILD_EXAMPLES)
add_subdirectory(example)
endif ()
if(JSON_VALIDATOR_INSTALL)
# Set the install path to the cmake config files (Relative, so install works correctly under Hunter as well)
set(INSTALL_CMAKE_DIR "lib/cmake/${PROJECT_NAME}")
set(INSTALL_CMAKEDIR_ROOT share/cmake)
# Install Targets #[==============================================================================================[
install(EXPORT ${PROJECT_NAME}Targets # Install or Export #
FILE ${PROJECT_NAME}Targets.cmake ]==============================================================================================]
DESTINATION "${INSTALL_CMAKE_DIR}")
include(CMakePackageConfigHelpers) if (JSON_VALIDATOR_INSTALL)
write_basic_package_version_file( # Note other install targets found in subdirectories
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake # Here mostly the cmake boilerplate are set
VERSION ${PROJECT_VERSION} write_basic_package_version_file(nlohmann_json_schema_validatorConfigVersion.cmake
COMPATIBILITY SameMajorVersion VERSION ${PROJECT_VERSION}
) COMPATIBILITY SameMajorVersion
)
configure_package_config_file(cmake/nlohmann_json_schema_validatorConfig.cmake.in
nlohmann_json_schema_validatorConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/nlohmann_json_schema_validator
)
configure_package_config_file( # Install Targets files
${PROJECT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in export(EXPORT nlohmann_json_schema_validatorTargets
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake NAMESPACE nlohmann_json_schema_validator::
INSTALL_DESTINATION ${INSTALL_CMAKEDIR_ROOT}/${PROJECT_NAME} FILE nlohmann_json_schema_validatorTargets.cmake
) )
install(EXPORT nlohmann_json_schema_validatorTargets
FILE nlohmann_json_schema_validatorTargets.cmake
NAMESPACE nlohmann_json_schema_validator::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/nlohmann_json_schema_validator
COMPONENT nlohmann_json_schema_validator_Development
)
# Install cmake export files
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/nlohmann_json_schema_validatorConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/nlohmann_json_schema_validatorConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/nlohmann_json_schema_validator
COMPONENT nlohmann_json_schema_validator_Development
)
endif ()
install( # Handle the project being included externally (e.g. FetchContent)
FILES if (NOT PROJECT_IS_TOP_LEVEL)
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake # Export variables set in nlohmann_json_schema_validatorConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake # TODO: Remove when bumping cmake >= 3.25
DESTINATION if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.25)
${INSTALL_CMAKE_DIR} return(PROPAGATE
) nlohmann_json_schema_validator_VERSION
endif() nlohmann_json_schema_validator_VERSION_MAJOR
nlohmann_json_schema_validator_VERSION_MINOR
nlohmann_json_schema_validator_VERSION_PATCH
nlohmann_json_schema_validator_VERSION_TWEAK
)
else ()
set(nlohmann_json_schema_validator_VERSION ${nlohmann_json_schema_validator_VERSION} PARENT_SCOPE)
set(nlohmann_json_schema_validator_VERSION_MAJOR ${nlohmann_json_schema_validator_VERSION_MAJOR} PARENT_SCOPE)
set(nlohmann_json_schema_validator_VERSION_MINOR ${nlohmann_json_schema_validator_VERSION_MINOR} PARENT_SCOPE)
set(nlohmann_json_schema_validator_VERSION_PATCH ${nlohmann_json_schema_validator_VERSION_PATCH} PARENT_SCOPE)
set(nlohmann_json_schema_validator_VERSION_TWEAK ${nlohmann_json_schema_validator_VERSION_TWEAK} PARENT_SCOPE)
endif ()
endif ()

7
CMakePresets.json Normal file
View File

@ -0,0 +1,7 @@
{
"version": 6,
"include": [
"cmake/CMakePresets-defaults.json",
"cmake/CMakePresets-CI.json"
]
}

View File

@ -1,4 +1,3 @@
[![Build Status](https://travis-ci.org/pboettch/json-schema-validator.svg?branch=master)](https://travis-ci.org/pboettch/json-schema-validator) [![Build Status](https://travis-ci.org/pboettch/json-schema-validator.svg?branch=master)](https://travis-ci.org/pboettch/json-schema-validator)
# JSON schema validator for JSON for Modern C++ # JSON schema validator for JSON for Modern C++
@ -23,7 +22,7 @@ is rather simple.
Although significant changes have been done for the 2nd version Although significant changes have been done for the 2nd version
(a complete rewrite) the API is compatible with the 1.0.0 release. Except for (a complete rewrite) the API is compatible with the 1.0.0 release. Except for
the namespace which is now `nlohmann::json_schema. the namespace which is now `nlohmann::json_schema`.
Version **2** supports JSON schema draft 7, whereas 1 was supporting draft 4 Version **2** supports JSON schema draft 7, whereas 1 was supporting draft 4
only. Please update your schemas. only. Please update your schemas.
@ -101,6 +100,7 @@ By default a static library is built. Shared libraries can be generated by using
the `BUILD_SHARED_LIBS`-cmake variable: the `BUILD_SHARED_LIBS`-cmake variable:
In your initial call to cmake simply add: In your initial call to cmake simply add:
```bash ```bash
cmake [..] -DBUILD_SHARED_LIBS=ON [..] cmake [..] -DBUILD_SHARED_LIBS=ON [..]
``` ```
@ -151,6 +151,7 @@ and
```CMake ```CMake
target_link_libraries(<your-target> [..] nlohmann_json_schema_validator) target_link_libraries(<your-target> [..] nlohmann_json_schema_validator)
``` ```
to build and link. to build and link.
## Code ## Code
@ -298,9 +299,10 @@ json_validator validator(loader, // or nullptr for no loader
Supported formats: `date-time, date, time, email, hostname, ipv4, ipv6, uuid, regex` Supported formats: `date-time, date, time, email, hostname, ipv4, ipv6, uuid, regex`
More formats can be added in `src/string-format-check.cpp`. Please contribute implementions for missing json schema draft formats. More formats can be added in `src/string-format-check.cpp`. Please contribute implementions for missing json schema draft formats.
## Default value processing ## Default value processing
As a result of the validation, the library returns a json patch including the default values of the specified schema. As a result of the validation, the library returns a json patch including the default values of the specified schema.
```C++ ```C++
@ -348,15 +350,17 @@ int main()
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
``` ```
The example above will output the specified default values `{"height":10,"width":20}` to stdout. The example above will output the specified default values `{"height":10,"width":20}` to stdout.
> Note that the default value specified in a `$ref` may be overridden by the current instance location. Also note that this behavior will break draft-7, but it is compliant to newer drafts (e.g. `2019-09` or `2020-12`). > Note that the default value specified in a `$ref` may be overridden by the current instance location. Also note that this behavior will break draft-7, but it is compliant to newer drafts (e.g. `2019-09` or `2020-12`).
# Contributing # Contributing
Before opening a pull request, please apply the coding style given in the This project uses [`pre-commit`](https://pre-commit.com/) to enforce style-checks. Please install and run it before
`.clang-format` by running clang-format from the git top-level for all touched creating commits and making pull requests.
files:
```shell ```console
git diff master --name-only | grep '\.[ch]pp$' | xargs -P 3 -I{} clang-format -i {} $ pip install pre-commit
$ pre-commit install
``` ```

259
cmake/CMakePresets-CI.json Normal file
View File

@ -0,0 +1,259 @@
{
"version": 6,
"include": [
"CMakePresets-defaults.json"
],
"configurePresets": [
{
"name": "ci-base",
"hidden": true,
"generator": "Ninja",
"inherits": [
"default"
],
"cacheVariables": {
"JSON_VALIDATOR_BUILD_TESTS": {
"type": "BOOL",
"value": true
}
},
"errors": {
"deprecated": true
}
},
{
"name": "gcc-ci",
"displayName": "Configure preset for GCC toolchain",
"inherits": [
"ci-base"
],
"binaryDir": "cmake-build-release-gcc",
"cacheVariables": {
"CMAKE_CXX_COMPILER": {
"type": "FILEPATH",
"value": "g++"
},
"CMAKE_LINKER": {
"type": "FILEPATH",
"value": "ld"
}
}
},
{
"name": "intel-ci",
"displayName": "Configure preset for Intel toolchain",
"inherits": [
"ci-base"
],
"binaryDir": "cmake-build-release-intel",
"cacheVariables": {
"CMAKE_CXX_COMPILER": {
"type": "FILEPATH",
"value": "icpx"
}
}
},
{
"name": "llvm-ci",
"displayName": "Configure preset for LLVM toolchain",
"inherits": [
"ci-base"
],
"binaryDir": "cmake-build-release-llvm",
"cacheVariables": {
"CMAKE_CXX_COMPILER": {
"type": "FILEPATH",
"value": "clang++"
},
"CMAKE_LINKER": {
"type": "FILEPATH",
"value": "lld"
}
}
},
{
"name": "ci-coverage",
"displayName": "Configure preset for test coverage",
"inherits": [
"gcc-ci"
],
"binaryDir": "cmake-build-coverage",
"errors": {
"deprecated": false
},
"cacheVariables": {
"JSON_VALIDATOR_TEST_COVERAGE": {
"type": "BOOL",
"value": true
}
}
},
{
"name": "pre-commit",
"displayName": "Configure preset for pre-commit checks",
"inherits": [
"default"
],
"binaryDir": "cmake-build-pre-commit"
}
],
"buildPresets": [
{
"name": "ci-base",
"hidden": true,
"inherits": [
"default"
],
"cleanFirst": true
},
{
"name": "ci-coverage",
"displayName": "Build preset for test coverage",
"inherits": [
"ci-base"
],
"configurePreset": "ci-coverage"
},
{
"name": "gcc-ci",
"displayName": "Build preset for GCC toolchain",
"inherits": [
"ci-base"
],
"configurePreset": "gcc-ci"
},
{
"name": "intel-ci",
"displayName": "Build preset for Intel toolchain",
"inherits": [
"ci-base"
],
"configurePreset": "intel-ci"
},
{
"name": "llvm-ci",
"displayName": "Build preset for LLVM toolchain",
"inherits": [
"ci-base"
],
"configurePreset": "llvm-ci"
}
],
"testPresets": [
{
"name": "ci-base",
"hidden": true,
"inherits": [
"default"
],
"output": {
"outputOnFailure": true
}
},
{
"name": "ci-coverage",
"inherits": [
"default"
],
"configurePreset": "ci-coverage"
},
{
"name": "gcc-ci",
"displayName": "Test preset for GCC toolchain",
"inherits": [
"ci-base"
],
"configurePreset": "gcc-ci"
},
{
"name": "intel-ci",
"displayName": "Test preset for Intel toolchain",
"inherits": [
"ci-base"
],
"configurePreset": "intel-ci"
},
{
"name": "llvm-ci",
"displayName": "Test preset for LLVM toolchain",
"inherits": [
"ci-base"
],
"configurePreset": "llvm-ci"
}
],
"workflowPresets": [
{
"name": "gcc-ci",
"displayName": "CI test for GCC toolchain",
"steps": [
{
"type": "configure",
"name": "gcc-ci"
},
{
"type": "build",
"name": "gcc-ci"
},
{
"type": "test",
"name": "gcc-ci"
}
]
},
{
"name": "intel-ci",
"displayName": "CI test for Intel toolchain",
"steps": [
{
"type": "configure",
"name": "intel-ci"
},
{
"type": "build",
"name": "intel-ci"
},
{
"type": "test",
"name": "intel-ci"
}
]
},
{
"name": "llvm-ci",
"displayName": "CI test for LLVM toolchain",
"steps": [
{
"type": "configure",
"name": "llvm-ci"
},
{
"type": "build",
"name": "llvm-ci"
},
{
"type": "test",
"name": "llvm-ci"
}
]
},
{
"name": "ci-coverage",
"displayName": "Coverage tests",
"steps": [
{
"type": "configure",
"name": "ci-coverage"
},
{
"type": "build",
"name": "ci-coverage"
},
{
"type": "test",
"name": "ci-coverage"
}
]
}
]
}

View File

@ -0,0 +1,50 @@
{
"version": 6,
"configurePresets": [
{
"name": "default",
"displayName": "Default configuration preset",
"binaryDir": "cmake-build-release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": {
"type": "STRING",
"value": "Release"
}
}
}
],
"buildPresets": [
{
"name": "default",
"displayName": "Default build preset",
"configurePreset": "default"
}
],
"testPresets": [
{
"name": "default",
"displayName": "Default test preset",
"configurePreset": "default"
}
],
"workflowPresets": [
{
"name": "default",
"displayName": "Default workflow",
"steps": [
{
"type": "configure",
"name": "default"
},
{
"type": "build",
"name": "default"
},
{
"type": "test",
"name": "default"
}
]
}
]
}

View File

@ -1,539 +0,0 @@
# Copyright (c) 2013-2019, Ruslan Baratov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This is a gate file to Hunter package manager.
# Include this file using `include` command and add package you need, example:
#
# cmake_minimum_required(VERSION 3.2)
#
# include("cmake/HunterGate.cmake")
# HunterGate(
# URL "https://github.com/path/to/hunter/archive.tar.gz"
# SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d"
# )
#
# project(MyProject)
#
# hunter_add_package(Foo)
# hunter_add_package(Boo COMPONENTS Bar Baz)
#
# Projects:
# * https://github.com/hunter-packages/gate/
# * https://github.com/ruslo/hunter
option(HUNTER_ENABLED "Enable Hunter package manager support" ON)
if(HUNTER_ENABLED)
if(CMAKE_VERSION VERSION_LESS "3.2")
message(
FATAL_ERROR
"At least CMake version 3.2 required for Hunter dependency management."
" Update CMake or set HUNTER_ENABLED to OFF."
)
endif()
endif()
include(CMakeParseArguments) # cmake_parse_arguments
option(HUNTER_STATUS_PRINT "Print working status" ON)
option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON)
set(HUNTER_ERROR_PAGE "https://docs.hunter.sh/en/latest/reference/errors")
function(hunter_gate_status_print)
if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
foreach(print_message ${ARGV})
message(STATUS "[hunter] ${print_message}")
endforeach()
endif()
endfunction()
function(hunter_gate_status_debug)
if(HUNTER_STATUS_DEBUG)
foreach(print_message ${ARGV})
string(TIMESTAMP timestamp)
message(STATUS "[hunter *** DEBUG *** ${timestamp}] ${print_message}")
endforeach()
endif()
endfunction()
function(hunter_gate_error_page error_page)
message("------------------------------ ERROR ------------------------------")
message(" ${HUNTER_ERROR_PAGE}/${error_page}.html")
message("-------------------------------------------------------------------")
message("")
message(FATAL_ERROR "")
endfunction()
function(hunter_gate_internal_error)
message("")
foreach(print_message ${ARGV})
message("[hunter ** INTERNAL **] ${print_message}")
endforeach()
message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
message("")
hunter_gate_error_page("error.internal")
endfunction()
function(hunter_gate_fatal_error)
cmake_parse_arguments(hunter "" "ERROR_PAGE" "" "${ARGV}")
if("${hunter_ERROR_PAGE}" STREQUAL "")
hunter_gate_internal_error("Expected ERROR_PAGE")
endif()
message("")
foreach(x ${hunter_UNPARSED_ARGUMENTS})
message("[hunter ** FATAL ERROR **] ${x}")
endforeach()
message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
message("")
hunter_gate_error_page("${hunter_ERROR_PAGE}")
endfunction()
function(hunter_gate_user_error)
hunter_gate_fatal_error(${ARGV} ERROR_PAGE "error.incorrect.input.data")
endfunction()
function(hunter_gate_self root version sha1 result)
string(COMPARE EQUAL "${root}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("root is empty")
endif()
string(COMPARE EQUAL "${version}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("version is empty")
endif()
string(COMPARE EQUAL "${sha1}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("sha1 is empty")
endif()
string(SUBSTRING "${sha1}" 0 7 archive_id)
if(EXISTS "${root}/cmake/Hunter")
set(hunter_self "${root}")
else()
set(
hunter_self
"${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked"
)
endif()
set("${result}" "${hunter_self}" PARENT_SCOPE)
endfunction()
# Set HUNTER_GATE_ROOT cmake variable to suitable value.
function(hunter_gate_detect_root)
# Check CMake variable
string(COMPARE NOTEQUAL "${HUNTER_ROOT}" "" not_empty)
if(not_empty)
set(HUNTER_GATE_ROOT "${HUNTER_ROOT}" PARENT_SCOPE)
hunter_gate_status_debug("HUNTER_ROOT detected by cmake variable")
return()
endif()
# Check environment variable
string(COMPARE NOTEQUAL "$ENV{HUNTER_ROOT}" "" not_empty)
if(not_empty)
set(HUNTER_GATE_ROOT "$ENV{HUNTER_ROOT}" PARENT_SCOPE)
hunter_gate_status_debug("HUNTER_ROOT detected by environment variable")
return()
endif()
# Check HOME environment variable
string(COMPARE NOTEQUAL "$ENV{HOME}" "" result)
if(result)
set(HUNTER_GATE_ROOT "$ENV{HOME}/.hunter" PARENT_SCOPE)
hunter_gate_status_debug("HUNTER_ROOT set using HOME environment variable")
return()
endif()
# Check SYSTEMDRIVE and USERPROFILE environment variable (windows only)
if(WIN32)
string(COMPARE NOTEQUAL "$ENV{SYSTEMDRIVE}" "" result)
if(result)
set(HUNTER_GATE_ROOT "$ENV{SYSTEMDRIVE}/.hunter" PARENT_SCOPE)
hunter_gate_status_debug(
"HUNTER_ROOT set using SYSTEMDRIVE environment variable"
)
return()
endif()
string(COMPARE NOTEQUAL "$ENV{USERPROFILE}" "" result)
if(result)
set(HUNTER_GATE_ROOT "$ENV{USERPROFILE}/.hunter" PARENT_SCOPE)
hunter_gate_status_debug(
"HUNTER_ROOT set using USERPROFILE environment variable"
)
return()
endif()
endif()
hunter_gate_fatal_error(
"Can't detect HUNTER_ROOT"
ERROR_PAGE "error.detect.hunter.root"
)
endfunction()
function(hunter_gate_download dir)
string(
COMPARE
NOTEQUAL
"$ENV{HUNTER_DISABLE_AUTOINSTALL}"
""
disable_autoinstall
)
if(disable_autoinstall AND NOT HUNTER_RUN_INSTALL)
hunter_gate_fatal_error(
"Hunter not found in '${dir}'"
"Set HUNTER_RUN_INSTALL=ON to auto-install it from '${HUNTER_GATE_URL}'"
"Settings:"
" HUNTER_ROOT: ${HUNTER_GATE_ROOT}"
" HUNTER_SHA1: ${HUNTER_GATE_SHA1}"
ERROR_PAGE "error.run.install"
)
endif()
string(COMPARE EQUAL "${dir}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("Empty 'dir' argument")
endif()
string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("HUNTER_GATE_SHA1 empty")
endif()
string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("HUNTER_GATE_URL empty")
endif()
set(done_location "${dir}/DONE")
set(sha1_location "${dir}/SHA1")
set(build_dir "${dir}/Build")
set(cmakelists "${dir}/CMakeLists.txt")
hunter_gate_status_debug("Locking directory: ${dir}")
file(LOCK "${dir}" DIRECTORY GUARD FUNCTION)
hunter_gate_status_debug("Lock done")
if(EXISTS "${done_location}")
# while waiting for lock other instance can do all the job
hunter_gate_status_debug("File '${done_location}' found, skip install")
return()
endif()
file(REMOVE_RECURSE "${build_dir}")
file(REMOVE_RECURSE "${cmakelists}")
file(MAKE_DIRECTORY "${build_dir}") # check directory permissions
# Disabling languages speeds up a little bit, reduces noise in the output
# and avoids path too long windows error
file(
WRITE
"${cmakelists}"
"cmake_minimum_required(VERSION 3.2)\n"
"project(HunterDownload LANGUAGES NONE)\n"
"include(ExternalProject)\n"
"ExternalProject_Add(\n"
" Hunter\n"
" URL\n"
" \"${HUNTER_GATE_URL}\"\n"
" URL_HASH\n"
" SHA1=${HUNTER_GATE_SHA1}\n"
" DOWNLOAD_DIR\n"
" \"${dir}\"\n"
" TLS_VERIFY\n"
" ${HUNTER_TLS_VERIFY}\n"
" SOURCE_DIR\n"
" \"${dir}/Unpacked\"\n"
" CONFIGURE_COMMAND\n"
" \"\"\n"
" BUILD_COMMAND\n"
" \"\"\n"
" INSTALL_COMMAND\n"
" \"\"\n"
")\n"
)
if(HUNTER_STATUS_DEBUG)
set(logging_params "")
else()
set(logging_params OUTPUT_QUIET)
endif()
hunter_gate_status_debug("Run generate")
# Need to add toolchain file too.
# Otherwise on Visual Studio + MDD this will fail with error:
# "Could not find an appropriate version of the Windows 10 SDK installed on this machine"
if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
get_filename_component(absolute_CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE)
set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=${absolute_CMAKE_TOOLCHAIN_FILE}")
else()
# 'toolchain_arg' can't be empty
set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=")
endif()
string(COMPARE EQUAL "${CMAKE_MAKE_PROGRAM}" "" no_make)
if(no_make)
set(make_arg "")
else()
# Test case: remove Ninja from PATH but set it via CMAKE_MAKE_PROGRAM
set(make_arg "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}")
endif()
execute_process(
COMMAND
"${CMAKE_COMMAND}"
"-H${dir}"
"-B${build_dir}"
"-G${CMAKE_GENERATOR}"
"${toolchain_arg}"
${make_arg}
WORKING_DIRECTORY "${dir}"
RESULT_VARIABLE download_result
${logging_params}
)
if(NOT download_result EQUAL 0)
hunter_gate_internal_error(
"Configure project failed."
"To reproduce the error run: ${CMAKE_COMMAND} -H${dir} -B${build_dir} -G${CMAKE_GENERATOR} ${toolchain_arg} ${make_arg}"
"In directory ${dir}"
)
endif()
hunter_gate_status_print(
"Initializing Hunter workspace (${HUNTER_GATE_SHA1})"
" ${HUNTER_GATE_URL}"
" -> ${dir}"
)
execute_process(
COMMAND "${CMAKE_COMMAND}" --build "${build_dir}"
WORKING_DIRECTORY "${dir}"
RESULT_VARIABLE download_result
${logging_params}
)
if(NOT download_result EQUAL 0)
hunter_gate_internal_error("Build project failed")
endif()
file(REMOVE_RECURSE "${build_dir}")
file(REMOVE_RECURSE "${cmakelists}")
file(WRITE "${sha1_location}" "${HUNTER_GATE_SHA1}")
file(WRITE "${done_location}" "DONE")
hunter_gate_status_debug("Finished")
endfunction()
# Must be a macro so master file 'cmake/Hunter' can
# apply all variables easily just by 'include' command
# (otherwise PARENT_SCOPE magic needed)
macro(HunterGate)
if(HUNTER_GATE_DONE)
# variable HUNTER_GATE_DONE set explicitly for external project
# (see `hunter_download`)
set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
endif()
# First HunterGate command will init Hunter, others will be ignored
get_property(_hunter_gate_done GLOBAL PROPERTY HUNTER_GATE_DONE SET)
if(NOT HUNTER_ENABLED)
# Empty function to avoid error "unknown function"
function(hunter_add_package)
endfunction()
set(
_hunter_gate_disabled_mode_dir
"${CMAKE_CURRENT_LIST_DIR}/cmake/Hunter/disabled-mode"
)
if(EXISTS "${_hunter_gate_disabled_mode_dir}")
hunter_gate_status_debug(
"Adding \"disabled-mode\" modules: ${_hunter_gate_disabled_mode_dir}"
)
list(APPEND CMAKE_PREFIX_PATH "${_hunter_gate_disabled_mode_dir}")
endif()
elseif(_hunter_gate_done)
hunter_gate_status_debug("Secondary HunterGate (use old settings)")
hunter_gate_self(
"${HUNTER_CACHED_ROOT}"
"${HUNTER_VERSION}"
"${HUNTER_SHA1}"
_hunter_self
)
include("${_hunter_self}/cmake/Hunter")
else()
set(HUNTER_GATE_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}")
string(COMPARE NOTEQUAL "${PROJECT_NAME}" "" _have_project_name)
if(_have_project_name)
hunter_gate_fatal_error(
"Please set HunterGate *before* 'project' command. "
"Detected project: ${PROJECT_NAME}"
ERROR_PAGE "error.huntergate.before.project"
)
endif()
cmake_parse_arguments(
HUNTER_GATE "LOCAL" "URL;SHA1;GLOBAL;FILEPATH" "" ${ARGV}
)
string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" _empty_sha1)
string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" _empty_url)
string(
COMPARE
NOTEQUAL
"${HUNTER_GATE_UNPARSED_ARGUMENTS}"
""
_have_unparsed
)
string(COMPARE NOTEQUAL "${HUNTER_GATE_GLOBAL}" "" _have_global)
string(COMPARE NOTEQUAL "${HUNTER_GATE_FILEPATH}" "" _have_filepath)
if(_have_unparsed)
hunter_gate_user_error(
"HunterGate unparsed arguments: ${HUNTER_GATE_UNPARSED_ARGUMENTS}"
)
endif()
if(_empty_sha1)
hunter_gate_user_error("SHA1 suboption of HunterGate is mandatory")
endif()
if(_empty_url)
hunter_gate_user_error("URL suboption of HunterGate is mandatory")
endif()
if(_have_global)
if(HUNTER_GATE_LOCAL)
hunter_gate_user_error("Unexpected LOCAL (already has GLOBAL)")
endif()
if(_have_filepath)
hunter_gate_user_error("Unexpected FILEPATH (already has GLOBAL)")
endif()
endif()
if(HUNTER_GATE_LOCAL)
if(_have_global)
hunter_gate_user_error("Unexpected GLOBAL (already has LOCAL)")
endif()
if(_have_filepath)
hunter_gate_user_error("Unexpected FILEPATH (already has LOCAL)")
endif()
endif()
if(_have_filepath)
if(_have_global)
hunter_gate_user_error("Unexpected GLOBAL (already has FILEPATH)")
endif()
if(HUNTER_GATE_LOCAL)
hunter_gate_user_error("Unexpected LOCAL (already has FILEPATH)")
endif()
endif()
hunter_gate_detect_root() # set HUNTER_GATE_ROOT
# Beautify path, fix probable problems with windows path slashes
get_filename_component(
HUNTER_GATE_ROOT "${HUNTER_GATE_ROOT}" ABSOLUTE
)
hunter_gate_status_debug("HUNTER_ROOT: ${HUNTER_GATE_ROOT}")
if(NOT HUNTER_ALLOW_SPACES_IN_PATH)
string(FIND "${HUNTER_GATE_ROOT}" " " _contain_spaces)
if(NOT _contain_spaces EQUAL -1)
hunter_gate_fatal_error(
"HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces."
"Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error"
"(Use at your own risk!)"
ERROR_PAGE "error.spaces.in.hunter.root"
)
endif()
endif()
string(
REGEX
MATCH
"[0-9]+\\.[0-9]+\\.[0-9]+[-_a-z0-9]*"
HUNTER_GATE_VERSION
"${HUNTER_GATE_URL}"
)
string(COMPARE EQUAL "${HUNTER_GATE_VERSION}" "" _is_empty)
if(_is_empty)
set(HUNTER_GATE_VERSION "unknown")
endif()
hunter_gate_self(
"${HUNTER_GATE_ROOT}"
"${HUNTER_GATE_VERSION}"
"${HUNTER_GATE_SHA1}"
_hunter_self
)
set(_master_location "${_hunter_self}/cmake/Hunter")
if(EXISTS "${HUNTER_GATE_ROOT}/cmake/Hunter")
# Hunter downloaded manually (e.g. by 'git clone')
set(_unused "xxxxxxxxxx")
set(HUNTER_GATE_SHA1 "${_unused}")
set(HUNTER_GATE_VERSION "${_unused}")
else()
get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE)
set(_done_location "${_archive_id_location}/DONE")
set(_sha1_location "${_archive_id_location}/SHA1")
# Check Hunter already downloaded by HunterGate
if(NOT EXISTS "${_done_location}")
hunter_gate_download("${_archive_id_location}")
endif()
if(NOT EXISTS "${_done_location}")
hunter_gate_internal_error("hunter_gate_download failed")
endif()
if(NOT EXISTS "${_sha1_location}")
hunter_gate_internal_error("${_sha1_location} not found")
endif()
file(READ "${_sha1_location}" _sha1_value)
string(COMPARE EQUAL "${_sha1_value}" "${HUNTER_GATE_SHA1}" _is_equal)
if(NOT _is_equal)
hunter_gate_internal_error(
"Short SHA1 collision:"
" ${_sha1_value} (from ${_sha1_location})"
" ${HUNTER_GATE_SHA1} (HunterGate)"
)
endif()
if(NOT EXISTS "${_master_location}")
hunter_gate_user_error(
"Master file not found:"
" ${_master_location}"
"try to update Hunter/HunterGate"
)
endif()
endif()
include("${_master_location}")
set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
endif()
endmacro()

14
example/CMakeLists.txt Normal file
View File

@ -0,0 +1,14 @@
# simple nlohmann_json_schema_validator-executable
add_executable(json-schema-validate json-schema-validate.cpp)
target_link_libraries(json-schema-validate nlohmann_json_schema_validator)
add_executable(readme-json-schema readme.cpp)
target_link_libraries(readme-json-schema nlohmann_json_schema_validator)
add_executable(format-json-schema format.cpp)
target_link_libraries(format-json-schema nlohmann_json_schema_validator)
if (JSON_VALIDATOR_INSTALL)
install(TARGETS json-schema-validate readme-json-schema format-json-schema
DESTINATION ${CMAKE_INSTALL_BINDIR})
endif ()

74
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,74 @@
target_sources(nlohmann_json_schema_validator PRIVATE
smtp-address-validator.cpp
json-schema-draft7.json.cpp
json-uri.cpp
json-validator.cpp
json-patch.cpp
string-format-check.cpp
)
target_include_directories(nlohmann_json_schema_validator PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)
set_target_properties(nlohmann_json_schema_validator PROPERTIES
PUBLIC_HEADER nlohmann/json-schema.hpp)
# TODO: Why would this need to be if guarded?
if (JSON_VALIDATOR_SHARED_LIBS)
target_compile_definitions(nlohmann_json_schema_validator PRIVATE
-DJSON_SCHEMA_VALIDATOR_EXPORTS)
endif ()
# TODO: Consider setting minimum cxx standard instead
target_compile_features(nlohmann_json_schema_validator PUBLIC
cxx_range_for) # for C++11 - flags
# TODO: This should be handled by the CI/presets, not the cmake
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
target_compile_options(nlohmann_json_schema_validator
PRIVATE
-Wall -Wextra -Wshadow)
endif ()
# TODO: gcc support for <4.9 should be removed
# regex with boost if gcc < 4.9 - default is std::regex
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9.0")
find_package(Boost COMPONENTS regex)
if (NOT Boost_FOUND)
message(STATUS "GCC less then 4.9 and boost-regex NOT found - no regex used")
target_compile_definitions(nlohmann_json_schema_validator PRIVATE -DJSON_SCHEMA_NO_REGEX)
else ()
message(STATUS "GCC less then 4.9 and boost-regex FOUND - using boost::regex")
target_compile_definitions(nlohmann_json_schema_validator PRIVATE -DJSON_SCHEMA_BOOST_REGEX)
target_include_directories(nlohmann_json_schema_validator PRIVATE ${Boost_INCLUDE_DIRS})
target_link_libraries(nlohmann_json_schema_validator PRIVATE ${Boost_LIBRARIES})
endif ()
endif ()
endif ()
target_link_libraries(nlohmann_json_schema_validator PUBLIC
nlohmann_json::nlohmann_json)
if (JSON_VALIDATOR_INSTALL)
# Normal installation target to system. When using scikit-build check python subdirectory
if (WIN32)
# TODO: Probably wrong, please fix
install(TARGETS nlohmann_json_schema_validator
EXPORT nlohmann_json_schema_validatorTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT nlohmann_json_schema_validator_Runtime
NAMELINK_COMPONENT nlohmann_json_schema_validator_Development
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT nlohmann_json_schema_validator_Development
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/nlohmann COMPONENT nlohmann_json_schema_validator_Development
RUNTIME DESTINATION ${CMAKE_INSTALL_RUNTIMEDIR} COMPONENT nlohmann_json_schema_validator_Runtime)
else ()
install(TARGETS nlohmann_json_schema_validator
EXPORT nlohmann_json_schema_validatorTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT nlohmann_json_schema_validator_Runtime
NAMELINK_COMPONENT nlohmann_json_schema_validator_Development
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT nlohmann_json_schema_validator_Development
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/nlohmann COMPONENT nlohmann_json_schema_validator_Development)
endif ()
endif ()

View File

@ -10,189 +10,221 @@
#define NLOHMANN_JSON_SCHEMA_HPP__ #define NLOHMANN_JSON_SCHEMA_HPP__
#ifdef _WIN32 #ifdef _WIN32
# if defined(JSON_SCHEMA_VALIDATOR_EXPORTS) #if defined(JSON_SCHEMA_VALIDATOR_EXPORTS)
# define JSON_SCHEMA_VALIDATOR_API __declspec(dllexport) #define JSON_SCHEMA_VALIDATOR_API __declspec(dllexport)
# elif defined(JSON_SCHEMA_VALIDATOR_IMPORTS) #elif defined(JSON_SCHEMA_VALIDATOR_IMPORTS)
# define JSON_SCHEMA_VALIDATOR_API __declspec(dllimport) #define JSON_SCHEMA_VALIDATOR_API __declspec(dllimport)
# else
# define JSON_SCHEMA_VALIDATOR_API
# endif
#else #else
# define JSON_SCHEMA_VALIDATOR_API #define JSON_SCHEMA_VALIDATOR_API
#endif
#else
#define JSON_SCHEMA_VALIDATOR_API
#endif #endif
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#ifdef NLOHMANN_JSON_VERSION_MAJOR #ifdef NLOHMANN_JSON_VERSION_MAJOR
# if (NLOHMANN_JSON_VERSION_MAJOR * 10000 + NLOHMANN_JSON_VERSION_MINOR * 100 + NLOHMANN_JSON_VERSION_PATCH) < 30800 #if (NLOHMANN_JSON_VERSION_MAJOR * 10000 + NLOHMANN_JSON_VERSION_MINOR * 100 + NLOHMANN_JSON_VERSION_PATCH) < 30800
# error "Please use this library with NLohmann's JSON version 3.8.0 or higher" #error "Please use this library with NLohmann's JSON version 3.8.0 or higher"
# endif #endif
#else #else
# error "expected existing NLOHMANN_JSON_VERSION_MAJOR preproc variable, please update to NLohmann's JSON 3.8.0" #error "expected existing NLOHMANN_JSON_VERSION_MAJOR preproc variable, please update to NLohmann's JSON 3.8.0"
#endif #endif
// make yourself a home - welcome to nlohmann's namespace // make yourself a home - welcome to nlohmann's namespace
namespace nlohmann namespace nlohmann {
{ /**
* A class representing a JSON-URI for schemas derived from
* section 8 of JSON Schema: A Media Type for Describing JSON Documents
* draft-wright-json-schema-00
*
* New URIs can be derived from it using the derive()-method.
* This is useful for resolving refs or subschema-IDs in json-schemas.
*
* This is done implement the requirements described in section 8.2.
*/
class JSON_SCHEMA_VALIDATOR_API json_uri {
std::string urn_;
// A class representing a JSON-URI for schemas derived from std::string scheme_;
// section 8 of JSON Schema: A Media Type for Describing JSON Documents std::string authority_;
// draft-wright-json-schema-00 std::string path_;
//
// New URIs can be derived from it using the derive()-method.
// This is useful for resolving refs or subschema-IDs in json-schemas.
//
// This is done implement the requirements described in section 8.2.
//
class JSON_SCHEMA_VALIDATOR_API json_uri
{
std::string urn_;
std::string scheme_; /**
std::string authority_; * fragment part if JSON-Pointer
std::string path_; */
json::json_pointer pointer_;
/**
* fragment part if Locatation Independent ID
*/
std::string identifier_;
json::json_pointer pointer_; // fragment part if JSON-Pointer protected:
std::string identifier_; // fragment part if Locatation Independent ID /**
* decodes a JSON uri and replaces all or part of the currently stored values
*
* @param uri
*/
void update(const std::string& uri);
protected: std::tuple<std::string, std::string, std::string, std::string, std::string> as_tuple() const {
// decodes a JSON uri and replaces all or part of the currently stored values return std::make_tuple(urn_, scheme_, authority_, path_,
void update(const std::string &uri); identifier_ != "" ? identifier_ : pointer_.to_string());
}
std::tuple<std::string, std::string, std::string, std::string, std::string> as_tuple() const public:
{ json_uri(const std::string& uri) {
return std::make_tuple(urn_, scheme_, authority_, path_, identifier_ != "" ? identifier_ : pointer_.to_string()); update(uri);
} }
public: const std::string& scheme() const { return scheme_; }
json_uri(const std::string &uri)
{
update(uri);
}
const std::string &scheme() const { return scheme_; } const std::string& authority() const { return authority_; }
const std::string &authority() const { return authority_; }
const std::string &path() const { return path_; }
const json::json_pointer &pointer() const { return pointer_; } const std::string& path() const { return path_; }
const std::string &identifier() const { return identifier_; }
std::string fragment() const const json::json_pointer& pointer() const { return pointer_; }
{
if (identifier_ == "")
return pointer_.to_string();
else
return identifier_;
}
std::string url() const { return location(); } const std::string& identifier() const { return identifier_; }
std::string location() const;
static std::string escape(const std::string &); std::string fragment() const {
if (identifier_ == "")
return pointer_.to_string();
else
return identifier_;
}
// create a new json_uri based in this one and the given uri std::string url() const { return location(); }
// resolves relative changes (pathes or pointers) and resets part if proto or hostname changes
json_uri derive(const std::string &uri) const
{
json_uri u = *this;
u.update(uri);
return u;
}
// append a pointer-field to the pointer-part of this uri std::string location() const;
json_uri append(const std::string &field) const
{
if (identifier_ != "")
return *this;
json_uri u = *this; static std::string escape(const std::string&);
u.pointer_ /= field;
return u;
}
std::string to_string() const; /**
* create a new json_uri based in this one and the given uri
* resolves relative changes (pathes or pointers) and resets part if proto or hostname changes
*
* @param uri
* @return
*/
json_uri derive(const std::string& uri) const {
json_uri u = *this;
u.update(uri);
return u;
}
friend bool operator<(const json_uri &l, const json_uri &r) /**
{ * append a pointer-field to the pointer-part of this uri
return l.as_tuple() < r.as_tuple(); */
} json_uri append(const std::string& field) const {
if (identifier_ != "")
return *this;
friend bool operator==(const json_uri &l, const json_uri &r) json_uri u = *this;
{ u.pointer_ /= field;
return l.as_tuple() == r.as_tuple(); return u;
} }
friend std::ostream &operator<<(std::ostream &os, const json_uri &u); std::string to_string() const;
};
namespace json_schema friend bool operator<(const json_uri& l, const json_uri& r) {
{ return l.as_tuple() < r.as_tuple();
}
extern json draft7_schema_builtin; friend bool operator==(const json_uri& l, const json_uri& r) {
return l.as_tuple() == r.as_tuple();
}
typedef std::function<void(const json_uri & /*id*/, json & /*value*/)> schema_loader; friend std::ostream& operator<<(std::ostream& os, const json_uri& u);
typedef std::function<void(const std::string & /*format*/, const std::string & /*value*/)> format_checker; };
typedef std::function<void(const std::string & /*contentEncoding*/, const std::string & /*contentMediaType*/, const json & /*instance*/)> content_checker;
// Interface for validation error handlers namespace json_schema {
class JSON_SCHEMA_VALIDATOR_API error_handler
{
public:
virtual ~error_handler() {}
virtual void error(const json::json_pointer & /*ptr*/, const json & /*instance*/, const std::string & /*message*/) = 0;
};
class JSON_SCHEMA_VALIDATOR_API basic_error_handler : public error_handler extern json draft7_schema_builtin;
{
bool error_{false};
public: typedef std::function<void(const json_uri& /*id*/, json& /*value*/)> schema_loader;
void error(const json::json_pointer & /*ptr*/, const json & /*instance*/, const std::string & /*message*/) override typedef std::function<void(const std::string& /*format*/, const std::string& /*value*/)> format_checker;
{ typedef std::function<void(const std::string& /*contentEncoding*/, const std::string& /*contentMediaType*/,
error_ = true; const json& /*instance*/)>
} content_checker;
virtual void reset() { error_ = false; } /**
operator bool() const { return error_; } * Interface for validation error handlers
}; */
class JSON_SCHEMA_VALIDATOR_API error_handler {
public:
virtual ~error_handler() {}
/** virtual void
* Checks validity of JSON schema built-in string format specifiers like 'date-time', 'ipv4', ... error(const json::json_pointer& /*ptr*/, const json& /*instance*/, const std::string& /*message*/) = 0;
*/ };
void JSON_SCHEMA_VALIDATOR_API default_string_format_check(const std::string &format, const std::string &value);
class root_schema; class JSON_SCHEMA_VALIDATOR_API basic_error_handler : public error_handler {
bool error_{false};
class JSON_SCHEMA_VALIDATOR_API json_validator public:
{ void error(const json::json_pointer& /*ptr*/, const json& /*instance*/,
std::unique_ptr<root_schema> root_; const std::string& /*message*/) override {
error_ = true;
}
public: virtual void reset() { error_ = false; }
json_validator(schema_loader = nullptr, format_checker = nullptr, content_checker = nullptr);
json_validator(const json &, schema_loader = nullptr, format_checker = nullptr, content_checker = nullptr); operator bool() const { return error_; }
json_validator(json &&, schema_loader = nullptr, format_checker = nullptr, content_checker = nullptr); };
json_validator(json_validator &&); /**
json_validator &operator=(json_validator &&); * Checks validity of JSON schema built-in string format specifiers like 'date-time', 'ipv4', ...
*/
void JSON_SCHEMA_VALIDATOR_API default_string_format_check(const std::string& format, const std::string& value);
json_validator(json_validator const &) = delete; class root_schema;
json_validator &operator=(json_validator const &) = delete;
~json_validator(); class JSON_SCHEMA_VALIDATOR_API json_validator {
std::unique_ptr<root_schema> root_;
// insert and set the root-schema public:
void set_root_schema(const json &); json_validator(schema_loader = nullptr, format_checker = nullptr, content_checker = nullptr);
void set_root_schema(json &&);
// validate a json-document based on the root-schema json_validator(const json&, schema_loader = nullptr, format_checker = nullptr, content_checker = nullptr);
json validate(const json &) const;
// validate a json-document based on the root-schema with a custom error-handler json_validator(json&&, schema_loader = nullptr, format_checker = nullptr, content_checker = nullptr);
json validate(const json &, error_handler &, const json_uri &initial_uri = json_uri("#")) const;
};
} // namespace json_schema json_validator(json_validator&&);
} // namespace nlohmann
json_validator& operator=(json_validator&&);
json_validator(json_validator const&) = delete;
json_validator& operator=(json_validator const&) = delete;
~json_validator();
/**
* insert and set the root-schema
*
*/
void set_root_schema(const json&);
void set_root_schema(json&&);
/**
* validate a json-document based on the root-schema
*
* @return
*/
json validate(const json&) const;
/**
* validate a json-document based on the root-schema with a custom error-handler
*
* @param initial_uri
* @return
*/
json validate(const json&, error_handler&, const json_uri& initial_uri = json_uri("#")) const;
};
}// namespace json_schema
}// namespace nlohmann
#endif /* NLOHMANN_JSON_SCHEMA_HPP__ */ #endif /* NLOHMANN_JSON_SCHEMA_HPP__ */

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,6 @@ SOFTWARE.
*/ */
bool is_address(const char* p, const char* pe); bool is_address(const char *p, const char *pe);
#endif // SMTP_ADDRESS_PARSER_HPP_INCLUDED #endif // SMTP_ADDRESS_PARSER_HPP_INCLUDED

View File

@ -182,7 +182,7 @@ const std::string uuid{R"([0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-
// from http://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address // from http://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address
const std::string hostname{R"(^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$)"}; const std::string hostname{R"(^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$)"};
bool is_ascii(std::string const& value) bool is_ascii(std::string const &value)
{ {
for (auto ch : value) { for (auto ch : value) {
if (ch & 0x80) { if (ch & 0x80) {

View File

@ -74,7 +74,7 @@
"description": "forbidden property", "description": "forbidden property",
"schema": { "schema": {
"properties": { "properties": {
"foo": { "foo": {
"not": {} "not": {}
} }
} }

View File

@ -82,4 +82,4 @@
} }
] ]
} }
] ]

View File

@ -334,7 +334,7 @@
"tests": [ "tests": [
{ {
"description": "valid tree", "description": "valid tree",
"data": { "data": {
"meta": "root", "meta": "root",
"nodes": [ "nodes": [
{ {
@ -363,7 +363,7 @@
}, },
{ {
"description": "invalid tree", "description": "invalid tree",
"data": { "data": {
"meta": "root", "meta": "root",
"nodes": [ "nodes": [
{ {

View File

@ -149,7 +149,7 @@ int main()
// TODO when we set `string` in array and set `contentEncoding` = "binary" - what it means? We expected string or binary? // TODO when we set `string` in array and set `contentEncoding` = "binary" - what it means? We expected string or binary?
// Or we expect only binary? Now if you set `contentEncoding` = "binary", then it means that you expect only binary data, // Or we expect only binary? Now if you set `contentEncoding` = "binary", then it means that you expect only binary data,
// not string // not string
//val.validate({{"something", "string"}}, err); -> produce error about type // val.validate({{"something", "string"}}, err); -> produce error about type
EXPECT_EQ(err.failed_pointers.size(), 0); EXPECT_EQ(err.failed_pointers.size(), 0);
err.reset(); err.reset();

View File

@ -1,15 +0,0 @@
# Configure install script
configure_file(test.sh.in
${CMAKE_CURRENT_BINARY_DIR}/test.sh @ONLY)
get_filename_component(TEST_NAME
${CMAKE_CURRENT_SOURCE_DIR}
NAME)
# this build test only works, if nlohmann-json was found via a cmake-package
if(TARGET nlohmann_json::nlohmann_json)
add_test(NAME Build::${TEST_NAME}
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test.sh
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endif()

View File

@ -1,34 +0,0 @@
# This is a simple project that tests using cmake to load the installed libraries
cmake_minimum_required(VERSION 3.2)
project(cmake_install_test LANGUAGES CXX)
set(PROJECT_VERSION 1.0.0)
# Find the nlohmann_json and the validator package
set(CMAKE_FIND_DEBUG_MODE ON)
find_package(nlohmann_json REQUIRED)
find_package(nlohmann_json_schema_validator REQUIRED)
# Add simple json-schema-validator-executable
add_executable(json-schema-validate ${CMAKE_CURRENT_SOURCE_DIR}/../../../app/json-schema-validate.cpp)
target_link_libraries(json-schema-validate nlohmann_json_schema_validator)
enable_testing()
# Add built-in tests function needed for issues
set(PIPE_IN_TEST_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/../../test-pipe-in.sh)
function(add_test_simple_schema name schema instance)
add_test(
NAME ${name}
COMMAND ${PIPE_IN_TEST_SCRIPT}
$<TARGET_FILE:json-schema-validate>
${schema}
${instance}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endfunction()
# Run tests for issues 9, 12, 27, 48, 54
foreach(NUMBER "9" "12" "27" "48" "54")
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../issue-${NUMBER}" "${CMAKE_CURRENT_BINARY_DIR}/issue-${NUMBER}" EXCLUDE_FROM_ALL)
endforeach()

View File

@ -1,55 +0,0 @@
#!/bin/bash
## Configure, build, install, and test json-schema-validator with CMAKE
## This script is instantiated via configure_file() to run cmake the same the original build has been invoked.
set -xe
EXTRA_ARGS=$@
SRC_DIR=@PROJECT_SOURCE_DIR@
BUILD_DIR=@CMAKE_CURRENT_BINARY_DIR@/build-dir
INSTALL_DIR=@CMAKE_CURRENT_BINARY_DIR@/install-dir
NLOHMANN_JSON_DIR=@nlohmann_json_DIR@
TEST_SRC_DIR=@CMAKE_CURRENT_SOURCE_DIR@/project
cmake --version
# Clear out build directory
rm -rf ${BUILD_DIR}
# Create build-dir
mkdir -p ${BUILD_DIR}
cd ${BUILD_DIR}
# configure json-schema-validator
printf "\n-----------------------------------------------------------\n"
printf "Configuring, building, and installing json-schema-validator"
printf "\n-----------------------------------------------------------\n"
cmake \
-DCMAKE_INSTALL_PREFIX:PATH=${INSTALL_DIR} \
-Dnlohmann_json_DIR:PATH=${NLOHMANN_JSON_DIR} \
${EXTRA_ARGS} \
${SRC_DIR}
CPU_COUNT=$(nproc)
# Build and install json-schema-validator
cmake --build . -- -j${CPU_COUNT}
cmake --build . --target install -- -j${CPU_COUNT}
# Make sure build directory is empty
rm -rf ./*
# configure test project
printf "\n-----------------------------------------------------------\n"
printf "Configuring, building, and running test project"
printf "\n-----------------------------------------------------------\n"
cmake \
-Dnlohmann_json_DIR:PATH=${NLOHMANN_JSON_DIR} \
-Dnlohmann_json_schema_validator_DIR:PATH=${INSTALL_DIR}/lib/cmake/nlohmann_json_schema_validator \
-DVALIDATOR_INSTALL_DIR:PATH=${INSTALL_DIR} \
${EXTRA_ARGS} \
${TEST_SRC_DIR}
# Build test project and test
cmake --build .
ctest --output-on-failure

View File

@ -119,7 +119,7 @@ int main(void)
{"age", 42}, {"age", 42},
{"name", "John"}, {"name", "John"},
{"phones", {0}}, {"phones", {0}},
{"post-code", 12345}, {"post-code", 12345},
}, },
err); // name must be a string err); // name must be a string
EXPECT_EQ(err.failed_pointers.size(), 1); EXPECT_EQ(err.failed_pointers.size(), 1);

View File

@ -64,7 +64,7 @@ auto schema_draft = R"(
urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f
urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f# urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f#
http://example.com/root.json#/definitions/C http://example.com/root.json#/definitions/C
*/ */
auto schema = R"( auto schema = R"(
{ {

View File

@ -102,7 +102,7 @@ int main(void)
const auto &readPath = single_op["path"].get<std::string>(); const auto &readPath = single_op["path"].get<std::string>();
if (readPath != "/address/street") { if (readPath != "/address/street") {
std::cerr << "Patch with defaults contains wrong path. It is " << readPath << " and should be " std::cerr << "Patch with defaults contains wrong path. It is " << readPath << " and should be "
<< "/address/street" << std::endl; << "/address/street" << std::endl;
return 1; return 1;
} }
@ -156,7 +156,7 @@ int main(void)
const auto &readPath = single_op["path"].get<std::string>(); const auto &readPath = single_op["path"].get<std::string>();
if (readPath != "/address") { if (readPath != "/address") {
std::cerr << "Patch with defaults contains wrong path. It is " << readPath << " and should be " std::cerr << "Patch with defaults contains wrong path. It is " << readPath << " and should be "
<< "/address" << std::endl; << "/address" << std::endl;
return 1; return 1;
} }
@ -165,7 +165,7 @@ int main(void)
return 1; return 1;
} }
if ( !single_op["value"].is_object() || !single_op["value"].empty()) { if (!single_op["value"].is_object() || !single_op["value"].empty()) {
std::cerr << "Patch with defaults contains wrong value" << std::endl; std::cerr << "Patch with defaults contains wrong value" << std::endl;
return 1; return 1;
} }

View File

@ -4,5 +4,3 @@ add_test_simple_schema(Issue::27
set_tests_properties(Issue::27 set_tests_properties(Issue::27
PROPERTIES PROPERTIES
WILL_FAIL 1) WILL_FAIL 1)

View File

@ -112,7 +112,7 @@ int main(void)
{"age", 42}, {"age", 42},
{"name", "John"}, {"name", "John"},
{"phones", {0}}, {"phones", {0}},
{"post-code", 12345}, {"post-code", 12345},
}, },
err); // name must be a string err); // name must be a string
EXPECT_EQ(err.failed_pointers.size(), 1); EXPECT_EQ(err.failed_pointers.size(), 1);

View File

@ -10,4 +10,4 @@
"type": "string" "type": "string"
} }
} }
} }

View File

@ -10,4 +10,4 @@
"type": "string" "type": "string"
} }
} }
} }

View File

@ -20,29 +20,29 @@ using nlohmann::json_patch;
code; \ code; \
std::cerr << "UNEXPECTED SUCCESS.\n"; \ std::cerr << "UNEXPECTED SUCCESS.\n"; \
return 1; \ return 1; \
} catch (const std::exception &e) { \ } catch (const std::exception &e) { \
std::cerr << "EXPECTED FAIL: " << e.what() << "\n"; \ std::cerr << "EXPECTED FAIL: " << e.what() << "\n"; \
} \ } \
} while (0) } while (0)
int main(void) int main(void)
{ {
OK( json_patch p1( R"([{"op":"add","path":"/0/renderable/bg","value":"Black"}])"_json)); OK(json_patch p1(R"([{"op":"add","path":"/0/renderable/bg","value":"Black"}])"_json));
OK( json_patch p1( R"([{"op":"replace","path":"/0/renderable/bg","value":"Black"}])"_json)); OK(json_patch p1(R"([{"op":"replace","path":"/0/renderable/bg","value":"Black"}])"_json));
OK( json_patch p1( R"([{"op":"remove","path":"/0/renderable/bg"}])"_json)); OK(json_patch p1(R"([{"op":"remove","path":"/0/renderable/bg"}])"_json));
// value not needed // value not needed
KO( json_patch p1( R"([{"op":"remove","path":"/0/renderable/bg", "value":"Black"}])"_json)); KO(json_patch p1(R"([{"op":"remove","path":"/0/renderable/bg", "value":"Black"}])"_json));
// value missing // value missing
KO( json_patch p1( R"([{"op":"add","path":"/0/renderable/bg"}])"_json)); KO(json_patch p1(R"([{"op":"add","path":"/0/renderable/bg"}])"_json));
// value missing // value missing
KO( json_patch p1( R"([{"op":"replace","path":"/0/renderable/bg"}])"_json)); KO(json_patch p1(R"([{"op":"replace","path":"/0/renderable/bg"}])"_json));
// wrong op // wrong op
KO( json_patch p1( R"([{"op":"ad","path":"/0/renderable/bg","value":"Black"}])"_json)); KO(json_patch p1(R"([{"op":"ad","path":"/0/renderable/bg","value":"Black"}])"_json));
// invalid json-pointer // invalid json-pointer
KO( json_patch p1( R"([{"op":"add","path":"0/renderable/bg","value":"Black"}])"_json)); KO(json_patch p1(R"([{"op":"add","path":"0/renderable/bg","value":"Black"}])"_json));
return 0; return 0;
} }