From c96db73c09dbb528eca6d19a50bd258b37e9fd5e Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Tue, 6 Dec 2022 13:55:58 -0800 Subject: Create alternate absl-prefixed versions of absl logging macros. This will allow OSS code to use absl logging without necessarily polluting the preprocessor symbols with definitions for LOG and CHECK PiperOrigin-RevId: 493404211 Change-Id: I7bc5807252218dd7fc26da3af13d5734ef8b2601 --- absl/log/check_test_impl.h | 449 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 449 insertions(+) create mode 100644 absl/log/check_test_impl.h (limited to 'absl/log/check_test_impl.h') diff --git a/absl/log/check_test_impl.h b/absl/log/check_test_impl.h new file mode 100644 index 00000000..bcf5711f --- /dev/null +++ b/absl/log/check_test_impl.h @@ -0,0 +1,449 @@ +// +// Copyright 2022 The Abseil 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. + +#ifndef ABSL_LOG_CHECK_TEST_IMPL_H_ +#define ABSL_LOG_CHECK_TEST_IMPL_H_ + +// Verify that both sets of macros behave identically by parameterizing the +// entire test file. +#ifndef ABSL_TEST_CHECK +#error ABSL_TEST_CHECK must be defined for these tests to work. +#endif + +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/base/attributes.h" +#include "absl/base/config.h" +#include "absl/log/internal/test_helpers.h" + +namespace absl_log_internal { + +using ::testing::AllOf; +using ::testing::HasSubstr; +using ::testing::Not; + +auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment( + new absl::log_internal::LogTestEnvironment); + +#if GTEST_HAS_DEATH_TEST + +TEST(CHECKDeathTest, TestBasicValues) { + ABSL_TEST_CHECK(true); + + EXPECT_DEATH(ABSL_TEST_CHECK(false), "Check failed: false"); + + int i = 2; + ABSL_TEST_CHECK(i != 3); // NOLINT +} + +#endif // GTEST_HAS_DEATH_TEST + +TEST(CHECKTest, TestLogicExpressions) { + int i = 5; + ABSL_TEST_CHECK(i > 0 && i < 10); + ABSL_TEST_CHECK(i < 0 || i > 3); +} + +#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L +ABSL_CONST_INIT const auto global_var_check = [](int i) { + ABSL_TEST_CHECK(i > 0); // NOLINT + return i + 1; +}(3); + +ABSL_CONST_INIT const auto global_var = [](int i) { + ABSL_TEST_CHECK_GE(i, 0); // NOLINT + return i + 1; +}(global_var_check); +#endif // ABSL_INTERNAL_CPLUSPLUS_LANG + +TEST(CHECKTest, TestPlacementsInCompoundStatements) { + // check placement inside if/else clauses + if (true) ABSL_TEST_CHECK(true); + + if (false) + ; // NOLINT + else + ABSL_TEST_CHECK(true); + + switch (0) + case 0: + ABSL_TEST_CHECK(true); // NOLINT + +#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L + constexpr auto var = [](int i) { + ABSL_TEST_CHECK(i > 0); // NOLINT + return i + 1; + }(global_var); + (void)var; +#endif // ABSL_INTERNAL_CPLUSPLUS_LANG +} + +TEST(CHECKTest, TestBoolConvertible) { + struct Tester { + } tester; + ABSL_TEST_CHECK([&]() { return &tester; }()); +} + +#if GTEST_HAS_DEATH_TEST + +TEST(CHECKDeathTest, TestChecksWithSideEffects) { + int var = 0; + ABSL_TEST_CHECK([&var]() { + ++var; + return true; + }()); + EXPECT_EQ(var, 1); + + EXPECT_DEATH(ABSL_TEST_CHECK([&var]() { + ++var; + return false; + }()) << var, + "Check failed: .* 2"); +} + +#endif // GTEST_HAS_DEATH_TEST + +#if GTEST_HAS_DEATH_TEST + +TEST(CHECKDeachTest, TestOrderOfInvocationsBetweenCheckAndMessage) { + int counter = 0; + + auto GetStr = [&counter]() -> std::string { + return counter++ == 0 ? "" : "non-empty"; + }; + + EXPECT_DEATH(ABSL_TEST_CHECK(!GetStr().empty()) << GetStr(), + HasSubstr("non-empty")); +} + +TEST(CHECKTest, TestSecondaryFailure) { + auto FailingRoutine = []() { + ABSL_TEST_CHECK(false) << "Secondary"; + return false; + }; + EXPECT_DEATH(ABSL_TEST_CHECK(FailingRoutine()) << "Primary", + AllOf(HasSubstr("Secondary"), Not(HasSubstr("Primary")))); +} + +TEST(CHECKTest, TestSecondaryFailureInMessage) { + auto MessageGen = []() { + ABSL_TEST_CHECK(false) << "Secondary"; + return "Primary"; + }; + EXPECT_DEATH(ABSL_TEST_CHECK(false) << MessageGen(), + AllOf(HasSubstr("Secondary"), Not(HasSubstr("Primary")))); +} + +#endif // GTEST_HAS_DEATH_TEST + +TEST(CHECKTest, TestBinaryChecksWithPrimitives) { + ABSL_TEST_CHECK_EQ(1, 1); + ABSL_TEST_CHECK_NE(1, 2); + ABSL_TEST_CHECK_GE(1, 1); + ABSL_TEST_CHECK_GE(2, 1); + ABSL_TEST_CHECK_LE(1, 1); + ABSL_TEST_CHECK_LE(1, 2); + ABSL_TEST_CHECK_GT(2, 1); + ABSL_TEST_CHECK_LT(1, 2); +} + +// For testing using CHECK*() on anonymous enums. +enum { CASE_A, CASE_B }; + +TEST(CHECKTest, TestBinaryChecksWithEnumValues) { + // Tests using CHECK*() on anonymous enums. + ABSL_TEST_CHECK_EQ(CASE_A, CASE_A); + ABSL_TEST_CHECK_NE(CASE_A, CASE_B); + ABSL_TEST_CHECK_GE(CASE_A, CASE_A); + ABSL_TEST_CHECK_GE(CASE_B, CASE_A); + ABSL_TEST_CHECK_LE(CASE_A, CASE_A); + ABSL_TEST_CHECK_LE(CASE_A, CASE_B); + ABSL_TEST_CHECK_GT(CASE_B, CASE_A); + ABSL_TEST_CHECK_LT(CASE_A, CASE_B); +} + +TEST(CHECKTest, TestBinaryChecksWithNullptr) { + const void* p_null = nullptr; + const void* p_not_null = &p_null; + ABSL_TEST_CHECK_EQ(p_null, nullptr); + ABSL_TEST_CHECK_EQ(nullptr, p_null); + ABSL_TEST_CHECK_NE(p_not_null, nullptr); + ABSL_TEST_CHECK_NE(nullptr, p_not_null); +} + +#if GTEST_HAS_DEATH_TEST + +// Test logging of various char-typed values by failing CHECK*(). +TEST(CHECKDeathTest, TestComparingCharsValues) { + { + char a = ';'; + char b = 'b'; + EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), + "Check failed: a == b \\(';' vs. 'b'\\)"); + b = 1; + EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), + "Check failed: a == b \\(';' vs. char value 1\\)"); + } + { + signed char a = ';'; + signed char b = 'b'; + EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), + "Check failed: a == b \\(';' vs. 'b'\\)"); + b = -128; + EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), + "Check failed: a == b \\(';' vs. signed char value -128\\)"); + } + { + unsigned char a = ';'; + unsigned char b = 'b'; + EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), + "Check failed: a == b \\(';' vs. 'b'\\)"); + b = 128; + EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), + "Check failed: a == b \\(';' vs. unsigned char value 128\\)"); + } +} + +TEST(CHECKDeathTest, TestNullValuesAreReportedCleanly) { + const char* a = nullptr; + const char* b = nullptr; + EXPECT_DEATH(ABSL_TEST_CHECK_NE(a, b), + "Check failed: a != b \\(\\(null\\) vs. \\(null\\)\\)"); + + a = "xx"; + EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), + "Check failed: a == b \\(xx vs. \\(null\\)\\)"); + EXPECT_DEATH(ABSL_TEST_CHECK_EQ(b, a), + "Check failed: b == a \\(\\(null\\) vs. xx\\)"); + + std::nullptr_t n{}; + EXPECT_DEATH(ABSL_TEST_CHECK_NE(n, nullptr), + "Check failed: n != nullptr \\(\\(null\\) vs. \\(null\\)\\)"); +} + +#endif // GTEST_HAS_DEATH_TEST + +TEST(CHECKTest, TestSTREQ) { + ABSL_TEST_CHECK_STREQ("this", "this"); + ABSL_TEST_CHECK_STREQ(nullptr, nullptr); + ABSL_TEST_CHECK_STRCASEEQ("this", "tHiS"); + ABSL_TEST_CHECK_STRCASEEQ(nullptr, nullptr); + ABSL_TEST_CHECK_STRNE("this", "tHiS"); + ABSL_TEST_CHECK_STRNE("this", nullptr); + ABSL_TEST_CHECK_STRCASENE("this", "that"); + ABSL_TEST_CHECK_STRCASENE(nullptr, "that"); + ABSL_TEST_CHECK_STREQ((std::string("a") + "b").c_str(), "ab"); + ABSL_TEST_CHECK_STREQ(std::string("test").c_str(), + (std::string("te") + std::string("st")).c_str()); +} + +TEST(CHECKTest, TestComparisonPlacementsInCompoundStatements) { + // check placement inside if/else clauses + if (true) ABSL_TEST_CHECK_EQ(1, 1); + if (true) ABSL_TEST_CHECK_STREQ("c", "c"); + + if (false) + ; // NOLINT + else + ABSL_TEST_CHECK_LE(0, 1); + + if (false) + ; // NOLINT + else + ABSL_TEST_CHECK_STRNE("a", "b"); + + switch (0) + case 0: + ABSL_TEST_CHECK_NE(1, 0); + + switch (0) + case 0: + ABSL_TEST_CHECK_STRCASEEQ("A", "a"); + +#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L + constexpr auto var = [](int i) { + ABSL_TEST_CHECK_GT(i, 0); + return i + 1; + }(global_var); + (void)var; + + // CHECK_STR... checks are not supported in constexpr routines. + // constexpr auto var2 = [](int i) { + // ABSL_TEST_CHECK_STRNE("c", "d"); + // return i + 1; + // }(global_var); + +#if defined(__GNUC__) + int var3 = (({ ABSL_TEST_CHECK_LE(1, 2); }), global_var < 10) ? 1 : 0; + (void)var3; + + int var4 = (({ ABSL_TEST_CHECK_STREQ("a", "a"); }), global_var < 10) ? 1 : 0; + (void)var4; +#endif // __GNUC__ +#endif // ABSL_INTERNAL_CPLUSPLUS_LANG +} + +TEST(CHECKTest, TestDCHECK) { +#ifdef NDEBUG + ABSL_TEST_DCHECK(1 == 2) << " DCHECK's shouldn't be compiled in normal mode"; +#endif + ABSL_TEST_DCHECK(1 == 1); // NOLINT(readability/check) + ABSL_TEST_DCHECK_EQ(1, 1); + ABSL_TEST_DCHECK_NE(1, 2); + ABSL_TEST_DCHECK_GE(1, 1); + ABSL_TEST_DCHECK_GE(2, 1); + ABSL_TEST_DCHECK_LE(1, 1); + ABSL_TEST_DCHECK_LE(1, 2); + ABSL_TEST_DCHECK_GT(2, 1); + ABSL_TEST_DCHECK_LT(1, 2); + + // Test DCHECK on std::nullptr_t + const void* p_null = nullptr; + const void* p_not_null = &p_null; + ABSL_TEST_DCHECK_EQ(p_null, nullptr); + ABSL_TEST_DCHECK_EQ(nullptr, p_null); + ABSL_TEST_DCHECK_NE(p_not_null, nullptr); + ABSL_TEST_DCHECK_NE(nullptr, p_not_null); +} + +TEST(CHECKTest, TestQCHECK) { + // The tests that QCHECK does the same as CHECK + ABSL_TEST_QCHECK(1 == 1); // NOLINT(readability/check) + ABSL_TEST_QCHECK_EQ(1, 1); + ABSL_TEST_QCHECK_NE(1, 2); + ABSL_TEST_QCHECK_GE(1, 1); + ABSL_TEST_QCHECK_GE(2, 1); + ABSL_TEST_QCHECK_LE(1, 1); + ABSL_TEST_QCHECK_LE(1, 2); + ABSL_TEST_QCHECK_GT(2, 1); + ABSL_TEST_QCHECK_LT(1, 2); + + // Tests using QCHECK*() on anonymous enums. + ABSL_TEST_QCHECK_EQ(CASE_A, CASE_A); + ABSL_TEST_QCHECK_NE(CASE_A, CASE_B); + ABSL_TEST_QCHECK_GE(CASE_A, CASE_A); + ABSL_TEST_QCHECK_GE(CASE_B, CASE_A); + ABSL_TEST_QCHECK_LE(CASE_A, CASE_A); + ABSL_TEST_QCHECK_LE(CASE_A, CASE_B); + ABSL_TEST_QCHECK_GT(CASE_B, CASE_A); + ABSL_TEST_QCHECK_LT(CASE_A, CASE_B); +} + +TEST(CHECKTest, TestQCHECKPlacementsInCompoundStatements) { + // check placement inside if/else clauses + if (true) ABSL_TEST_QCHECK(true); + + if (false) + ; // NOLINT + else + ABSL_TEST_QCHECK(true); + + if (false) + ; // NOLINT + else + ABSL_TEST_QCHECK(true); + + switch (0) + case 0: + ABSL_TEST_QCHECK(true); + +#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L + constexpr auto var = [](int i) { + ABSL_TEST_QCHECK(i > 0); // NOLINT + return i + 1; + }(global_var); + (void)var; + +#if defined(__GNUC__) + int var2 = (({ ABSL_TEST_CHECK_LE(1, 2); }), global_var < 10) ? 1 : 0; + (void)var2; +#endif // __GNUC__ +#endif // ABSL_INTERNAL_CPLUSPLUS_LANG +} + +class ComparableType { + public: + explicit ComparableType(int v) : v_(v) {} + + void MethodWithCheck(int i) { + ABSL_TEST_CHECK_EQ(*this, i); + ABSL_TEST_CHECK_EQ(i, *this); + } + + int Get() const { return v_; } + + private: + friend bool operator==(const ComparableType& lhs, const ComparableType& rhs) { + return lhs.v_ == rhs.v_; + } + friend bool operator!=(const ComparableType& lhs, const ComparableType& rhs) { + return lhs.v_ != rhs.v_; + } + friend bool operator<(const ComparableType& lhs, const ComparableType& rhs) { + return lhs.v_ < rhs.v_; + } + friend bool operator<=(const ComparableType& lhs, const ComparableType& rhs) { + return lhs.v_ <= rhs.v_; + } + friend bool operator>(const ComparableType& lhs, const ComparableType& rhs) { + return lhs.v_ > rhs.v_; + } + friend bool operator>=(const ComparableType& lhs, const ComparableType& rhs) { + return lhs.v_ >= rhs.v_; + } + friend bool operator==(const ComparableType& lhs, int rhs) { + return lhs.v_ == rhs; + } + friend bool operator==(int lhs, const ComparableType& rhs) { + return lhs == rhs.v_; + } + + friend std::ostream& operator<<(std::ostream& out, const ComparableType& v) { + return out << "ComparableType{" << v.Get() << "}"; + } + + int v_; +}; + +TEST(CHECKTest, TestUserDefinedCompOp) { + ABSL_TEST_CHECK_EQ(ComparableType{0}, ComparableType{0}); + ABSL_TEST_CHECK_NE(ComparableType{1}, ComparableType{2}); + ABSL_TEST_CHECK_LT(ComparableType{1}, ComparableType{2}); + ABSL_TEST_CHECK_LE(ComparableType{1}, ComparableType{2}); + ABSL_TEST_CHECK_GT(ComparableType{2}, ComparableType{1}); + ABSL_TEST_CHECK_GE(ComparableType{2}, ComparableType{2}); +} + +TEST(CHECKTest, TestCheckInMethod) { + ComparableType v{1}; + v.MethodWithCheck(1); +} + +TEST(CHECKDeathTest, TestUserDefinedStreaming) { + ComparableType v1{1}; + ComparableType v2{2}; + + EXPECT_DEATH( + ABSL_TEST_CHECK_EQ(v1, v2), + HasSubstr( + "Check failed: v1 == v2 (ComparableType{1} vs. ComparableType{2})")); +} + +} // namespace absl_log_internal + +#endif // ABSL_LOG_CHECK_TEST_IMPL_H_ -- cgit v1.2.3 From ec583f2df279c86a8e8ba123b8929e92d2ee00f2 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Thu, 8 Dec 2022 13:44:17 -0800 Subject: Fixing macro expansion changes in new logging macros. This was an unintentional behavior change when we added a new layer of macros. Not using function-like macro aliases would get around this, but unfortunately that would flood the macro namespace downstream with CHECK and LOG (and break existing code). Note, the old behavior only applied to CHECK and QCHECK. Other CHECK macros already had multiple layers of function-like macros and were unaffected. PiperOrigin-RevId: 493984662 Change-Id: I9a050dcaf01f2b6935f02cd42e23bc3a4d5fc62a --- absl/log/absl_check.h | 4 ++-- absl/log/check.h | 4 ++-- absl/log/check_test_impl.h | 13 +++++++++++++ absl/log/internal/check_impl.h | 15 ++++++++------- 4 files changed, 25 insertions(+), 11 deletions(-) (limited to 'absl/log/check_test_impl.h') diff --git a/absl/log/absl_check.h b/absl/log/absl_check.h index b8428bf7..2775adbe 100644 --- a/absl/log/absl_check.h +++ b/absl/log/absl_check.h @@ -37,8 +37,8 @@ #include "absl/log/internal/check_impl.h" -#define ABSL_CHECK(condition) ABSL_CHECK_IMPL(condition) -#define ABSL_QCHECK(condition) ABSL_QCHECK_IMPL(condition) +#define ABSL_CHECK(condition) ABSL_CHECK_IMPL(condition, #condition) +#define ABSL_QCHECK(condition) ABSL_QCHECK_IMPL(condition, #condition) #define ABSL_PCHECK(condition) ABSL_PCHECK_IMPL(condition) #define ABSL_DCHECK(condition) ABSL_DCHECK_IMPL(condition) diff --git a/absl/log/check.h b/absl/log/check.h index 172436a6..ef1bd531 100644 --- a/absl/log/check.h +++ b/absl/log/check.h @@ -54,7 +54,7 @@ // Might produce a message like: // // Check failed: !cheese.empty() Out of Cheese -#define CHECK(condition) ABSL_CHECK_IMPL(condition) +#define CHECK(condition) ABSL_CHECK_IMPL(condition, #condition) // QCHECK() // @@ -62,7 +62,7 @@ // not run registered error handlers (as `QFATAL`). It is useful when the // problem is definitely unrelated to program flow, e.g. when validating user // input. -#define QCHECK(condition) ABSL_QCHECK_IMPL(condition) +#define QCHECK(condition) ABSL_QCHECK_IMPL(condition, #condition) // PCHECK() // diff --git a/absl/log/check_test_impl.h b/absl/log/check_test_impl.h index bcf5711f..2c09a60c 100644 --- a/absl/log/check_test_impl.h +++ b/absl/log/check_test_impl.h @@ -120,6 +120,19 @@ TEST(CHECKDeathTest, TestChecksWithSideEffects) { #if GTEST_HAS_DEATH_TEST +TEST(CHECKTest, TestMacroExpansionInMessage) { +#define MACRO(x) x + auto MessageGen = []() { ABSL_TEST_CHECK(MACRO(false)); }; + EXPECT_DEATH(MessageGen(), HasSubstr("MACRO(false)")); +#undef MACRO +} + +TEST(CHECKTest, TestNestedMacroExpansionInMessage) { +#define MACRO(x) x + EXPECT_DEATH(ABSL_TEST_CHECK(MACRO(false)), HasSubstr("MACRO(false)")); +#undef MACRO +} + TEST(CHECKDeachTest, TestOrderOfInvocationsBetweenCheckAndMessage) { int counter = 0; diff --git a/absl/log/internal/check_impl.h b/absl/log/internal/check_impl.h index 301b2915..d3238861 100644 --- a/absl/log/internal/check_impl.h +++ b/absl/log/internal/check_impl.h @@ -22,22 +22,23 @@ #include "absl/log/internal/strip.h" // CHECK -#define ABSL_CHECK_IMPL(condition) \ +#define ABSL_CHECK_IMPL(condition, condition_str) \ ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, \ ABSL_PREDICT_FALSE(!(condition))) \ - ABSL_LOG_INTERNAL_CHECK(#condition).InternalStream() + ABSL_LOG_INTERNAL_CHECK(condition_str).InternalStream() -#define ABSL_QCHECK_IMPL(condition) \ +#define ABSL_QCHECK_IMPL(condition, condition_str) \ ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, \ ABSL_PREDICT_FALSE(!(condition))) \ - ABSL_LOG_INTERNAL_QCHECK(#condition).InternalStream() + ABSL_LOG_INTERNAL_QCHECK(condition_str).InternalStream() -#define ABSL_PCHECK_IMPL(condition) ABSL_CHECK_IMPL(condition).WithPerror() +#define ABSL_PCHECK_IMPL(condition) \ + ABSL_CHECK_IMPL(condition, #condition).WithPerror() #ifndef NDEBUG -#define ABSL_DCHECK_IMPL(condition) ABSL_CHECK_IMPL(condition) +#define ABSL_DCHECK_IMPL(condition) ABSL_CHECK_IMPL(condition, #condition) #else -#define ABSL_DCHECK_IMPL(condition) ABSL_CHECK_IMPL(true || (condition)) +#define ABSL_DCHECK_IMPL(condition) ABSL_CHECK_IMPL(true || (condition), "true") #endif // CHECK_EQ -- cgit v1.2.3 From a13ef44bf3f2ef5399c6fc587a18f3b203b4d37a Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Tue, 13 Dec 2022 15:11:53 -0800 Subject: Prevent all CHECK functions from expanding macros for the error string. This was likely an unintentional behavior change made a while ago while trying to reduce duplication. The new behavior will always include the unexpanded macro in the error string. For example, `CHECK_EQ(MACRO(x), MACRO(y))` will now output "MACRO(x) == MACRO(y)" if it fails. Before this change, CHECK and QCHECK were the only macros that had this behavior. Not using function-like macro aliases is a possible alternative here, but unfortunately that would flood the macro namespace downstream with CHECK* and break existing code. PiperOrigin-RevId: 495138582 Change-Id: I6a1afd89a6b9334003362e5d3e55da68f86eec98 --- absl/log/BUILD.bazel | 1 + absl/log/CMakeLists.txt | 2 + absl/log/absl_check.h | 98 +++++++++++++++--------- absl/log/absl_check_test.cc | 3 + absl/log/check.h | 78 ++++++++++--------- absl/log/check_test.cc | 3 + absl/log/check_test_impl.h | 80 +++++++++++++++++-- absl/log/internal/check_impl.h | 170 ++++++++++++++++++++++++----------------- absl/log/internal/check_op.h | 87 +++++++++++---------- 9 files changed, 329 insertions(+), 193 deletions(-) (limited to 'absl/log/check_test_impl.h') diff --git a/absl/log/BUILD.bazel b/absl/log/BUILD.bazel index a420f21a..10916446 100644 --- a/absl/log/BUILD.bazel +++ b/absl/log/BUILD.bazel @@ -294,6 +294,7 @@ cc_library( "//absl/base:config", "//absl/base:core_headers", "//absl/log/internal:test_helpers", + "//absl/status", "@com_google_googletest//:gtest", ], ) diff --git a/absl/log/CMakeLists.txt b/absl/log/CMakeLists.txt index 36a60da3..de2eaf39 100644 --- a/absl/log/CMakeLists.txt +++ b/absl/log/CMakeLists.txt @@ -686,6 +686,7 @@ absl_cc_test( absl::config absl::core_headers absl::log_internal_test_helpers + absl::status GTest::gmock GTest::gtest_main ) @@ -729,6 +730,7 @@ absl_cc_test( absl::config absl::core_headers absl::log_internal_test_helpers + absl::status GTest::gmock GTest::gtest_main ) diff --git a/absl/log/absl_check.h b/absl/log/absl_check.h index 2775adbe..14a2307f 100644 --- a/absl/log/absl_check.h +++ b/absl/log/absl_check.h @@ -37,45 +37,69 @@ #include "absl/log/internal/check_impl.h" -#define ABSL_CHECK(condition) ABSL_CHECK_IMPL(condition, #condition) -#define ABSL_QCHECK(condition) ABSL_QCHECK_IMPL(condition, #condition) -#define ABSL_PCHECK(condition) ABSL_PCHECK_IMPL(condition) -#define ABSL_DCHECK(condition) ABSL_DCHECK_IMPL(condition) +#define ABSL_CHECK(condition) ABSL_CHECK_IMPL((condition), #condition) +#define ABSL_QCHECK(condition) ABSL_QCHECK_IMPL((condition), #condition) +#define ABSL_PCHECK(condition) ABSL_PCHECK_IMPL((condition), #condition) +#define ABSL_DCHECK(condition) ABSL_DCHECK_IMPL((condition), #condition) -#define ABSL_CHECK_EQ(val1, val2) ABSL_CHECK_EQ_IMPL(val1, val2) -#define ABSL_CHECK_NE(val1, val2) ABSL_CHECK_NE_IMPL(val1, val2) -#define ABSL_CHECK_LE(val1, val2) ABSL_CHECK_LE_IMPL(val1, val2) -#define ABSL_CHECK_LT(val1, val2) ABSL_CHECK_LT_IMPL(val1, val2) -#define ABSL_CHECK_GE(val1, val2) ABSL_CHECK_GE_IMPL(val1, val2) -#define ABSL_CHECK_GT(val1, val2) ABSL_CHECK_GT_IMPL(val1, val2) -#define ABSL_QCHECK_EQ(val1, val2) ABSL_QCHECK_EQ_IMPL(val1, val2) -#define ABSL_QCHECK_NE(val1, val2) ABSL_QCHECK_NE_IMPL(val1, val2) -#define ABSL_QCHECK_LE(val1, val2) ABSL_QCHECK_LE_IMPL(val1, val2) -#define ABSL_QCHECK_LT(val1, val2) ABSL_QCHECK_LT_IMPL(val1, val2) -#define ABSL_QCHECK_GE(val1, val2) ABSL_QCHECK_GE_IMPL(val1, val2) -#define ABSL_QCHECK_GT(val1, val2) ABSL_QCHECK_GT_IMPL(val1, val2) -#define ABSL_DCHECK_EQ(val1, val2) ABSL_DCHECK_EQ_IMPL(val1, val2) -#define ABSL_DCHECK_NE(val1, val2) ABSL_DCHECK_NE_IMPL(val1, val2) -#define ABSL_DCHECK_LE(val1, val2) ABSL_DCHECK_LE_IMPL(val1, val2) -#define ABSL_DCHECK_LT(val1, val2) ABSL_DCHECK_LT_IMPL(val1, val2) -#define ABSL_DCHECK_GE(val1, val2) ABSL_DCHECK_GE_IMPL(val1, val2) -#define ABSL_DCHECK_GT(val1, val2) ABSL_DCHECK_GT_IMPL(val1, val2) +#define ABSL_CHECK_EQ(val1, val2) \ + ABSL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2) +#define ABSL_CHECK_NE(val1, val2) \ + ABSL_CHECK_NE_IMPL((val1), #val1, (val2), #val2) +#define ABSL_CHECK_LE(val1, val2) \ + ABSL_CHECK_LE_IMPL((val1), #val1, (val2), #val2) +#define ABSL_CHECK_LT(val1, val2) \ + ABSL_CHECK_LT_IMPL((val1), #val1, (val2), #val2) +#define ABSL_CHECK_GE(val1, val2) \ + ABSL_CHECK_GE_IMPL((val1), #val1, (val2), #val2) +#define ABSL_CHECK_GT(val1, val2) \ + ABSL_CHECK_GT_IMPL((val1), #val1, (val2), #val2) +#define ABSL_QCHECK_EQ(val1, val2) \ + ABSL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2) +#define ABSL_QCHECK_NE(val1, val2) \ + ABSL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2) +#define ABSL_QCHECK_LE(val1, val2) \ + ABSL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2) +#define ABSL_QCHECK_LT(val1, val2) \ + ABSL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2) +#define ABSL_QCHECK_GE(val1, val2) \ + ABSL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2) +#define ABSL_QCHECK_GT(val1, val2) \ + ABSL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2) +#define ABSL_DCHECK_EQ(val1, val2) \ + ABSL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2) +#define ABSL_DCHECK_NE(val1, val2) \ + ABSL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2) +#define ABSL_DCHECK_LE(val1, val2) \ + ABSL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2) +#define ABSL_DCHECK_LT(val1, val2) \ + ABSL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2) +#define ABSL_DCHECK_GE(val1, val2) \ + ABSL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2) +#define ABSL_DCHECK_GT(val1, val2) \ + ABSL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2) -#define ABSL_CHECK_OK(status) ABSL_CHECK_OK_IMPL(status) -#define ABSL_QCHECK_OK(status) ABSL_QCHECK_OK_IMPL(status) -#define ABSL_DCHECK_OK(status) ABSL_DCHECK_OK_IMPL(status) +#define ABSL_CHECK_OK(status) ABSL_CHECK_OK_IMPL((status), #status) +#define ABSL_QCHECK_OK(status) ABSL_QCHECK_OK_IMPL((status), #status) +#define ABSL_DCHECK_OK(status) ABSL_DCHECK_OK_IMPL((status), #status) -#define ABSL_CHECK_STREQ(s1, s2) ABSL_CHECK_STREQ_IMPL(s1, s2) -#define ABSL_CHECK_STRNE(s1, s2) ABSL_CHECK_STRNE_IMPL(s1, s2) -#define ABSL_CHECK_STRCASEEQ(s1, s2) ABSL_CHECK_STRCASEEQ_IMPL(s1, s2) -#define ABSL_CHECK_STRCASENE(s1, s2) ABSL_CHECK_STRCASENE_IMPL(s1, s2) -#define ABSL_QCHECK_STREQ(s1, s2) ABSL_QCHECK_STREQ_IMPL(s1, s2) -#define ABSL_QCHECK_STRNE(s1, s2) ABSL_QCHECK_STRNE_IMPL(s1, s2) -#define ABSL_QCHECK_STRCASEEQ(s1, s2) ABSL_QCHECK_STRCASEEQ_IMPL(s1, s2) -#define ABSL_QCHECK_STRCASENE(s1, s2) ABSL_QCHECK_STRCASENE_IMPL(s1, s2) -#define ABSL_DCHECK_STREQ(s1, s2) ABSL_DCHECK_STREQ_IMPL(s1, s2) -#define ABSL_DCHECK_STRNE(s1, s2) ABSL_DCHECK_STRNE_IMPL(s1, s2) -#define ABSL_DCHECK_STRCASEEQ(s1, s2) ABSL_DCHECK_STRCASEEQ_IMPL(s1, s2) -#define ABSL_DCHECK_STRCASENE(s1, s2) ABSL_DCHECK_STRCASENE_IMPL(s1, s2) +#define ABSL_CHECK_STREQ(s1, s2) ABSL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2) +#define ABSL_CHECK_STRNE(s1, s2) ABSL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2) +#define ABSL_CHECK_STRCASEEQ(s1, s2) \ + ABSL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) +#define ABSL_CHECK_STRCASENE(s1, s2) \ + ABSL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) +#define ABSL_QCHECK_STREQ(s1, s2) ABSL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2) +#define ABSL_QCHECK_STRNE(s1, s2) ABSL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2) +#define ABSL_QCHECK_STRCASEEQ(s1, s2) \ + ABSL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) +#define ABSL_QCHECK_STRCASENE(s1, s2) \ + ABSL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) +#define ABSL_DCHECK_STREQ(s1, s2) ABSL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2) +#define ABSL_DCHECK_STRNE(s1, s2) ABSL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2) +#define ABSL_DCHECK_STRCASEEQ(s1, s2) \ + ABSL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) +#define ABSL_DCHECK_STRCASENE(s1, s2) \ + ABSL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) #endif // ABSL_LOG_ABSL_CHECK_H_ diff --git a/absl/log/absl_check_test.cc b/absl/log/absl_check_test.cc index 2c4853dd..8ddacdb1 100644 --- a/absl/log/absl_check_test.cc +++ b/absl/log/absl_check_test.cc @@ -16,6 +16,7 @@ #include "absl/log/absl_check.h" #define ABSL_TEST_CHECK ABSL_CHECK +#define ABSL_TEST_CHECK_OK ABSL_CHECK_OK #define ABSL_TEST_CHECK_EQ ABSL_CHECK_EQ #define ABSL_TEST_CHECK_NE ABSL_CHECK_NE #define ABSL_TEST_CHECK_GE ABSL_CHECK_GE @@ -28,6 +29,7 @@ #define ABSL_TEST_CHECK_STRCASENE ABSL_CHECK_STRCASENE #define ABSL_TEST_DCHECK ABSL_DCHECK +#define ABSL_TEST_DCHECK_OK ABSL_DCHECK_OK #define ABSL_TEST_DCHECK_EQ ABSL_DCHECK_EQ #define ABSL_TEST_DCHECK_NE ABSL_DCHECK_NE #define ABSL_TEST_DCHECK_GE ABSL_DCHECK_GE @@ -40,6 +42,7 @@ #define ABSL_TEST_DCHECK_STRCASENE ABSL_DCHECK_STRCASENE #define ABSL_TEST_QCHECK ABSL_QCHECK +#define ABSL_TEST_QCHECK_OK ABSL_QCHECK_OK #define ABSL_TEST_QCHECK_EQ ABSL_QCHECK_EQ #define ABSL_TEST_QCHECK_NE ABSL_QCHECK_NE #define ABSL_TEST_QCHECK_GE ABSL_QCHECK_GE diff --git a/absl/log/check.h b/absl/log/check.h index ef1bd531..33145a57 100644 --- a/absl/log/check.h +++ b/absl/log/check.h @@ -54,7 +54,7 @@ // Might produce a message like: // // Check failed: !cheese.empty() Out of Cheese -#define CHECK(condition) ABSL_CHECK_IMPL(condition, #condition) +#define CHECK(condition) ABSL_CHECK_IMPL((condition), #condition) // QCHECK() // @@ -62,7 +62,7 @@ // not run registered error handlers (as `QFATAL`). It is useful when the // problem is definitely unrelated to program flow, e.g. when validating user // input. -#define QCHECK(condition) ABSL_QCHECK_IMPL(condition, #condition) +#define QCHECK(condition) ABSL_QCHECK_IMPL((condition), #condition) // PCHECK() // @@ -77,7 +77,7 @@ // Might produce a message like: // // Check failed: fd != -1 posix is difficult: No such file or directory [2] -#define PCHECK(condition) ABSL_PCHECK_IMPL(condition) +#define PCHECK(condition) ABSL_PCHECK_IMPL((condition), #condition) // DCHECK() // @@ -85,7 +85,7 @@ // `DLOG`). Unlike with `CHECK` (but as with `assert`), it is not safe to rely // on evaluation of `condition`: when `NDEBUG` is enabled, DCHECK does not // evaluate the condition. -#define DCHECK(condition) ABSL_DCHECK_IMPL(condition) +#define DCHECK(condition) ABSL_DCHECK_IMPL((condition), #condition) // `CHECK_EQ` and friends are syntactic sugar for `CHECK(x == y)` that // automatically output the expression being tested and the evaluated values on @@ -113,24 +113,24 @@ // // WARNING: Passing `NULL` as an argument to `CHECK_EQ` and similar macros does // not compile. Use `nullptr` instead. -#define CHECK_EQ(val1, val2) ABSL_CHECK_EQ_IMPL(val1, val2) -#define CHECK_NE(val1, val2) ABSL_CHECK_NE_IMPL(val1, val2) -#define CHECK_LE(val1, val2) ABSL_CHECK_LE_IMPL(val1, val2) -#define CHECK_LT(val1, val2) ABSL_CHECK_LT_IMPL(val1, val2) -#define CHECK_GE(val1, val2) ABSL_CHECK_GE_IMPL(val1, val2) -#define CHECK_GT(val1, val2) ABSL_CHECK_GT_IMPL(val1, val2) -#define QCHECK_EQ(val1, val2) ABSL_QCHECK_EQ_IMPL(val1, val2) -#define QCHECK_NE(val1, val2) ABSL_QCHECK_NE_IMPL(val1, val2) -#define QCHECK_LE(val1, val2) ABSL_QCHECK_LE_IMPL(val1, val2) -#define QCHECK_LT(val1, val2) ABSL_QCHECK_LT_IMPL(val1, val2) -#define QCHECK_GE(val1, val2) ABSL_QCHECK_GE_IMPL(val1, val2) -#define QCHECK_GT(val1, val2) ABSL_QCHECK_GT_IMPL(val1, val2) -#define DCHECK_EQ(val1, val2) ABSL_DCHECK_EQ_IMPL(val1, val2) -#define DCHECK_NE(val1, val2) ABSL_DCHECK_NE_IMPL(val1, val2) -#define DCHECK_LE(val1, val2) ABSL_DCHECK_LE_IMPL(val1, val2) -#define DCHECK_LT(val1, val2) ABSL_DCHECK_LT_IMPL(val1, val2) -#define DCHECK_GE(val1, val2) ABSL_DCHECK_GE_IMPL(val1, val2) -#define DCHECK_GT(val1, val2) ABSL_DCHECK_GT_IMPL(val1, val2) +#define CHECK_EQ(val1, val2) ABSL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2) +#define CHECK_NE(val1, val2) ABSL_CHECK_NE_IMPL((val1), #val1, (val2), #val2) +#define CHECK_LE(val1, val2) ABSL_CHECK_LE_IMPL((val1), #val1, (val2), #val2) +#define CHECK_LT(val1, val2) ABSL_CHECK_LT_IMPL((val1), #val1, (val2), #val2) +#define CHECK_GE(val1, val2) ABSL_CHECK_GE_IMPL((val1), #val1, (val2), #val2) +#define CHECK_GT(val1, val2) ABSL_CHECK_GT_IMPL((val1), #val1, (val2), #val2) +#define QCHECK_EQ(val1, val2) ABSL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2) +#define QCHECK_NE(val1, val2) ABSL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2) +#define QCHECK_LE(val1, val2) ABSL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2) +#define QCHECK_LT(val1, val2) ABSL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2) +#define QCHECK_GE(val1, val2) ABSL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2) +#define QCHECK_GT(val1, val2) ABSL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2) +#define DCHECK_EQ(val1, val2) ABSL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2) +#define DCHECK_NE(val1, val2) ABSL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2) +#define DCHECK_LE(val1, val2) ABSL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2) +#define DCHECK_LT(val1, val2) ABSL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2) +#define DCHECK_GE(val1, val2) ABSL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2) +#define DCHECK_GT(val1, val2) ABSL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2) // `CHECK_OK` and friends validate that the provided `absl::Status` or // `absl::StatusOr` is OK. If it isn't, they print a failure message that @@ -146,9 +146,9 @@ // Might produce a message like: // // Check failed: FunctionReturnsStatus(x, y, z) is OK (ABORTED: timeout) oops! -#define CHECK_OK(status) ABSL_CHECK_OK_IMPL(status) -#define QCHECK_OK(status) ABSL_QCHECK_OK_IMPL(status) -#define DCHECK_OK(status) ABSL_DCHECK_OK_IMPL(status) +#define CHECK_OK(status) ABSL_CHECK_OK_IMPL((status), #status) +#define QCHECK_OK(status) ABSL_QCHECK_OK_IMPL((status), #status) +#define DCHECK_OK(status) ABSL_DCHECK_OK_IMPL((status), #status) // `CHECK_STREQ` and friends provide `CHECK_EQ` functionality for C strings, // i.e., nul-terminated char arrays. The `CASE` versions are case-insensitive. @@ -163,17 +163,21 @@ // Example: // // CHECK_STREQ(Foo().c_str(), Bar().c_str()); -#define CHECK_STREQ(s1, s2) ABSL_CHECK_STREQ_IMPL(s1, s2) -#define CHECK_STRNE(s1, s2) ABSL_CHECK_STRNE_IMPL(s1, s2) -#define CHECK_STRCASEEQ(s1, s2) ABSL_CHECK_STRCASEEQ_IMPL(s1, s2) -#define CHECK_STRCASENE(s1, s2) ABSL_CHECK_STRCASENE_IMPL(s1, s2) -#define QCHECK_STREQ(s1, s2) ABSL_QCHECK_STREQ_IMPL(s1, s2) -#define QCHECK_STRNE(s1, s2) ABSL_QCHECK_STRNE_IMPL(s1, s2) -#define QCHECK_STRCASEEQ(s1, s2) ABSL_QCHECK_STRCASEEQ_IMPL(s1, s2) -#define QCHECK_STRCASENE(s1, s2) ABSL_QCHECK_STRCASENE_IMPL(s1, s2) -#define DCHECK_STREQ(s1, s2) ABSL_DCHECK_STREQ_IMPL(s1, s2) -#define DCHECK_STRNE(s1, s2) ABSL_DCHECK_STRNE_IMPL(s1, s2) -#define DCHECK_STRCASEEQ(s1, s2) ABSL_DCHECK_STRCASEEQ_IMPL(s1, s2) -#define DCHECK_STRCASENE(s1, s2) ABSL_DCHECK_STRCASENE_IMPL(s1, s2) +#define CHECK_STREQ(s1, s2) ABSL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2) +#define CHECK_STRNE(s1, s2) ABSL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2) +#define CHECK_STRCASEEQ(s1, s2) ABSL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) +#define CHECK_STRCASENE(s1, s2) ABSL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) +#define QCHECK_STREQ(s1, s2) ABSL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2) +#define QCHECK_STRNE(s1, s2) ABSL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2) +#define QCHECK_STRCASEEQ(s1, s2) \ + ABSL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) +#define QCHECK_STRCASENE(s1, s2) \ + ABSL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) +#define DCHECK_STREQ(s1, s2) ABSL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2) +#define DCHECK_STRNE(s1, s2) ABSL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2) +#define DCHECK_STRCASEEQ(s1, s2) \ + ABSL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) +#define DCHECK_STRCASENE(s1, s2) \ + ABSL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) #endif // ABSL_LOG_CHECK_H_ diff --git a/absl/log/check_test.cc b/absl/log/check_test.cc index a03183a5..f44a686e 100644 --- a/absl/log/check_test.cc +++ b/absl/log/check_test.cc @@ -16,6 +16,7 @@ #include "absl/log/check.h" #define ABSL_TEST_CHECK CHECK +#define ABSL_TEST_CHECK_OK CHECK_OK #define ABSL_TEST_CHECK_EQ CHECK_EQ #define ABSL_TEST_CHECK_NE CHECK_NE #define ABSL_TEST_CHECK_GE CHECK_GE @@ -28,6 +29,7 @@ #define ABSL_TEST_CHECK_STRCASENE CHECK_STRCASENE #define ABSL_TEST_DCHECK DCHECK +#define ABSL_TEST_DCHECK_OK DCHECK_OK #define ABSL_TEST_DCHECK_EQ DCHECK_EQ #define ABSL_TEST_DCHECK_NE DCHECK_NE #define ABSL_TEST_DCHECK_GE DCHECK_GE @@ -40,6 +42,7 @@ #define ABSL_TEST_DCHECK_STRCASENE DCHECK_STRCASENE #define ABSL_TEST_QCHECK QCHECK +#define ABSL_TEST_QCHECK_OK QCHECK_OK #define ABSL_TEST_QCHECK_EQ QCHECK_EQ #define ABSL_TEST_QCHECK_NE QCHECK_NE #define ABSL_TEST_QCHECK_GE QCHECK_GE diff --git a/absl/log/check_test_impl.h b/absl/log/check_test_impl.h index 2c09a60c..d5c0aee4 100644 --- a/absl/log/check_test_impl.h +++ b/absl/log/check_test_impl.h @@ -30,6 +30,9 @@ #include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/log/internal/test_helpers.h" +#include "absl/status/status.h" + +// NOLINTBEGIN(misc-definitions-in-headers) namespace absl_log_internal { @@ -118,21 +121,82 @@ TEST(CHECKDeathTest, TestChecksWithSideEffects) { #endif // GTEST_HAS_DEATH_TEST +template +constexpr int sum() { + return a + b; +} +#define MACRO_ONE 1 +#define TEMPLATE_SUM(a, b) sum() +#define CONCAT(a, b) a b +#define IDENTITY(x) x + +TEST(CHECKTest, TestPassingMacroExpansion) { + ABSL_TEST_CHECK(IDENTITY(true)); + ABSL_TEST_CHECK_EQ(TEMPLATE_SUM(MACRO_ONE, 2), 3); + ABSL_TEST_CHECK_STREQ(CONCAT("x", "y"), "xy"); +} + #if GTEST_HAS_DEATH_TEST TEST(CHECKTest, TestMacroExpansionInMessage) { -#define MACRO(x) x - auto MessageGen = []() { ABSL_TEST_CHECK(MACRO(false)); }; - EXPECT_DEATH(MessageGen(), HasSubstr("MACRO(false)")); -#undef MACRO + auto MessageGen = []() { ABSL_TEST_CHECK(IDENTITY(false)); }; + EXPECT_DEATH(MessageGen(), HasSubstr("IDENTITY(false)")); } TEST(CHECKTest, TestNestedMacroExpansionInMessage) { -#define MACRO(x) x - EXPECT_DEATH(ABSL_TEST_CHECK(MACRO(false)), HasSubstr("MACRO(false)")); -#undef MACRO + EXPECT_DEATH(ABSL_TEST_CHECK(IDENTITY(false)), HasSubstr("IDENTITY(false)")); +} + +TEST(CHECKTest, TestMacroExpansionCompare) { + EXPECT_DEATH(ABSL_TEST_CHECK_EQ(IDENTITY(false), IDENTITY(true)), + HasSubstr("IDENTITY(false) == IDENTITY(true)")); + EXPECT_DEATH(ABSL_TEST_CHECK_GT(IDENTITY(1), IDENTITY(2)), + HasSubstr("IDENTITY(1) > IDENTITY(2)")); +} + +TEST(CHECKTest, TestMacroExpansionStrCompare) { + EXPECT_DEATH(ABSL_TEST_CHECK_STREQ(IDENTITY("x"), IDENTITY("y")), + HasSubstr("IDENTITY(\"x\") == IDENTITY(\"y\")")); + EXPECT_DEATH(ABSL_TEST_CHECK_STRCASENE(IDENTITY("a"), IDENTITY("A")), + HasSubstr("IDENTITY(\"a\") != IDENTITY(\"A\")")); +} + +TEST(CHECKTest, TestMacroExpansionStatus) { + EXPECT_DEATH( + ABSL_TEST_CHECK_OK(IDENTITY(absl::FailedPreconditionError("message"))), + HasSubstr("IDENTITY(absl::FailedPreconditionError(\"message\"))")); +} + +TEST(CHECKTest, TestMacroExpansionComma) { + EXPECT_DEATH(ABSL_TEST_CHECK(TEMPLATE_SUM(MACRO_ONE, 2) == 4), + HasSubstr("TEMPLATE_SUM(MACRO_ONE, 2) == 4")); +} + +TEST(CHECKTest, TestMacroExpansionCommaCompare) { + EXPECT_DEATH( + ABSL_TEST_CHECK_EQ(TEMPLATE_SUM(2, MACRO_ONE), TEMPLATE_SUM(3, 2)), + HasSubstr("TEMPLATE_SUM(2, MACRO_ONE) == TEMPLATE_SUM(3, 2)")); + EXPECT_DEATH( + ABSL_TEST_CHECK_GT(TEMPLATE_SUM(2, MACRO_ONE), TEMPLATE_SUM(3, 2)), + HasSubstr("TEMPLATE_SUM(2, MACRO_ONE) > TEMPLATE_SUM(3, 2)")); +} + +TEST(CHECKTest, TestMacroExpansionCommaStrCompare) { + EXPECT_DEATH(ABSL_TEST_CHECK_STREQ(CONCAT("x", "y"), "z"), + HasSubstr("CONCAT(\"x\", \"y\") == \"z\"")); + EXPECT_DEATH(ABSL_TEST_CHECK_STRNE(CONCAT("x", "y"), "xy"), + HasSubstr("CONCAT(\"x\", \"y\") != \"xy\"")); } +#endif // GTEST_HAS_DEATH_TEST + +#undef TEMPLATE_SUM +#undef CONCAT +#undef MACRO +#undef ONE + +#if GTEST_HAS_DEATH_TEST + TEST(CHECKDeachTest, TestOrderOfInvocationsBetweenCheckAndMessage) { int counter = 0; @@ -459,4 +523,6 @@ TEST(CHECKDeathTest, TestUserDefinedStreaming) { } // namespace absl_log_internal +// NOLINTEND(misc-definitions-in-headers) + #endif // ABSL_LOG_CHECK_TEST_IMPL_H_ diff --git a/absl/log/internal/check_impl.h b/absl/log/internal/check_impl.h index d3238861..c9c28e3e 100644 --- a/absl/log/internal/check_impl.h +++ b/absl/log/internal/check_impl.h @@ -22,103 +22,129 @@ #include "absl/log/internal/strip.h" // CHECK -#define ABSL_CHECK_IMPL(condition, condition_str) \ +#define ABSL_CHECK_IMPL(condition, condition_text) \ ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, \ ABSL_PREDICT_FALSE(!(condition))) \ - ABSL_LOG_INTERNAL_CHECK(condition_str).InternalStream() + ABSL_LOG_INTERNAL_CHECK(condition_text).InternalStream() -#define ABSL_QCHECK_IMPL(condition, condition_str) \ +#define ABSL_QCHECK_IMPL(condition, condition_text) \ ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, \ ABSL_PREDICT_FALSE(!(condition))) \ - ABSL_LOG_INTERNAL_QCHECK(condition_str).InternalStream() + ABSL_LOG_INTERNAL_QCHECK(condition_text).InternalStream() -#define ABSL_PCHECK_IMPL(condition) \ - ABSL_CHECK_IMPL(condition, #condition).WithPerror() +#define ABSL_PCHECK_IMPL(condition, condition_text) \ + ABSL_CHECK_IMPL(condition, condition_text).WithPerror() #ifndef NDEBUG -#define ABSL_DCHECK_IMPL(condition) ABSL_CHECK_IMPL(condition, #condition) +#define ABSL_DCHECK_IMPL(condition, condition_text) \ + ABSL_CHECK_IMPL(condition, condition_text) #else -#define ABSL_DCHECK_IMPL(condition) ABSL_CHECK_IMPL(true || (condition), "true") +#define ABSL_DCHECK_IMPL(condition, condition_text) \ + ABSL_CHECK_IMPL(true || (condition), "true") #endif // CHECK_EQ -#define ABSL_CHECK_EQ_IMPL(val1, val2) \ - ABSL_LOG_INTERNAL_CHECK_OP(Check_EQ, ==, val1, val2) -#define ABSL_CHECK_NE_IMPL(val1, val2) \ - ABSL_LOG_INTERNAL_CHECK_OP(Check_NE, !=, val1, val2) -#define ABSL_CHECK_LE_IMPL(val1, val2) \ - ABSL_LOG_INTERNAL_CHECK_OP(Check_LE, <=, val1, val2) -#define ABSL_CHECK_LT_IMPL(val1, val2) \ - ABSL_LOG_INTERNAL_CHECK_OP(Check_LT, <, val1, val2) -#define ABSL_CHECK_GE_IMPL(val1, val2) \ - ABSL_LOG_INTERNAL_CHECK_OP(Check_GE, >=, val1, val2) -#define ABSL_CHECK_GT_IMPL(val1, val2) \ - ABSL_LOG_INTERNAL_CHECK_OP(Check_GT, >, val1, val2) -#define ABSL_QCHECK_EQ_IMPL(val1, val2) \ - ABSL_LOG_INTERNAL_QCHECK_OP(Check_EQ, ==, val1, val2) -#define ABSL_QCHECK_NE_IMPL(val1, val2) \ - ABSL_LOG_INTERNAL_QCHECK_OP(Check_NE, !=, val1, val2) -#define ABSL_QCHECK_LE_IMPL(val1, val2) \ - ABSL_LOG_INTERNAL_QCHECK_OP(Check_LE, <=, val1, val2) -#define ABSL_QCHECK_LT_IMPL(val1, val2) \ - ABSL_LOG_INTERNAL_QCHECK_OP(Check_LT, <, val1, val2) -#define ABSL_QCHECK_GE_IMPL(val1, val2) \ - ABSL_LOG_INTERNAL_QCHECK_OP(Check_GE, >=, val1, val2) -#define ABSL_QCHECK_GT_IMPL(val1, val2) \ - ABSL_LOG_INTERNAL_QCHECK_OP(Check_GT, >, val1, val2) +#define ABSL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_CHECK_OP(Check_EQ, ==, val1, val1_text, val2, val2_text) +#define ABSL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_CHECK_OP(Check_NE, !=, val1, val1_text, val2, val2_text) +#define ABSL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_CHECK_OP(Check_LE, <=, val1, val1_text, val2, val2_text) +#define ABSL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_CHECK_OP(Check_LT, <, val1, val1_text, val2, val2_text) +#define ABSL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_CHECK_OP(Check_GE, >=, val1, val1_text, val2, val2_text) +#define ABSL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_CHECK_OP(Check_GT, >, val1, val1_text, val2, val2_text) +#define ABSL_QCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_QCHECK_OP(Check_EQ, ==, val1, val1_text, val2, val2_text) +#define ABSL_QCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_QCHECK_OP(Check_NE, !=, val1, val1_text, val2, val2_text) +#define ABSL_QCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_QCHECK_OP(Check_LE, <=, val1, val1_text, val2, val2_text) +#define ABSL_QCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_QCHECK_OP(Check_LT, <, val1, val1_text, val2, val2_text) +#define ABSL_QCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_QCHECK_OP(Check_GE, >=, val1, val1_text, val2, val2_text) +#define ABSL_QCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_QCHECK_OP(Check_GT, >, val1, val1_text, val2, val2_text) #ifndef NDEBUG -#define ABSL_DCHECK_EQ_IMPL(val1, val2) ABSL_CHECK_EQ_IMPL(val1, val2) -#define ABSL_DCHECK_NE_IMPL(val1, val2) ABSL_CHECK_NE_IMPL(val1, val2) -#define ABSL_DCHECK_LE_IMPL(val1, val2) ABSL_CHECK_LE_IMPL(val1, val2) -#define ABSL_DCHECK_LT_IMPL(val1, val2) ABSL_CHECK_LT_IMPL(val1, val2) -#define ABSL_DCHECK_GE_IMPL(val1, val2) ABSL_CHECK_GE_IMPL(val1, val2) -#define ABSL_DCHECK_GT_IMPL(val1, val2) ABSL_CHECK_GT_IMPL(val1, val2) +#define ABSL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text) +#define ABSL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text) +#define ABSL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text) +#define ABSL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text) +#define ABSL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text) +#define ABSL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text) #else // ndef NDEBUG -#define ABSL_DCHECK_EQ_IMPL(val1, val2) ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) -#define ABSL_DCHECK_NE_IMPL(val1, val2) ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) -#define ABSL_DCHECK_LE_IMPL(val1, val2) ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) -#define ABSL_DCHECK_LT_IMPL(val1, val2) ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) -#define ABSL_DCHECK_GE_IMPL(val1, val2) ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) -#define ABSL_DCHECK_GT_IMPL(val1, val2) ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) +#define ABSL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) +#define ABSL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) +#define ABSL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) +#define ABSL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) +#define ABSL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) +#define ABSL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) #endif // def NDEBUG // CHECK_OK -#define ABSL_CHECK_OK_IMPL(status) ABSL_LOG_INTERNAL_CHECK_OK(status) -#define ABSL_QCHECK_OK_IMPL(status) ABSL_LOG_INTERNAL_QCHECK_OK(status) +#define ABSL_CHECK_OK_IMPL(status, status_text) \ + ABSL_LOG_INTERNAL_CHECK_OK(status, status_text) +#define ABSL_QCHECK_OK_IMPL(status, status_text) \ + ABSL_LOG_INTERNAL_QCHECK_OK(status, status_text) #ifndef NDEBUG -#define ABSL_DCHECK_OK_IMPL(status) ABSL_LOG_INTERNAL_CHECK_OK(status) +#define ABSL_DCHECK_OK_IMPL(status, status_text) \ + ABSL_LOG_INTERNAL_CHECK_OK(status, status_text) #else -#define ABSL_DCHECK_OK_IMPL(status) \ +#define ABSL_DCHECK_OK_IMPL(status, status_text) \ ABSL_LOG_INTERNAL_DCHECK_NOP(status, nullptr) #endif // CHECK_STREQ -#define ABSL_CHECK_STREQ_IMPL(s1, s2) \ - ABSL_LOG_INTERNAL_CHECK_STROP(strcmp, ==, true, s1, s2) -#define ABSL_CHECK_STRNE_IMPL(s1, s2) \ - ABSL_LOG_INTERNAL_CHECK_STROP(strcmp, !=, false, s1, s2) -#define ABSL_CHECK_STRCASEEQ_IMPL(s1, s2) \ - ABSL_LOG_INTERNAL_CHECK_STROP(strcasecmp, ==, true, s1, s2) -#define ABSL_CHECK_STRCASENE_IMPL(s1, s2) \ - ABSL_LOG_INTERNAL_CHECK_STROP(strcasecmp, !=, false, s1, s2) -#define ABSL_QCHECK_STREQ_IMPL(s1, s2) \ - ABSL_LOG_INTERNAL_QCHECK_STROP(strcmp, ==, true, s1, s2) -#define ABSL_QCHECK_STRNE_IMPL(s1, s2) \ - ABSL_LOG_INTERNAL_QCHECK_STROP(strcmp, !=, false, s1, s2) -#define ABSL_QCHECK_STRCASEEQ_IMPL(s1, s2) \ - ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, ==, true, s1, s2) -#define ABSL_QCHECK_STRCASENE_IMPL(s1, s2) \ - ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, !=, false, s1, s2) +#define ABSL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_CHECK_STROP(strcmp, ==, true, s1, s1_text, s2, s2_text) +#define ABSL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_CHECK_STROP(strcmp, !=, false, s1, s1_text, s2, s2_text) +#define ABSL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_CHECK_STROP(strcasecmp, ==, true, s1, s1_text, s2, s2_text) +#define ABSL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_CHECK_STROP(strcasecmp, !=, false, s1, s1_text, s2, s2_text) +#define ABSL_QCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_QCHECK_STROP(strcmp, ==, true, s1, s1_text, s2, s2_text) +#define ABSL_QCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_QCHECK_STROP(strcmp, !=, false, s1, s1_text, s2, s2_text) +#define ABSL_QCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, ==, true, s1, s1_text, s2, s2_text) +#define ABSL_QCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, !=, false, s1, s1_text, s2, \ + s2_text) #ifndef NDEBUG -#define ABSL_DCHECK_STREQ_IMPL(s1, s2) ABSL_CHECK_STREQ_IMPL(s1, s2) -#define ABSL_DCHECK_STRCASEEQ_IMPL(s1, s2) ABSL_CHECK_STRCASEEQ_IMPL(s1, s2) -#define ABSL_DCHECK_STRNE_IMPL(s1, s2) ABSL_CHECK_STRNE_IMPL(s1, s2) -#define ABSL_DCHECK_STRCASENE_IMPL(s1, s2) ABSL_CHECK_STRCASENE_IMPL(s1, s2) +#define ABSL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) +#define ABSL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) +#define ABSL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) +#define ABSL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) #else // ndef NDEBUG -#define ABSL_DCHECK_STREQ_IMPL(s1, s2) ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2) -#define ABSL_DCHECK_STRCASEEQ_IMPL(s1, s2) ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2) -#define ABSL_DCHECK_STRNE_IMPL(s1, s2) ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2) -#define ABSL_DCHECK_STRCASENE_IMPL(s1, s2) ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2) +#define ABSL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2) +#define ABSL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2) +#define ABSL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2) +#define ABSL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2) #endif // def NDEBUG #endif // ABSL_LOG_INTERNAL_CHECK_IMPL_H_ diff --git a/absl/log/internal/check_op.h b/absl/log/internal/check_op.h index 559e5afc..4907b89b 100644 --- a/absl/log/internal/check_op.h +++ b/absl/log/internal/check_op.h @@ -57,35 +57,40 @@ ::absl::log_internal::NullStream().InternalStream() #endif -#define ABSL_LOG_INTERNAL_CHECK_OP(name, op, val1, val2) \ +#define ABSL_LOG_INTERNAL_CHECK_OP(name, op, val1, val1_text, val2, val2_text) \ while ( \ ::std::string* absl_log_internal_check_op_result ABSL_ATTRIBUTE_UNUSED = \ ::absl::log_internal::name##Impl( \ ::absl::log_internal::GetReferenceableValue(val1), \ ::absl::log_internal::GetReferenceableValue(val2), \ - ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(#val1 " " #op \ - " " #val2))) \ + ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val1_text \ + " " #op " " val2_text))) \ ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_op_result).InternalStream() -#define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val2) \ - while (::std::string* absl_log_internal_qcheck_op_result = \ - ::absl::log_internal::name##Impl( \ - ::absl::log_internal::GetReferenceableValue(val1), \ - ::absl::log_internal::GetReferenceableValue(val2), \ - ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(#val1 " " #op \ - " " #val2))) \ +#define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val1_text, val2, \ + val2_text) \ + while (::std::string* absl_log_internal_qcheck_op_result = \ + ::absl::log_internal::name##Impl( \ + ::absl::log_internal::GetReferenceableValue(val1), \ + ::absl::log_internal::GetReferenceableValue(val2), \ + ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL( \ + val1_text " " #op " " val2_text))) \ ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_op_result).InternalStream() -#define ABSL_LOG_INTERNAL_CHECK_STROP(func, op, expected, s1, s2) \ +#define ABSL_LOG_INTERNAL_CHECK_STROP(func, op, expected, s1, s1_text, s2, \ + s2_text) \ while (::std::string* absl_log_internal_check_strop_result = \ ::absl::log_internal::Check##func##expected##Impl( \ (s1), (s2), \ - ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(#s1 " " #op " " #s2))) \ + ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op \ + " " s2_text))) \ ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_strop_result) \ .InternalStream() -#define ABSL_LOG_INTERNAL_QCHECK_STROP(func, op, expected, s1, s2) \ +#define ABSL_LOG_INTERNAL_QCHECK_STROP(func, op, expected, s1, s1_text, s2, \ + s2_text) \ while (::std::string* absl_log_internal_qcheck_strop_result = \ ::absl::log_internal::Check##func##expected##Impl( \ (s1), (s2), \ - ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(#s1 " " #op " " #s2))) \ + ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op \ + " " s2_text))) \ ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_strop_result) \ .InternalStream() // This one is tricky: @@ -108,33 +113,35 @@ // * As usual, no braces so we can stream into the expansion with `operator<<`. // * Also as usual, it must expand to a single (partial) statement with no // ambiguous-else problems. -#define ABSL_LOG_INTERNAL_CHECK_OK(val) \ - for (::std::pair \ - absl_log_internal_check_ok_goo; \ - absl_log_internal_check_ok_goo.first = \ - ::absl::log_internal::AsStatus(val), \ - absl_log_internal_check_ok_goo.second = \ - ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \ - ? nullptr \ - : ::absl::status_internal::MakeCheckFailString( \ - absl_log_internal_check_ok_goo.first, \ - ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(#val " is OK")), \ - !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());) \ - ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_ok_goo.second) \ +#define ABSL_LOG_INTERNAL_CHECK_OK(val, val_text) \ + for (::std::pair \ + absl_log_internal_check_ok_goo; \ + absl_log_internal_check_ok_goo.first = \ + ::absl::log_internal::AsStatus(val), \ + absl_log_internal_check_ok_goo.second = \ + ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \ + ? nullptr \ + : ::absl::status_internal::MakeCheckFailString( \ + absl_log_internal_check_ok_goo.first, \ + ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text \ + " is OK")), \ + !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());) \ + ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_ok_goo.second) \ .InternalStream() -#define ABSL_LOG_INTERNAL_QCHECK_OK(val) \ - for (::std::pair \ - absl_log_internal_check_ok_goo; \ - absl_log_internal_check_ok_goo.first = \ - ::absl::log_internal::AsStatus(val), \ - absl_log_internal_check_ok_goo.second = \ - ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \ - ? nullptr \ - : ::absl::status_internal::MakeCheckFailString( \ - absl_log_internal_check_ok_goo.first, \ - ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(#val " is OK")), \ - !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());) \ - ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_check_ok_goo.second) \ +#define ABSL_LOG_INTERNAL_QCHECK_OK(val, val_text) \ + for (::std::pair \ + absl_log_internal_check_ok_goo; \ + absl_log_internal_check_ok_goo.first = \ + ::absl::log_internal::AsStatus(val), \ + absl_log_internal_check_ok_goo.second = \ + ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \ + ? nullptr \ + : ::absl::status_internal::MakeCheckFailString( \ + absl_log_internal_check_ok_goo.first, \ + ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text \ + " is OK")), \ + !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());) \ + ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_check_ok_goo.second) \ .InternalStream() namespace absl { -- cgit v1.2.3