From a59998f2907dd2669671ea2285b5ab19327b0a67 Mon Sep 17 00:00:00 2001 From: Wyatt Hepler Date: Fri, 19 Mar 2021 14:35:10 -0700 Subject: pw_assert: Rename assert/check headers - Rename assert.h to check.h, since it provides PW_CHECK. - Rename light.h to assert.h, since it provides PW_ASSERT. - Move short CHECK macros to pw_assert/short.h. - Have light.h include assert.h and assert.h include check.h for backwards compatibility. Bug: 350 Change-Id: I3ad69d1593a3ca9b8daf63aec2c849f9388aa58c Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/38720 Reviewed-by: Keir Mierle Commit-Queue: Wyatt Hepler --- pw_assert/BUILD | 4 +- pw_assert/BUILD.gn | 15 +- pw_assert/assert_facade_test.cc | 23 +- pw_assert/docs.rst | 51 ++- pw_assert/public/pw_assert/assert.h | 142 +++----- pw_assert/public/pw_assert/check.h | 121 +++++++ pw_assert/public/pw_assert/internal/assert_impl.h | 403 ---------------------- pw_assert/public/pw_assert/internal/check_impl.h | 327 ++++++++++++++++++ pw_assert/public/pw_assert/light.h | 47 +-- pw_assert/public/pw_assert/short.h | 81 +++++ 10 files changed, 617 insertions(+), 597 deletions(-) create mode 100644 pw_assert/public/pw_assert/check.h delete mode 100644 pw_assert/public/pw_assert/internal/assert_impl.h create mode 100644 pw_assert/public/pw_assert/internal/check_impl.h create mode 100644 pw_assert/public/pw_assert/short.h (limited to 'pw_assert') diff --git a/pw_assert/BUILD b/pw_assert/BUILD index 682dfd4c1..58ce60111 100644 --- a/pw_assert/BUILD +++ b/pw_assert/BUILD @@ -29,9 +29,11 @@ pw_cc_library( name = "facade", hdrs = [ "public/pw_assert/assert.h", - "public/pw_assert/internal/assert_impl.h", + "public/pw_assert/check.h", + "public/pw_assert/internal/check_impl.h", "public/pw_assert/light.h", "public/pw_assert/options.h", + "public/pw_assert/short.h", ], includes = ["public"], deps = [ diff --git a/pw_assert/BUILD.gn b/pw_assert/BUILD.gn index 084aa00be..5e83da1eb 100644 --- a/pw_assert/BUILD.gn +++ b/pw_assert/BUILD.gn @@ -31,15 +31,21 @@ pw_facade("pw_assert") { backend = pw_assert_BACKEND public_configs = [ ":default_config" ] public = [ - "public/pw_assert/assert.h", - "public/pw_assert/internal/assert_impl.h", + "public/pw_assert/check.h", + "public/pw_assert/internal/check_impl.h", + "public/pw_assert/short.h", ] public_deps = [ dir_pw_preprocessor, - # Also expose light.h to all users of pw_assert. + # Also expose assert.h to all users of pw_assert. ":light", ] + + # TODO(pwbug/350): Allow assert.h to include check.h for backwards + # compatibility. Remove this when projects have migrated. + allow_circular_includes_from = [ ":light" ] + deps = [ ":light" ] } # Provide a way include "pw_assert/light.h" without depending on the full @@ -51,6 +57,7 @@ pw_facade("pw_assert") { pw_source_set("light") { public_configs = [ ":default_config" ] public = [ + "public/pw_assert/assert.h", "public/pw_assert/light.h", # Needed for PW_ASSERT_ENABLE_DEBUG. Note that depending on :pw_assert to @@ -85,7 +92,7 @@ pw_test("assert_facade_test") { sources = [ "assert_facade_test.cc", "fake_backend.cc", - "public/pw_assert/internal/assert_impl.h", + "public/pw_assert/internal/check_impl.h", "pw_assert_test/fake_backend.h", ] deps = [ diff --git a/pw_assert/assert_facade_test.cc b/pw_assert/assert_facade_test.cc index 376bdf533..088f72596 100644 --- a/pw_assert/assert_facade_test.cc +++ b/pw_assert/assert_facade_test.cc @@ -22,8 +22,7 @@ // assert backend from triggering. // // clang-format off -#define PW_ASSERT_USE_SHORT_NAMES 1 -#include "pw_assert/internal/assert_impl.h" +#include "pw_assert/internal/check_impl.h" // clang-format on #include "gtest/gtest.h" @@ -453,26 +452,6 @@ TEST(AssertPass, DCheckDisabledBinaryOpTwoSideEffectingCalls_2) { } #endif // PW_ASSERT_ENABLE_DEBUG -// Note: This requires enabling PW_ASSERT_USE_SHORT_NAMES 1 above. -TEST(Check, ShortNamesWork) { - // Crash - CRASH("msg"); - CRASH("msg: %d", 5); - - // Check - CHECK(true); - CHECK(true, "msg"); - CHECK(true, "msg: %d", 5); - CHECK(false); - CHECK(false, "msg"); - CHECK(false, "msg: %d", 5); - - // Check with binary comparison - CHECK_INT_LE(1, 2); - CHECK_INT_LE(1, 2, "msg"); - CHECK_INT_LE(1, 2, "msg: %d", 5); -} - // Verify PW_CHECK_OK, including message handling. TEST_F(AssertFail, StatusNotOK) { pw::Status status = pw::Status::Unknown(); diff --git a/pw_assert/docs.rst b/pw_assert/docs.rst index aec33436a..73f0659c6 100644 --- a/pw_assert/docs.rst +++ b/pw_assert/docs.rst @@ -25,11 +25,11 @@ The ``pw_assert`` API provides three classes of macros: a message. - **PW_CHECK__(a, b[, fmt, ...])** - Assert that the expression ``a b`` is true, optionally with a message. -- **PW_ASSERT(condition)** - Header- and constexpr- assert. +- **PW_ASSERT(condition)** - Header- and constexpr-safe assert. .. tip:: - All of the assert macros optionally support a message with additional + All of the ``CHECK`` macros optionally support a message with additional arguments, to assist in debugging when an assert triggers: .. code-block:: cpp @@ -42,7 +42,7 @@ Example .. code-block:: cpp - #include "pw_assert/assert.h" + #include "pw_assert/check.h" int main() { bool sensor_running = StartSensor(&msg); @@ -72,7 +72,7 @@ Example .. tip:: - Use ``PW_ASSERT`` from ``pw_assert/light.h`` for asserts in headers or + Use ``PW_ASSERT`` from ``pw_assert/assert.h`` for asserts in headers or asserting in ``constexpr`` contexts. Structure of assert modules @@ -102,9 +102,8 @@ See the Backend API section below for more details. ---------- Facade API ---------- - The below functions describe the assert API functions that applications should -invoke to assert. These macros found in the ``pw_assert/assert.h`` header. +invoke to assert. These macros are found in the ``pw_assert/check.h`` header. .. cpp:function:: PW_CRASH(format, ...) @@ -392,9 +391,9 @@ invoke to assert. These macros found in the ``pw_assert/assert.h`` header. code; for example ``status == RESOURCE_EXHAUSTED`` instead of ``status == 5``. ---------- -Light API ---------- +---------- +Assert API +---------- The normal ``PW_CHECK_*`` and ``PW_DCHECK_*`` family of macros are intended to provide rich debug information, like the file, line number, value of operands in boolean comparisons, and more. However, this comes at a cost: these macros @@ -411,12 +410,11 @@ There are several issues with the normal ``PW_CHECK_*`` suite of macros: 4. ``PW_CHECK_*`` can trigger circular dependencies when asserts are used from low-level contexts, like in ````. -**Light asserts** solve all of the above three problems: No risk of ODR -violations, are constexpr safe, and have a tiny call site footprint; and there -is no header dependency on the backend preventing circular include issues. -However, there are **no format messages, no captured line number, no captured -file, no captured expression, or anything other than a binary indication of -failure**. +**PW_ASSERT** solves all of the above problems: No risk of ODR violations, are +constexpr safe, and have a tiny call site footprint; and there is no header +dependency on the backend preventing circular include issues. However, there +are **no format messages, no captured line number, no captured file, no captured +expression, or anything other than a binary indication of failure**. Example ------- @@ -425,7 +423,7 @@ Example // This example demonstrates asserting in a header. - #include "pw_assert/light.h" + #include "pw_assert/assert.h" class InlinedSubsystem { public: @@ -441,8 +439,8 @@ Example } }; -Light API reference -------------------- +PW_ASSERT API reference +----------------------- .. cpp:function:: PW_ASSERT(condition) A header- and constexpr-safe version of ``PW_CHECK()``. @@ -468,10 +466,11 @@ Light API reference Use ``PW_CHECK_*()`` whenever possible. -Light API backend ------------------ -The light API ultimately calls the C function ``pw_assert_HandleFailure()``, -which must be provided by the assert backend. +PW_ASSERT API backend +--------------------- +The ``PW_ASSERT`` API ultimately calls the C function +``pw_assert_HandleFailure()``, which must be provided by the ``pw_assert`` +backend. ----------- Backend API @@ -547,14 +546,14 @@ and that header must define the following macros: See :ref:`module-pw_assert_basic` for one way to combine these arguments into a meaningful error message. -Additionally, the backend must provide a link-time function for the light -assert handler. This does not need to appear in the backend header, but instead -is in a ``.cc`` file. +Additionally, the backend must provide a link-time function for the +``PW_ASSERT`` assert handler. This does not need to appear in the backend +header, but instead is in a ``.cc`` file. .. cpp:function:: pw_assert_HandleFailure() Handle a low-level crash. This crash entry happens through - ``pw_assert/light.h``. In this crash handler, there is no access to line, + ``pw_assert/assert.h``. In this crash handler, there is no access to line, file, expression, or other rich assert information. Backends should do something reasonable in this case; typically, capturing the stack is useful. diff --git a/pw_assert/public/pw_assert/assert.h b/pw_assert/public/pw_assert/assert.h index 2a4c999bc..a6756a658 100644 --- a/pw_assert/public/pw_assert/assert.h +++ b/pw_assert/public/pw_assert/assert.h @@ -11,104 +11,52 @@ // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. -// ============================================================================= -// -// This file describes Pigweed's public user-facing assert API. -// -// THIS API IS NOT STABLE OR COMPLETE! NEITHER FACADE NOR BACKEND API! -// #pragma once -#include "pw_preprocessor/arguments.h" +#include "pw_assert/options.h" // For PW_ASSERT_ENABLE_DEBUG +#include "pw_preprocessor/util.h" -// The pw_assert public API: -// -// Trigger a crash with a message. Replaces LOG_FATAL() in other systems. -// PW_CRASH(msg, ...) -// -// In all below cases, the message argument is optional: -// PW_CHECK_INT_LE(x, y) or -// PW_CHECK_INT_LE(x, y, "Was booting %s subsystem", subsystem_name) -// -// Asserts the condition, crashes on failure. Equivalent to assert. -// PW_CHECK(condition) or -// PW_CHECK(condition, msg, ...) -// -// Some common typed checks. -// PW_CHECK_OK(status, msg, ...) Asserts status == PW_STATUS_OK -// PW_CHECK_NOTNULL(ptr, msg, ...) Asserts ptr != NULL -// -// In many cases an assert is a binary comparison. In those cases, using the -// special binary assert macros below for <, <=, >, >=, == enables reporting -// the values of the operands in addition to the string of the condition. -// -// Binary comparison asserts for 'int' type ("%d" in format strings): -// PW_CHECK_INT_LE(a, b, msg, ...) Asserts a <= b -// PW_CHECK_INT_LT(a, b, msg, ...) Asserts a < b -// PW_CHECK_INT_GE(a, b, msg, ...) Asserts a >= b -// PW_CHECK_INT_GT(a, b, msg, ...) Asserts a > b -// PW_CHECK_INT_EQ(a, b, msg, ...) Asserts a == b -// PW_CHECK_INT_NE(a, b, msg, ...) Asserts a != b -// -// Binary comparison asserts for 'unsigned int' type ("%u" in format strings): -// PW_CHECK_UINT_LE(a, b, msg, ...) Asserts a <= b -// PW_CHECK_UINT_LT(a, b, msg, ...) Asserts a < b -// PW_CHECK_UINT_GE(a, b, msg, ...) Asserts a >= b -// PW_CHECK_UINT_GT(a, b, msg, ...) Asserts a > b -// PW_CHECK_UINT_EQ(a, b, msg, ...) Asserts a == b -// PW_CHECK_UINT_NE(a, b, msg, ...) Asserts a != b -// -// Binary comparison asserts for 'void*' type ("%p" in format strings): -// PW_CHECK_PTR_LE(a, b, msg, ...) Asserts a <= b -// PW_CHECK_PTR_LT(a, b, msg, ...) Asserts a < b -// PW_CHECK_PTR_GE(a, b, msg, ...) Asserts a >= b -// PW_CHECK_PTR_GT(a, b, msg, ...) Asserts a > b -// PW_CHECK_PTR_EQ(a, b, msg, ...) Asserts a == b -// PW_CHECK_PTR_NE(a, b, msg, ...) Asserts a != b -// -// Binary comparison asserts for 'float' type ("%f" in format strings): -// PW_CHECK_FLOAT_NEAR(a, b, abs_tolerance, msg, ...) -// Asserts (a >= (b - abs_tolerance)) && (a <= (b + abs_tolerance)) -// PW_CHECK_FLOAT_EXACT_LE(a, b, msg, ...) Asserts a <= b -// PW_CHECK_FLOAT_EXACT_LT(a, b, msg, ...) Asserts a < b -// PW_CHECK_FLOAT_EXACT_GE(a, b, msg, ...) Asserts a >= b -// PW_CHECK_FLOAT_EXACT_GT(a, b, msg, ...) Asserts a > b -// PW_CHECK_FLOAT_EXACT_EQ(a, b, msg, ...) Asserts a == b -// PW_CHECK_FLOAT_EXACT_NE(a, b, msg, ...) Asserts a != b -// -// The above CHECK_*_*() are also available in DCHECK variants, which will -// only evaluate their arguments and trigger if the NDEBUG macro is defined. -// -// Note: For float, proper comparator checks which take floating point -// precision and ergo error accumulation into account are not provided on -// purpose as this comes with some complexity and requires application -// specific tolerances in terms of Units of Least Precision (ULP). Instead, -// we recommend developers carefully consider how floating point precision and -// error impact the data they are bounding and whether CHECKs are appropriate. -// -// Note: PW_CRASH is the equivalent of LOG_FATAL in other systems, where a -// device crash is triggered with a message. In Pigweed, logging and -// crashing/asserting are separated. There is a LOG_CRITICAL level in the -// logging module, but it does not have side effects; for LOG_FATAL, instead -// use this macro (PW_CRASH). -// -// The public macro definitions are split out into an impl file to facilitate -// testing the facade logic directly, without going through the facade/backend -// build facilities. -#include "pw_assert/internal/assert_impl.h" +// For backwards compatibility, include check.h from assert.h. +// TODO(pwbug/350): Remove this include when projects have migrated. +#include "pw_assert/check.h" -// The pw_assert_backend must provide these macros: -// -// PW_HANDLE_CRASH(msg, ...) -// PW_HANDLE_ASSERT_FAILURE(condition, msg, ...) -// PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(a, op, b, type_fmt, msg, ...) -// -// The low level functionality of triggering a crash, rebooting a device, -// collecting information, or hanging out in a while(1) loop, must be -// provided by the underlying assert backend as part of the crash or assert -// failure handling. -// -// Note that for the assert failures, the handler should assume the assert -// has already failed (the facade checks the condition before delegating). -// -#include "pw_assert_backend/assert_backend.h" +PW_EXTERN_C_START + +void pw_assert_HandleFailure(void); + +PW_EXTERN_C_END + +// A header- and constexpr-safe version of PW_CHECK(). +// +// If the given condition is false, crash the system. Otherwise, do nothing. +// The condition is guaranteed to be evaluated. This assert implementation is +// guaranteed to be constexpr-safe. +// +// IMPORTANT: Unlike the PW_CHECK_*() suite of macros, this API captures no +// rich information like line numbers, the file, expression arguments, or the +// stringified expression. Use these macros only when absolutely necessary -- +// in headers, constexr contexts, or in rare cases where the call site overhead +// of a full PW_CHECK must be avoided. Use PW_CHECK_*() whenever possible. +#define PW_ASSERT(condition) \ + do { \ + if (!(condition)) { \ + pw_assert_HandleFailure(); \ + } \ + } while (0) + +// A header- and constexpr-safe version of PW_DCHECK(). +// +// Same as PW_ASSERT(), except that if PW_ASSERT_ENABLE_DEBUG == 1, the assert +// is disabled and condition is not evaluated. +// +// IMPORTANT: Unlike the PW_CHECK_*() suite of macros, this API captures no +// rich information like line numbers, the file, expression arguments, or the +// stringified expression. Use these macros only when absolutely necessary -- +// in headers, constexr contexts, or in rare cases where the call site overhead +// of a full PW_CHECK must be avoided. Use PW_DCHECK_*() whenever possible. +#define PW_DASSERT(condition) \ + do { \ + if ((PW_ASSERT_ENABLE_DEBUG == 1) && !(condition)) { \ + pw_assert_HandleFailure(); \ + } \ + } while (0) diff --git a/pw_assert/public/pw_assert/check.h b/pw_assert/public/pw_assert/check.h new file mode 100644 index 000000000..1cb4eb73e --- /dev/null +++ b/pw_assert/public/pw_assert/check.h @@ -0,0 +1,121 @@ +// Copyright 2020 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +// ============================================================================= +// +// This file describes Pigweed's public user-facing assert API. +// +// THIS API IS NOT STABLE OR COMPLETE! NEITHER FACADE NOR BACKEND API! +// +#pragma once + +#include "pw_preprocessor/arguments.h" + +// The pw_assert public API: +// +// Trigger a crash with a message. Replaces LOG_FATAL() in other systems. +// PW_CRASH(msg, ...) +// +// In all below cases, the message argument is optional: +// PW_CHECK_INT_LE(x, y) or +// PW_CHECK_INT_LE(x, y, "Was booting %s subsystem", subsystem_name) +// +// Asserts the condition, crashes on failure. Equivalent to assert. +// PW_CHECK(condition) or +// PW_CHECK(condition, msg, ...) +// +// Some common typed checks. +// PW_CHECK_OK(status, msg, ...) Asserts status == PW_STATUS_OK +// PW_CHECK_NOTNULL(ptr, msg, ...) Asserts ptr != NULL +// +// In many cases an assert is a binary comparison. In those cases, using the +// special binary assert macros below for <, <=, >, >=, == enables reporting +// the values of the operands in addition to the string of the condition. +// +// Binary comparison asserts for 'int' type ("%d" in format strings): +// PW_CHECK_INT_LE(a, b, msg, ...) Asserts a <= b +// PW_CHECK_INT_LT(a, b, msg, ...) Asserts a < b +// PW_CHECK_INT_GE(a, b, msg, ...) Asserts a >= b +// PW_CHECK_INT_GT(a, b, msg, ...) Asserts a > b +// PW_CHECK_INT_EQ(a, b, msg, ...) Asserts a == b +// PW_CHECK_INT_NE(a, b, msg, ...) Asserts a != b +// +// Binary comparison asserts for 'unsigned int' type ("%u" in format strings): +// PW_CHECK_UINT_LE(a, b, msg, ...) Asserts a <= b +// PW_CHECK_UINT_LT(a, b, msg, ...) Asserts a < b +// PW_CHECK_UINT_GE(a, b, msg, ...) Asserts a >= b +// PW_CHECK_UINT_GT(a, b, msg, ...) Asserts a > b +// PW_CHECK_UINT_EQ(a, b, msg, ...) Asserts a == b +// PW_CHECK_UINT_NE(a, b, msg, ...) Asserts a != b +// +// Binary comparison asserts for 'void*' type ("%p" in format strings): +// PW_CHECK_PTR_LE(a, b, msg, ...) Asserts a <= b +// PW_CHECK_PTR_LT(a, b, msg, ...) Asserts a < b +// PW_CHECK_PTR_GE(a, b, msg, ...) Asserts a >= b +// PW_CHECK_PTR_GT(a, b, msg, ...) Asserts a > b +// PW_CHECK_PTR_EQ(a, b, msg, ...) Asserts a == b +// PW_CHECK_PTR_NE(a, b, msg, ...) Asserts a != b +// +// Binary comparison asserts for 'float' type ("%f" in format strings): +// PW_CHECK_FLOAT_NEAR(a, b, abs_tolerance, msg, ...) +// Asserts (a >= (b - abs_tolerance)) && (a <= (b + abs_tolerance)) +// PW_CHECK_FLOAT_EXACT_LE(a, b, msg, ...) Asserts a <= b +// PW_CHECK_FLOAT_EXACT_LT(a, b, msg, ...) Asserts a < b +// PW_CHECK_FLOAT_EXACT_GE(a, b, msg, ...) Asserts a >= b +// PW_CHECK_FLOAT_EXACT_GT(a, b, msg, ...) Asserts a > b +// PW_CHECK_FLOAT_EXACT_EQ(a, b, msg, ...) Asserts a == b +// PW_CHECK_FLOAT_EXACT_NE(a, b, msg, ...) Asserts a != b +// +// The above CHECK_*_*() are also available in DCHECK variants, which will +// only evaluate their arguments and trigger if the NDEBUG macro is defined. +// +// Note: For float, proper comparator checks which take floating point +// precision and ergo error accumulation into account are not provided on +// purpose as this comes with some complexity and requires application +// specific tolerances in terms of Units of Least Precision (ULP). Instead, +// we recommend developers carefully consider how floating point precision and +// error impact the data they are bounding and whether CHECKs are appropriate. +// +// Note: PW_CRASH is the equivalent of LOG_FATAL in other systems, where a +// device crash is triggered with a message. In Pigweed, logging and +// crashing/asserting are separated. There is a LOG_CRITICAL level in the +// logging module, but it does not have side effects; for LOG_FATAL, instead +// use this macro (PW_CRASH). +// +// The public macro definitions are split out into an impl file to facilitate +// testing the facade logic directly, without going through the facade/backend +// build facilities. +#include "pw_assert/internal/check_impl.h" + +// For compatibility, include short.h if PW_ASSERT_USE_SHORT_NAMES is set. +// TODO(pwbug/350): Remove this include and the PW_ASSERT_USE_SHORT_NAMES macro +// when projects have migrated to including the short.h header. +#if defined(PW_ASSERT_USE_SHORT_NAMES) && PW_ASSERT_USE_SHORT_NAMES == 1 +#include "pw_assert/short.h" +#endif // defined(PW_ASSERT_USE_SHORT_NAMES) && PW_ASSERT_USE_SHORT_NAMES == 1 + +// The pw_assert_backend must provide these macros: +// +// PW_HANDLE_CRASH(msg, ...) +// PW_HANDLE_ASSERT_FAILURE(condition, msg, ...) +// PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(a, op, b, type_fmt, msg, ...) +// +// The low level functionality of triggering a crash, rebooting a device, +// collecting information, or hanging out in a while(1) loop, must be +// provided by the underlying assert backend as part of the crash or assert +// failure handling. +// +// Note that for the assert failures, the handler should assume the assert +// has already failed (the facade checks the condition before delegating). +// +#include "pw_assert_backend/assert_backend.h" diff --git a/pw_assert/public/pw_assert/internal/assert_impl.h b/pw_assert/public/pw_assert/internal/assert_impl.h deleted file mode 100644 index c13c29885..000000000 --- a/pw_assert/public/pw_assert/internal/assert_impl.h +++ /dev/null @@ -1,403 +0,0 @@ -// Copyright 2020 The Pigweed Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -#pragma once - -#ifndef __cplusplus -#include -#endif // __cplusplus - -// Note: This file depends on the backend header already being included. - -#include "pw_assert/options.h" -#include "pw_preprocessor/arguments.h" -#include "pw_preprocessor/compiler.h" - -// PW_CRASH - Crash the system, with a message. -#define PW_CRASH PW_HANDLE_CRASH - -// PW_CHECK - If condition evaluates to false, crash. Message optional. -#define PW_CHECK(condition, ...) \ - do { \ - if (!(condition)) { \ - _PW_CHECK_SELECT_MACRO( \ - #condition, PW_HAS_ARGS(__VA_ARGS__), __VA_ARGS__); \ - } \ - } while (0) - -#define PW_DCHECK(...) \ - do { \ - if (PW_ASSERT_ENABLE_DEBUG) { \ - PW_CHECK(__VA_ARGS__); \ - } \ - } while (0) - -// PW_D?CHECK__ macros - Binary comparison asserts. -// -// The below blocks are structured in table form, violating the 80-column -// Pigweed style, in order to make it clearer what is common and what isn't -// between the multitude of assert macro instantiations. To best view this -// section, turn off editor wrapping or make your editor wide. -// -// clang-format off - -// Checks for int: LE, LT, GE, GT, EQ. -#define PW_CHECK_INT_LE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, <=, argb, int, "%d", __VA_ARGS__) -#define PW_CHECK_INT_LT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, < , argb, int, "%d", __VA_ARGS__) -#define PW_CHECK_INT_GE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, >=, argb, int, "%d", __VA_ARGS__) -#define PW_CHECK_INT_GT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, > , argb, int, "%d", __VA_ARGS__) -#define PW_CHECK_INT_EQ(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, ==, argb, int, "%d", __VA_ARGS__) -#define PW_CHECK_INT_NE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, !=, argb, int, "%d", __VA_ARGS__) - -// Debug checks for int: LE, LT, GE, GT, EQ. -#define PW_DCHECK_INT_LE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_INT_LE(__VA_ARGS__) -#define PW_DCHECK_INT_LT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_INT_LT(__VA_ARGS__) -#define PW_DCHECK_INT_GE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_INT_GE(__VA_ARGS__) -#define PW_DCHECK_INT_GT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_INT_GT(__VA_ARGS__) -#define PW_DCHECK_INT_EQ(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_INT_EQ(__VA_ARGS__) -#define PW_DCHECK_INT_NE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_INT_NE(__VA_ARGS__) - -// Checks for unsigned int: LE, LT, GE, GT, EQ. -#define PW_CHECK_UINT_LE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, <=, argb, unsigned int, "%u", __VA_ARGS__) -#define PW_CHECK_UINT_LT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, < , argb, unsigned int, "%u", __VA_ARGS__) -#define PW_CHECK_UINT_GE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, >=, argb, unsigned int, "%u", __VA_ARGS__) -#define PW_CHECK_UINT_GT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, > , argb, unsigned int, "%u", __VA_ARGS__) -#define PW_CHECK_UINT_EQ(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, ==, argb, unsigned int, "%u", __VA_ARGS__) -#define PW_CHECK_UINT_NE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, !=, argb, unsigned int, "%u", __VA_ARGS__) - -// Debug checks for unsigned int: LE, LT, GE, GT, EQ. -#define PW_DCHECK_UINT_LE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_UINT_LE(__VA_ARGS__) -#define PW_DCHECK_UINT_LT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_UINT_LT(__VA_ARGS__) -#define PW_DCHECK_UINT_GE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_UINT_GE(__VA_ARGS__) -#define PW_DCHECK_UINT_GT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_UINT_GT(__VA_ARGS__) -#define PW_DCHECK_UINT_EQ(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_UINT_EQ(__VA_ARGS__) -#define PW_DCHECK_UINT_NE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_UINT_NE(__VA_ARGS__) - -// Checks for pointer: LE, LT, GE, GT, EQ, NE. -#define PW_CHECK_PTR_LE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, <=, argb, const void*, "%p", __VA_ARGS__) -#define PW_CHECK_PTR_LT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, < , argb, const void*, "%p", __VA_ARGS__) -#define PW_CHECK_PTR_GE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, >=, argb, const void*, "%p", __VA_ARGS__) -#define PW_CHECK_PTR_GT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, > , argb, const void*, "%p", __VA_ARGS__) -#define PW_CHECK_PTR_EQ(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, ==, argb, const void*, "%p", __VA_ARGS__) -#define PW_CHECK_PTR_NE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, !=, argb, const void*, "%p", __VA_ARGS__) - -// Check for pointer: NOTNULL. Use "nullptr" in C++, "NULL" in C. -#ifdef __cplusplus -#define PW_CHECK_NOTNULL(arga, ...) \ - _PW_CHECK_BINARY_CMP_IMPL(arga, !=, nullptr, const void*, "%p", __VA_ARGS__) -#else // __cplusplus -#define PW_CHECK_NOTNULL(arga, ...) \ - _PW_CHECK_BINARY_CMP_IMPL(arga, !=, NULL, const void*, "%p", __VA_ARGS__) -#endif // __cplusplus - -// Debug checks for pointer: LE, LT, GE, GT, EQ, NE, and NOTNULL. -#define PW_DCHECK_PTR_LE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_PTR_LE(__VA_ARGS__) -#define PW_DCHECK_PTR_LT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_PTR_LT(__VA_ARGS__) -#define PW_DCHECK_PTR_GE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_PTR_GE(__VA_ARGS__) -#define PW_DCHECK_PTR_GT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_PTR_GT(__VA_ARGS__) -#define PW_DCHECK_PTR_EQ(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_PTR_EQ(__VA_ARGS__) -#define PW_DCHECK_PTR_NE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_PTR_NE(__VA_ARGS__) -#define PW_DCHECK_NOTNULL(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_NOTNULL(__VA_ARGS__) - -// Checks for float: EXACT_LE, EXACT_LT, EXACT_GE, EXACT_GT, EXACT_EQ, EXACT_NE, -// NEAR. -#define PW_CHECK_FLOAT_NEAR(arga, argb, abs_tolerance, ...) \ - _PW_CHECK_FLOAT_NEAR(arga, argb, abs_tolerance, __VA_ARGS__) -#define PW_CHECK_FLOAT_EXACT_LE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, <=, argb, float, "%f", __VA_ARGS__) -#define PW_CHECK_FLOAT_EXACT_LT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, < , argb, float, "%f", __VA_ARGS__) -#define PW_CHECK_FLOAT_EXACT_GE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, >=, argb, float, "%f", __VA_ARGS__) -#define PW_CHECK_FLOAT_EXACT_GT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, > , argb, float, "%f", __VA_ARGS__) -#define PW_CHECK_FLOAT_EXACT_EQ(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, ==, argb, float, "%f", __VA_ARGS__) -#define PW_CHECK_FLOAT_EXACT_NE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, !=, argb, float, "%f", __VA_ARGS__) - -// Debug checks for float: NEAR, EXACT_LE, EXACT_LT, EXACT_GE, EXACT_GT, -// EXACT_EQ. -#define PW_DCHECK_FLOAT_NEAR(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_NEAR(__VA_ARGS__) -#define PW_DCHECK_FLOAT_EXACT_LE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_EXACT_LE(__VA_ARGS__) -#define PW_DCHECK_FLOAT_EXACT_LT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_EXACT_LT(__VA_ARGS__) -#define PW_DCHECK_FLOAT_EXACT_GE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_EXACT_GE(__VA_ARGS__) -#define PW_DCHECK_FLOAT_EXACT_GT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_EXACT_GT(__VA_ARGS__) -#define PW_DCHECK_FLOAT_EXACT_EQ(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_EXACT_EQ(__VA_ARGS__) -#define PW_DCHECK_FLOAT_EXACT_NE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_EXACT_NE(__VA_ARGS__) - -// clang-format on - -// PW_CHECK - If condition evaluates to false, crash. Message optional. -#define PW_CHECK_OK(status, ...) \ - do { \ - if (status != PW_STATUS_OK) { \ - _PW_CHECK_OK_SELECT_MACRO(#status, \ - pw_StatusString(status), \ - PW_HAS_ARGS(__VA_ARGS__), \ - __VA_ARGS__); \ - } \ - } while (0) - -#define PW_DCHECK_OK(...) \ - if (!(PW_ASSERT_ENABLE_DEBUG)) { \ - } else \ - PW_CHECK_OK(__VA_ARGS__) - -// ========================================================================= -// Implementation for PW_CHECK - -// Two layers of select macros are used to enable the preprocessor to expand -// macros in the arguments to ultimately token paste the final macro name based -// on whether there are printf-style arguments. -#define _PW_CHECK_SELECT_MACRO(condition, has_args, ...) \ - _PW_CHECK_SELECT_MACRO_EXPANDED(condition, has_args, __VA_ARGS__) - -// Delegate to the macro -#define _PW_CHECK_SELECT_MACRO_EXPANDED(condition, has_args, ...) \ - _PW_CHECK_HAS_MSG_##has_args(condition, __VA_ARGS__) - -// PW_CHECK version 1: No message or args -#define _PW_CHECK_HAS_MSG_0(condition, ignored_arg) \ - PW_HANDLE_ASSERT_FAILURE(condition, "") - -// PW_CHECK version 2: With message (and maybe args) -#define _PW_CHECK_HAS_MSG_1(condition, ...) \ - PW_HANDLE_ASSERT_FAILURE(condition, __VA_ARGS__) - -// ========================================================================= -// Implementation for PW_CHECK__ - -// Two layers of select macros are used to enable the preprocessor to expand -// macros in the arguments to ultimately token paste the final macro name based -// on whether there are printf-style arguments. -#define _PW_CHECK_BINARY_COMPARISON_SELECT_MACRO(argument_a_str, \ - argument_a_val, \ - comparison_op_str, \ - argument_b_str, \ - argument_b_val, \ - type_fmt, \ - has_args, \ - ...) \ - _PW_CHECK_SELECT_BINARY_COMPARISON_MACRO_EXPANDED(argument_a_str, \ - argument_a_val, \ - comparison_op_str, \ - argument_b_str, \ - argument_b_val, \ - type_fmt, \ - has_args, \ - __VA_ARGS__) - -// Delegate to the macro -#define _PW_CHECK_SELECT_BINARY_COMPARISON_MACRO_EXPANDED(argument_a_str, \ - argument_a_val, \ - comparison_op_str, \ - argument_b_str, \ - argument_b_val, \ - type_fmt, \ - has_args, \ - ...) \ - _PW_CHECK_BINARY_COMPARISON_HAS_MSG_##has_args(argument_a_str, \ - argument_a_val, \ - comparison_op_str, \ - argument_b_str, \ - argument_b_val, \ - type_fmt, \ - __VA_ARGS__) - -// PW_CHECK_BINARY_COMPARISON version 1: No message or args -#define _PW_CHECK_BINARY_COMPARISON_HAS_MSG_0(argument_a_str, \ - argument_a_val, \ - comparison_op_str, \ - argument_b_str, \ - argument_b_val, \ - type_fmt, \ - ignored_arg) \ - PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(argument_a_str, \ - argument_a_val, \ - comparison_op_str, \ - argument_b_str, \ - argument_b_val, \ - type_fmt, \ - "") - -// PW_CHECK_BINARY_COMPARISON version 2: With message (and maybe args) -#define _PW_CHECK_BINARY_COMPARISON_HAS_MSG_1(argument_a_str, \ - argument_a_val, \ - comparison_op_str, \ - argument_b_str, \ - argument_b_val, \ - type_fmt, \ - ...) \ - PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(argument_a_str, \ - argument_a_val, \ - comparison_op_str, \ - argument_b_str, \ - argument_b_val, \ - type_fmt, \ - __VA_ARGS__) - -// For the binary assertions, this private macro is re-used for almost all of -// the variants. Due to limitations of C formatting, it is necessary to have -// separate macros for the types. -// -// The macro avoids evaluating the arguments multiple times at the cost of some -// macro complexity. -#define _PW_CHECK_BINARY_CMP_IMPL( \ - argument_a, comparison_op, argument_b, type_decl, type_fmt, ...) \ - do { \ - type_decl evaluated_argument_a = (type_decl)(argument_a); \ - type_decl evaluated_argument_b = (type_decl)(argument_b); \ - if (!(evaluated_argument_a comparison_op evaluated_argument_b)) { \ - _PW_CHECK_BINARY_COMPARISON_SELECT_MACRO(#argument_a, \ - evaluated_argument_a, \ - #comparison_op, \ - #argument_b, \ - evaluated_argument_b, \ - type_fmt, \ - PW_HAS_ARGS(__VA_ARGS__), \ - __VA_ARGS__); \ - } \ - } while (0) - -// Custom implementation for FLOAT_NEAR which is implemented through two -// underlying checks which are not trivially replaced through the use of -// FLOAT_EXACT_LE & FLOAT_EXACT_GE. -#define _PW_CHECK_FLOAT_NEAR(argument_a, argument_b, abs_tolerance, ...) \ - do { \ - PW_CHECK_FLOAT_EXACT_GE(abs_tolerance, 0.0f); \ - float evaluated_argument_a = (float)(argument_a); \ - float evaluated_argument_b_min = (float)(argument_b)-abs_tolerance; \ - float evaluated_argument_b_max = (float)(argument_b) + abs_tolerance; \ - if (!(evaluated_argument_a >= evaluated_argument_b_min)) { \ - _PW_CHECK_BINARY_COMPARISON_SELECT_MACRO(#argument_a, \ - evaluated_argument_a, \ - ">=", \ - #argument_b " - abs_tolerance", \ - evaluated_argument_b_min, \ - "%f", \ - PW_HAS_ARGS(__VA_ARGS__), \ - __VA_ARGS__); \ - } else if (!(evaluated_argument_a <= evaluated_argument_b_max)) { \ - _PW_CHECK_BINARY_COMPARISON_SELECT_MACRO(#argument_a, \ - evaluated_argument_a, \ - "<=", \ - #argument_b " + abs_tolerance", \ - evaluated_argument_b_max, \ - "%f", \ - PW_HAS_ARGS(__VA_ARGS__), \ - __VA_ARGS__); \ - } \ - } while (0) - -// ========================================================================= -// Implementation for PW_CHECK_OK - -// Two layers of select macros are used to enable the preprocessor to expand -// macros in the arguments to ultimately token paste the final macro name based -// on whether there are printf-style arguments. -#define _PW_CHECK_OK_SELECT_MACRO( \ - status_expr_str, status_value_str, has_args, ...) \ - _PW_CHECK_OK_SELECT_MACRO_EXPANDED( \ - status_expr_str, status_value_str, has_args, __VA_ARGS__) - -// Delegate to the macro -#define _PW_CHECK_OK_SELECT_MACRO_EXPANDED( \ - status_expr_str, status_value_str, has_args, ...) \ - _PW_CHECK_OK_HAS_MSG_##has_args( \ - status_expr_str, status_value_str, __VA_ARGS__) - -// PW_CHECK_OK version 1: No message or args -#define _PW_CHECK_OK_HAS_MSG_0(status_expr_str, status_value_str, ignored_arg) \ - PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE( \ - status_expr_str, status_value_str, "==", "OkStatus()", "OK", "%s", "") - -// PW_CHECK_OK version 2: With message (and maybe args) -#define _PW_CHECK_OK_HAS_MSG_1(status_expr_str, status_value_str, ...) \ - PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(status_expr_str, \ - status_value_str, \ - "==", \ - "OkStatus()", \ - "OK", \ - "%s", \ - __VA_ARGS__) - -// Define short, usable names if requested. Note that the CHECK() macro will -// conflict with Google Log, which expects stream style logs. -#ifndef PW_ASSERT_USE_SHORT_NAMES -#define PW_ASSERT_USE_SHORT_NAMES 0 -#endif - -// ========================================================================= -// Short name definitions (optional) - -// clang-format off -#if PW_ASSERT_USE_SHORT_NAMES - -// Checks that always run even in production. -#define CRASH PW_CRASH -#define CHECK PW_CHECK -#define CHECK_PTR_LE PW_CHECK_PTR_LE -#define CHECK_PTR_LT PW_CHECK_PTR_LT -#define CHECK_PTR_GE PW_CHECK_PTR_GE -#define CHECK_PTR_GT PW_CHECK_PTR_GT -#define CHECK_PTR_EQ PW_CHECK_PTR_EQ -#define CHECK_PTR_NE PW_CHECK_PTR_NE -#define CHECK_NOTNULL PW_CHECK_NOTNULL -#define CHECK_INT_LE PW_CHECK_INT_LE -#define CHECK_INT_LT PW_CHECK_INT_LT -#define CHECK_INT_GE PW_CHECK_INT_GE -#define CHECK_INT_GT PW_CHECK_INT_GT -#define CHECK_INT_EQ PW_CHECK_INT_EQ -#define CHECK_INT_NE PW_CHECK_INT_NE -#define CHECK_UINT_LE PW_CHECK_UINT_LE -#define CHECK_UINT_LT PW_CHECK_UINT_LT -#define CHECK_UINT_GE PW_CHECK_UINT_GE -#define CHECK_UINT_GT PW_CHECK_UINT_GT -#define CHECK_UINT_EQ PW_CHECK_UINT_EQ -#define CHECK_UINT_NE PW_CHECK_UINT_NE -#define CHECK_FLOAT_NEAR PW_CHECK_FLOAT_NEAR -#define CHECK_FLOAT_EXACT_LE PW_CHECK_FLOAT_EXACT_LE -#define CHECK_FLOAT_EXACT_LT PW_CHECK_FLOAT_EXACT_LT -#define CHECK_FLOAT_EXACT_GE PW_CHECK_FLOAT_EXACT_GE -#define CHECK_FLOAT_EXACT_GT PW_CHECK_FLOAT_EXACT_GT -#define CHECK_FLOAT_EXACT_EQ PW_CHECK_FLOAT_EXACT_EQ -#define CHECK_FLOAT_EXACT_NE PW_CHECK_FLOAT_EXACT_NE -#define CHECK_OK PW_CHECK_OK - -// Checks that are disabled if NDEBUG is not defined. -#define DCHECK PW_DCHECK -#define DCHECK_PTR_LE PW_DCHECK_PTR_LE -#define DCHECK_PTR_LT PW_DCHECK_PTR_LT -#define DCHECK_PTR_GE PW_DCHECK_PTR_GE -#define DCHECK_PTR_GT PW_DCHECK_PTR_GT -#define DCHECK_PTR_EQ PW_DCHECK_PTR_EQ -#define DCHECK_PTR_NE PW_DCHECK_PTR_NE -#define DCHECK_NOTNULL PW_DCHECK_NOTNULL -#define DCHECK_INT_LE PW_DCHECK_INT_LE -#define DCHECK_INT_LT PW_DCHECK_INT_LT -#define DCHECK_INT_GE PW_DCHECK_INT_GE -#define DCHECK_INT_GT PW_DCHECK_INT_GT -#define DCHECK_INT_EQ PW_DCHECK_INT_EQ -#define DCHECK_INT_NE PW_DCHECK_INT_NE -#define DCHECK_UINT_LE PW_DCHECK_UINT_LE -#define DCHECK_UINT_LT PW_DCHECK_UINT_LT -#define DCHECK_UINT_GE PW_DCHECK_UINT_GE -#define DCHECK_UINT_GT PW_DCHECK_UINT_GT -#define DCHECK_UINT_EQ PW_DCHECK_UINT_EQ -#define DCHECK_UINT_NE PW_DCHECK_UINT_NE -#define DCHECK_FLOAT_NEAR PW_DCHECK_FLOAT_NEAR -#define DCHECK_FLOAT_EXACT_LT PW_DCHECK_FLOAT_EXACT_LT -#define DCHECK_FLOAT_EXACT_LE PW_DCHECK_FLOAT_EXACT_LE -#define DCHECK_FLOAT_EXACT_GT PW_DCHECK_FLOAT_EXACT_GT -#define DCHECK_FLOAT_EXACT_GE PW_DCHECK_FLOAT_EXACT_GE -#define DCHECK_FLOAT_EXACT_EQ PW_DCHECK_FLOAT_EXACT_EQ -#define DCHECK_FLOAT_EXACT_NE PW_DCHECK_FLOAT_EXACT_NE -#define DCHECK_OK PW_DCHECK_OK - -#endif // PW_ASSERT_SHORT_NAMES -// clang-format on diff --git a/pw_assert/public/pw_assert/internal/check_impl.h b/pw_assert/public/pw_assert/internal/check_impl.h new file mode 100644 index 000000000..584dd0f33 --- /dev/null +++ b/pw_assert/public/pw_assert/internal/check_impl.h @@ -0,0 +1,327 @@ +// Copyright 2020 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +#pragma once + +#ifndef __cplusplus +#include +#endif // __cplusplus + +// Note: This file depends on the backend header already being included. + +#include "pw_assert/options.h" +#include "pw_preprocessor/arguments.h" +#include "pw_preprocessor/compiler.h" + +// PW_CRASH - Crash the system, with a message. +#define PW_CRASH PW_HANDLE_CRASH + +// PW_CHECK - If condition evaluates to false, crash. Message optional. +#define PW_CHECK(condition, ...) \ + do { \ + if (!(condition)) { \ + _PW_CHECK_SELECT_MACRO( \ + #condition, PW_HAS_ARGS(__VA_ARGS__), __VA_ARGS__); \ + } \ + } while (0) + +#define PW_DCHECK(...) \ + do { \ + if (PW_ASSERT_ENABLE_DEBUG) { \ + PW_CHECK(__VA_ARGS__); \ + } \ + } while (0) + +// PW_D?CHECK__ macros - Binary comparison asserts. +// +// The below blocks are structured in table form, violating the 80-column +// Pigweed style, in order to make it clearer what is common and what isn't +// between the multitude of assert macro instantiations. To best view this +// section, turn off editor wrapping or make your editor wide. +// +// clang-format off + +// Checks for int: LE, LT, GE, GT, EQ. +#define PW_CHECK_INT_LE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, <=, argb, int, "%d", __VA_ARGS__) +#define PW_CHECK_INT_LT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, < , argb, int, "%d", __VA_ARGS__) +#define PW_CHECK_INT_GE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, >=, argb, int, "%d", __VA_ARGS__) +#define PW_CHECK_INT_GT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, > , argb, int, "%d", __VA_ARGS__) +#define PW_CHECK_INT_EQ(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, ==, argb, int, "%d", __VA_ARGS__) +#define PW_CHECK_INT_NE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, !=, argb, int, "%d", __VA_ARGS__) + +// Debug checks for int: LE, LT, GE, GT, EQ. +#define PW_DCHECK_INT_LE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_INT_LE(__VA_ARGS__) +#define PW_DCHECK_INT_LT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_INT_LT(__VA_ARGS__) +#define PW_DCHECK_INT_GE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_INT_GE(__VA_ARGS__) +#define PW_DCHECK_INT_GT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_INT_GT(__VA_ARGS__) +#define PW_DCHECK_INT_EQ(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_INT_EQ(__VA_ARGS__) +#define PW_DCHECK_INT_NE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_INT_NE(__VA_ARGS__) + +// Checks for unsigned int: LE, LT, GE, GT, EQ. +#define PW_CHECK_UINT_LE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, <=, argb, unsigned int, "%u", __VA_ARGS__) +#define PW_CHECK_UINT_LT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, < , argb, unsigned int, "%u", __VA_ARGS__) +#define PW_CHECK_UINT_GE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, >=, argb, unsigned int, "%u", __VA_ARGS__) +#define PW_CHECK_UINT_GT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, > , argb, unsigned int, "%u", __VA_ARGS__) +#define PW_CHECK_UINT_EQ(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, ==, argb, unsigned int, "%u", __VA_ARGS__) +#define PW_CHECK_UINT_NE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, !=, argb, unsigned int, "%u", __VA_ARGS__) + +// Debug checks for unsigned int: LE, LT, GE, GT, EQ. +#define PW_DCHECK_UINT_LE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_UINT_LE(__VA_ARGS__) +#define PW_DCHECK_UINT_LT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_UINT_LT(__VA_ARGS__) +#define PW_DCHECK_UINT_GE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_UINT_GE(__VA_ARGS__) +#define PW_DCHECK_UINT_GT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_UINT_GT(__VA_ARGS__) +#define PW_DCHECK_UINT_EQ(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_UINT_EQ(__VA_ARGS__) +#define PW_DCHECK_UINT_NE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_UINT_NE(__VA_ARGS__) + +// Checks for pointer: LE, LT, GE, GT, EQ, NE. +#define PW_CHECK_PTR_LE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, <=, argb, const void*, "%p", __VA_ARGS__) +#define PW_CHECK_PTR_LT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, < , argb, const void*, "%p", __VA_ARGS__) +#define PW_CHECK_PTR_GE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, >=, argb, const void*, "%p", __VA_ARGS__) +#define PW_CHECK_PTR_GT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, > , argb, const void*, "%p", __VA_ARGS__) +#define PW_CHECK_PTR_EQ(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, ==, argb, const void*, "%p", __VA_ARGS__) +#define PW_CHECK_PTR_NE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, !=, argb, const void*, "%p", __VA_ARGS__) + +// Check for pointer: NOTNULL. Use "nullptr" in C++, "NULL" in C. +#ifdef __cplusplus +#define PW_CHECK_NOTNULL(arga, ...) \ + _PW_CHECK_BINARY_CMP_IMPL(arga, !=, nullptr, const void*, "%p", __VA_ARGS__) +#else // __cplusplus +#define PW_CHECK_NOTNULL(arga, ...) \ + _PW_CHECK_BINARY_CMP_IMPL(arga, !=, NULL, const void*, "%p", __VA_ARGS__) +#endif // __cplusplus + +// Debug checks for pointer: LE, LT, GE, GT, EQ, NE, and NOTNULL. +#define PW_DCHECK_PTR_LE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_PTR_LE(__VA_ARGS__) +#define PW_DCHECK_PTR_LT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_PTR_LT(__VA_ARGS__) +#define PW_DCHECK_PTR_GE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_PTR_GE(__VA_ARGS__) +#define PW_DCHECK_PTR_GT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_PTR_GT(__VA_ARGS__) +#define PW_DCHECK_PTR_EQ(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_PTR_EQ(__VA_ARGS__) +#define PW_DCHECK_PTR_NE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_PTR_NE(__VA_ARGS__) +#define PW_DCHECK_NOTNULL(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_NOTNULL(__VA_ARGS__) + +// Checks for float: EXACT_LE, EXACT_LT, EXACT_GE, EXACT_GT, EXACT_EQ, EXACT_NE, +// NEAR. +#define PW_CHECK_FLOAT_NEAR(arga, argb, abs_tolerance, ...) \ + _PW_CHECK_FLOAT_NEAR(arga, argb, abs_tolerance, __VA_ARGS__) +#define PW_CHECK_FLOAT_EXACT_LE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, <=, argb, float, "%f", __VA_ARGS__) +#define PW_CHECK_FLOAT_EXACT_LT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, < , argb, float, "%f", __VA_ARGS__) +#define PW_CHECK_FLOAT_EXACT_GE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, >=, argb, float, "%f", __VA_ARGS__) +#define PW_CHECK_FLOAT_EXACT_GT(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, > , argb, float, "%f", __VA_ARGS__) +#define PW_CHECK_FLOAT_EXACT_EQ(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, ==, argb, float, "%f", __VA_ARGS__) +#define PW_CHECK_FLOAT_EXACT_NE(arga, argb, ...) _PW_CHECK_BINARY_CMP_IMPL(arga, !=, argb, float, "%f", __VA_ARGS__) + +// Debug checks for float: NEAR, EXACT_LE, EXACT_LT, EXACT_GE, EXACT_GT, +// EXACT_EQ. +#define PW_DCHECK_FLOAT_NEAR(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_NEAR(__VA_ARGS__) +#define PW_DCHECK_FLOAT_EXACT_LE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_EXACT_LE(__VA_ARGS__) +#define PW_DCHECK_FLOAT_EXACT_LT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_EXACT_LT(__VA_ARGS__) +#define PW_DCHECK_FLOAT_EXACT_GE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_EXACT_GE(__VA_ARGS__) +#define PW_DCHECK_FLOAT_EXACT_GT(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_EXACT_GT(__VA_ARGS__) +#define PW_DCHECK_FLOAT_EXACT_EQ(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_EXACT_EQ(__VA_ARGS__) +#define PW_DCHECK_FLOAT_EXACT_NE(...) if (!(PW_ASSERT_ENABLE_DEBUG)) {} else PW_CHECK_FLOAT_EXACT_NE(__VA_ARGS__) + +// clang-format on + +// PW_CHECK - If condition evaluates to false, crash. Message optional. +#define PW_CHECK_OK(status, ...) \ + do { \ + if (status != PW_STATUS_OK) { \ + _PW_CHECK_OK_SELECT_MACRO(#status, \ + pw_StatusString(status), \ + PW_HAS_ARGS(__VA_ARGS__), \ + __VA_ARGS__); \ + } \ + } while (0) + +#define PW_DCHECK_OK(...) \ + if (!(PW_ASSERT_ENABLE_DEBUG)) { \ + } else \ + PW_CHECK_OK(__VA_ARGS__) + +// ========================================================================= +// Implementation for PW_CHECK + +// Two layers of select macros are used to enable the preprocessor to expand +// macros in the arguments to ultimately token paste the final macro name based +// on whether there are printf-style arguments. +#define _PW_CHECK_SELECT_MACRO(condition, has_args, ...) \ + _PW_CHECK_SELECT_MACRO_EXPANDED(condition, has_args, __VA_ARGS__) + +// Delegate to the macro +#define _PW_CHECK_SELECT_MACRO_EXPANDED(condition, has_args, ...) \ + _PW_CHECK_HAS_MSG_##has_args(condition, __VA_ARGS__) + +// PW_CHECK version 1: No message or args +#define _PW_CHECK_HAS_MSG_0(condition, ignored_arg) \ + PW_HANDLE_ASSERT_FAILURE(condition, "") + +// PW_CHECK version 2: With message (and maybe args) +#define _PW_CHECK_HAS_MSG_1(condition, ...) \ + PW_HANDLE_ASSERT_FAILURE(condition, __VA_ARGS__) + +// ========================================================================= +// Implementation for PW_CHECK__ + +// Two layers of select macros are used to enable the preprocessor to expand +// macros in the arguments to ultimately token paste the final macro name based +// on whether there are printf-style arguments. +#define _PW_CHECK_BINARY_COMPARISON_SELECT_MACRO(argument_a_str, \ + argument_a_val, \ + comparison_op_str, \ + argument_b_str, \ + argument_b_val, \ + type_fmt, \ + has_args, \ + ...) \ + _PW_CHECK_SELECT_BINARY_COMPARISON_MACRO_EXPANDED(argument_a_str, \ + argument_a_val, \ + comparison_op_str, \ + argument_b_str, \ + argument_b_val, \ + type_fmt, \ + has_args, \ + __VA_ARGS__) + +// Delegate to the macro +#define _PW_CHECK_SELECT_BINARY_COMPARISON_MACRO_EXPANDED(argument_a_str, \ + argument_a_val, \ + comparison_op_str, \ + argument_b_str, \ + argument_b_val, \ + type_fmt, \ + has_args, \ + ...) \ + _PW_CHECK_BINARY_COMPARISON_HAS_MSG_##has_args(argument_a_str, \ + argument_a_val, \ + comparison_op_str, \ + argument_b_str, \ + argument_b_val, \ + type_fmt, \ + __VA_ARGS__) + +// PW_CHECK_BINARY_COMPARISON version 1: No message or args +#define _PW_CHECK_BINARY_COMPARISON_HAS_MSG_0(argument_a_str, \ + argument_a_val, \ + comparison_op_str, \ + argument_b_str, \ + argument_b_val, \ + type_fmt, \ + ignored_arg) \ + PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(argument_a_str, \ + argument_a_val, \ + comparison_op_str, \ + argument_b_str, \ + argument_b_val, \ + type_fmt, \ + "") + +// PW_CHECK_BINARY_COMPARISON version 2: With message (and maybe args) +#define _PW_CHECK_BINARY_COMPARISON_HAS_MSG_1(argument_a_str, \ + argument_a_val, \ + comparison_op_str, \ + argument_b_str, \ + argument_b_val, \ + type_fmt, \ + ...) \ + PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(argument_a_str, \ + argument_a_val, \ + comparison_op_str, \ + argument_b_str, \ + argument_b_val, \ + type_fmt, \ + __VA_ARGS__) + +// For the binary assertions, this private macro is re-used for almost all of +// the variants. Due to limitations of C formatting, it is necessary to have +// separate macros for the types. +// +// The macro avoids evaluating the arguments multiple times at the cost of some +// macro complexity. +#define _PW_CHECK_BINARY_CMP_IMPL( \ + argument_a, comparison_op, argument_b, type_decl, type_fmt, ...) \ + do { \ + type_decl evaluated_argument_a = (type_decl)(argument_a); \ + type_decl evaluated_argument_b = (type_decl)(argument_b); \ + if (!(evaluated_argument_a comparison_op evaluated_argument_b)) { \ + _PW_CHECK_BINARY_COMPARISON_SELECT_MACRO(#argument_a, \ + evaluated_argument_a, \ + #comparison_op, \ + #argument_b, \ + evaluated_argument_b, \ + type_fmt, \ + PW_HAS_ARGS(__VA_ARGS__), \ + __VA_ARGS__); \ + } \ + } while (0) + +// Custom implementation for FLOAT_NEAR which is implemented through two +// underlying checks which are not trivially replaced through the use of +// FLOAT_EXACT_LE & FLOAT_EXACT_GE. +#define _PW_CHECK_FLOAT_NEAR(argument_a, argument_b, abs_tolerance, ...) \ + do { \ + PW_CHECK_FLOAT_EXACT_GE(abs_tolerance, 0.0f); \ + float evaluated_argument_a = (float)(argument_a); \ + float evaluated_argument_b_min = (float)(argument_b)-abs_tolerance; \ + float evaluated_argument_b_max = (float)(argument_b) + abs_tolerance; \ + if (!(evaluated_argument_a >= evaluated_argument_b_min)) { \ + _PW_CHECK_BINARY_COMPARISON_SELECT_MACRO(#argument_a, \ + evaluated_argument_a, \ + ">=", \ + #argument_b " - abs_tolerance", \ + evaluated_argument_b_min, \ + "%f", \ + PW_HAS_ARGS(__VA_ARGS__), \ + __VA_ARGS__); \ + } else if (!(evaluated_argument_a <= evaluated_argument_b_max)) { \ + _PW_CHECK_BINARY_COMPARISON_SELECT_MACRO(#argument_a, \ + evaluated_argument_a, \ + "<=", \ + #argument_b " + abs_tolerance", \ + evaluated_argument_b_max, \ + "%f", \ + PW_HAS_ARGS(__VA_ARGS__), \ + __VA_ARGS__); \ + } \ + } while (0) + +// ========================================================================= +// Implementation for PW_CHECK_OK + +// Two layers of select macros are used to enable the preprocessor to expand +// macros in the arguments to ultimately token paste the final macro name based +// on whether there are printf-style arguments. +#define _PW_CHECK_OK_SELECT_MACRO( \ + status_expr_str, status_value_str, has_args, ...) \ + _PW_CHECK_OK_SELECT_MACRO_EXPANDED( \ + status_expr_str, status_value_str, has_args, __VA_ARGS__) + +// Delegate to the macro +#define _PW_CHECK_OK_SELECT_MACRO_EXPANDED( \ + status_expr_str, status_value_str, has_args, ...) \ + _PW_CHECK_OK_HAS_MSG_##has_args( \ + status_expr_str, status_value_str, __VA_ARGS__) + +// PW_CHECK_OK version 1: No message or args +#define _PW_CHECK_OK_HAS_MSG_0(status_expr_str, status_value_str, ignored_arg) \ + PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE( \ + status_expr_str, status_value_str, "==", "OkStatus()", "OK", "%s", "") + +// PW_CHECK_OK version 2: With message (and maybe args) +#define _PW_CHECK_OK_HAS_MSG_1(status_expr_str, status_value_str, ...) \ + PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(status_expr_str, \ + status_value_str, \ + "==", \ + "OkStatus()", \ + "OK", \ + "%s", \ + __VA_ARGS__) diff --git a/pw_assert/public/pw_assert/light.h b/pw_assert/public/pw_assert/light.h index 95457a8ba..635bb3f5d 100644 --- a/pw_assert/public/pw_assert/light.h +++ b/pw_assert/public/pw_assert/light.h @@ -1,4 +1,4 @@ -// Copyright 2020 The Pigweed Authors +// Copyright 2021 The Pigweed Authors // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of @@ -13,46 +13,5 @@ // the License. #pragma once -#include "pw_assert/options.h" // For PW_ASSERT_ENABLE_DEBUG -#include "pw_preprocessor/util.h" - -PW_EXTERN_C_START - -void pw_assert_HandleFailure(void); - -PW_EXTERN_C_END - -// A header- and constexpr-safe version of PW_CHECK(). -// -// If the given condition is false, crash the system. Otherwise, do nothing. -// The condition is guaranteed to be evaluated. This assert implementation is -// guaranteed to be constexpr-safe. -// -// IMPORTANT: Unlike the PW_CHECK_*() suite of macros, this API captures no -// rich information like line numbers, the file, expression arguments, or the -// stringified expression. Use these macros only when absolutely necessary -- -// in headers, constexr contexts, or in rare cases where the call site overhead -// of a full PW_CHECK must be avoided. Use PW_CHECK_*() whenever possible. -#define PW_ASSERT(condition) \ - do { \ - if (!(condition)) { \ - pw_assert_HandleFailure(); \ - } \ - } while (0) - -// A header- and constexpr-safe version of PW_DCHECK(). -// -// Same as PW_ASSERT(), except that if PW_ASSERT_ENABLE_DEBUG == 1, the assert -// is disabled and condition is not evaluated. -// -// IMPORTANT: Unlike the PW_CHECK_*() suite of macros, this API captures no -// rich information like line numbers, the file, expression arguments, or the -// stringified expression. Use these macros only when absolutely necessary -- -// in headers, constexr contexts, or in rare cases where the call site overhead -// of a full PW_CHECK must be avoided. Use PW_DCHECK_*() whenever possible. -#define PW_DASSERT(condition) \ - do { \ - if ((PW_ASSERT_ENABLE_DEBUG == 1) && !(condition)) { \ - pw_assert_HandleFailure(); \ - } \ - } while (0) +// TODO(pwbug/350): Remove the deprecated light.h header in favor of assert.h. +#include "pw_assert/assert.h" diff --git a/pw_assert/public/pw_assert/short.h b/pw_assert/public/pw_assert/short.h new file mode 100644 index 000000000..be4ed2d06 --- /dev/null +++ b/pw_assert/public/pw_assert/short.h @@ -0,0 +1,81 @@ +// Copyright 2021 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +#pragma once + +#include "pw_assert/check.h" + +// Optional short CHECK name definitions + +// clang-format off +// Checks that always run even in production. +#define CRASH PW_CRASH +#define CHECK PW_CHECK +#define CHECK_PTR_LE PW_CHECK_PTR_LE +#define CHECK_PTR_LT PW_CHECK_PTR_LT +#define CHECK_PTR_GE PW_CHECK_PTR_GE +#define CHECK_PTR_GT PW_CHECK_PTR_GT +#define CHECK_PTR_EQ PW_CHECK_PTR_EQ +#define CHECK_PTR_NE PW_CHECK_PTR_NE +#define CHECK_NOTNULL PW_CHECK_NOTNULL +#define CHECK_INT_LE PW_CHECK_INT_LE +#define CHECK_INT_LT PW_CHECK_INT_LT +#define CHECK_INT_GE PW_CHECK_INT_GE +#define CHECK_INT_GT PW_CHECK_INT_GT +#define CHECK_INT_EQ PW_CHECK_INT_EQ +#define CHECK_INT_NE PW_CHECK_INT_NE +#define CHECK_UINT_LE PW_CHECK_UINT_LE +#define CHECK_UINT_LT PW_CHECK_UINT_LT +#define CHECK_UINT_GE PW_CHECK_UINT_GE +#define CHECK_UINT_GT PW_CHECK_UINT_GT +#define CHECK_UINT_EQ PW_CHECK_UINT_EQ +#define CHECK_UINT_NE PW_CHECK_UINT_NE +#define CHECK_FLOAT_NEAR PW_CHECK_FLOAT_NEAR +#define CHECK_FLOAT_EXACT_LE PW_CHECK_FLOAT_EXACT_LE +#define CHECK_FLOAT_EXACT_LT PW_CHECK_FLOAT_EXACT_LT +#define CHECK_FLOAT_EXACT_GE PW_CHECK_FLOAT_EXACT_GE +#define CHECK_FLOAT_EXACT_GT PW_CHECK_FLOAT_EXACT_GT +#define CHECK_FLOAT_EXACT_EQ PW_CHECK_FLOAT_EXACT_EQ +#define CHECK_FLOAT_EXACT_NE PW_CHECK_FLOAT_EXACT_NE +#define CHECK_OK PW_CHECK_OK + +// Checks that are disabled if NDEBUG is not defined. +#define DCHECK PW_DCHECK +#define DCHECK_PTR_LE PW_DCHECK_PTR_LE +#define DCHECK_PTR_LT PW_DCHECK_PTR_LT +#define DCHECK_PTR_GE PW_DCHECK_PTR_GE +#define DCHECK_PTR_GT PW_DCHECK_PTR_GT +#define DCHECK_PTR_EQ PW_DCHECK_PTR_EQ +#define DCHECK_PTR_NE PW_DCHECK_PTR_NE +#define DCHECK_NOTNULL PW_DCHECK_NOTNULL +#define DCHECK_INT_LE PW_DCHECK_INT_LE +#define DCHECK_INT_LT PW_DCHECK_INT_LT +#define DCHECK_INT_GE PW_DCHECK_INT_GE +#define DCHECK_INT_GT PW_DCHECK_INT_GT +#define DCHECK_INT_EQ PW_DCHECK_INT_EQ +#define DCHECK_INT_NE PW_DCHECK_INT_NE +#define DCHECK_UINT_LE PW_DCHECK_UINT_LE +#define DCHECK_UINT_LT PW_DCHECK_UINT_LT +#define DCHECK_UINT_GE PW_DCHECK_UINT_GE +#define DCHECK_UINT_GT PW_DCHECK_UINT_GT +#define DCHECK_UINT_EQ PW_DCHECK_UINT_EQ +#define DCHECK_UINT_NE PW_DCHECK_UINT_NE +#define DCHECK_FLOAT_NEAR PW_DCHECK_FLOAT_NEAR +#define DCHECK_FLOAT_EXACT_LT PW_DCHECK_FLOAT_EXACT_LT +#define DCHECK_FLOAT_EXACT_LE PW_DCHECK_FLOAT_EXACT_LE +#define DCHECK_FLOAT_EXACT_GT PW_DCHECK_FLOAT_EXACT_GT +#define DCHECK_FLOAT_EXACT_GE PW_DCHECK_FLOAT_EXACT_GE +#define DCHECK_FLOAT_EXACT_EQ PW_DCHECK_FLOAT_EXACT_EQ +#define DCHECK_FLOAT_EXACT_NE PW_DCHECK_FLOAT_EXACT_NE +#define DCHECK_OK PW_DCHECK_OK +// clang-format on -- cgit v1.2.3