From 60a8c5f1c9cf039453824b439d1a40c7e76a93c4 Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Sat, 21 Mar 2020 15:03:41 +0200 Subject: [PATCH] Added padding support and set_pattern to custom_flags --- example/example.cpp | 6 +-- include/spdlog/pattern_formatter-inl.h | 15 ++++-- include/spdlog/pattern_formatter.h | 11 +++-- tests/test_pattern_formatter.cpp | 66 +++++++++++++++++++------- 4 files changed, 70 insertions(+), 28 deletions(-) diff --git a/example/example.cpp b/example/example.cpp index 08e83af9..1c8d189e 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -276,8 +276,8 @@ public: void custom_flags_example() { - using spdlog::details::make_unique; //for pre c++14 - auto formatter = make_unique("[%+] [%*]"); - formatter->add_flag('*').recompile(); + using spdlog::details::make_unique; // for pre c++14 + auto formatter = make_unique(); + formatter->add_flag('*').set_pattern("[%n] [%*] [%^%l%$] %v"); spdlog::set_formatter(std::move(formatter)); } diff --git a/include/spdlog/pattern_formatter-inl.h b/include/spdlog/pattern_formatter-inl.h index 6c3e0b79..787ab422 100644 --- a/include/spdlog/pattern_formatter-inl.h +++ b/include/spdlog/pattern_formatter-inl.h @@ -1024,8 +1024,9 @@ SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, memory details::fmt_helper::append_string_view(eol_, dest); } -SPDLOG_INLINE void pattern_formatter::recompile() +SPDLOG_INLINE void pattern_formatter::set_pattern(std::string pattern) { + pattern_ = std::move(pattern); compile_pattern_(pattern_); } @@ -1041,15 +1042,19 @@ SPDLOG_INLINE std::tm pattern_formatter::get_time_(const details::log_msg &msg) template SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_info padding) { + // process custom flags auto it = custom_handlers_.find(flag); - if (it != custom_handlers_.end()) + if (it != custom_handlers_.end()) { - formatters_.push_back(it->second->clone()); + auto custom_handler = it->second->clone(); + custom_handler->set_padding_info(padding); + formatters_.push_back(std::move(custom_handler)); return; } - switch (flag) - { + // process built-in flags + switch (flag) + { case ('+'): // default formatter formatters_.push_back(details::make_unique(padding)); break; diff --git a/include/spdlog/pattern_formatter.h b/include/spdlog/pattern_formatter.h index 33987e4e..ecea6bcf 100644 --- a/include/spdlog/pattern_formatter.h +++ b/include/spdlog/pattern_formatter.h @@ -41,8 +41,8 @@ struct padding_info { return enabled_; } - const size_t width_ = 0; - const pad_side side_ = left; + size_t width_ = 0; + pad_side side_ = left; bool truncate_ = false; bool enabled_ = false; }; @@ -67,6 +67,11 @@ class SPDLOG_API custom_flag_formatter : public details::flag_formatter { public: virtual std::unique_ptr clone() const = 0; + + void set_padding_info(details::padding_info padding) + { + flag_formatter::padinfo_ = padding; + } }; class SPDLOG_API pattern_formatter final : public formatter @@ -92,7 +97,7 @@ public: custom_handlers_[flag] = details::make_unique(args...); return *this; } - void recompile(); + void set_pattern(std::string pattern); private: std::string pattern_; diff --git a/tests/test_pattern_formatter.cpp b/tests/test_pattern_formatter.cpp index 7315a1fb..42ce40e7 100644 --- a/tests/test_pattern_formatter.cpp +++ b/tests/test_pattern_formatter.cpp @@ -246,8 +246,6 @@ TEST_CASE("paddinng_truncate_funcname", "[pattern_formatter]") REQUIRE(lines[1] == "message [funct]"); } - - TEST_CASE("clone-default-formatter", "[pattern_formatter]") { auto formatter_1 = std::make_shared(); @@ -307,17 +305,26 @@ TEST_CASE("clone-formatter-2", "[pattern_formatter]") REQUIRE(fmt::to_string(formatted_1) == fmt::to_string(formatted_2)); } - class custom_test_flag : public spdlog::custom_flag_formatter { public: - class custom_test_flag (std::string txt) : some_txt{std::move(txt)} + class custom_test_flag(std::string txt) + : some_txt{std::move(txt)} {} void format(const spdlog::details::log_msg &, const std::tm &, spdlog::memory_buf_t &dest) override { + if (some_txt == "throw_me") + { + throw spdlog::spdlog_ex("custom_flag_exception_test"); + } + some_txt = std::string(padinfo_.width_, ' ') + some_txt; dest.append(some_txt.data(), some_txt.data() + some_txt.size()); } + spdlog::details::padding_info get_padding_info() + { + return padinfo_; + } std::string some_txt; @@ -329,8 +336,9 @@ public: // test clone with custom flag formatters TEST_CASE("clone-custom_formatter", "[pattern_formatter]") { - auto formatter_1 = std::make_shared("[%n] [%t] %v", spdlog::pattern_time_type::utc, ""); - formatter_1->add_flag('t', "custom_output").recompile(); + + auto formatter_1 = std::make_shared(); + formatter_1->add_flag('t', "custom_output").set_pattern("[%n] [%t] %v"); auto formatter_2 = formatter_1->clone(); std::string logger_name = "logger-name"; spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message"); @@ -338,10 +346,11 @@ TEST_CASE("clone-custom_formatter", "[pattern_formatter]") memory_buf_t formatted_1; memory_buf_t formatted_2; formatter_1->format(msg, formatted_1); - formatter_2->format(msg, formatted_2); - - REQUIRE(fmt::to_string(formatted_1) == "[logger-name] [custom_output] some message"); - REQUIRE(fmt::to_string(formatted_2) == "[logger-name] [custom_output] some message"); + formatter_2->format(msg, formatted_2); + + auto expected = fmt::format("[logger-name] [custom_output] some message{}", spdlog::details::os::default_eol); + REQUIRE(fmt::to_string(formatted_1) == expected); + REQUIRE(fmt::to_string(formatted_2) == expected); } // @@ -398,15 +407,38 @@ TEST_CASE("full filename formatter", "[pattern_formatter]") REQUIRE(fmt::to_string(formatted) == test_path); } - TEST_CASE("custom flags", "[pattern_formatter]") { - auto formatter = std::make_shared("[%n] [%t] [%u] %v", spdlog::pattern_time_type::utc, ""); - formatter->add_flag('t', "custom1").add_flag('u', "custom2").recompile(); - + auto formatter = std::make_shared(); + formatter->add_flag('t', "custom1").add_flag('u', "custom2").set_pattern("[%n] [%t] [%u] %v"); + memory_buf_t formatted; - + spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message"); - formatter->format(msg, formatted); - REQUIRE(fmt::to_string(formatted) == "[logger-name] [custom1] [custom2] some message"); + formatter->format(msg, formatted); + auto expected = fmt::format("[logger-name] [custom1] [custom2] some message{}", spdlog::details::os::default_eol); + REQUIRE(fmt::to_string(formatted) == expected); +} + +TEST_CASE("custom flags-padding", "[pattern_formatter]") +{ + auto formatter = std::make_shared(); + formatter->add_flag('t', "custom1").add_flag('u', "custom2").set_pattern("[%n] [%t] [%5u] %v"); + + memory_buf_t formatted; + + spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message"); + formatter->format(msg, formatted); + auto expected = fmt::format("[logger-name] [custom1] [ custom2] some message{}", spdlog::details::os::default_eol); + REQUIRE(fmt::to_string(formatted) == expected); +} + +TEST_CASE("custom flags-exception", "[pattern_formatter]") +{ + auto formatter = std::make_shared(); + formatter->add_flag('t', "throw_me").add_flag('u', "custom2").set_pattern("[%n] [%t] [%u] %v"); + + memory_buf_t formatted; + spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message"); + CHECK_THROWS_AS(formatter->format(msg, formatted), spdlog::spdlog_ex); }