summaryrefslogtreecommitdiff
path: root/src/Logging.hpp
diff options
context:
space:
mode:
authorJoel Rosdahl <joel@rosdahl.net>2020-10-20 20:49:50 +0200
committerJoel Rosdahl <joel@rosdahl.net>2020-10-23 15:32:26 +0200
commit60904e7b571642ec67ec750edfde724f735a0d2e (patch)
tree5cfb1f80c916824c5f7ba4a18fbfbb7d95630fb4 /src/Logging.hpp
parent08b3c4765a7ccdb8f3f2d260e44e08d6189b7508 (diff)
downloadccache-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.hpp48
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