ams: support building unit test programs on windows/linux/macos

This commit is contained in:
Michael Scire
2022-03-06 12:08:20 -08:00
committed by SciresM
parent 9a38be201a
commit 64a97576d0
756 changed files with 33359 additions and 9372 deletions

View File

@@ -219,6 +219,14 @@ namespace ams {
}
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX) && defined(ATMOSPHERE_ARCH_ARM64) && defined(ATMOSPHERE_IS_STRATOSPHERE)
namespace diag::impl {
void FatalErrorByResultForNx(Result result) noexcept NORETURN;
}
#endif
}
/* Macros for defining new results. */
@@ -353,61 +361,66 @@ namespace ams::result::impl {
/// Returns a result.
#define R_THROW(res_expr) \
({ \
{ \
const ::ams::Result _tmp_r_throw_rc = (res_expr); \
if constexpr (std::same_as<decltype(__TmpCurrentResultReference), ::ams::Result &>) { __TmpCurrentResultReference = _tmp_r_throw_rc; } \
return _tmp_r_throw_rc; \
})
}
/// Returns ResultSuccess()
#define R_SUCCEED() R_THROW(::ams::ResultSuccess())
/// Evaluates an expression that returns a result, and returns the result if it would fail.
#define R_TRY(res_expr) \
({ \
{ \
if (const auto _tmp_r_try_rc = (res_expr); R_FAILED(_tmp_r_try_rc)) { \
R_THROW(_tmp_r_try_rc); \
} \
})
}
/// Return a result.
#define R_RETURN(res_expr) R_THROW(res_expr)
#ifdef AMS_ENABLE_DEBUG_PRINT
#define AMS_CALL_ON_RESULT_ASSERTION_IMPL(cond, val) ::ams::result::impl::OnResultAssertion(__FILE__, __LINE__, __PRETTY_FUNCTION__, cond, val)
#define AMS_CALL_ON_RESULT_ABORT_IMPL(cond, val) ::ams::result::impl::OnResultAbort(__FILE__, __LINE__, __PRETTY_FUNCTION__, cond, val)
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX) && defined(ATMOSPHERE_IS_STRATOSPHERE) && !defined(AMS_ENABLE_DETAILED_ASSERTIONS) && !defined(AMS_BUILD_FOR_DEBUGGING) && !defined(AMS_BUILD_FOR_AUDITING)
#define AMS_CALL_ON_RESULT_ASSERTION_IMPL(cond, val) do { ::ams::diag::impl::FatalErrorByResultForNx(val); AMS_INFINITE_LOOP(); AMS_ASSUME(false); } while (false)
#define AMS_CALL_ON_RESULT_ABORT_IMPL(cond, val) do { ::ams::diag::impl::FatalErrorByResultForNx(val); AMS_INFINITE_LOOP(); AMS_ASSUME(false); } while (false)
#else
#define AMS_CALL_ON_RESULT_ASSERTION_IMPL(cond, val) ::ams::result::impl::OnResultAssertion("", 0, "", "", val)
#define AMS_CALL_ON_RESULT_ABORT_IMPL(cond, val) ::ams::result::impl::OnResultAbort("", 0, "", "", val)
#if defined(AMS_ENABLE_DETAILED_ASSERTIONS)
#define AMS_CALL_ON_RESULT_ASSERTION_IMPL(cond, val) ::ams::result::impl::OnResultAssertion(__FILE__, __LINE__, __PRETTY_FUNCTION__, cond, val)
#define AMS_CALL_ON_RESULT_ABORT_IMPL(cond, val) ::ams::result::impl::OnResultAbort(__FILE__, __LINE__, __PRETTY_FUNCTION__, cond, val)
#else
#define AMS_CALL_ON_RESULT_ASSERTION_IMPL(cond, val) ::ams::result::impl::OnResultAssertion("", 0, "", "", val)
#define AMS_CALL_ON_RESULT_ABORT_IMPL(cond, val) ::ams::result::impl::OnResultAbort("", 0, "", "", val)
#endif
#endif
/// Evaluates an expression that returns a result, and asserts the result if it would fail.
#ifdef AMS_ENABLE_ASSERTIONS
#define R_ASSERT(res_expr) \
({ \
{ \
if (const auto _tmp_r_assert_rc = (res_expr); AMS_UNLIKELY(R_FAILED(_tmp_r_assert_rc))) { \
AMS_CALL_ON_RESULT_ASSERTION_IMPL(#res_expr, _tmp_r_assert_rc); \
} \
})
}
#else
#define R_ASSERT(res_expr) AMS_UNUSED((res_expr));
#endif
/// Evaluates an expression that returns a result, and aborts if the result would fail.
#define R_ABORT_UNLESS(res_expr) \
({ \
{ \
if (const auto _tmp_r_abort_rc = (res_expr); AMS_UNLIKELY(R_FAILED(_tmp_r_abort_rc))) { \
AMS_CALL_ON_RESULT_ABORT_IMPL(#res_expr, _tmp_r_abort_rc); \
} \
})
}
/// Evaluates a boolean expression, and returns a result unless that expression is true.
#define R_UNLESS(expr, res) \
({ \
{ \
if (!(expr)) { \
R_THROW(res); \
} \
})
}
/// Evaluates a boolean expression, and succeeds if that expression is true.
#define R_SUCCEED_IF(expr) R_UNLESS(!(expr), ResultSuccess())
@@ -415,24 +428,24 @@ namespace ams::result::impl {
/// Helpers for pattern-matching on a result expression, if the result would fail.
#define R_CURRENT_RESULT _tmp_r_try_catch_current_result
#define R_TRY_CATCH(res_expr) \
({ \
#define R_TRY_CATCH(res_expr) \
{ \
const auto R_CURRENT_RESULT = (res_expr); \
if (R_FAILED(R_CURRENT_RESULT)) { \
if (R_FAILED(R_CURRENT_RESULT)) { \
if (false)
#define R_CATCH(...) \
#define R_CATCH(...) \
} else if (::ams::result::impl::EvaluateAnyResultIncludes<__VA_ARGS__>(R_CURRENT_RESULT)) { \
if (true)
#define R_CATCH_MODULE(__module__) \
#define R_CATCH_MODULE(__module__) \
} else if ((R_CURRENT_RESULT).GetModule() == ::ams::R_NAMESPACE_MODULE_ID(__module__)) { \
if (true)
#define R_CONVERT(catch_type, convert_type) \
R_CATCH(catch_type) { R_THROW(static_cast<::ams::Result>(convert_type)); }
#define R_CATCH_ALL() \
#define R_CATCH_ALL() \
} else if (R_FAILED(R_CURRENT_RESULT)) { \
if (true)
@@ -442,26 +455,26 @@ namespace ams::result::impl {
#define R_CATCH_RETHROW(catch_type) \
R_CONVERT(catch_type, R_CURRENT_RESULT)
#define R_END_TRY_CATCH \
#define R_END_TRY_CATCH \
else if (R_FAILED(R_CURRENT_RESULT)) { \
R_THROW(R_CURRENT_RESULT); \
} \
} \
})
R_THROW(R_CURRENT_RESULT); \
} \
} \
}
#define R_END_TRY_CATCH_WITH_ASSERT \
else { \
#define R_END_TRY_CATCH_WITH_ASSERT \
else { \
R_ASSERT(R_CURRENT_RESULT); \
} \
} \
})
} \
} \
}
#define R_END_TRY_CATCH_WITH_ABORT_UNLESS \
else { \
#define R_END_TRY_CATCH_WITH_ABORT_UNLESS \
else { \
R_ABORT_UNLESS(R_CURRENT_RESULT); \
} \
} \
})
} \
} \
}