diff --git a/src/json.hpp b/src/json.hpp index d4d13b43..e53fbcf2 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -11461,17 +11461,6 @@ class basic_json return codepoint; } - /*! - @brief create diagnostic representation of a codepoint - @return string "U+XXXX" for codepoint XXXX - */ - static std::string codepoint_to_string(int codepoint) - { - std::stringstream ss; - ss << "U+" << std::setw(4) << std::uppercase << std::setfill('0') << std::hex << codepoint; - return ss.str(); - } - /*! @brief scan a string literal @@ -11497,9 +11486,7 @@ class basic_json while (true) { // get next character - get(); - - switch (current) + switch (get()) { // end of file while parsing string case std::char_traits::eof(): @@ -12396,40 +12383,24 @@ scan_number_done: return token_type::value_float; } - token_type scan_true() + /*! + @param[in] literal_text the literal text to expect + @param[in] length the length of the passed literal text + @param[in] return_type the token type to return on success + */ + token_type scan_literal(const char* literal_text, const size_t length, + token_type return_type) { - assert(current == 't'); - if (JSON_LIKELY((get() == 'r' and get() == 'u' and get() == 'e'))) + assert(current == literal_text[0]); + for (size_t i = 1; i < length; ++i) { - return token_type::literal_true; + if (JSON_UNLIKELY(get() != literal_text[i])) + { + error_message = "invalid literal"; + return token_type::parse_error; + } } - - error_message = "invalid literal; expected 'true'"; - return token_type::parse_error; - } - - token_type scan_false() - { - assert(current == 'f'); - if (JSON_LIKELY((get() == 'a' and get() == 'l' and get() == 's' and get() == 'e'))) - { - return token_type::literal_false; - } - - error_message = "invalid literal; expected 'false'"; - return token_type::parse_error; - } - - token_type scan_null() - { - assert(current == 'n'); - if (JSON_LIKELY((get() == 'u' and get() == 'l' and get() == 'l'))) - { - return token_type::literal_null; - } - - error_message = "invalid literal; expected 'null'"; - return token_type::parse_error; + return return_type; } ///////////////////// @@ -12461,6 +12432,7 @@ scan_number_done: { yytext.resize(2 * yytext.capacity(), '\0'); } + assert(yylen < yytext.size()); yytext[yylen++] = static_cast(c); } @@ -12523,7 +12495,9 @@ scan_number_done: else if ('\x00' <= c and c <= '\x1f') { // escape control characters - result += "<" + codepoint_to_string(c) + ">"; + std::stringstream ss; + ss << "(c) << ">"; + result += ss.str(); } else { @@ -12572,11 +12546,11 @@ scan_number_done: // literals case 't': - return scan_true(); + return scan_literal("true", 4, token_type::literal_true); case 'f': - return scan_false(); + return scan_literal("false", 5, token_type::literal_false); case 'n': - return scan_null(); + return scan_literal("null", 4, token_type::literal_null); // string case '\"': diff --git a/test/src/unit-class_parser.cpp b/test/src/unit-class_parser.cpp index 1cca2adf..ed55eba5 100644 --- a/test/src/unit-class_parser.cpp +++ b/test/src/unit-class_parser.cpp @@ -338,7 +338,7 @@ TEST_CASE("parser class") CHECK_THROWS_WITH(json::parser(json::input_adapter::create(std::string("-0e-:"))).parse(), "[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read: '-0e-:'"); CHECK_THROWS_WITH(json::parser(json::input_adapter::create(std::string("-0f"))).parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'false'; last read: '-0f'; expected end of input"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: '-0f'; expected end of input"); } } } @@ -656,22 +656,22 @@ TEST_CASE("parser class") CHECK_THROWS_AS(json::parser(json::input_adapter::create(std::string("nu"))).parse(), json::parse_error); CHECK_THROWS_AS(json::parser(json::input_adapter::create(std::string("nul"))).parse(), json::parse_error); CHECK_THROWS_WITH(json::parser(json::input_adapter::create(std::string("n"))).parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'null'; last read: 'n'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; last read: 'n'"); CHECK_THROWS_WITH(json::parser(json::input_adapter::create(std::string("nu"))).parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'null'; last read: 'nu'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: 'nu'"); CHECK_THROWS_WITH(json::parser(json::input_adapter::create(std::string("nul"))).parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'null'; last read: 'nul'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'nul'"); // unexpected end of true CHECK_THROWS_AS(json::parser(json::input_adapter::create(std::string("t"))).parse(), json::parse_error); CHECK_THROWS_AS(json::parser(json::input_adapter::create(std::string("tr"))).parse(), json::parse_error); CHECK_THROWS_AS(json::parser(json::input_adapter::create(std::string("tru"))).parse(), json::parse_error); CHECK_THROWS_WITH(json::parser(json::input_adapter::create(std::string("t"))).parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'true'; last read: 't'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; last read: 't'"); CHECK_THROWS_WITH(json::parser(json::input_adapter::create(std::string("tr"))).parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'true'; last read: 'tr'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: 'tr'"); CHECK_THROWS_WITH(json::parser(json::input_adapter::create(std::string("tru"))).parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'true'; last read: 'tru'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'tru'"); // unexpected end of false CHECK_THROWS_AS(json::parser(json::input_adapter::create(std::string("f"))).parse(), json::parse_error); @@ -679,13 +679,13 @@ TEST_CASE("parser class") CHECK_THROWS_AS(json::parser(json::input_adapter::create(std::string("fal"))).parse(), json::parse_error); CHECK_THROWS_AS(json::parser(json::input_adapter::create(std::string("fals"))).parse(), json::parse_error); CHECK_THROWS_WITH(json::parser(json::input_adapter::create(std::string("f"))).parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'false'; last read: 'f'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; last read: 'f'"); CHECK_THROWS_WITH(json::parser(json::input_adapter::create(std::string("fa"))).parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'false'; last read: 'fa'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: 'fa'"); CHECK_THROWS_WITH(json::parser(json::input_adapter::create(std::string("fal"))).parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'false'; last read: 'fal'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; last read: 'fal'"); CHECK_THROWS_WITH(json::parser(json::input_adapter::create(std::string("fals"))).parse(), - "[json.exception.parse_error.101] parse error at 5: syntax error - invalid literal; expected 'false'; last read: 'fals'"); + "[json.exception.parse_error.101] parse error at 5: syntax error - invalid literal; last read: 'fals'"); // missing/unexpected end of array CHECK_THROWS_AS(json::parser(json::input_adapter::create(std::string("["))).parse(), json::parse_error);