🚸 improve diagnostics

This commit is contained in:
Niels Lohmann 2020-06-21 13:28:00 +02:00
parent 139a0258cc
commit e22ce45065
No known key found for this signature in database
GPG key ID: 7F3CEA63AE251B69
4 changed files with 43 additions and 2 deletions

View file

@ -865,7 +865,10 @@ class lexer : public lexer_base<BasicJsonType>
{ {
case std::char_traits<char_type>::eof(): case std::char_traits<char_type>::eof():
case '\0': case '\0':
{
error_message = "invalid comment; missing closing '*/'";
return false; return false;
}
case '*': case '*':
{ {
@ -890,7 +893,10 @@ class lexer : public lexer_base<BasicJsonType>
// unexpected character after reading '/' // unexpected character after reading '/'
default: default:
{
error_message = "invalid comment; expecting '/' or '*' after '/'";
return false; return false;
}
} }
} }
@ -1504,7 +1510,6 @@ scan_number_done:
{ {
if (not scan_comment()) if (not scan_comment())
{ {
error_message = "invalid comment";
return token_type::parse_error; return token_type::parse_error;
} }

View file

@ -8932,7 +8932,10 @@ class lexer : public lexer_base<BasicJsonType>
{ {
case std::char_traits<char_type>::eof(): case std::char_traits<char_type>::eof():
case '\0': case '\0':
{
error_message = "invalid comment; missing closing '*/'";
return false; return false;
}
case '*': case '*':
{ {
@ -8957,7 +8960,10 @@ class lexer : public lexer_base<BasicJsonType>
// unexpected character after reading '/' // unexpected character after reading '/'
default: default:
{
error_message = "invalid comment; expecting '/' or '*' after '/'";
return false; return false;
}
} }
} }
@ -9571,7 +9577,6 @@ scan_number_done:
{ {
if (not scan_comment()) if (not scan_comment())
{ {
error_message = "invalid comment";
return token_type::parse_error; return token_type::parse_error;
} }

View file

@ -45,6 +45,15 @@ json::lexer::token_type scan_string(const char* s, const bool ignore_comments)
} }
} }
std::string get_error_message(const char* s, const bool ignore_comments = false);
std::string get_error_message(const char* s, const bool ignore_comments)
{
auto ia = nlohmann::detail::input_adapter(s);
auto lexer = nlohmann::detail::lexer<json, decltype(ia)>(std::move(ia), ignore_comments);
lexer.scan();
return lexer.get_error_message();
}
TEST_CASE("lexer class") TEST_CASE("lexer class")
{ {
SECTION("scan") SECTION("scan")
@ -185,32 +194,48 @@ TEST_CASE("lexer class")
SECTION("fail on comments") SECTION("fail on comments")
{ {
CHECK((scan_string("/", false) == json::lexer::token_type::parse_error)); CHECK((scan_string("/", false) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/", false) == "invalid literal");
CHECK((scan_string("/!", false) == json::lexer::token_type::parse_error)); CHECK((scan_string("/!", false) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/!", false) == "invalid literal");
CHECK((scan_string("/*", false) == json::lexer::token_type::parse_error)); CHECK((scan_string("/*", false) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/*", false) == "invalid literal");
CHECK((scan_string("/**", false) == json::lexer::token_type::parse_error)); CHECK((scan_string("/**", false) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/**", false) == "invalid literal");
CHECK((scan_string("//", false) == json::lexer::token_type::parse_error)); CHECK((scan_string("//", false) == json::lexer::token_type::parse_error));
CHECK(get_error_message("//", false) == "invalid literal");
CHECK((scan_string("/**/", false) == json::lexer::token_type::parse_error)); CHECK((scan_string("/**/", false) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/**/", false) == "invalid literal");
CHECK((scan_string("/** /", false) == json::lexer::token_type::parse_error)); CHECK((scan_string("/** /", false) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/** /", false) == "invalid literal");
CHECK((scan_string("/***/", false) == json::lexer::token_type::parse_error)); CHECK((scan_string("/***/", false) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/***/", false) == "invalid literal");
CHECK((scan_string("/* true */", false) == json::lexer::token_type::parse_error)); CHECK((scan_string("/* true */", false) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/* true */", false) == "invalid literal");
CHECK((scan_string("/*/**/", false) == json::lexer::token_type::parse_error)); CHECK((scan_string("/*/**/", false) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/*/**/", false) == "invalid literal");
CHECK((scan_string("/*/* */", false) == json::lexer::token_type::parse_error)); CHECK((scan_string("/*/* */", false) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/*/* */", false) == "invalid literal");
} }
SECTION("ignore comments") SECTION("ignore comments")
{ {
CHECK((scan_string("/", true) == json::lexer::token_type::parse_error)); CHECK((scan_string("/", true) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/", true) == "invalid comment; expecting '/' or '*' after '/'");
CHECK((scan_string("/!", true) == json::lexer::token_type::parse_error)); CHECK((scan_string("/!", true) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/!", true) == "invalid comment; expecting '/' or '*' after '/'");
CHECK((scan_string("/*", true) == json::lexer::token_type::parse_error)); CHECK((scan_string("/*", true) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/*", true) == "invalid comment; missing closing '*/'");
CHECK((scan_string("/**", true) == json::lexer::token_type::parse_error)); CHECK((scan_string("/**", true) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/**", true) == "invalid comment; missing closing '*/'");
CHECK((scan_string("//", true) == json::lexer::token_type::end_of_input)); CHECK((scan_string("//", true) == json::lexer::token_type::end_of_input));
CHECK((scan_string("/**/", true) == json::lexer::token_type::end_of_input)); CHECK((scan_string("/**/", true) == json::lexer::token_type::end_of_input));
CHECK((scan_string("/** /", true) == json::lexer::token_type::parse_error)); CHECK((scan_string("/** /", true) == json::lexer::token_type::parse_error));
CHECK(get_error_message("/** /", true) == "invalid comment; missing closing '*/'");
CHECK((scan_string("/***/", true) == json::lexer::token_type::end_of_input)); CHECK((scan_string("/***/", true) == json::lexer::token_type::end_of_input));
CHECK((scan_string("/* true */", true) == json::lexer::token_type::end_of_input)); CHECK((scan_string("/* true */", true) == json::lexer::token_type::end_of_input));

View file

@ -1877,4 +1877,10 @@ TEST_CASE("parser class")
} }
} }
} }
SECTION("error messages for comments")
{
CHECK_THROWS_WITH_AS(json::parse("/a", nullptr, true, true), "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid comment; expecting '/' or '*' after '/'; last read: '/a'", json::parse_error);
CHECK_THROWS_WITH_AS(json::parse("/*", nullptr, true, true), "[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid comment; missing closing '*/'; last read: '/*<U+0000>'", json::parse_error);
}
} }