From 3fed057513d3b9bd64d31b81937756ddaa7202bf Mon Sep 17 00:00:00 2001 From: "Cameron T. Druyor" Date: Thu, 28 Apr 2016 17:49:14 -0400 Subject: [PATCH 01/12] Just poking around right now. --- src/json.hpp | 5 +++++ test/unit.cpp | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index 57a8f4c72..60387e9c9 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -6294,6 +6294,11 @@ class basic_json << std::fixed << m_value.number_float; o << ss.str(); } + std::stringstream applesauce; + applesauce << o.rdbuf(); + std::string s2 = applesauce.str(); + if(s2.compare("2e01") == 0) + throw std::logic_error("found it"); } else { diff --git a/test/unit.cpp b/test/unit.cpp index 2666e1111..4a06e3041 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -12716,7 +12716,7 @@ TEST_CASE("regression tests") json j2a = 2342e-2; //issue #230 - //json j2b = json::parse("2342e-2"); + json j2b = json::parse("2342e-2"); json j3a = 10E3; json j3b = json::parse("10E3"); @@ -12740,7 +12740,7 @@ TEST_CASE("regression tests") CHECK(j2a.dump() == "23.42"); //issue #230 - //CHECK(j2b.dump() == "23.42"); + CHECK(j2b.dump() == "23.42"); CHECK(j3a.dump() == "10000"); CHECK(j3b.dump() == "1E04"); @@ -12757,4 +12757,5 @@ TEST_CASE("regression tests") CHECK(dest == expected); } + } From cd2e559efd1b45f5e7906f4c107abc071104a173 Mon Sep 17 00:00:00 2001 From: "Cameron T. Druyor" Date: Thu, 28 Apr 2016 22:43:11 -0400 Subject: [PATCH 02/12] added a helper function to make it easier to identify issue 230 at different execution points. --- src/Issue230Helpers.h | 15 +++++++++++++++ src/json.hpp | 11 ++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/Issue230Helpers.h diff --git a/src/Issue230Helpers.h b/src/Issue230Helpers.h new file mode 100644 index 000000000..c183dc527 --- /dev/null +++ b/src/Issue230Helpers.h @@ -0,0 +1,15 @@ +#pragma once + +template +bool isIssue230(MType& m_type, MValue& m_value){ + if(m_value.number_float != 23.42) + return false; + if(m_type.bits.exp_cap == 0 and + m_type.bits.exp_plus == 0 and + m_type.bits.has_exp == 1 and + m_type.bits.parsed == 1 and + m_type.bits.precision == 0 and + m_type.bits.type == 7) + return true; + return false; +} \ No newline at end of file diff --git a/src/json.hpp b/src/json.hpp index 60387e9c9..49e88fa65 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -52,6 +52,7 @@ SOFTWARE. #include #include #include +#include "Issue230Helpers.h" // disable float-equal warnings on GCC/clang #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) @@ -6297,8 +6298,16 @@ class basic_json std::stringstream applesauce; applesauce << o.rdbuf(); std::string s2 = applesauce.str(); - if(s2.compare("2e01") == 0) + if(isIssue230(m_type,m_value)) { + printf("m_type.bits.exp_cap = %i \n",m_type.bits.exp_cap); + printf("m_type.bits.exp_plus = %i \n",m_type.bits.exp_plus); + printf("m_type.bits.has_exp = %i \n",m_type.bits.has_exp); + printf("m_type.bits.parsed = %i \n",m_type.bits.parsed); + printf("m_type.bits.precision = %i \n",m_type.bits.precision); + printf("m_type.bits.type = %i \n",m_type.bits.type); + printf("m_value = %f\n",m_value.number_float); throw std::logic_error("found it"); + } } else { From e2163c36b56f632f70d2d98c22da87fddbcbdd17 Mon Sep 17 00:00:00 2001 From: "Cameron T. Druyor" Date: Fri, 29 Apr 2016 16:48:05 -0400 Subject: [PATCH 03/12] to add diabolical test case with trailing zeros and no radix point --- src/json.hpp | 31 +++++++++++++++++-------------- test/unit.cpp | 5 ++++- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index 49e88fa65..a29803901 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -6295,19 +6295,6 @@ class basic_json << std::fixed << m_value.number_float; o << ss.str(); } - std::stringstream applesauce; - applesauce << o.rdbuf(); - std::string s2 = applesauce.str(); - if(isIssue230(m_type,m_value)) { - printf("m_type.bits.exp_cap = %i \n",m_type.bits.exp_cap); - printf("m_type.bits.exp_plus = %i \n",m_type.bits.exp_plus); - printf("m_type.bits.has_exp = %i \n",m_type.bits.has_exp); - printf("m_type.bits.parsed = %i \n",m_type.bits.parsed); - printf("m_type.bits.precision = %i \n",m_type.bits.precision); - printf("m_type.bits.type = %i \n",m_type.bits.type); - printf("m_value = %f\n",m_value.number_float); - throw std::logic_error("found it"); - } } else { @@ -8635,7 +8622,23 @@ basic_json_parser_63: // If no radix point was found then precision would now be set to // the number of digits, which is wrong - clear it. - result.m_type.bits.precision = precision & found_radix_point; + if(found_radix_point == 0) { + auto ptr = m_start; + int trailing_zeros = 0; + for (int j = precision-1;j>=0;--j){ + if(*(ptr+j) == '0') + ++trailing_zeros; + else if(*(ptr+j) > '0' and *(ptr+j) <= '9' or *(ptr+j) == '-') + break; + else + throw std::logic_error("wtf character did I grab?: "+std::to_string(*(ptr+j))); + } + precision -= trailing_zeros; + result.m_type.bits.precision = precision-1; + } + else{ + result.m_type.bits.precision = precision & found_radix_point; + } // save the value (if not a float) if (type == value_t::number_unsigned) diff --git a/test/unit.cpp b/test/unit.cpp index 4a06e3041..8f0e3c6cb 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -12717,6 +12717,8 @@ TEST_CASE("regression tests") json j2a = 2342e-2; //issue #230 json j2b = json::parse("2342e-2"); + //diabolical version + json j2c = json::parse("234200e-4"); json j3a = 10E3; json j3b = json::parse("10E3"); @@ -12740,7 +12742,8 @@ TEST_CASE("regression tests") CHECK(j2a.dump() == "23.42"); //issue #230 - CHECK(j2b.dump() == "23.42"); + CHECK(j2b.dump() == "2.342e01"); + CHECK(j2c.dump() == "2.342e01"); CHECK(j3a.dump() == "10000"); CHECK(j3b.dump() == "1E04"); From 3beff40c37e8f60178a44ab5768f4f7a27c66271 Mon Sep 17 00:00:00 2001 From: "Cameron T. Druyor" Date: Fri, 29 Apr 2016 16:49:04 -0400 Subject: [PATCH 04/12] to get rid of debugging helper functions --- src/Issue230Helpers.h | 15 --------------- src/json.hpp | 1 - 2 files changed, 16 deletions(-) delete mode 100644 src/Issue230Helpers.h diff --git a/src/Issue230Helpers.h b/src/Issue230Helpers.h deleted file mode 100644 index c183dc527..000000000 --- a/src/Issue230Helpers.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -template -bool isIssue230(MType& m_type, MValue& m_value){ - if(m_value.number_float != 23.42) - return false; - if(m_type.bits.exp_cap == 0 and - m_type.bits.exp_plus == 0 and - m_type.bits.has_exp == 1 and - m_type.bits.parsed == 1 and - m_type.bits.precision == 0 and - m_type.bits.type == 7) - return true; - return false; -} \ No newline at end of file diff --git a/src/json.hpp b/src/json.hpp index a29803901..1f0de5ee2 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -52,7 +52,6 @@ SOFTWARE. #include #include #include -#include "Issue230Helpers.h" // disable float-equal warnings on GCC/clang #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) From 25ba51ec000127b591760ec3a0eb2817646ab934 Mon Sep 17 00:00:00 2001 From: "Cameron T. Druyor" Date: Fri, 29 Apr 2016 17:10:36 -0400 Subject: [PATCH 05/12] updating to better match the style of the rest of the codebase --- src/json.hpp | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index 1f0de5ee2..e851a91d5 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -8537,9 +8537,8 @@ basic_json_parser_63: // remember this number was parsed (for later serialization) result.m_type.bits.parsed = true; - // 'found_radix_point' will be set to 0xFF upon finding a radix - // point and later used to mask in/out the precision depending - // whether a radix is found i.e. 'precision &= found_radix_point' + // 'found_radix_point' will be set to true upon finding a radix + // point. If no radix point is found, the precision will be corrected uint8_t found_radix_point = 0; uint8_t precision = 0; @@ -8620,24 +8619,23 @@ basic_json_parser_63: } // If no radix point was found then precision would now be set to - // the number of digits, which is wrong - clear it. - if(found_radix_point == 0) { - auto ptr = m_start; + // the number of digits, which is wrong - decrement it to sig figs - 1 + if(found_radix_point == 0) + { int trailing_zeros = 0; - for (int j = precision-1;j>=0;--j){ - if(*(ptr+j) == '0') + for (int j = precision-1;j>=0;--j) + { + auto c = *(m_start+j); + if(c == '0') ++trailing_zeros; - else if(*(ptr+j) > '0' and *(ptr+j) <= '9' or *(ptr+j) == '-') + else if(c > '0' and c <= '9' or c == '-') break; else - throw std::logic_error("wtf character did I grab?: "+std::to_string(*(ptr+j))); + throw std::logic_error("unexpected character: "+std::to_string(c)); } - precision -= trailing_zeros; - result.m_type.bits.precision = precision-1; - } - else{ - result.m_type.bits.precision = precision & found_radix_point; + precision -= (trailing_zeros + 1); } + result.m_type.bits.precision = precision; // save the value (if not a float) if (type == value_t::number_unsigned) From 8468750409130ecd9d66360ca695b858da4533e3 Mon Sep 17 00:00:00 2001 From: "Cameron T. Druyor" Date: Fri, 29 Apr 2016 20:44:51 -0400 Subject: [PATCH 06/12] After realizing how the lexer code generation works, I went back and made my changes to json.hpp.re2c as I should have. Tests back to green, with no direct edits to json.hpp --- Makefile | 306 +++++++++---- src/json.hpp | 1075 +++++++++++++++------------------------------ src/json.hpp.re2c | 26 +- 3 files changed, 586 insertions(+), 821 deletions(-) diff --git a/Makefile b/Makefile index d0a80379c..de45dd68e 100644 --- a/Makefile +++ b/Makefile @@ -1,98 +1,226 @@ -.PHONY: pretty clean ChangeLog.md +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 -# used programs -RE2C = re2c -SED = sed +# Default target executed when no arguments are given to make. +default_target: all -# main target -all: json_unit +.PHONY : default_target -# clean up +# Allow only one "make -f Makefile2" at a time, but pass parallelism. +.NOTPARALLEL: + + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + + +# A target that is always out of date. +cmake_force: + +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/local/Cellar/cmake/3.5.1/bin/cmake + +# The command to remove a file. +RM = /usr/local/Cellar/cmake/3.5.1/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /Users/cameron/Projects/json + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /Users/cameron/Projects/json + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/local/Cellar/cmake/3.5.1/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache + +.PHONY : rebuild_cache/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components + +.PHONY : list_install_components/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/local/Cellar/cmake/3.5.1/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/local/Cellar/cmake/3.5.1/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/local/Cellar/cmake/3.5.1/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: install/strip + +.PHONY : install/strip/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/local/Cellar/cmake/3.5.1/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: install/local + +.PHONY : install/local/fast + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..." + /usr/local/Cellar/cmake/3.5.1/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache + +.PHONY : edit_cache/fast + +# The main all target +all: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /Users/cameron/Projects/json/CMakeFiles /Users/cameron/Projects/json/CMakeFiles/progress.marks + $(MAKE) -f CMakeFiles/Makefile2 all + $(CMAKE_COMMAND) -E cmake_progress_start /Users/cameron/Projects/json/CMakeFiles 0 +.PHONY : all + +# The main clean target clean: - rm -fr json_unit json_benchmarks fuzz fuzz-testing *.dSYM + $(MAKE) -f CMakeFiles/Makefile2 clean +.PHONY : clean + +# The main clean target +clean/fast: clean + +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +#============================================================================= +# Target rules for targets named json_unit + +# Build rule for target. +json_unit: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 json_unit +.PHONY : json_unit + +# fast build rule for target. +json_unit/fast: + $(MAKE) -f CMakeFiles/json_unit.dir/build.make CMakeFiles/json_unit.dir/build +.PHONY : json_unit/fast + +test/unit.o: test/unit.cpp.o + +.PHONY : test/unit.o + +# target to build an object file +test/unit.cpp.o: + $(MAKE) -f CMakeFiles/json_unit.dir/build.make CMakeFiles/json_unit.dir/test/unit.cpp.o +.PHONY : test/unit.cpp.o + +test/unit.i: test/unit.cpp.i + +.PHONY : test/unit.i + +# target to preprocess a source file +test/unit.cpp.i: + $(MAKE) -f CMakeFiles/json_unit.dir/build.make CMakeFiles/json_unit.dir/test/unit.cpp.i +.PHONY : test/unit.cpp.i + +test/unit.s: test/unit.cpp.s + +.PHONY : test/unit.s + +# target to generate assembly for a file +test/unit.cpp.s: + $(MAKE) -f CMakeFiles/json_unit.dir/build.make CMakeFiles/json_unit.dir/test/unit.cpp.s +.PHONY : test/unit.cpp.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... rebuild_cache" + @echo "... list_install_components" + @echo "... install" + @echo "... install/strip" + @echo "... install/local" + @echo "... edit_cache" + @echo "... json_unit" + @echo "... test/unit.o" + @echo "... test/unit.i" + @echo "... test/unit.s" +.PHONY : help -########################################################################## -# unit tests -########################################################################## -# additional flags -FLAGS = -Wall -Wextra -pedantic -Weffc++ -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-declarations -Wmissing-include-dirs -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-overflow=5 -Wswitch -Wundef -Wno-unused -Wnon-virtual-dtor -Wreorder -Wdeprecated -Wfloat-equal +#============================================================================= +# Special targets to cleanup operation of make. -# build unit tests -json_unit: test/unit.cpp src/json.hpp test/catch.hpp - $(CXX) -std=c++11 $(CXXFLAGS) $(FLAGS) $(CPPFLAGS) -I src -I test $< $(LDFLAGS) -o $@ +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system - -########################################################################## -# documentation tests -########################################################################## - -# compile example files and check output -doctest: - make check_output -C doc - - -########################################################################## -# fuzzing -########################################################################## - -# the overall fuzz testing target -fuzz_testing: - rm -fr fuzz-testing - mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out - $(MAKE) fuzz CXX=afl-clang++ - mv fuzz fuzz-testing - find test/json_tests -size -5k -name *json | xargs -I{} cp "{}" fuzz-testing/testcases - @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzz" - -# the fuzzer binary -fuzz: test/fuzz.cpp src/json.hpp - $(CXX) -std=c++11 $(CXXFLAGS) $(FLAGS) $(CPPFLAGS) -I src $< $(LDFLAGS) -o $@ - - -########################################################################## -# static analyzer -########################################################################## - -# call cppcheck on the main header file -cppcheck: - cppcheck --enable=all --inconclusive --std=c++11 src/json.hpp - - -########################################################################## -# maintainer targets -########################################################################## - -# create scanner with re2c -re2c: src/json.hpp.re2c - $(RE2C) --bit-vectors --nested-ifs --no-debug-info $< | $(SED) '1d' > src/json.hpp - -# pretty printer -pretty: - astyle --style=allman --indent=spaces=4 --indent-modifiers \ - --indent-switches --indent-preproc-block --indent-preproc-define \ - --indent-col1-comments --pad-oper --pad-header --align-pointer=type \ - --align-reference=type --add-brackets --convert-tabs --close-templates \ - --lineend=linux --preserve-date --suffix=none --formatted \ - src/json.hpp src/json.hpp.re2c test/unit.cpp test/fuzz.cpp benchmarks/benchmarks.cpp doc/examples/*.cpp - - -########################################################################## -# benchmarks -########################################################################## - -# benchmarks -json_benchmarks: benchmarks/benchmarks.cpp benchmarks/benchpress.hpp benchmarks/cxxopts.hpp src/json.hpp - $(CXX) -std=c++11 $(CXXFLAGS) -O3 -flto -I src -I benchmarks $< $(LDFLAGS) -o $@ - ./json_benchmarks - - -########################################################################## -# changelog -########################################################################## - -ChangeLog.md: - github_changelog_generator -o ChangeLog.md --simple-list --release-url https://github.com/nlohmann/json/releases/tag/%s - gsed -i 's|https://github.com/nlohmann/json/releases/tag/HEAD|https://github.com/nlohmann/json/tree/HEAD|' ChangeLog.md - gsed -i '2i All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).' ChangeLog.md diff --git a/src/json.hpp b/src/json.hpp index e851a91d5..fa5fb5c43 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -7523,758 +7523,381 @@ class basic_json m_start = m_cursor; assert(m_start != nullptr); - - { - lexer_char_t yych; - unsigned int yyaccept = 0; - static const unsigned char yybm[] = - { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 32, 0, 0, 32, 0, 0, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 160, 128, 0, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 0, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - }; - if ((m_limit - m_cursor) < 5) - { - yyfill(); // LCOV_EXCL_LINE; + + { + lexer_char_t yych; + unsigned int yyaccept = 0; + static const unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 32, 0, 0, 32, 0, 0, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 160, 128, 0, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 0, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + }; + if ((m_limit - m_cursor) < 5) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yybm[0+yych] & 32) { + goto basic_json_parser_6; + } + if (yych <= '\\') { + if (yych <= '-') { + if (yych <= '"') { + if (yych <= 0x00) goto basic_json_parser_2; + if (yych <= '!') goto basic_json_parser_4; + goto basic_json_parser_9; + } else { + if (yych <= '+') goto basic_json_parser_4; + if (yych <= ',') goto basic_json_parser_10; + goto basic_json_parser_12; } - yych = *m_cursor; - if (yybm[0 + yych] & 32) - { - goto basic_json_parser_6; + } else { + if (yych <= '9') { + if (yych <= '/') goto basic_json_parser_4; + if (yych <= '0') goto basic_json_parser_13; + goto basic_json_parser_15; + } else { + if (yych <= ':') goto basic_json_parser_17; + if (yych == '[') goto basic_json_parser_19; + goto basic_json_parser_4; } - if (yych <= '\\') - { - if (yych <= '-') - { - if (yych <= '"') - { - if (yych <= 0x00) - { - goto basic_json_parser_2; - } - if (yych <= '!') - { - goto basic_json_parser_4; - } - goto basic_json_parser_9; - } - else - { - if (yych <= '+') - { - goto basic_json_parser_4; - } - if (yych <= ',') - { - goto basic_json_parser_10; - } - goto basic_json_parser_12; - } - } - else - { - if (yych <= '9') - { - if (yych <= '/') - { - goto basic_json_parser_4; - } - if (yych <= '0') - { - goto basic_json_parser_13; - } - goto basic_json_parser_15; - } - else - { - if (yych <= ':') - { - goto basic_json_parser_17; - } - if (yych == '[') - { - goto basic_json_parser_19; - } - goto basic_json_parser_4; - } - } + } + } else { + if (yych <= 't') { + if (yych <= 'f') { + if (yych <= ']') goto basic_json_parser_21; + if (yych <= 'e') goto basic_json_parser_4; + goto basic_json_parser_23; + } else { + if (yych == 'n') goto basic_json_parser_24; + if (yych <= 's') goto basic_json_parser_4; + goto basic_json_parser_25; } - else - { - if (yych <= 't') - { - if (yych <= 'f') - { - if (yych <= ']') - { - goto basic_json_parser_21; - } - if (yych <= 'e') - { - goto basic_json_parser_4; - } - goto basic_json_parser_23; - } - else - { - if (yych == 'n') - { - goto basic_json_parser_24; - } - if (yych <= 's') - { - goto basic_json_parser_4; - } - goto basic_json_parser_25; - } - } - else - { - if (yych <= '|') - { - if (yych == '{') - { - goto basic_json_parser_26; - } - goto basic_json_parser_4; - } - else - { - if (yych <= '}') - { - goto basic_json_parser_28; - } - if (yych == 0xEF) - { - goto basic_json_parser_30; - } - goto basic_json_parser_4; - } - } + } else { + if (yych <= '|') { + if (yych == '{') goto basic_json_parser_26; + goto basic_json_parser_4; + } else { + if (yych <= '}') goto basic_json_parser_28; + if (yych == 0xEF) goto basic_json_parser_30; + goto basic_json_parser_4; } + } + } basic_json_parser_2: - ++m_cursor; - { - return token_type::end_of_input; - } + ++m_cursor; + { return token_type::end_of_input; } basic_json_parser_4: - ++m_cursor; + ++m_cursor; basic_json_parser_5: - { - return token_type::parse_error; - } + { return token_type::parse_error; } basic_json_parser_6: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yybm[0 + yych] & 32) - { - goto basic_json_parser_6; - } - { - return scan(); - } + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yybm[0+yych] & 32) { + goto basic_json_parser_6; + } + { return scan(); } basic_json_parser_9: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych <= 0x0F) - { - goto basic_json_parser_5; - } - goto basic_json_parser_32; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych <= 0x0F) goto basic_json_parser_5; + goto basic_json_parser_32; basic_json_parser_10: - ++m_cursor; - { - return token_type::value_separator; - } + ++m_cursor; + { return token_type::value_separator; } basic_json_parser_12: - yych = *++m_cursor; - if (yych <= '/') - { - goto basic_json_parser_5; - } - if (yych <= '0') - { - goto basic_json_parser_13; - } - if (yych <= '9') - { - goto basic_json_parser_15; - } - goto basic_json_parser_5; + yych = *++m_cursor; + if (yych <= '/') goto basic_json_parser_5; + if (yych <= '0') goto basic_json_parser_13; + if (yych <= '9') goto basic_json_parser_15; + goto basic_json_parser_5; basic_json_parser_13: - yyaccept = 1; - yych = *(m_marker = ++m_cursor); - if (yych <= 'D') - { - if (yych == '.') - { - goto basic_json_parser_37; - } - } - else - { - if (yych <= 'E') - { - goto basic_json_parser_38; - } - if (yych == 'e') - { - goto basic_json_parser_38; - } - } + yyaccept = 1; + yych = *(m_marker = ++m_cursor); + if (yych <= 'D') { + if (yych == '.') goto basic_json_parser_37; + } else { + if (yych <= 'E') goto basic_json_parser_38; + if (yych == 'e') goto basic_json_parser_38; + } basic_json_parser_14: - { - return token_type::value_number; - } + { return token_type::value_number; } basic_json_parser_15: - yyaccept = 1; - m_marker = ++m_cursor; - if ((m_limit - m_cursor) < 3) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yybm[0 + yych] & 64) - { - goto basic_json_parser_15; - } - if (yych <= 'D') - { - if (yych == '.') - { - goto basic_json_parser_37; - } - goto basic_json_parser_14; - } - else - { - if (yych <= 'E') - { - goto basic_json_parser_38; - } - if (yych == 'e') - { - goto basic_json_parser_38; - } - goto basic_json_parser_14; - } + yyaccept = 1; + m_marker = ++m_cursor; + if ((m_limit - m_cursor) < 3) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yybm[0+yych] & 64) { + goto basic_json_parser_15; + } + if (yych <= 'D') { + if (yych == '.') goto basic_json_parser_37; + goto basic_json_parser_14; + } else { + if (yych <= 'E') goto basic_json_parser_38; + if (yych == 'e') goto basic_json_parser_38; + goto basic_json_parser_14; + } basic_json_parser_17: - ++m_cursor; - { - return token_type::name_separator; - } + ++m_cursor; + { return token_type::name_separator; } basic_json_parser_19: - ++m_cursor; - { - return token_type::begin_array; - } + ++m_cursor; + { return token_type::begin_array; } basic_json_parser_21: - ++m_cursor; - { - return token_type::end_array; - } + ++m_cursor; + { return token_type::end_array; } basic_json_parser_23: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'a') - { - goto basic_json_parser_39; - } - goto basic_json_parser_5; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'a') goto basic_json_parser_39; + goto basic_json_parser_5; basic_json_parser_24: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'u') - { - goto basic_json_parser_40; - } - goto basic_json_parser_5; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'u') goto basic_json_parser_40; + goto basic_json_parser_5; basic_json_parser_25: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 'r') - { - goto basic_json_parser_41; - } - goto basic_json_parser_5; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 'r') goto basic_json_parser_41; + goto basic_json_parser_5; basic_json_parser_26: - ++m_cursor; - { - return token_type::begin_object; - } + ++m_cursor; + { return token_type::begin_object; } basic_json_parser_28: - ++m_cursor; - { - return token_type::end_object; - } + ++m_cursor; + { return token_type::end_object; } basic_json_parser_30: - yyaccept = 0; - yych = *(m_marker = ++m_cursor); - if (yych == 0xBB) - { - goto basic_json_parser_42; - } - goto basic_json_parser_5; + yyaccept = 0; + yych = *(m_marker = ++m_cursor); + if (yych == 0xBB) goto basic_json_parser_42; + goto basic_json_parser_5; basic_json_parser_31: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; basic_json_parser_32: - if (yybm[0 + yych] & 128) - { - goto basic_json_parser_31; - } - if (yych <= 0x0F) - { - goto basic_json_parser_33; - } - if (yych <= '"') - { - goto basic_json_parser_34; - } - goto basic_json_parser_36; + if (yybm[0+yych] & 128) { + goto basic_json_parser_31; + } + if (yych <= 0x0F) goto basic_json_parser_33; + if (yych <= '"') goto basic_json_parser_34; + goto basic_json_parser_36; basic_json_parser_33: - m_cursor = m_marker; - if (yyaccept == 0) - { - goto basic_json_parser_5; - } - else - { - goto basic_json_parser_14; - } + m_cursor = m_marker; + if (yyaccept == 0) { + goto basic_json_parser_5; + } else { + goto basic_json_parser_14; + } basic_json_parser_34: - ++m_cursor; - { - return token_type::value_string; - } + ++m_cursor; + { return token_type::value_string; } basic_json_parser_36: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= 'e') - { - if (yych <= '/') - { - if (yych == '"') - { - goto basic_json_parser_31; - } - if (yych <= '.') - { - goto basic_json_parser_33; - } - goto basic_json_parser_31; - } - else - { - if (yych <= '\\') - { - if (yych <= '[') - { - goto basic_json_parser_33; - } - goto basic_json_parser_31; - } - else - { - if (yych == 'b') - { - goto basic_json_parser_31; - } - goto basic_json_parser_33; - } - } - } - else - { - if (yych <= 'q') - { - if (yych <= 'f') - { - goto basic_json_parser_31; - } - if (yych == 'n') - { - goto basic_json_parser_31; - } - goto basic_json_parser_33; - } - else - { - if (yych <= 's') - { - if (yych <= 'r') - { - goto basic_json_parser_31; - } - goto basic_json_parser_33; - } - else - { - if (yych <= 't') - { - goto basic_json_parser_31; - } - if (yych <= 'u') - { - goto basic_json_parser_43; - } - goto basic_json_parser_33; - } - } - } -basic_json_parser_37: - yych = *++m_cursor; - if (yych <= '/') - { - goto basic_json_parser_33; - } - if (yych <= '9') - { - goto basic_json_parser_44; - } - goto basic_json_parser_33; -basic_json_parser_38: - yych = *++m_cursor; - if (yych <= ',') - { - if (yych == '+') - { - goto basic_json_parser_46; - } - goto basic_json_parser_33; - } - else - { - if (yych <= '-') - { - goto basic_json_parser_46; - } - if (yych <= '/') - { - goto basic_json_parser_33; - } - if (yych <= '9') - { - goto basic_json_parser_47; - } - goto basic_json_parser_33; - } -basic_json_parser_39: - yych = *++m_cursor; - if (yych == 'l') - { - goto basic_json_parser_49; - } - goto basic_json_parser_33; -basic_json_parser_40: - yych = *++m_cursor; - if (yych == 'l') - { - goto basic_json_parser_50; - } - goto basic_json_parser_33; -basic_json_parser_41: - yych = *++m_cursor; - if (yych == 'u') - { - goto basic_json_parser_51; - } - goto basic_json_parser_33; -basic_json_parser_42: - yych = *++m_cursor; - if (yych == 0xBF) - { - goto basic_json_parser_52; - } - goto basic_json_parser_33; -basic_json_parser_43: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= '@') - { - if (yych <= '/') - { - goto basic_json_parser_33; - } - if (yych <= '9') - { - goto basic_json_parser_54; - } - goto basic_json_parser_33; - } - else - { - if (yych <= 'F') - { - goto basic_json_parser_54; - } - if (yych <= '`') - { - goto basic_json_parser_33; - } - if (yych <= 'f') - { - goto basic_json_parser_54; - } - goto basic_json_parser_33; - } -basic_json_parser_44: - yyaccept = 1; - m_marker = ++m_cursor; - if ((m_limit - m_cursor) < 3) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= 'D') - { - if (yych <= '/') - { - goto basic_json_parser_14; - } - if (yych <= '9') - { - goto basic_json_parser_44; - } - goto basic_json_parser_14; - } - else - { - if (yych <= 'E') - { - goto basic_json_parser_38; - } - if (yych == 'e') - { - goto basic_json_parser_38; - } - goto basic_json_parser_14; - } -basic_json_parser_46: - yych = *++m_cursor; - if (yych <= '/') - { - goto basic_json_parser_33; - } - if (yych >= ':') - { - goto basic_json_parser_33; - } -basic_json_parser_47: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= '/') - { - goto basic_json_parser_14; - } - if (yych <= '9') - { - goto basic_json_parser_47; - } - goto basic_json_parser_14; -basic_json_parser_49: - yych = *++m_cursor; - if (yych == 's') - { - goto basic_json_parser_55; - } - goto basic_json_parser_33; -basic_json_parser_50: - yych = *++m_cursor; - if (yych == 'l') - { - goto basic_json_parser_56; - } - goto basic_json_parser_33; -basic_json_parser_51: - yych = *++m_cursor; - if (yych == 'e') - { - goto basic_json_parser_58; - } - goto basic_json_parser_33; -basic_json_parser_52: - ++m_cursor; - { - return scan(); - } -basic_json_parser_54: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= '@') - { - if (yych <= '/') - { - goto basic_json_parser_33; - } - if (yych <= '9') - { - goto basic_json_parser_60; - } - goto basic_json_parser_33; - } - else - { - if (yych <= 'F') - { - goto basic_json_parser_60; - } - if (yych <= '`') - { - goto basic_json_parser_33; - } - if (yych <= 'f') - { - goto basic_json_parser_60; - } - goto basic_json_parser_33; - } -basic_json_parser_55: - yych = *++m_cursor; - if (yych == 'e') - { - goto basic_json_parser_61; - } - goto basic_json_parser_33; -basic_json_parser_56: - ++m_cursor; - { - return token_type::literal_null; - } -basic_json_parser_58: - ++m_cursor; - { - return token_type::literal_true; - } -basic_json_parser_60: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= '@') - { - if (yych <= '/') - { - goto basic_json_parser_33; - } - if (yych <= '9') - { - goto basic_json_parser_63; - } - goto basic_json_parser_33; - } - else - { - if (yych <= 'F') - { - goto basic_json_parser_63; - } - if (yych <= '`') - { - goto basic_json_parser_33; - } - if (yych <= 'f') - { - goto basic_json_parser_63; - } - goto basic_json_parser_33; - } -basic_json_parser_61: - ++m_cursor; - { - return token_type::literal_false; - } -basic_json_parser_63: - ++m_cursor; - if (m_limit <= m_cursor) - { - yyfill(); // LCOV_EXCL_LINE; - } - yych = *m_cursor; - if (yych <= '@') - { - if (yych <= '/') - { - goto basic_json_parser_33; - } - if (yych <= '9') - { - goto basic_json_parser_31; - } - goto basic_json_parser_33; - } - else - { - if (yych <= 'F') - { - goto basic_json_parser_31; - } - if (yych <= '`') - { - goto basic_json_parser_33; - } - if (yych <= 'f') - { - goto basic_json_parser_31; - } + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= 'e') { + if (yych <= '/') { + if (yych == '"') goto basic_json_parser_31; + if (yych <= '.') goto basic_json_parser_33; + goto basic_json_parser_31; + } else { + if (yych <= '\\') { + if (yych <= '[') goto basic_json_parser_33; + goto basic_json_parser_31; + } else { + if (yych == 'b') goto basic_json_parser_31; goto basic_json_parser_33; } } + } else { + if (yych <= 'q') { + if (yych <= 'f') goto basic_json_parser_31; + if (yych == 'n') goto basic_json_parser_31; + goto basic_json_parser_33; + } else { + if (yych <= 's') { + if (yych <= 'r') goto basic_json_parser_31; + goto basic_json_parser_33; + } else { + if (yych <= 't') goto basic_json_parser_31; + if (yych <= 'u') goto basic_json_parser_43; + goto basic_json_parser_33; + } + } + } +basic_json_parser_37: + yych = *++m_cursor; + if (yych <= '/') goto basic_json_parser_33; + if (yych <= '9') goto basic_json_parser_44; + goto basic_json_parser_33; +basic_json_parser_38: + yych = *++m_cursor; + if (yych <= ',') { + if (yych == '+') goto basic_json_parser_46; + goto basic_json_parser_33; + } else { + if (yych <= '-') goto basic_json_parser_46; + if (yych <= '/') goto basic_json_parser_33; + if (yych <= '9') goto basic_json_parser_47; + goto basic_json_parser_33; + } +basic_json_parser_39: + yych = *++m_cursor; + if (yych == 'l') goto basic_json_parser_49; + goto basic_json_parser_33; +basic_json_parser_40: + yych = *++m_cursor; + if (yych == 'l') goto basic_json_parser_50; + goto basic_json_parser_33; +basic_json_parser_41: + yych = *++m_cursor; + if (yych == 'u') goto basic_json_parser_51; + goto basic_json_parser_33; +basic_json_parser_42: + yych = *++m_cursor; + if (yych == 0xBF) goto basic_json_parser_52; + goto basic_json_parser_33; +basic_json_parser_43: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= '@') { + if (yych <= '/') goto basic_json_parser_33; + if (yych <= '9') goto basic_json_parser_54; + goto basic_json_parser_33; + } else { + if (yych <= 'F') goto basic_json_parser_54; + if (yych <= '`') goto basic_json_parser_33; + if (yych <= 'f') goto basic_json_parser_54; + goto basic_json_parser_33; + } +basic_json_parser_44: + yyaccept = 1; + m_marker = ++m_cursor; + if ((m_limit - m_cursor) < 3) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= 'D') { + if (yych <= '/') goto basic_json_parser_14; + if (yych <= '9') goto basic_json_parser_44; + goto basic_json_parser_14; + } else { + if (yych <= 'E') goto basic_json_parser_38; + if (yych == 'e') goto basic_json_parser_38; + goto basic_json_parser_14; + } +basic_json_parser_46: + yych = *++m_cursor; + if (yych <= '/') goto basic_json_parser_33; + if (yych >= ':') goto basic_json_parser_33; +basic_json_parser_47: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= '/') goto basic_json_parser_14; + if (yych <= '9') goto basic_json_parser_47; + goto basic_json_parser_14; +basic_json_parser_49: + yych = *++m_cursor; + if (yych == 's') goto basic_json_parser_55; + goto basic_json_parser_33; +basic_json_parser_50: + yych = *++m_cursor; + if (yych == 'l') goto basic_json_parser_56; + goto basic_json_parser_33; +basic_json_parser_51: + yych = *++m_cursor; + if (yych == 'e') goto basic_json_parser_58; + goto basic_json_parser_33; +basic_json_parser_52: + ++m_cursor; + { return scan(); } +basic_json_parser_54: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= '@') { + if (yych <= '/') goto basic_json_parser_33; + if (yych <= '9') goto basic_json_parser_60; + goto basic_json_parser_33; + } else { + if (yych <= 'F') goto basic_json_parser_60; + if (yych <= '`') goto basic_json_parser_33; + if (yych <= 'f') goto basic_json_parser_60; + goto basic_json_parser_33; + } +basic_json_parser_55: + yych = *++m_cursor; + if (yych == 'e') goto basic_json_parser_61; + goto basic_json_parser_33; +basic_json_parser_56: + ++m_cursor; + { return token_type::literal_null; } +basic_json_parser_58: + ++m_cursor; + { return token_type::literal_true; } +basic_json_parser_60: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= '@') { + if (yych <= '/') goto basic_json_parser_33; + if (yych <= '9') goto basic_json_parser_63; + goto basic_json_parser_33; + } else { + if (yych <= 'F') goto basic_json_parser_63; + if (yych <= '`') goto basic_json_parser_33; + if (yych <= 'f') goto basic_json_parser_63; + goto basic_json_parser_33; + } +basic_json_parser_61: + ++m_cursor; + { return token_type::literal_false; } +basic_json_parser_63: + ++m_cursor; + if (m_limit <= m_cursor) yyfill(); // LCOV_EXCL_LINE; + yych = *m_cursor; + if (yych <= '@') { + if (yych <= '/') goto basic_json_parser_33; + if (yych <= '9') goto basic_json_parser_31; + goto basic_json_parser_33; + } else { + if (yych <= 'F') goto basic_json_parser_31; + if (yych <= '`') goto basic_json_parser_33; + if (yych <= 'f') goto basic_json_parser_31; + goto basic_json_parser_33; + } + } } @@ -8537,9 +8160,9 @@ basic_json_parser_63: // remember this number was parsed (for later serialization) result.m_type.bits.parsed = true; - // 'found_radix_point' will be set to true upon finding a radix - // point. If no radix point is found, the precision will be corrected - uint8_t found_radix_point = 0; + // 'found_radix_point' will be set to 0xFF upon finding a radix + // point. if it is not found, then the precision will be updated + bool found_radix_point = false; uint8_t precision = 0; // accumulate the integer conversion result (unsigned for now) @@ -8581,7 +8204,7 @@ basic_json_parser_63: // reset precision count precision = 0; - found_radix_point = 0xFF; + found_radix_point = true; continue; } // assume exponent (if not then will fail parse): change to @@ -8620,7 +8243,7 @@ basic_json_parser_63: // If no radix point was found then precision would now be set to // the number of digits, which is wrong - decrement it to sig figs - 1 - if(found_radix_point == 0) + if(not found_radix_point) { int trailing_zeros = 0; for (int j = precision-1;j>=0;--j) diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index cdd96ee91..579aad6a7 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -7848,9 +7848,8 @@ class basic_json result.m_type.bits.parsed = true; // 'found_radix_point' will be set to 0xFF upon finding a radix - // point and later used to mask in/out the precision depending - // whether a radix is found i.e. 'precision &= found_radix_point' - uint8_t found_radix_point = 0; + // point. if it is not found, then the precision will be updated + bool found_radix_point = false; uint8_t precision = 0; // accumulate the integer conversion result (unsigned for now) @@ -7892,7 +7891,7 @@ class basic_json // reset precision count precision = 0; - found_radix_point = 0xFF; + found_radix_point = true; continue; } // assume exponent (if not then will fail parse): change to @@ -7930,8 +7929,23 @@ class basic_json } // If no radix point was found then precision would now be set to - // the number of digits, which is wrong - clear it. - result.m_type.bits.precision = precision & found_radix_point; + // the number of digits, which is wrong - decrement it to sig figs - 1 + if(not found_radix_point) + { + int trailing_zeros = 0; + for (int j = precision-1;j>=0;--j) + { + auto c = *(m_start+j); + if(c == '0') + ++trailing_zeros; + else if(c > '0' and c <= '9' or c == '-') + break; + else + throw std::logic_error("unexpected character: "+std::to_string(c)); + } + precision -= (trailing_zeros + 1); + } + result.m_type.bits.precision = precision; // save the value (if not a float) if (type == value_t::number_unsigned) From 372c6dd790c4fbc88ff2a0b4c911a81fc9f1c720 Mon Sep 17 00:00:00 2001 From: "Cameron T. Druyor" Date: Sat, 30 Apr 2016 12:25:30 -0400 Subject: [PATCH 07/12] I accidentally wiped the makefile before, so now I'm putting it back. --- Makefile | 306 ++++++++++++++++--------------------------------------- 1 file changed, 89 insertions(+), 217 deletions(-) diff --git a/Makefile b/Makefile index de45dd68e..d0a80379c 100644 --- a/Makefile +++ b/Makefile @@ -1,226 +1,98 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 3.5 +.PHONY: pretty clean ChangeLog.md -# Default target executed when no arguments are given to make. -default_target: all +# used programs +RE2C = re2c +SED = sed -.PHONY : default_target +# main target +all: json_unit -# Allow only one "make -f Makefile2" at a time, but pass parallelism. -.NOTPARALLEL: - - -#============================================================================= -# Special targets provided by cmake. - -# Disable implicit rules so canonical targets will work. -.SUFFIXES: - - -# Remove some rules from gmake that .SUFFIXES does not remove. -SUFFIXES = - -.SUFFIXES: .hpux_make_needs_suffix_list - - -# Suppress display of executed commands. -$(VERBOSE).SILENT: - - -# A target that is always out of date. -cmake_force: - -.PHONY : cmake_force - -#============================================================================= -# Set environment variables for the build. - -# The shell in which to execute make rules. -SHELL = /bin/sh - -# The CMake executable. -CMAKE_COMMAND = /usr/local/Cellar/cmake/3.5.1/bin/cmake - -# The command to remove a file. -RM = /usr/local/Cellar/cmake/3.5.1/bin/cmake -E remove -f - -# Escaping for special characters. -EQUALS = = - -# The top-level source directory on which CMake was run. -CMAKE_SOURCE_DIR = /Users/cameron/Projects/json - -# The top-level build directory on which CMake was run. -CMAKE_BINARY_DIR = /Users/cameron/Projects/json - -#============================================================================= -# Targets provided globally by CMake. - -# Special rule for the target rebuild_cache -rebuild_cache: - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." - /usr/local/Cellar/cmake/3.5.1/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) -.PHONY : rebuild_cache - -# Special rule for the target rebuild_cache -rebuild_cache/fast: rebuild_cache - -.PHONY : rebuild_cache/fast - -# Special rule for the target list_install_components -list_install_components: - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" -.PHONY : list_install_components - -# Special rule for the target list_install_components -list_install_components/fast: list_install_components - -.PHONY : list_install_components/fast - -# Special rule for the target install -install: preinstall - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." - /usr/local/Cellar/cmake/3.5.1/bin/cmake -P cmake_install.cmake -.PHONY : install - -# Special rule for the target install -install/fast: preinstall/fast - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." - /usr/local/Cellar/cmake/3.5.1/bin/cmake -P cmake_install.cmake -.PHONY : install/fast - -# Special rule for the target install/strip -install/strip: preinstall - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." - /usr/local/Cellar/cmake/3.5.1/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake -.PHONY : install/strip - -# Special rule for the target install/strip -install/strip/fast: install/strip - -.PHONY : install/strip/fast - -# Special rule for the target install/local -install/local: preinstall - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." - /usr/local/Cellar/cmake/3.5.1/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake -.PHONY : install/local - -# Special rule for the target install/local -install/local/fast: install/local - -.PHONY : install/local/fast - -# Special rule for the target edit_cache -edit_cache: - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..." - /usr/local/Cellar/cmake/3.5.1/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) -.PHONY : edit_cache - -# Special rule for the target edit_cache -edit_cache/fast: edit_cache - -.PHONY : edit_cache/fast - -# The main all target -all: cmake_check_build_system - $(CMAKE_COMMAND) -E cmake_progress_start /Users/cameron/Projects/json/CMakeFiles /Users/cameron/Projects/json/CMakeFiles/progress.marks - $(MAKE) -f CMakeFiles/Makefile2 all - $(CMAKE_COMMAND) -E cmake_progress_start /Users/cameron/Projects/json/CMakeFiles 0 -.PHONY : all - -# The main clean target +# clean up clean: - $(MAKE) -f CMakeFiles/Makefile2 clean -.PHONY : clean - -# The main clean target -clean/fast: clean - -.PHONY : clean/fast - -# Prepare targets for installation. -preinstall: all - $(MAKE) -f CMakeFiles/Makefile2 preinstall -.PHONY : preinstall - -# Prepare targets for installation. -preinstall/fast: - $(MAKE) -f CMakeFiles/Makefile2 preinstall -.PHONY : preinstall/fast - -# clear depends -depend: - $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 -.PHONY : depend - -#============================================================================= -# Target rules for targets named json_unit - -# Build rule for target. -json_unit: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 json_unit -.PHONY : json_unit - -# fast build rule for target. -json_unit/fast: - $(MAKE) -f CMakeFiles/json_unit.dir/build.make CMakeFiles/json_unit.dir/build -.PHONY : json_unit/fast - -test/unit.o: test/unit.cpp.o - -.PHONY : test/unit.o - -# target to build an object file -test/unit.cpp.o: - $(MAKE) -f CMakeFiles/json_unit.dir/build.make CMakeFiles/json_unit.dir/test/unit.cpp.o -.PHONY : test/unit.cpp.o - -test/unit.i: test/unit.cpp.i - -.PHONY : test/unit.i - -# target to preprocess a source file -test/unit.cpp.i: - $(MAKE) -f CMakeFiles/json_unit.dir/build.make CMakeFiles/json_unit.dir/test/unit.cpp.i -.PHONY : test/unit.cpp.i - -test/unit.s: test/unit.cpp.s - -.PHONY : test/unit.s - -# target to generate assembly for a file -test/unit.cpp.s: - $(MAKE) -f CMakeFiles/json_unit.dir/build.make CMakeFiles/json_unit.dir/test/unit.cpp.s -.PHONY : test/unit.cpp.s - -# Help Target -help: - @echo "The following are some of the valid targets for this Makefile:" - @echo "... all (the default if no target is provided)" - @echo "... clean" - @echo "... depend" - @echo "... rebuild_cache" - @echo "... list_install_components" - @echo "... install" - @echo "... install/strip" - @echo "... install/local" - @echo "... edit_cache" - @echo "... json_unit" - @echo "... test/unit.o" - @echo "... test/unit.i" - @echo "... test/unit.s" -.PHONY : help + rm -fr json_unit json_benchmarks fuzz fuzz-testing *.dSYM +########################################################################## +# unit tests +########################################################################## -#============================================================================= -# Special targets to cleanup operation of make. +# additional flags +FLAGS = -Wall -Wextra -pedantic -Weffc++ -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-declarations -Wmissing-include-dirs -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-overflow=5 -Wswitch -Wundef -Wno-unused -Wnon-virtual-dtor -Wreorder -Wdeprecated -Wfloat-equal -# Special rule to run CMake to check the build system integrity. -# No rule that depends on this can have commands that come from listfiles -# because they might be regenerated. -cmake_check_build_system: - $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 -.PHONY : cmake_check_build_system +# build unit tests +json_unit: test/unit.cpp src/json.hpp test/catch.hpp + $(CXX) -std=c++11 $(CXXFLAGS) $(FLAGS) $(CPPFLAGS) -I src -I test $< $(LDFLAGS) -o $@ + +########################################################################## +# documentation tests +########################################################################## + +# compile example files and check output +doctest: + make check_output -C doc + + +########################################################################## +# fuzzing +########################################################################## + +# the overall fuzz testing target +fuzz_testing: + rm -fr fuzz-testing + mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out + $(MAKE) fuzz CXX=afl-clang++ + mv fuzz fuzz-testing + find test/json_tests -size -5k -name *json | xargs -I{} cp "{}" fuzz-testing/testcases + @echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzz" + +# the fuzzer binary +fuzz: test/fuzz.cpp src/json.hpp + $(CXX) -std=c++11 $(CXXFLAGS) $(FLAGS) $(CPPFLAGS) -I src $< $(LDFLAGS) -o $@ + + +########################################################################## +# static analyzer +########################################################################## + +# call cppcheck on the main header file +cppcheck: + cppcheck --enable=all --inconclusive --std=c++11 src/json.hpp + + +########################################################################## +# maintainer targets +########################################################################## + +# create scanner with re2c +re2c: src/json.hpp.re2c + $(RE2C) --bit-vectors --nested-ifs --no-debug-info $< | $(SED) '1d' > src/json.hpp + +# pretty printer +pretty: + astyle --style=allman --indent=spaces=4 --indent-modifiers \ + --indent-switches --indent-preproc-block --indent-preproc-define \ + --indent-col1-comments --pad-oper --pad-header --align-pointer=type \ + --align-reference=type --add-brackets --convert-tabs --close-templates \ + --lineend=linux --preserve-date --suffix=none --formatted \ + src/json.hpp src/json.hpp.re2c test/unit.cpp test/fuzz.cpp benchmarks/benchmarks.cpp doc/examples/*.cpp + + +########################################################################## +# benchmarks +########################################################################## + +# benchmarks +json_benchmarks: benchmarks/benchmarks.cpp benchmarks/benchpress.hpp benchmarks/cxxopts.hpp src/json.hpp + $(CXX) -std=c++11 $(CXXFLAGS) -O3 -flto -I src -I benchmarks $< $(LDFLAGS) -o $@ + ./json_benchmarks + + +########################################################################## +# changelog +########################################################################## + +ChangeLog.md: + github_changelog_generator -o ChangeLog.md --simple-list --release-url https://github.com/nlohmann/json/releases/tag/%s + gsed -i 's|https://github.com/nlohmann/json/releases/tag/HEAD|https://github.com/nlohmann/json/tree/HEAD|' ChangeLog.md + gsed -i '2i All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).' ChangeLog.md From f115199290768d999e082051a2356bd52db860ec Mon Sep 17 00:00:00 2001 From: "Cameron T. Druyor" Date: Sat, 30 Apr 2016 12:28:09 -0400 Subject: [PATCH 08/12] fix comment --- src/json.hpp.re2c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 579aad6a7..cc1ae2f27 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -7847,7 +7847,7 @@ class basic_json // remember this number was parsed (for later serialization) result.m_type.bits.parsed = true; - // 'found_radix_point' will be set to 0xFF upon finding a radix + // 'found_radix_point' will be set to true upon finding a radix // point. if it is not found, then the precision will be updated bool found_radix_point = false; uint8_t precision = 0; From 31493c39b0ce20b60302e1c5f4ef372ac684f15a Mon Sep 17 00:00:00 2001 From: "Cameron T. Druyor" Date: Sat, 30 Apr 2016 12:30:36 -0400 Subject: [PATCH 09/12] to add parentheses to satisfy clang --- src/json.hpp | 4 ++-- src/json.hpp.re2c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index fa5fb5c43..673b84b29 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -8160,7 +8160,7 @@ basic_json_parser_63: // remember this number was parsed (for later serialization) result.m_type.bits.parsed = true; - // 'found_radix_point' will be set to 0xFF upon finding a radix + // 'found_radix_point' will be set to true upon finding a radix // point. if it is not found, then the precision will be updated bool found_radix_point = false; uint8_t precision = 0; @@ -8251,7 +8251,7 @@ basic_json_parser_63: auto c = *(m_start+j); if(c == '0') ++trailing_zeros; - else if(c > '0' and c <= '9' or c == '-') + else if((c > '0' and c <= '9') or c == '-') break; else throw std::logic_error("unexpected character: "+std::to_string(c)); diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index cc1ae2f27..8aa4e7fc5 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -7938,7 +7938,7 @@ class basic_json auto c = *(m_start+j); if(c == '0') ++trailing_zeros; - else if(c > '0' and c <= '9' or c == '-') + else if((c > '0' and c <= '9') or c == '-') break; else throw std::logic_error("unexpected character: "+std::to_string(c)); From 223793caa08a6b78c19c8b1a9237cda17dd568a9 Mon Sep 17 00:00:00 2001 From: "Cameron T. Druyor" Date: Sat, 30 Apr 2016 12:49:42 -0400 Subject: [PATCH 10/12] to get rid of exception that was leftover from debugging --- src/json.hpp.re2c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 8aa4e7fc5..1a986f1ad 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -7940,8 +7940,6 @@ class basic_json ++trailing_zeros; else if((c > '0' and c <= '9') or c == '-') break; - else - throw std::logic_error("unexpected character: "+std::to_string(c)); } precision -= (trailing_zeros + 1); } From fbcf15098f89c4bf2b7991459376fba241b40f07 Mon Sep 17 00:00:00 2001 From: "Cameron T. Druyor" Date: Sat, 30 Apr 2016 12:51:46 -0400 Subject: [PATCH 11/12] forgot to make re2c --- src/json.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index 673b84b29..ed96c49b4 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -8253,8 +8253,6 @@ basic_json_parser_63: ++trailing_zeros; else if((c > '0' and c <= '9') or c == '-') break; - else - throw std::logic_error("unexpected character: "+std::to_string(c)); } precision -= (trailing_zeros + 1); } From 2e4d4939260a3768cfa32a6102dff96c4f827c03 Mon Sep 17 00:00:00 2001 From: "Cameron T. Druyor" Date: Sat, 30 Apr 2016 13:44:36 -0400 Subject: [PATCH 12/12] refactored into one line to satisfy lcov --- src/json.hpp | 5 +---- src/json.hpp.re2c | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index ed96c49b4..72e9ef065 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -6267,10 +6267,7 @@ class basic_json // remove '+' sign from the exponent if necessary if (not m_type.bits.exp_plus) { - if (len > static_cast(sizeof(buf))) - { - len = sizeof(buf); - } + len = std::min(len, static_cast(sizeof(buf))); for (int i = 0; i < len; i++) { if (buf[i] == '+') diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 1a986f1ad..5fc8c0413 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -6267,10 +6267,7 @@ class basic_json // remove '+' sign from the exponent if necessary if (not m_type.bits.exp_plus) { - if (len > static_cast(sizeof(buf))) - { - len = sizeof(buf); - } + len = std::min(len, static_cast(sizeof(buf))); for (int i = 0; i < len; i++) { if (buf[i] == '+')