diff --git a/bench/formatter-bench.cpp b/bench/formatter-bench.cpp index b2cc0dcf..d6756216 100644 --- a/bench/formatter-bench.cpp +++ b/bench/formatter-bench.cpp @@ -15,7 +15,8 @@ void bench_formatter(benchmark::State &state, std::string pattern) std::string logger_name = "logger-name"; const char *text = "Hello. This is some message with length of 80 "; - spdlog::details::log_msg msg(logger_name, spdlog::level::info, text); + spdlog::source_loc source_loc{"a/b/c/d/myfile.cpp", 123, "some_func()"}; + spdlog::details::log_msg msg(source_loc, logger_name, spdlog::level::info, text); for (auto _ : state) { @@ -28,7 +29,7 @@ void bench_formatter(benchmark::State &state, std::string pattern) void bench_formatters() { // basic patterns(single flag) - std::string all_flags = "+vtPnlLaAbBcCYDmdHIMSefFprRTXzEi%"; + std::string all_flags = "+vtPnlLaAbBcCYDmdHIMSefFprRTXzEisg@l%"; std::vector basic_patterns; for (auto &flag : all_flags) { diff --git a/include/spdlog/common.h b/include/spdlog/common.h index fdd887b7..82f1629b 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -53,19 +53,6 @@ #endif #endif -// Get the basename of __FILE__ (at compile time if possible) -#if FMT_HAS_FEATURE(__builtin_strrchr) -#define SPDLOG_STRRCHR(str, sep) __builtin_strrchr(str, sep) -#else -#define SPDLOG_STRRCHR(str, sep) strrchr(str, sep) -#endif //__builtin_strrchr not defined - -#ifdef _WIN32 -#define SPDLOG_FILE_BASENAME(file) SPDLOG_STRRCHR("\\" file, '\\') + 1 -#else -#define SPDLOG_FILE_BASENAME(file) SPDLOG_STRRCHR("/" file, '/') + 1 -#endif - #ifndef SPDLOG_FUNCTION #define SPDLOG_FUNCTION __FUNCTION__ #endif diff --git a/include/spdlog/details/pattern_formatter-inl.h b/include/spdlog/details/pattern_formatter-inl.h index 99964030..6124c946 100644 --- a/include/spdlog/details/pattern_formatter-inl.h +++ b/include/spdlog/details/pattern_formatter-inl.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -820,6 +821,31 @@ public: } }; +class short_filename_formatter final : public flag_formatter +{ +public: + explicit short_filename_formatter(padding_info padinfo) + : flag_formatter(padinfo) + {} + + static const char* basename(const char* filename) + { + const char *rv = std::strrchr(filename, os::folder_sep); + return rv != nullptr ? rv + 1: filename; + } + + void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override + { + if (msg.source.empty()) + { + return; + } + auto filename = basename(msg.source.filename); + scoped_pad p(filename, padinfo_, dest); + fmt_helper::append_string_view(filename, dest); + } +}; + class source_linenum_formatter final : public flag_formatter { public: @@ -944,7 +970,8 @@ public: if (!msg.source.empty()) { dest.push_back('['); - fmt_helper::append_string_view(msg.source.filename, dest); + const char *filename = details::short_filename_formatter::basename(msg.source.filename); + fmt_helper::append_string_view(filename, dest); dest.push_back(':'); fmt_helper::append_int(msg.source.line, dest); dest.push_back(']'); @@ -1154,7 +1181,11 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i formatters_.push_back(details::make_unique(padding)); break; - case ('s'): // source filename + case ('s'): // short source filename - without directory name + formatters_.push_back(details::make_unique(padding)); + break; + + case ('g'): // full source filename formatters_.push_back(details::make_unique(padding)); break; diff --git a/include/spdlog/spdlog.h b/include/spdlog/spdlog.h index fa4c9649..d3dd2af1 100644 --- a/include/spdlog/spdlog.h +++ b/include/spdlog/spdlog.h @@ -267,7 +267,7 @@ inline void critical(const wchar_t *fmt, const Args &... args) do \ { \ if (logger->should_log(level)) \ - logger->log(spdlog::source_loc{SPDLOG_FILE_BASENAME(__FILE__), __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__); \ + logger->log(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__); \ } while (0) #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE diff --git a/tests/test_pattern_formatter.cpp b/tests/test_pattern_formatter.cpp index 43d2e547..c661db28 100644 --- a/tests/test_pattern_formatter.cpp +++ b/tests/test_pattern_formatter.cpp @@ -253,3 +253,52 @@ TEST_CASE("clone-formatter-2", "[pattern_formatter]") formatter_2->format(msg, formatted_2); REQUIRE(fmt::to_string(formatted_1) == fmt::to_string(formatted_2)); } + +// +// Test source location formatting +// + +TEST_CASE("short filename formatter-1", "[pattern_formatter]") +{ + spdlog::pattern_formatter formatter("%s", spdlog::pattern_time_type::local, ""); + fmt::memory_buffer formatted; + std::string logger_name = "logger-name"; + spdlog::source_loc source_loc{"/a/b/c/d/myfile.cpp", 123, "some_func()"}; + spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello"); + formatter.format(msg, formatted); + REQUIRE(fmt::to_string(formatted) == "myfile.cpp"); +} + +TEST_CASE("short filename formatter-2", "[pattern_formatter]") +{ + spdlog::pattern_formatter formatter("%s:%#", spdlog::pattern_time_type::local, ""); + fmt::memory_buffer formatted; + std::string logger_name = "logger-name"; + spdlog::source_loc source_loc{"myfile.cpp", 123, "some_func()"}; + spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello"); + formatter.format(msg, formatted); + REQUIRE(fmt::to_string(formatted) == "myfile.cpp:123"); +} + +TEST_CASE("short filename formatter-3", "[pattern_formatter]") +{ + spdlog::pattern_formatter formatter("%s %v", spdlog::pattern_time_type::local, ""); + fmt::memory_buffer formatted; + std::string logger_name = "logger-name"; + spdlog::source_loc source_loc{"", 123, "some_func()"}; + spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello"); + formatter.format(msg, formatted); + REQUIRE(fmt::to_string(formatted) == " Hello"); +} + +TEST_CASE("full filename formatter", "[pattern_formatter]") +{ + spdlog::pattern_formatter formatter("%g:%#", spdlog::pattern_time_type::local, ""); + fmt::memory_buffer formatted; + std::string logger_name = "logger-name"; + spdlog::source_loc source_loc{"/a/b/c/d/myfile.cpp", 123, "some_func()"}; + spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello"); + formatter.format(msg, formatted); + REQUIRE(fmt::to_string(formatted) == "/a/b/c/d/myfile.cpp:123"); +} +