diff options
author | Joel Rosdahl <joel@rosdahl.net> | 2020-10-20 20:49:50 +0200 |
---|---|---|
committer | Joel Rosdahl <joel@rosdahl.net> | 2020-10-23 15:32:26 +0200 |
commit | 60904e7b571642ec67ec750edfde724f735a0d2e (patch) | |
tree | 5cfb1f80c916824c5f7ba4a18fbfbb7d95630fb4 /src/Logging.hpp | |
parent | 08b3c4765a7ccdb8f3f2d260e44e08d6189b7508 (diff) | |
download | ccache-60904e7b571642ec67ec750edfde724f735a0d2e.tar.gz |
Detect errors in log strings at compile time
fmtlib can detect format string errors at compile time if (1) applying
FMT_STRING to the format string literal and (2) compiling for C++14 or
higher.
Requirement 1 is implemented by introducing a LOG macro which applies
FMT_STRING to the first argument and calls Logging::log (if logging is
enabled). Also added are a companion LOG_RAW macro (since C++11 requires
at least one argument for the “...” part in variadic macros) and a
BULK_LOG macro which calls Logging::bulk_log (if logging is enabled).
Requirement 2 is implemented by setting CMAKE_CXX_STANDARD to 14 for one
CI build with a known C++14-capable compiler. We can’t set it to 14 by
default since we still want the code to be buildable with C++11
compilers.
This will catch errors such as the one fixed by PR #691.
Diffstat (limited to 'src/Logging.hpp')
-rw-r--r-- | src/Logging.hpp | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/src/Logging.hpp b/src/Logging.hpp index 278812bd..38553f25 100644 --- a/src/Logging.hpp +++ b/src/Logging.hpp @@ -23,12 +23,36 @@ #include "FormatNonstdStringView.hpp" #include "third_party/fmt/core.h" +#include "third_party/fmt/format.h" #include "third_party/nonstd/optional.hpp" #include "third_party/nonstd/string_view.hpp" #include <string> #include <utility> +// Log a raw message (plus a newline character). +#define LOG_RAW(message_) \ + do { \ + if (Logging::enabled()) { \ + Logging::log(nonstd::string_view(message_)); \ + } \ + } while (false) + +// Log a message (plus a newline character) described by a format string with at +// least one placeholder. `format` is compile-time checked if CMAKE_CXX_STANDARD +// >= 14. +#define LOG(format_, ...) LOG_RAW(fmt::format(FMT_STRING(format_), __VA_ARGS__)) + +// Log a message (plus a newline character) described by a format string with at +// least one placeholder without flushing and with a reused timestamp. `format` +// is compile-time checked if CMAKE_CXX_STANDARD >= 14. +#define BULK_LOG(format_, ...) \ + do { \ + if (Logging::enabled()) { \ + Logging::bulk_log(fmt::format(FMT_STRING(format_), __VA_ARGS__)); \ + } \ + } while (false) + class Config; namespace Logging { @@ -50,28 +74,4 @@ void bulk_log(nonstd::string_view message); // Write the current log memory buffer `path`. void dump_log(const std::string& path); -// Log a message (plus a newline character). `args` are forwarded to -// `fmt::format`. -template<typename... T> -inline void -log(T&&... args) -{ - if (!enabled()) { - return; - } - log(nonstd::string_view(fmt::format(std::forward<T>(args)...))); -} - -// Log a message (plus a newline character) without flushing and with a reused -// timestamp. `args` are forwarded to `fmt::format`. -template<typename... T> -inline void -bulk_log(T&&... args) -{ - if (!enabled()) { - return; - } - bulk_log(nonstd::string_view(fmt::format(std::forward<T>(args)...))); -} - } // namespace Logging |