From 34d7bc859c8736871c32b6f551fb403fcdc1339b Mon Sep 17 00:00:00 2001 From: Josh Schmiedlin Date: Tue, 14 Jul 2020 09:41:21 -0400 Subject: [PATCH] * multi ranges now utilize standard arrays instead of vectors to save on dynamic allocations. --- include/spdlog/details/log_msg.h | 8 ++- include/spdlog/pattern_formatter-inl.h | 13 +++-- include/spdlog/sinks/ansicolor_sink-inl.h | 44 +++++++++------ include/spdlog/sinks/wincolor_sink-inl.h | 47 ++++++++++------ tests/test_pattern_formatter.cpp | 68 +++++++++++------------ tests/test_stdout_api.cpp | 11 ++++ 6 files changed, 118 insertions(+), 73 deletions(-) diff --git a/include/spdlog/details/log_msg.h b/include/spdlog/details/log_msg.h index 372f2bf9..83138050 100644 --- a/include/spdlog/details/log_msg.h +++ b/include/spdlog/details/log_msg.h @@ -8,6 +8,8 @@ namespace spdlog { namespace details { + +const size_t MAX_RANGES = 5; struct SPDLOG_API log_msg { log_msg() = default; @@ -22,8 +24,10 @@ struct SPDLOG_API log_msg size_t thread_id{0}; // wrapping the formatted text with color (updated by pattern_formatter). - mutable std::vector color_range_start; - mutable std::vector color_range_end; + mutable size_t color_ranges_start[MAX_RANGES] = {0}; + mutable size_t num_start_ranges = 0; + mutable size_t color_ranges_end[MAX_RANGES] = {0}; + mutable size_t num_end_ranges = 0; source_loc source; string_view_t payload; diff --git a/include/spdlog/pattern_formatter-inl.h b/include/spdlog/pattern_formatter-inl.h index c2801364..b40250d5 100644 --- a/include/spdlog/pattern_formatter-inl.h +++ b/include/spdlog/pattern_formatter-inl.h @@ -734,7 +734,8 @@ public: void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override { - msg.color_range_start.push_back(dest.size()); + if(msg.num_start_ranges < MAX_RANGES) + msg.color_ranges_start[msg.num_start_ranges++] = dest.size(); } }; @@ -747,7 +748,8 @@ public: void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override { - msg.color_range_end.push_back(dest.size()); + if(msg.num_end_ranges < MAX_RANGES) + msg.color_ranges_end[msg.num_end_ranges++] = dest.size(); } }; @@ -963,10 +965,13 @@ public: dest.push_back('['); // wrap the level name with color - msg.color_range_start.push_back(dest.size()); + if(msg.num_start_ranges < MAX_RANGES) + msg.color_ranges_start[msg.num_start_ranges++] = dest.size(); // fmt_helper::append_string_view(level::to_c_str(msg.level), dest); fmt_helper::append_string_view(level::to_string_view(msg.level), dest); - msg.color_range_end.push_back(dest.size()); + + if(msg.num_end_ranges < MAX_RANGES) + msg.color_ranges_end[msg.num_end_ranges++] = dest.size(); dest.push_back(']'); dest.push_back(' '); diff --git a/include/spdlog/sinks/ansicolor_sink-inl.h b/include/spdlog/sinks/ansicolor_sink-inl.h index e58dd8ff..eaba7c09 100644 --- a/include/spdlog/sinks/ansicolor_sink-inl.h +++ b/include/spdlog/sinks/ansicolor_sink-inl.h @@ -43,30 +43,42 @@ SPDLOG_INLINE void ansicolor_sink::log(const details::log_msg &msg // Wrap the originally formatted message in color codes. // If color is not supported in the terminal, log as is instead. std::lock_guard lock(mutex_); - msg.color_range_start.clear(); - msg.color_range_end.clear(); + msg.num_start_ranges = 0; + memset(msg.color_ranges_start, 0, sizeof(size_t) * spdlog::details::MAX_RANGES); + msg.num_end_ranges = 0; + memset(msg.color_ranges_end, 0, sizeof(size_t) * spdlog::details::MAX_RANGES); memory_buf_t formatted; formatter_->format(msg, formatted); - if (should_do_colors_ && !msg.color_range_start.empty() && msg.color_range_start.size() == msg.color_range_end.size()) + if (should_do_colors_ && msg.num_start_ranges == msg.num_end_ranges) { - // before color range - print_range_(formatted, 0, msg.color_range_start[0]); + if(msg.num_start_ranges > 0) + { + // before color range + print_range_(formatted, 0, msg.color_ranges_start[0]); - for(size_t i=0; i void SPDLOG_INLINE wincolor_sink::log(const details::log_msg &msg) { std::lock_guard lock(mutex_); - msg.color_range_start.clear(); - msg.color_range_end.clear(); + msg.num_start_ranges = 0; + memset(msg.color_ranges_start, 0, sizeof(size_t) * spdlog::details::MAX_RANGES); + msg.num_end_ranges = 0; + memset(msg.color_ranges_end, 0, sizeof(size_t) * spdlog::details::MAX_RANGES); memory_buf_t formatted; formatter_->format(msg, formatted); if (!in_console_) @@ -61,28 +63,39 @@ void SPDLOG_INLINE wincolor_sink::log(const details::log_msg &msg) write_to_file_(formatted); return; } - if (should_do_colors_ && !msg.color_range_start.empty() && msg.color_range_start.size() == msg.color_range_end.size()) + if (should_do_colors_ && msg.num_start_ranges == msg.num_end_ranges) { - // before color range - print_range_(formatted, 0, msg.color_range_start[0]); + if(msg.num_start_ranges > 0) + { + // before color range + print_range_(formatted, 0, msg.color_ranges_start[0]); - for(size_t i=0; iformat(msg, formatted); - REQUIRE(msg.color_range_start.size() == 1); - REQUIRE(msg.color_range_end.size() == 1); - REQUIRE(msg.color_range_start[0] == 0); - REQUIRE(msg.color_range_end[0] == 5); + REQUIRE(msg.num_start_ranges == 1); + REQUIRE(msg.num_end_ranges == 1); + REQUIRE(msg.color_ranges_start[0] == 0); + REQUIRE(msg.color_ranges_end[0] == 5); REQUIRE(log_to_str("hello", "%^%v%$", spdlog::pattern_time_type::local, "\n") == "hello\n"); } @@ -83,10 +83,10 @@ TEST_CASE("color range test2", "[pattern_formatter]") spdlog::details::log_msg msg(logger_name, spdlog::level::info, ""); memory_buf_t formatted; formatter->format(msg, formatted); - REQUIRE(msg.color_range_start.size() == 1); - REQUIRE(msg.color_range_end.size() == 1); - REQUIRE(msg.color_range_start[0] == 0); - REQUIRE(msg.color_range_end[0] == 0); + REQUIRE(msg.num_start_ranges == 1); + REQUIRE(msg.num_end_ranges == 1); + REQUIRE(msg.color_ranges_start[0] == 0); + REQUIRE(msg.color_ranges_end[0] == 0); REQUIRE(log_to_str("", "%^%$", spdlog::pattern_time_type::local, "\n") == "\n"); } @@ -97,10 +97,10 @@ TEST_CASE("color range test3", "[pattern_formatter]") spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored"); memory_buf_t formatted; formatter->format(msg, formatted); - REQUIRE(msg.color_range_start.size() == 1); - REQUIRE(msg.color_range_end.size() == 1); - REQUIRE(msg.color_range_start[0] == 0); - REQUIRE(msg.color_range_end[0] == 3); + REQUIRE(msg.num_start_ranges == 1); + REQUIRE(msg.num_end_ranges == 1); + REQUIRE(msg.color_ranges_start[0] == 0); + REQUIRE(msg.color_ranges_end[0] == 3); } TEST_CASE("color range test4", "[pattern_formatter]") @@ -111,10 +111,10 @@ TEST_CASE("color range test4", "[pattern_formatter]") memory_buf_t formatted; formatter->format(msg, formatted); - REQUIRE(msg.color_range_start.size() == 1); - REQUIRE(msg.color_range_end.size() == 1); - REQUIRE(msg.color_range_start[0] == 2); - REQUIRE(msg.color_range_end[0] == 5); + REQUIRE(msg.num_start_ranges == 1); + REQUIRE(msg.num_end_ranges == 1); + REQUIRE(msg.color_ranges_start[0] == 2); + REQUIRE(msg.color_ranges_end[0] == 5); REQUIRE(log_to_str("ignored", "XX%^YYY%$", spdlog::pattern_time_type::local, "\n") == "XXYYY\n"); } @@ -125,9 +125,9 @@ TEST_CASE("color range test5", "[pattern_formatter]") spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored"); memory_buf_t formatted; formatter->format(msg, formatted); - REQUIRE(msg.color_range_start.size() == 1); - REQUIRE(msg.color_range_end.empty()); - REQUIRE(msg.color_range_start[0] == 2); + REQUIRE(msg.num_start_ranges == 1); + REQUIRE(msg.num_end_ranges == 0); + REQUIRE(msg.color_ranges_start[0] == 2); } TEST_CASE("color range test6", "[pattern_formatter]") @@ -137,9 +137,9 @@ TEST_CASE("color range test6", "[pattern_formatter]") spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored"); memory_buf_t formatted; formatter->format(msg, formatted); - REQUIRE(msg.color_range_start.empty()); - REQUIRE(msg.color_range_end.size() == 1); - REQUIRE(msg.color_range_end[0] == 2); + REQUIRE(msg.num_start_ranges == 0); + REQUIRE(msg.num_end_ranges == 1); + REQUIRE(msg.color_ranges_end[0] == 2); } TEST_CASE("color multi-range test1", "[pattern_formatter]") @@ -149,12 +149,12 @@ TEST_CASE("color multi-range test1", "[pattern_formatter]") spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored"); memory_buf_t formatted; formatter->format(msg, formatted); - REQUIRE(msg.color_range_start.size() == 2); - REQUIRE(msg.color_range_end.size() == 2); - REQUIRE(msg.color_range_start[0] == 0); - REQUIRE(msg.color_range_start[1] == 0); - REQUIRE(msg.color_range_end[0] == 0); - REQUIRE(msg.color_range_end[1] == 0); + REQUIRE(msg.num_start_ranges == 2); + REQUIRE(msg.num_end_ranges == 2); + REQUIRE(msg.color_ranges_start[0] == 0); + REQUIRE(msg.color_ranges_start[1] == 0); + REQUIRE(msg.color_ranges_end[0] == 0); + REQUIRE(msg.color_ranges_end[1] == 0); } TEST_CASE("color multi-range test2", "[pattern_formatter]") @@ -164,12 +164,12 @@ TEST_CASE("color multi-range test2", "[pattern_formatter]") spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored"); memory_buf_t formatted; formatter->format(msg, formatted); - REQUIRE(msg.color_range_start.size() == 2); - REQUIRE(msg.color_range_end.size() == 2); - REQUIRE(msg.color_range_start[0] == 0); - REQUIRE(msg.color_range_start[1] == 6); - REQUIRE(msg.color_range_end[0] == 3); - REQUIRE(msg.color_range_end[1] == 9); + REQUIRE(msg.num_start_ranges == 2); + REQUIRE(msg.num_end_ranges == 2); + REQUIRE(msg.color_ranges_start[0] == 0); + REQUIRE(msg.color_ranges_start[1] == 6); + REQUIRE(msg.color_ranges_end[0] == 3); + REQUIRE(msg.color_ranges_end[1] == 9); } // diff --git a/tests/test_stdout_api.cpp b/tests/test_stdout_api.cpp index 449bb4d5..b0c19a87 100644 --- a/tests/test_stdout_api.cpp +++ b/tests/test_stdout_api.cpp @@ -90,6 +90,17 @@ TEST_CASE("stderr_multi_color_range", "[stderr]") spdlog::drop_all(); } +TEST_CASE("stderr_no_color_range", "[stderr]") +{ + auto l = spdlog::stderr_color_mt("test"); + l->set_pattern("No Color Ranges -- %v"); + l->info("uncolored text"); + l->warn("uncolored text"); + l->error("uncolored text"); + l->critical("uncolored text"); + spdlog::drop_all(); +} + #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT TEST_CASE("wchar_api", "[stdout]")