diff options
Diffstat (limited to 'absl/base')
-rw-r--r-- | absl/base/BUILD.bazel | 1 | ||||
-rw-r--r-- | absl/base/CMakeLists.txt | 2 | ||||
-rw-r--r-- | absl/base/internal/raw_logging.cc | 16 | ||||
-rw-r--r-- | absl/base/internal/raw_logging.h | 43 | ||||
-rw-r--r-- | absl/base/raw_logging_test.cc | 29 |
5 files changed, 90 insertions, 1 deletions
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 35414a252c62..06d092ebdfa8 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -362,6 +362,7 @@ cc_test( copts = ABSL_TEST_COPTS, deps = [ ":base", + "//absl/strings", "@com_google_googletest//:gtest_main", ], ) diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 303533e26d1b..01d2af085f58 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -310,7 +310,7 @@ absl_test( # test raw_logging_test set(RAW_LOGGING_TEST_SRC "raw_logging_test.cc") -set(RAW_LOGGING_TEST_PUBLIC_LIBRARIES absl::base) +set(RAW_LOGGING_TEST_PUBLIC_LIBRARIES absl::base absl::strings) absl_test( TARGET diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc index 1ce138887252..41101bd72eb8 100644 --- a/absl/base/internal/raw_logging.cc +++ b/absl/base/internal/raw_logging.cc @@ -206,6 +206,15 @@ void RawLog(absl::LogSeverity severity, const char* file, int line, va_end(ap); } +// Non-formatting version of RawLog(). +// +// TODO(gfalcon): When string_view no longer depends on base, change this +// interface to take its message as a string_view instead. +static void DefaultInternalLog(absl::LogSeverity severity, const char* file, + int line, const std::string& message) { + RawLog(severity, file, line, "%s", message.c_str()); +} + bool RawLoggingFullySupported() { #ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED return true; @@ -214,5 +223,12 @@ bool RawLoggingFullySupported() { #endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED } +ABSL_CONST_INIT absl::base_internal::AtomicHook<InternalLogFunction> + internal_log_function(DefaultInternalLog); + +void RegisterInternalLogFunction(InternalLogFunction func) { + internal_log_function.Store(func); +} + } // namespace raw_logging_internal } // namespace absl diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h index a2b7207a032c..67abfd30798d 100644 --- a/absl/base/internal/raw_logging.h +++ b/absl/base/internal/raw_logging.h @@ -19,7 +19,10 @@ #ifndef ABSL_BASE_INTERNAL_RAW_LOGGING_H_ #define ABSL_BASE_INTERNAL_RAW_LOGGING_H_ +#include <string> + #include "absl/base/attributes.h" +#include "absl/base/internal/atomic_hook.h" #include "absl/base/log_severity.h" #include "absl/base/macros.h" #include "absl/base/port.h" @@ -57,6 +60,34 @@ } \ } while (0) +// ABSL_INTERNAL_LOG and ABSL_INTERNAL_CHECK work like the RAW variants above, +// except that if the richer log library is linked into the binary, we dispatch +// to that instead. This is potentially useful for internal logging and +// assertions, where we are using RAW_LOG neither for its async-signal-safety +// nor for its non-allocating nature, but rather because raw logging has very +// few other dependencies. +// +// The API is a subset of the above: each macro only takes two arguments. Use +// StrCat if you need to build a richer message. +#define ABSL_INTERNAL_LOG(severity, message) \ + do { \ + constexpr const char* absl_raw_logging_internal_basename = \ + ::absl::raw_logging_internal::Basename(__FILE__, \ + sizeof(__FILE__) - 1); \ + ::absl::raw_logging_internal::internal_log_function( \ + ABSL_RAW_LOGGING_INTERNAL_##severity, \ + absl_raw_logging_internal_basename, __LINE__, message); \ + } while (0) + +#define ABSL_INTERNAL_CHECK(condition, message) \ + do { \ + if (ABSL_PREDICT_FALSE(!(condition))) { \ + std::string death_message = "Check " #condition " failed: "; \ + death_message += std::string(message); \ + ABSL_INTERNAL_LOG(FATAL, death_message); \ + } \ + } while (0) + #define ABSL_RAW_LOGGING_INTERNAL_INFO ::absl::LogSeverity::kInfo #define ABSL_RAW_LOGGING_INTERNAL_WARNING ::absl::LogSeverity::kWarning #define ABSL_RAW_LOGGING_INTERNAL_ERROR ::absl::LogSeverity::kError @@ -131,6 +162,18 @@ using LogPrefixHook = bool (*)(absl::LogSeverity severity, const char* file, using AbortHook = void (*)(const char* file, int line, const char* buf_start, const char* prefix_end, const char* buf_end); +// Internal logging function for ABSL_INTERNAL_LOG to dispatch to. +// +// TODO(gfalcon): When string_view no longer depends on base, change this +// interface to take its message as a string_view instead. +using InternalLogFunction = void (*)(absl::LogSeverity severity, + const char* file, int line, + const std::string& message); + +extern base_internal::AtomicHook<InternalLogFunction> internal_log_function; + +void RegisterInternalLogFunction(InternalLogFunction func); + } // namespace raw_logging_internal } // namespace absl diff --git a/absl/base/raw_logging_test.cc b/absl/base/raw_logging_test.cc index dae4b35138c5..ebbc5db90672 100644 --- a/absl/base/raw_logging_test.cc +++ b/absl/base/raw_logging_test.cc @@ -18,12 +18,20 @@ #include "absl/base/internal/raw_logging.h" +#include <tuple> + #include "gtest/gtest.h" +#include "absl/strings/str_cat.h" namespace { TEST(RawLoggingCompilationTest, Log) { ABSL_RAW_LOG(INFO, "RAW INFO: %d", 1); + ABSL_RAW_LOG(INFO, "RAW INFO: %d %d", 1, 2); + ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d", 1, 2, 3); + ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d %d", 1, 2, 3, 4); + ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d %d %d", 1, 2, 3, 4, 5); + ABSL_RAW_LOG(WARNING, "RAW WARNING: %d", 1); ABSL_RAW_LOG(ERROR, "RAW ERROR: %d", 1); } @@ -47,4 +55,25 @@ TEST(RawLoggingDeathTest, LogFatal) { kExpectedDeathOutput); } +TEST(InternalLog, CompilationTest) { + ABSL_INTERNAL_LOG(INFO, "Internal Log"); + std::string log_msg = "Internal Log"; + ABSL_INTERNAL_LOG(INFO, log_msg); + + ABSL_INTERNAL_LOG(INFO, log_msg + " 2"); + + float d = 1.1f; + ABSL_INTERNAL_LOG(INFO, absl::StrCat("Internal log ", 3, " + ", d)); +} + +TEST(InternalLogDeathTest, FailingCheck) { + EXPECT_DEATH_IF_SUPPORTED(ABSL_INTERNAL_CHECK(1 == 0, "explanation"), + kExpectedDeathOutput); +} + +TEST(InternalLogDeathTest, LogFatal) { + EXPECT_DEATH_IF_SUPPORTED(ABSL_INTERNAL_LOG(FATAL, "my dog has fleas"), + kExpectedDeathOutput); +} + } // namespace |