diff --git a/include/spdlog/pattern_formatter-inl.h b/include/spdlog/pattern_formatter-inl.h index e68b91be4..3726a8774 100644 --- a/include/spdlog/pattern_formatter-inl.h +++ b/include/spdlog/pattern_formatter-inl.h @@ -1246,9 +1246,24 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i default: // Unknown flag appears as is auto unknown_flag = details::make_unique(); - unknown_flag->add_ch('%'); - unknown_flag->add_ch(flag); - formatters_.push_back((std::move(unknown_flag))); + + if (!padding.truncate_) + { + unknown_flag->add_ch('%'); + unknown_flag->add_ch(flag); + formatters_.push_back((std::move(unknown_flag))); + } + // fix issue #1617 (prev char was '!' and should have been treated as funcname flag instead of truncating flag) + // spdlog::set_pattern("[%10!] %v") => "[ main] some message" + // spdlog::set_pattern("[%3!!] %v") => "[mai] some message" + else + { + padding.truncate_ = false; + formatters_.push_back(details::make_unique>(padding)); + unknown_flag->add_ch(flag); + formatters_.push_back((std::move(unknown_flag))); + } + break; } } diff --git a/tests/test_pattern_formatter.cpp b/tests/test_pattern_formatter.cpp index 848398fd3..944929298 100644 --- a/tests/test_pattern_formatter.cpp +++ b/tests/test_pattern_formatter.cpp @@ -227,7 +227,7 @@ TEST_CASE("paddinng_truncate", "[pattern_formatter]") REQUIRE(log_to_str("123456", "%0!v", spdlog::pattern_time_type::local, "\n") == "\n"); } -TEST_CASE("paddinng_truncate_funcname", "[pattern_formatter]") +TEST_CASE("padding_truncate_funcname", "[pattern_formatter]") { spdlog::sinks::test_sink_st test_sink; @@ -237,13 +237,28 @@ TEST_CASE("paddinng_truncate_funcname", "[pattern_formatter]") spdlog::details::log_msg msg1{spdlog::source_loc{"ignored", 1, "func"}, "test_logger", spdlog::level::info, "message"}; test_sink.log(msg1); + REQUIRE(test_sink.lines()[0] == "message [ func]"); spdlog::details::log_msg msg2{spdlog::source_loc{"ignored", 1, "function"}, "test_logger", spdlog::level::info, "message"}; test_sink.log(msg2); + REQUIRE(test_sink.lines()[1] == "message [funct]"); +} + +TEST_CASE("padding_funcname", "[pattern_formatter]") +{ + spdlog::sinks::test_sink_st test_sink; - auto lines = test_sink.lines(); - REQUIRE(lines[0] == "message [ func]"); - REQUIRE(lines[1] == "message [funct]"); + const char *pattern = "%v [%10!]"; + auto formatter = std::unique_ptr(new spdlog::pattern_formatter(pattern)); + test_sink.set_formatter(std::move(formatter)); + + spdlog::details::log_msg msg1{spdlog::source_loc{"ignored", 1, "func"}, "test_logger", spdlog::level::info, "message"}; + test_sink.log(msg1); + REQUIRE(test_sink.lines()[0] == "message [ func]"); + + spdlog::details::log_msg msg2{spdlog::source_loc{"ignored", 1, "func567890123"}, "test_logger", spdlog::level::info, "message"}; + test_sink.log(msg2); + REQUIRE(test_sink.lines()[1] == "message [func567890123]"); } TEST_CASE("clone-default-formatter", "[pattern_formatter]")