mirror of
https://github.com/biojppm/rapidyaml.git
synced 2026-01-18 13:31:19 +01:00
refactor error API: show failed check conditions
This commit is contained in:
@@ -18,6 +18,7 @@ if(RYML_DEFAULT_CALLBACKS)
|
||||
option(RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS "Throw exceptions instead of calling abort in the default error handler provided by ryml" OFF)
|
||||
endif()
|
||||
option(RYML_USE_ASSERT "Enable assertions regardless of build type. Default is only when NDEBUG is not defined (which is in release builds). This causes a slowdown of the code." OFF)
|
||||
option(RYML_SHORT_ERR_MSG "Use shorter error message from checks/asserts: do not show the check condition in the error message" OFF)
|
||||
option(RYML_BUILD_TOOLS "Build tools" OFF)
|
||||
option(RYML_BUILD_API "Enable API generation (python, etc)" OFF)
|
||||
option(RYML_DBG "Enable (very verbose) debug prints." OFF)
|
||||
@@ -97,14 +98,17 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(RYML_DBG)
|
||||
target_compile_definitions(ryml PRIVATE RYML_DBG)
|
||||
if(RYML_SHORT_CHECK_MSG)
|
||||
target_compile_definitions(ryml PUBLIC RYML_SHORT_CHECK_MSG)
|
||||
endif()
|
||||
|
||||
if(RYML_USE_ASSERT)
|
||||
target_compile_definitions(ryml PUBLIC RYML_USE_ASSERT=1)
|
||||
endif()
|
||||
|
||||
if(RYML_DBG)
|
||||
target_compile_definitions(ryml PRIVATE RYML_DBG)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
option(RYML_FANALYZER "Compile with -fanalyzer https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Static-Analyzer-Options.html" OFF)
|
||||
if(RYML_FANALYZER)
|
||||
|
||||
@@ -526,6 +526,7 @@ Currently [cmake](https://cmake.org/) is required to build ryml; we
|
||||
recommend a recent cmake version, at least 3.13.
|
||||
|
||||
|
||||
|
||||
### Package managers
|
||||
|
||||
ryml is available in most package managers (thanks to all the
|
||||
@@ -601,6 +602,9 @@ ryml:
|
||||
* `RYML_USE_ASSERT` - enable assertions in the code regardless of
|
||||
build type. This is disabled by default. Failed assertions will
|
||||
trigger a call to the error callback.
|
||||
* `RYML_SHORT_CHECK_MSG` - Use shorter error message from
|
||||
checks/asserts: do not show the check condition in the error
|
||||
message.
|
||||
* `RYML_STANDALONE=ON/OFF`. ryml uses
|
||||
[c4core](https://github.com/biojppm/c4core), a C++ library with low-level
|
||||
multi-platform utilities for C++. When `RYML_STANDALONE=ON`, c4core is
|
||||
|
||||
@@ -232,6 +232,9 @@ of ryml:
|
||||
- ``RYML_USE_ASSERT`` - enable assertions in the code regardless of
|
||||
build type. This is disabled by default. Failed assertions will
|
||||
trigger a call to the error callback.
|
||||
- ``RYML_SHORT_CHECK_MSG`` - Use shorter error message from
|
||||
checks/asserts: do not show the check condition in the error
|
||||
message.
|
||||
- ``RYML_STANDALONE=ON/OFF``. ryml uses
|
||||
`c4core <https://github.com/biojppm/c4core>`__, a C++ library with
|
||||
low-level multi-platform utilities for C++. When
|
||||
|
||||
@@ -191,6 +191,11 @@ static_assert(RYML_LOGBUF_SIZE < RYML_ERRMSG_SIZE, "invalid size");
|
||||
* is empty otherwise. The user is unable to override this macro. */
|
||||
# define RYML_NOEXCEPT
|
||||
|
||||
/** (Undefined by default) Use shorter error message from
|
||||
* checks/asserts: do not show the check condition in the error
|
||||
* message. */
|
||||
# defined RYML_SHORT_CHECK_MSG
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -210,18 +215,6 @@ static_assert(RYML_LOGBUF_SIZE < RYML_ERRMSG_SIZE, "invalid size");
|
||||
|
||||
#define RYML_DEPRECATED(msg) C4_DEPRECATED(msg)
|
||||
|
||||
#if defined(RYML_DBG) && !defined(NDEBUG) && !defined(C4_NO_DEBUG_BREAK)
|
||||
# define RYML_DEBUG_BREAK() \
|
||||
do { \
|
||||
if(c4::get_error_flags() & c4::ON_ERROR_DEBUGBREAK) \
|
||||
{ \
|
||||
C4_DEBUG_BREAK(); \
|
||||
} \
|
||||
} while(false)
|
||||
#else
|
||||
# define RYML_DEBUG_BREAK()
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,17 @@
|
||||
#if (defined(C4_EXCEPTIONS) && (!defined(RYML_NO_DEFAULT_CALLBACKS) && defined(RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS))) || defined(__DOXYGEN__)
|
||||
#define _RYML_WITH_EXCEPTIONS
|
||||
#endif
|
||||
#if defined(RYML_DBG) && !defined(NDEBUG) && !defined(C4_NO_DEBUG_BREAK)
|
||||
# define RYML_DEBUG_BREAK() \
|
||||
do { \
|
||||
if(c4::get_error_flags() & c4::ON_ERROR_DEBUGBREAK) \
|
||||
{ \
|
||||
C4_DEBUG_BREAK(); \
|
||||
} \
|
||||
} while(false)
|
||||
#else
|
||||
# define RYML_DEBUG_BREAK()
|
||||
#endif
|
||||
/// @endcond
|
||||
|
||||
#ifdef _RYML_WITH_EXCEPTIONS
|
||||
@@ -496,17 +507,17 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
|
||||
#if RYML_USE_ASSERT
|
||||
# define _RYML_ASSERT_BASIC(cond) _RYML_CHECK_BASIC(cond)
|
||||
# define _RYML_ASSERT_BASIC_(cb, cond) _RYML_CHECK_BASIC_((cb), (cond))
|
||||
# define _RYML_ASSERT_BASIC_MSG(cond, ...) _RYML_CHECK_BASIC_MSG((cond), __VA_ARGS__)
|
||||
# define _RYML_ASSERT_BASIC_MSG_(cb, cond, ...) _RYML_CHECK_BASIC_MSG_((cb), (cond), __VA_ARGS__)
|
||||
# define _RYML_ASSERT_PARSE(cond, ymlloc) _RYML_CHECK_PARSE(cond)
|
||||
# define _RYML_ASSERT_PARSE_(cb, cond, ymlloc) _RYML_CHECK_PARSE_((cb), (cond), (ymlloc))
|
||||
# define _RYML_ASSERT_PARSE_MSG(cond, ymlloc, ...) _RYML_CHECK_PARSE_MSG((cond), (ymlloc))
|
||||
# define _RYML_ASSERT_PARSE_MSG_(cb, cond, ymlloc, ...) _RYML_CHECK_PARSE_MSG_((cb), (cond), (ymlloc), __VA_ARGS__)
|
||||
# define _RYML_ASSERT_VISIT(cond, tree, node) _RYML_CHECK_VISIT((cond), (tree), (node))
|
||||
# define _RYML_ASSERT_VISIT_(cb, cond, tree, node) _RYML_CHECK_VISIT_((cb), (cond), (tree), (node))
|
||||
# define _RYML_ASSERT_VISIT_MSG(cond, tree, node, ...) _RYML_CHECK_VISIT_MSG((cond), (tree), (node), __VA_ARGS__)
|
||||
# define _RYML_ASSERT_VISIT_MSG_(cb, cond, tree, node, ...) _RYML_CHECK_VISIT_MSG_((cb), (cond), (tree), (node), __VA_ARGS__)
|
||||
# define _RYML_ASSERT_BASIC_(cb, cond) _RYML_CHECK_BASIC_((cb), cond)
|
||||
# define _RYML_ASSERT_BASIC_MSG(cond, ...) _RYML_CHECK_BASIC_MSG(cond, __VA_ARGS__)
|
||||
# define _RYML_ASSERT_BASIC_MSG_(cb, cond, ...) _RYML_CHECK_BASIC_MSG_((cb), cond, __VA_ARGS__)
|
||||
# define _RYML_ASSERT_PARSE(cond, ymlloc) _RYML_CHECK_PARSE(cond, (ymlloc))
|
||||
# define _RYML_ASSERT_PARSE_(cb, cond, ymlloc) _RYML_CHECK_PARSE_((cb), cond, (ymlloc))
|
||||
# define _RYML_ASSERT_PARSE_MSG(cond, ymlloc, ...) _RYML_CHECK_PARSE_MSG(cond, (ymlloc), __VA_ARGS__)
|
||||
# define _RYML_ASSERT_PARSE_MSG_(cb, cond, ymlloc, ...) _RYML_CHECK_PARSE_MSG_((cb), cond, (ymlloc), __VA_ARGS__)
|
||||
# define _RYML_ASSERT_VISIT(cond, tree, node) _RYML_CHECK_VISIT(cond, (tree), (node))
|
||||
# define _RYML_ASSERT_VISIT_(cb, cond, tree, node) _RYML_CHECK_VISIT_((cb), cond, (tree), (node))
|
||||
# define _RYML_ASSERT_VISIT_MSG(cond, tree, node, ...) _RYML_CHECK_VISIT_MSG(cond, (tree), (node), __VA_ARGS__)
|
||||
# define _RYML_ASSERT_VISIT_MSG_(cb, cond, tree, node, ...) _RYML_CHECK_VISIT_MSG_((cb), cond, (tree), (node), __VA_ARGS__)
|
||||
#else
|
||||
# define _RYML_ASSERT_BASIC(cond)
|
||||
# define _RYML_ASSERT_BASIC_(cb, cond)
|
||||
@@ -522,7 +533,6 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
# define _RYML_ASSERT_VISIT_MSG_(cb, cont, tree, node, ...)
|
||||
#endif
|
||||
|
||||
|
||||
#define _RYML_ERR_BASIC(...) \
|
||||
do \
|
||||
{ \
|
||||
@@ -569,12 +579,20 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
} while(false)
|
||||
|
||||
|
||||
#ifndef RYML_SHORT_CHECK_MSG
|
||||
#define _RYML_MAYBE_MSG(cond) ": " #cond
|
||||
#define _RYML_MAYBE_MSG_(cond) ": " #cond ": "
|
||||
#else
|
||||
#define _RYML_MAYBE_MSG(cond)
|
||||
#define _RYML_MAYBE_MSG_(cond) ": "
|
||||
#endif
|
||||
|
||||
#define _RYML_CHECK_BASIC(cond) \
|
||||
do { \
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
::c4::yml::err_basic((::c4::yml::ErrorDataBasic{RYML_LOC_HERE()}), "check failed"); \
|
||||
::c4::yml::err_basic((::c4::yml::ErrorDataBasic{RYML_LOC_HERE()}), "check failed" _RYML_MAYBE_MSG(cond)); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(false)
|
||||
@@ -583,7 +601,7 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
::c4::yml::err_parse((::c4::yml::ErrorDataParse{RYML_LOC_HERE(), ymlloc}), "check failed"); \
|
||||
::c4::yml::err_parse((::c4::yml::ErrorDataParse{RYML_LOC_HERE(), ymlloc}), "check failed" _RYML_MAYBE_MSG(cond)); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(false)
|
||||
@@ -592,7 +610,7 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
::c4::yml::err_visit((::c4::yml::ErrorDataVisit{RYML_LOC_HERE(), tree, node}), "check failed"); \
|
||||
::c4::yml::err_visit((::c4::yml::ErrorDataVisit{RYML_LOC_HERE(), tree, node}), "check failed" _RYML_MAYBE_MSG(cond)); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(false)
|
||||
@@ -603,7 +621,7 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
::c4::yml::err_basic((cb), (::c4::yml::ErrorDataBasic{RYML_LOC_HERE()}), "check failed"); \
|
||||
::c4::yml::err_basic((cb), (::c4::yml::ErrorDataBasic{RYML_LOC_HERE()}), "check failed" _RYML_MAYBE_MSG(cond)); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(false)
|
||||
@@ -612,7 +630,7 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
::c4::yml::err_parse((cb), (::c4::yml::ErrorDataParse{RYML_LOC_HERE(), ymlloc}), "check failed"); \
|
||||
::c4::yml::err_parse((cb), (::c4::yml::ErrorDataParse{RYML_LOC_HERE(), ymlloc}), "check failed" _RYML_MAYBE_MSG(cond)); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(false)
|
||||
@@ -621,7 +639,7 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
::c4::yml::err_visit((cb), (::c4::yml::ErrorDataVisit{RYML_LOC_HERE(), tree, node}), "check failed"); \
|
||||
::c4::yml::err_visit((cb), (::c4::yml::ErrorDataVisit{RYML_LOC_HERE(), tree, node}), "check failed" _RYML_MAYBE_MSG(cond)); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(false)
|
||||
@@ -632,7 +650,7 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
::c4::yml::err_basic((::c4::yml::ErrorDataBasic{RYML_LOC_HERE()}), "check failed: " __VA_ARGS__); \
|
||||
::c4::yml::err_basic((::c4::yml::ErrorDataBasic{RYML_LOC_HERE()}), "check failed" _RYML_MAYBE_MSG_(cond) __VA_ARGS__); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(false)
|
||||
@@ -641,7 +659,7 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
::c4::yml::err_parse((::c4::yml::ErrorDataParse{RYML_LOC_HERE(), ymlloc}), "check failed: " __VA_ARGS__); \
|
||||
::c4::yml::err_parse((::c4::yml::ErrorDataParse{RYML_LOC_HERE(), ymlloc}), "check failed" _RYML_MAYBE_MSG_(cond) __VA_ARGS__); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(false)
|
||||
@@ -650,7 +668,7 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
::c4::yml::err_visit((::c4::yml::ErrorDataVisit{RYML_LOC_HERE(), tree, node}), "check failed: " __VA_ARGS__); \
|
||||
::c4::yml::err_visit((::c4::yml::ErrorDataVisit{RYML_LOC_HERE(), tree, node}), "check failed" _RYML_MAYBE_MSG_(cond) __VA_ARGS__); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(false)
|
||||
@@ -661,7 +679,7 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
::c4::yml::err_basic((cb), (::c4::yml::ErrorDataBasic{RYML_LOC_HERE()}), "check failed: " __VA_ARGS__); \
|
||||
::c4::yml::err_basic((cb), (::c4::yml::ErrorDataBasic{RYML_LOC_HERE()}), "check failed" _RYML_MAYBE_MSG_(cond) __VA_ARGS__); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(false)
|
||||
@@ -670,7 +688,7 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
::c4::yml::err_parse((cb), (::c4::yml::ErrorDataParse{RYML_LOC_HERE(), ymlloc}), "check failed: " __VA_ARGS__); \
|
||||
::c4::yml::err_parse((cb), (::c4::yml::ErrorDataParse{RYML_LOC_HERE(), ymlloc}), "check failed" _RYML_MAYBE_MSG_(cond) __VA_ARGS__); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(false)
|
||||
@@ -679,7 +697,7 @@ struct RYML_EXPORT ExceptionVisit : public ExceptionBasic
|
||||
if(C4_UNLIKELY(!(cond))) \
|
||||
{ \
|
||||
RYML_DEBUG_BREAK(); \
|
||||
::c4::yml::err_visit((cb), (::c4::yml::ErrorDataVisit{RYML_LOC_HERE(), tree, node}), "check failed: " __VA_ARGS__); \
|
||||
::c4::yml::err_visit((cb), (::c4::yml::ErrorDataVisit{RYML_LOC_HERE(), tree, node}), "check failed" _RYML_MAYBE_MSG_(cond) __VA_ARGS__); \
|
||||
C4_UNREACHABLE_AFTER_ERR(); \
|
||||
} \
|
||||
} while(false)
|
||||
|
||||
@@ -765,6 +765,46 @@ TEST(error, basic)
|
||||
}
|
||||
}
|
||||
|
||||
template<class Fn>
|
||||
void test_check_basic(Fn &&fn, csubstr expected_msg)
|
||||
{
|
||||
set_callbacks(mk_test_callbacks());
|
||||
{
|
||||
std::string exc_msg;(void)exc_msg;
|
||||
RYML_IF_EXC(bool exc_ok = false);
|
||||
C4_IF_EXCEPTIONS_(try, if(setjmp(s_jmp_env_expect_error) == 0))
|
||||
{
|
||||
std::forward<Fn>(fn)();
|
||||
}
|
||||
RYML_IF_EXC(catch(ExceptionBasic const& exc){
|
||||
exc_msg = exc.what();
|
||||
exc_ok = true;
|
||||
})
|
||||
C4_IF_EXCEPTIONS_(catch(std::exception const& exc) { exc_msg = exc.what(); }, else { exc_msg = stored_msg; })
|
||||
std::cout << exc_msg << "\n";
|
||||
std::cout << stored_msg_full << "\n";
|
||||
RYML_IF_EXC(EXPECT_TRUE(exc_ok));
|
||||
EXPECT_NE(csubstr::npos, to_csubstr(exc_msg).find(expected_msg));
|
||||
}
|
||||
reset_callbacks();
|
||||
}
|
||||
TEST(check, basic)
|
||||
{
|
||||
bool disregard_this_message = false;
|
||||
csubstr msg = "disregard_this_message";
|
||||
csubstr fmsg = "disregard_this_message: extra args: 1,2";
|
||||
test_check_basic([&]{ _RYML_CHECK_BASIC(disregard_this_message); }, msg);
|
||||
test_check_basic([&]{ _RYML_CHECK_BASIC_(get_callbacks(), disregard_this_message); }, msg);
|
||||
test_check_basic([&]{ _RYML_CHECK_BASIC_MSG(disregard_this_message, "extra args: {},{}", 1, 2); }, fmsg);
|
||||
test_check_basic([&]{ _RYML_CHECK_BASIC_MSG_(get_callbacks(), disregard_this_message, "extra args: {},{}", 1, 2); }, fmsg);
|
||||
#if RYML_USE_ASSERT
|
||||
test_check_basic([&]{ _RYML_ASSERT_BASIC(disregard_this_message); }, msg);
|
||||
test_check_basic([&]{ _RYML_ASSERT_BASIC_(get_callbacks(), disregard_this_message); }, msg);
|
||||
test_check_basic([&]{ _RYML_ASSERT_BASIC_MSG(disregard_this_message, "extra args: {},{}", 1, 2); }, fmsg);
|
||||
test_check_basic([&]{ _RYML_ASSERT_BASIC_MSG_(get_callbacks(), disregard_this_message, "extra args: {},{}", 1, 2); }, fmsg);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _RYML_WITH_EXCEPTIONS
|
||||
template<class T, class ...Args>
|
||||
void testmsg(Args const& ...args)
|
||||
@@ -1062,6 +1102,70 @@ TEST(error, parse)
|
||||
}
|
||||
}
|
||||
|
||||
template<class Fn>
|
||||
void test_check_parse(Fn &&fn, csubstr expected_msg)
|
||||
{
|
||||
set_callbacks(mk_test_callbacks());
|
||||
{
|
||||
std::string exc_msg;(void)exc_msg;
|
||||
RYML_IF_EXC(bool exc_ok = false);
|
||||
C4_IF_EXCEPTIONS_(try, if(setjmp(s_jmp_env_expect_error) == 0))
|
||||
{
|
||||
std::forward<Fn>(fn)();
|
||||
}
|
||||
RYML_IF_EXC(catch(ExceptionParse const& exc){
|
||||
exc_msg = exc.what();
|
||||
exc_ok = true;
|
||||
})
|
||||
C4_IF_EXCEPTIONS_(catch(std::exception const& exc) { exc_msg = exc.what(); }, else { exc_msg = stored_msg; })
|
||||
std::cout << stored_msg_full << "\n";
|
||||
RYML_IF_EXC(EXPECT_TRUE(exc_ok));
|
||||
EXPECT_NE(csubstr::npos, to_csubstr(exc_msg).find(expected_msg));
|
||||
}
|
||||
reset_callbacks();
|
||||
}
|
||||
TEST(check, parse)
|
||||
{
|
||||
bool disregard_this_message = false;
|
||||
csubstr msg = "disregard_this_message";
|
||||
csubstr fmsg = "disregard_this_message: extra args: 1,2";
|
||||
Location ymlloc = {};
|
||||
{
|
||||
SCOPED_TRACE("here 0");
|
||||
test_check_parse([&]{ _RYML_CHECK_PARSE(disregard_this_message, ymlloc); }, msg);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("here 1");
|
||||
test_check_parse([&]{ _RYML_CHECK_PARSE_(get_callbacks(), disregard_this_message, ymlloc); }, msg);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("here 2");
|
||||
test_check_parse([&]{ _RYML_CHECK_PARSE_MSG(disregard_this_message, ymlloc, "extra args: {},{}", 1, 2); }, fmsg);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("here 3");
|
||||
test_check_parse([&]{ _RYML_CHECK_PARSE_MSG_(get_callbacks(), disregard_this_message, ymlloc, "extra args: {},{}", 1, 2); }, fmsg);
|
||||
}
|
||||
#if RYML_USE_ASSERT
|
||||
{
|
||||
SCOPED_TRACE("here 4");
|
||||
test_check_parse([&]{ _RYML_ASSERT_PARSE(disregard_this_message, ymlloc); }, msg);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("here 5");
|
||||
test_check_parse([&]{ _RYML_ASSERT_PARSE_(get_callbacks(), disregard_this_message, ymlloc); }, msg);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("here 6");
|
||||
test_check_parse([&]{ _RYML_ASSERT_PARSE_MSG(disregard_this_message, ymlloc, "extra args: {},{}", 1, 2); }, fmsg);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("here 7");
|
||||
test_check_parse([&]{ _RYML_ASSERT_PARSE_MSG_(get_callbacks(), disregard_this_message, ymlloc, "extra args: {},{}", 1, 2); }, fmsg);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -1298,6 +1402,71 @@ TEST(error, visit)
|
||||
}
|
||||
}
|
||||
|
||||
template<class Fn>
|
||||
void test_check_visit(Fn &&fn, csubstr expected_msg)
|
||||
{
|
||||
set_callbacks(mk_test_callbacks());
|
||||
{
|
||||
std::string exc_msg;(void)exc_msg;
|
||||
RYML_IF_EXC(bool exc_ok = false);
|
||||
C4_IF_EXCEPTIONS_(try, if(setjmp(s_jmp_env_expect_error) == 0))
|
||||
{
|
||||
std::forward<Fn>(fn)();
|
||||
}
|
||||
RYML_IF_EXC(catch(ExceptionVisit const& exc){
|
||||
exc_msg = exc.what();
|
||||
exc_ok = true;
|
||||
})
|
||||
C4_IF_EXCEPTIONS_(catch(std::exception const& exc) { exc_msg = exc.what(); }, else { exc_msg = stored_msg; })
|
||||
std::cout << stored_msg_full << "\n";
|
||||
RYML_IF_EXC(EXPECT_TRUE(exc_ok));
|
||||
EXPECT_NE(csubstr::npos, to_csubstr(exc_msg).find(expected_msg));
|
||||
}
|
||||
reset_callbacks();
|
||||
}
|
||||
TEST(check, visit)
|
||||
{
|
||||
bool disregard_this_message = false;
|
||||
csubstr msg = "disregard_this_message";
|
||||
csubstr fmsg = "disregard_this_message: extra args: 1,2";
|
||||
Tree tree = parse_in_arena("foo: bar");
|
||||
id_type id = tree.root_id();
|
||||
{
|
||||
SCOPED_TRACE("here 0");
|
||||
test_check_visit([&]{ _RYML_CHECK_VISIT(disregard_this_message, &tree, id); }, msg);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("here 1");
|
||||
test_check_visit([&]{ _RYML_CHECK_VISIT_(get_callbacks(), disregard_this_message, &tree, id); }, msg);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("here 2");
|
||||
test_check_visit([&]{ _RYML_CHECK_VISIT_MSG(disregard_this_message, &tree, id, "extra args: {},{}", 1, 2); }, fmsg);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("here 3");
|
||||
test_check_visit([&]{ _RYML_CHECK_VISIT_MSG_(get_callbacks(), disregard_this_message, &tree, id, "extra args: {},{}", 1, 2); }, fmsg);
|
||||
}
|
||||
#if RYML_USE_ASSERT
|
||||
{
|
||||
SCOPED_TRACE("here 4");
|
||||
test_check_visit([&]{ _RYML_ASSERT_VISIT(disregard_this_message, &tree, id); }, msg);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("here 5");
|
||||
test_check_visit([&]{ _RYML_ASSERT_VISIT_(get_callbacks(), disregard_this_message, &tree, id); }, msg);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("here 6");
|
||||
test_check_visit([&]{ _RYML_ASSERT_VISIT_MSG(disregard_this_message, &tree, id, "extra args: {},{}", 1, 2); }, fmsg);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("here 7");
|
||||
test_check_visit([&]{ _RYML_ASSERT_VISIT_MSG_(get_callbacks(), disregard_this_message, &tree, id, "extra args: {},{}", 1, 2); }, fmsg);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(RYML_CHECK, basic)
|
||||
{
|
||||
EXPECT_NE(get_callbacks().m_error_parse, &test_error_parse_impl);
|
||||
@@ -1312,7 +1481,7 @@ TEST(RYML_CHECK, basic)
|
||||
{
|
||||
;
|
||||
}
|
||||
EXPECT_EQ(stored_msg, "check failed");
|
||||
EXPECT_TRUE(to_csubstr(stored_msg).begins_with("check failed"));
|
||||
EXPECT_EQ(stored_cpploc.name, __FILE__);
|
||||
EXPECT_EQ(stored_cpploc.offset, npos);
|
||||
EXPECT_EQ(stored_cpploc.line, the_line);
|
||||
@@ -1338,7 +1507,7 @@ TEST(RYML_ASSERT, basic)
|
||||
;
|
||||
}
|
||||
#if RYML_USE_ASSERT
|
||||
EXPECT_EQ(stored_msg, "check failed");
|
||||
EXPECT_TRUE(to_csubstr(stored_msg).begins_with("check failed"));
|
||||
EXPECT_EQ(stored_cpploc.name, __FILE__);
|
||||
EXPECT_EQ(stored_cpploc.offset, npos);
|
||||
EXPECT_EQ(stored_cpploc.line, the_line);
|
||||
|
||||
Reference in New Issue
Block a user