From a453bccff056bf458c06fbdd8b0b0c54b9792be2 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Wed, 6 Jan 2021 03:55:46 -0500 Subject: [PATCH 1/9] Better support for / separators on Windows, improve wchar filename coverage --- appveyor.yml | 14 +++++- include/spdlog/common.h | 5 +- include/spdlog/details/file_helper-inl.h | 2 +- include/spdlog/details/os-inl.h | 13 +---- include/spdlog/details/os.h | 9 +++- include/spdlog/pattern_formatter-inl.h | 26 +++++++++- include/spdlog/tweakme.h | 8 +++ tests/test_create_dir.cpp | 62 ++++++++++++------------ tests/test_daily_logger.cpp | 44 +++++++++++------ tests/test_eventlog.cpp | 6 +-- tests/test_file_helper.cpp | 50 +++++++++---------- tests/test_file_logging.cpp | 30 ++++++------ tests/test_pattern_formatter.cpp | 2 +- tests/utils.cpp | 4 +- 14 files changed, 163 insertions(+), 112 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 3b654760..82c8f276 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,30 +5,42 @@ environment: - GENERATOR: '"Visual Studio 14 2015"' BUILD_TYPE: Debug WCHAR: 'OFF' + WCHAR_FILES: 'OFF' BUILD_SHARED: 'OFF' - GENERATOR: '"Visual Studio 14 2015"' BUILD_TYPE: Release WCHAR: 'ON' + WCHAR_FILES: 'OFF' BUILD_SHARED: 'OFF' - GENERATOR: '"Visual Studio 14 2015 Win64"' BUILD_TYPE: Debug WCHAR: 'ON' + WCHAR_FILES: 'OFF' BUILD_SHARED: 'OFF' - GENERATOR: '"Visual Studio 14 2015 Win64"' BUILD_TYPE: Release WCHAR: 'ON' + WCHAR_FILES: 'OFF' BUILD_SHARED: 'OFF' - GENERATOR: '"Visual Studio 15 2017 Win64"' BUILD_TYPE: Debug WCHAR: 'ON' + WCHAR_FILES: 'OFF' BUILD_SHARED: 'OFF' - GENERATOR: '"Visual Studio 15 2017 Win64"' BUILD_TYPE: Release WCHAR: 'OFF' + WCHAR_FILES: 'OFF' BUILD_SHARED: 'OFF' - GENERATOR: '"Visual Studio 15 2017 Win64"' BUILD_TYPE: Release WCHAR: 'OFF' + WCHAR_FILES: 'OFF' + BUILD_SHARED: 'ON' + - GENERATOR: '"Visual Studio 15 2017 Win64"' + BUILD_TYPE: Release + WCHAR: 'ON' + WCHAR_FILES: 'ON' BUILD_SHARED: 'ON' build_script: - cmd: >- @@ -40,7 +52,7 @@ build_script: set PATH=%PATH%;C:\Program Files\Git\usr\bin - cmake .. -G %GENERATOR% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DSPDLOG_WCHAR_SUPPORT=%WCHAR% -DSPDLOG_BUILD_SHARED=%BUILD_SHARED% -DSPDLOG_BUILD_EXAMPLE=ON -DSPDLOG_BUILD_EXAMPLE_HO=ON -DSPDLOG_BUILD_TESTS=ON -DSPDLOG_BUILD_TESTS_HO=OFF -DSPDLOG_BUILD_WARNINGS=ON + cmake .. -G %GENERATOR% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DSPDLOG_WCHAR_SUPPORT=%WCHAR% -DSPDLOG_WCHAR_FILENAMES=%WCHAR_FILES% -DSPDLOG_BUILD_SHARED=%BUILD_SHARED% -DSPDLOG_BUILD_EXAMPLE=ON -DSPDLOG_BUILD_EXAMPLE_HO=ON -DSPDLOG_BUILD_TESTS=ON -DSPDLOG_BUILD_TESTS_HO=OFF -DSPDLOG_BUILD_WARNINGS=ON cmake --build . --config %BUILD_TYPE% diff --git a/include/spdlog/common.h b/include/spdlog/common.h index 1c39995e..bb251e2f 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -88,7 +88,9 @@ class sink; #if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) using filename_t = std::wstring; -#define SPDLOG_FILENAME_T(s) L##s +// allow macro expansion to occur in SPDLOG_FILENAME_T +#define SPDLOG_FILENAME_T_INNER(s) L##s +#define SPDLOG_FILENAME_T(s) SPDLOG_FILENAME_T_INNER(s) #else using filename_t = std::string; #define SPDLOG_FILENAME_T(s) s @@ -101,6 +103,7 @@ using err_handler = std::function; using string_view_t = fmt::basic_string_view; using wstring_view_t = fmt::basic_string_view; using memory_buf_t = fmt::basic_memory_buffer; +using filename_memory_buf_t = fmt::basic_memory_buffer; #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT #ifndef _WIN32 diff --git a/include/spdlog/details/file_helper-inl.h b/include/spdlog/details/file_helper-inl.h index 7cb00f2f..2c761386 100644 --- a/include/spdlog/details/file_helper-inl.h +++ b/include/spdlog/details/file_helper-inl.h @@ -118,7 +118,7 @@ SPDLOG_INLINE std::tuple file_helper::split_by_extension } // treat cases like "/etc/rc.d/somelogfile or "/abc/.hiddenfile" - auto folder_index = fname.rfind(details::os::folder_sep); + auto folder_index = fname.find_last_of(details::os::folder_seps_filename); if (folder_index != filename_t::npos && folder_index >= ext_index - 1) { return std::make_tuple(fname, filename_t()); diff --git a/include/spdlog/details/os-inl.h b/include/spdlog/details/os-inl.h index 1133277d..20e6ffa3 100644 --- a/include/spdlog/details/os-inl.h +++ b/include/spdlog/details/os-inl.h @@ -533,15 +533,10 @@ SPDLOG_INLINE bool create_dir(filename_t path) return false; } -#ifdef _WIN32 - // support forward slash in windows - std::replace(path.begin(), path.end(), '/', folder_sep); -#endif - size_t search_offset = 0; do { - auto token_pos = path.find(folder_sep, search_offset); + auto token_pos = path.find_first_of(folder_seps_filename, search_offset); // treat the entire path as a folder if no folder separator not found if (token_pos == filename_t::npos) { @@ -567,11 +562,7 @@ SPDLOG_INLINE bool create_dir(filename_t path) // "abc///" => "abc//" SPDLOG_INLINE filename_t dir_name(filename_t path) { -#ifdef _WIN32 - // support forward slash in windows - std::replace(path.begin(), path.end(), '/', folder_sep); -#endif - auto pos = path.find_last_of(folder_sep); + auto pos = path.find_last_of(folder_seps_filename); return pos != filename_t::npos ? path.substr(0, pos) : filename_t{}; } diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index 88f13dbe..0c03aed4 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -32,11 +32,16 @@ SPDLOG_API std::tm gmtime() SPDLOG_NOEXCEPT; SPDLOG_CONSTEXPR static const char *default_eol = SPDLOG_EOL; // folder separator +#if !defined(SPDLOG_FOLDER_SEPS) #ifdef _WIN32 -static const char folder_sep = '\\'; +#define SPDLOG_FOLDER_SEPS "\\/" #else -SPDLOG_CONSTEXPR static const char folder_sep = '/'; +#define SPDLOG_FOLDER_SEPS "/" #endif +#endif + +SPDLOG_CONSTEXPR static const char folder_seps[] = SPDLOG_FOLDER_SEPS; +SPDLOG_CONSTEXPR static const filename_t::value_type folder_seps_filename[] = SPDLOG_FILENAME_T(SPDLOG_FOLDER_SEPS); // fopen_s on non windows for writing SPDLOG_API bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode); diff --git a/include/spdlog/pattern_formatter-inl.h b/include/spdlog/pattern_formatter-inl.h index 5a1c5eaf..1408bb5c 100644 --- a/include/spdlog/pattern_formatter-inl.h +++ b/include/spdlog/pattern_formatter-inl.h @@ -13,11 +13,13 @@ #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -814,11 +816,31 @@ public: : flag_formatter(padinfo) {} +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4127) // consider using 'if constexpr' instead +#endif // _MSC_VER static const char *basename(const char *filename) { - const char *rv = std::strrchr(filename, os::folder_sep); - return rv != nullptr ? rv + 1 : filename; + // if the size is 2 (1 character + null terminator) we can use the more efficient strrchr + // the branch will be elided by optimizations + if (sizeof(os::folder_seps) == 2) + { + const char *rv = std::strrchr(filename, os::folder_seps[0]); + return rv != nullptr ? rv + 1 : filename; + } + else + { + const std::reverse_iterator begin(filename + std::strlen(filename)); + const std::reverse_iterator end(filename); + + const auto it = std::find_first_of(begin, end, std::begin(os::folder_seps), std::end(os::folder_seps) - 1); + return it != end ? it.base() : filename; + } } +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override { diff --git a/include/spdlog/tweakme.h b/include/spdlog/tweakme.h index 244bc3b3..31e417ab 100644 --- a/include/spdlog/tweakme.h +++ b/include/spdlog/tweakme.h @@ -58,6 +58,14 @@ // #define SPDLOG_EOL ";-)\n" /////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// Uncomment to override default folder separators ("/" or "\\/" under +// Linux/Windows). Each character in the string is treated as a different +// separator. +// +// #define SPDLOG_FOLDER_SEPS "\\" +/////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////// // Uncomment to use your own copy of the fmt library instead of spdlog's copy. // In this case spdlog will try to include so set your -I flag diff --git a/tests/test_create_dir.cpp b/tests/test_create_dir.cpp index b538e80e..8d5161bd 100644 --- a/tests/test_create_dir.cpp +++ b/tests/test_create_dir.cpp @@ -6,7 +6,7 @@ using spdlog::details::os::create_dir; using spdlog::details::os::path_exists; -bool try_create_dir(const char *path, const char *normalized_path) +bool try_create_dir(const spdlog::filename_t &path, const spdlog::filename_t &normalized_path) { auto rv = create_dir(path); REQUIRE(rv == true); @@ -17,24 +17,24 @@ TEST_CASE("create_dir", "[create_dir]") { prepare_logdir(); - REQUIRE(try_create_dir("test_logs/dir1/dir1", "test_logs/dir1/dir1")); - REQUIRE(try_create_dir("test_logs/dir1/dir1", "test_logs/dir1/dir1")); // test existing - REQUIRE(try_create_dir("test_logs/dir1///dir2//", "test_logs/dir1/dir2")); - REQUIRE(try_create_dir("./test_logs/dir1/dir3", "test_logs/dir1/dir3")); - REQUIRE(try_create_dir("test_logs/../test_logs/dir1/dir4", "test_logs/dir1/dir4")); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/dir1/dir1"), SPDLOG_FILENAME_T("test_logs/dir1/dir1"))); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/dir1/dir1"), SPDLOG_FILENAME_T("test_logs/dir1/dir1"))); // test existing + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/dir1///dir2//"), SPDLOG_FILENAME_T("test_logs/dir1/dir2"))); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("./test_logs/dir1/dir3"), SPDLOG_FILENAME_T("test_logs/dir1/dir3"))); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/../test_logs/dir1/dir4"), SPDLOG_FILENAME_T("test_logs/dir1/dir4"))); #ifdef WIN32 // test backslash folder separator - REQUIRE(try_create_dir("test_logs\\dir1\\dir222", "test_logs\\dir1\\dir222")); - REQUIRE(try_create_dir("test_logs\\dir1\\dir223\\", "test_logs\\dir1\\dir223\\")); - REQUIRE(try_create_dir(".\\test_logs\\dir1\\dir2\\dir99\\..\\dir23", "test_logs\\dir1\\dir2\\dir23")); - REQUIRE(try_create_dir("test_logs\\..\\test_logs\\dir1\\dir5", "test_logs\\dir1\\dir5")); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs\\dir1\\dir222"), SPDLOG_FILENAME_T("test_logs\\dir1\\dir222"))); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs\\dir1\\dir223\\"), SPDLOG_FILENAME_T("test_logs\\dir1\\dir223\\"))); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T(".\\test_logs\\dir1\\dir2\\dir99\\..\\dir23"), SPDLOG_FILENAME_T("test_logs\\dir1\\dir2\\dir23"))); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs\\..\\test_logs\\dir1\\dir5"), SPDLOG_FILENAME_T("test_logs\\dir1\\dir5"))); #endif } TEST_CASE("create_invalid_dir", "[create_dir]") { - REQUIRE(create_dir("") == false); + REQUIRE(create_dir(SPDLOG_FILENAME_T("")) == false); REQUIRE(create_dir(spdlog::filename_t{}) == false); #ifdef __linux__ REQUIRE(create_dir("/proc/spdlog-utest") == false); @@ -44,28 +44,28 @@ TEST_CASE("create_invalid_dir", "[create_dir]") TEST_CASE("dir_name", "[create_dir]") { using spdlog::details::os::dir_name; - REQUIRE(dir_name("").empty()); - REQUIRE(dir_name("dir").empty()); + REQUIRE(dir_name(SPDLOG_FILENAME_T("")).empty()); + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir")).empty()); #ifdef WIN32 - REQUIRE(dir_name(R"(dir\)") == "dir"); - REQUIRE(dir_name(R"(dir\\\)") == R"(dir\\)"); - REQUIRE(dir_name(R"(dir\file)") == "dir"); - REQUIRE(dir_name(R"(dir/file)") == "dir"); - REQUIRE(dir_name(R"(dir\file.txt)") == "dir"); - REQUIRE(dir_name(R"(dir/file)") == "dir"); - REQUIRE(dir_name(R"(dir\file.txt\)") == R"(dir\file.txt)"); - REQUIRE(dir_name(R"(dir/file.txt/)") == R"(dir\file.txt)"); - REQUIRE(dir_name(R"(\dir\file.txt)") == R"(\dir)"); - REQUIRE(dir_name(R"(/dir/file.txt)") == R"(\dir)"); - REQUIRE(dir_name(R"(\\dir\file.txt)") == R"(\\dir)"); - REQUIRE(dir_name(R"(//dir/file.txt)") == R"(\\dir)"); - REQUIRE(dir_name(R"(..\file.txt)") == ".."); - REQUIRE(dir_name(R"(../file.txt)") == ".."); - REQUIRE(dir_name(R"(.\file.txt)") == "."); - REQUIRE(dir_name(R"(./file.txt)") == "."); - REQUIRE(dir_name(R"(c:\\a\b\c\d\file.txt)") == R"(c:\\a\b\c\d)"); - REQUIRE(dir_name(R"(c://a/b/c/d/file.txt)") == R"(c:\\a\b\c\d)"); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\)")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\\\)")) == SPDLOG_FILENAME_T(R"(dir\\)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\file)")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir/file)")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\file.txt)")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir/file)")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\file.txt\)")) == SPDLOG_FILENAME_T(R"(dir\file.txt)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir/file.txt/)")) == SPDLOG_FILENAME_T(R"(dir\file.txt)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(\dir\file.txt)")) == SPDLOG_FILENAME_T(R"(\dir)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(/dir/file.txt)")) == SPDLOG_FILENAME_T(R"(\dir)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(\\dir\file.txt)")) == SPDLOG_FILENAME_T(R"(\\dir)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(//dir/file.txt)")) == SPDLOG_FILENAME_T(R"(\\dir)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(..\file.txt)")) == SPDLOG_FILENAME_T("..")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(../file.txt)")) == SPDLOG_FILENAME_T("..")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(.\file.txt)")) == SPDLOG_FILENAME_T(".")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(./file.txt)")) == SPDLOG_FILENAME_T(".")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(c:\\a\b\c\d\file.txt)")) == SPDLOG_FILENAME_T(R"(c:\\a\b\c\d)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(c://a/b/c/d/file.txt)")) == SPDLOG_FILENAME_T(R"(c:\\a\b\c\d)")); #else REQUIRE(dir_name("dir/") == "dir"); REQUIRE(dir_name("dir///") == "dir//"); diff --git a/tests/test_daily_logger.cpp b/tests/test_daily_logger.cpp index a3e70e68..c66f283d 100644 --- a/tests/test_daily_logger.cpp +++ b/tests/test_daily_logger.cpp @@ -10,10 +10,10 @@ TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]") prepare_logdir(); // calculate filename (time based) - std::string basename = "test_logs/daily_dateonly"; + spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_dateonly"); std::tm tm = spdlog::details::os::localtime(); - spdlog::memory_buf_t w; - fmt::format_to(w, "{}_{:04d}-{:02d}-{:02d}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); + spdlog::filename_memory_buf_t w; + fmt::format_to(w, SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); auto logger = spdlog::create("logger", basename, 0, 0); for (int i = 0; i < 10; ++i) @@ -23,7 +23,13 @@ TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]") } logger->flush(); +#ifdef SPDLOG_WCHAR_FILENAMES + spdlog::memory_buf_t buf; + spdlog::details::os::wstr_to_utf8buf(fmt::to_string(w)); + auto filename = fmt::to_string(buf); +#else auto filename = fmt::to_string(w); +#endif require_message_count(filename, 10); } @@ -31,8 +37,8 @@ struct custom_daily_file_name_calculator { static spdlog::filename_t calc_filename(const spdlog::filename_t &basename, const tm &now_tm) { - spdlog::memory_buf_t w; - fmt::format_to(w, "{}{:04d}{:02d}{:02d}", basename, now_tm.tm_year + 1900, now_tm.tm_mon + 1, now_tm.tm_mday); + spdlog::filename_memory_buf_t w; + fmt::format_to(w, SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"), basename, now_tm.tm_year + 1900, now_tm.tm_mon + 1, now_tm.tm_mday); return fmt::to_string(w); } }; @@ -44,7 +50,7 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger]") prepare_logdir(); // calculate filename (time based) - std::string basename = "test_logs/daily_dateonly"; + spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_dateonly"); std::tm tm = spdlog::details::os::localtime(); spdlog::memory_buf_t w; fmt::format_to(w, "{}{:04d}{:02d}{:02d}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); @@ -57,7 +63,13 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger]") logger->flush(); +#ifdef SPDLOG_WCHAR_FILENAMES + spdlog::memory_buf_t buf; + spdlog::details::os::wstr_to_utf8buf(fmt::to_string(w)); + auto filename = fmt::to_string(buf); +#else auto filename = fmt::to_string(w); +#endif require_message_count(filename, 10); } @@ -67,20 +79,20 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger]") TEST_CASE("rotating_file_sink::calc_filename1", "[rotating_file_sink]]") { - auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename("rotated.txt", 3); - REQUIRE(filename == "rotated.3.txt"); + auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename(SPDLOG_FILENAME_T("rotated.txt"), 3); + REQUIRE(filename == SPDLOG_FILENAME_T("rotated.3.txt")); } TEST_CASE("rotating_file_sink::calc_filename2", "[rotating_file_sink]]") { - auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename("rotated", 3); - REQUIRE(filename == "rotated.3"); + auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename(SPDLOG_FILENAME_T("rotated"), 3); + REQUIRE(filename == SPDLOG_FILENAME_T("rotated.3")); } TEST_CASE("rotating_file_sink::calc_filename3", "[rotating_file_sink]]") { - auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename("rotated.txt", 0); - REQUIRE(filename == "rotated.txt"); + auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename(SPDLOG_FILENAME_T("rotated.txt"), 0); + REQUIRE(filename == SPDLOG_FILENAME_T("rotated.txt")); } // regex supported only from gcc 4.9 and above @@ -91,10 +103,10 @@ TEST_CASE("rotating_file_sink::calc_filename3", "[rotating_file_sink]]") TEST_CASE("daily_file_sink::daily_filename_calculator", "[daily_file_sink]]") { // daily_YYYY-MM-DD_hh-mm.txt - auto filename = spdlog::sinks::daily_filename_calculator::calc_filename("daily.txt", spdlog::details::os::localtime()); + auto filename = spdlog::sinks::daily_filename_calculator::calc_filename(SPDLOG_FILENAME_T("daily.txt"), spdlog::details::os::localtime()); // date regex based on https://www.regular-expressions.info/dates.html - std::regex re(R"(^daily_(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])\.txt$)"); - std::smatch match; + std::basic_regex re(SPDLOG_FILENAME_T(R"(^daily_(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])\.txt$)")); + std::match_results match; REQUIRE(std::regex_match(filename, match, re)); } #endif @@ -116,7 +128,7 @@ static void test_rotate(int days_to_run, uint16_t max_days, uint16_t expected_n_ prepare_logdir(); - std::string basename = "test_logs/daily_rotate.txt"; + spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_rotate.txt"); daily_file_sink_st sink{basename, 2, 30, true, max_days}; // simulate messages with 24 intervals diff --git a/tests/test_eventlog.cpp b/tests/test_eventlog.cpp index ea6b7942..e9205258 100644 --- a/tests/test_eventlog.cpp +++ b/tests/test_eventlog.cpp @@ -24,20 +24,20 @@ static void test_single_print(std::function do_log, s REQUIRE(CloseEventLog(handle_)); } } - } event_log{::OpenEventLog(nullptr, TEST_SOURCE)}; + } event_log{::OpenEventLogA(nullptr, TEST_SOURCE)}; REQUIRE(event_log.handle_); DWORD read_bytes{}, size_needed{}; auto ok = - ::ReadEventLog(event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0, &read_bytes, 0, &read_bytes, &size_needed); + ::ReadEventLogA(event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0, &read_bytes, 0, &read_bytes, &size_needed); REQUIRE(!ok); REQUIRE(::GetLastError() == ERROR_INSUFFICIENT_BUFFER); std::vector record_buffer(size_needed); PEVENTLOGRECORD record = (PEVENTLOGRECORD)record_buffer.data(); - ok = ::ReadEventLog( + ok = ::ReadEventLogA( event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0, record, size_needed, &read_bytes, &size_needed); REQUIRE(ok); diff --git a/tests/test_file_helper.cpp b/tests/test_file_helper.cpp index 061f125f..937cf0e9 100644 --- a/tests/test_file_helper.cpp +++ b/tests/test_file_helper.cpp @@ -18,7 +18,7 @@ TEST_CASE("file_helper_filename", "[file_helper::filename()]]") prepare_logdir(); file_helper helper; - std::string target_filename = "test_logs/file_helper_test.txt"; + spdlog::filename_t target_filename = SPDLOG_FILENAME_T("test_logs/file_helper_test.txt"); helper.open(target_filename); REQUIRE(helper.filename() == target_filename); } @@ -26,7 +26,7 @@ TEST_CASE("file_helper_filename", "[file_helper::filename()]]") TEST_CASE("file_helper_size", "[file_helper::size()]]") { prepare_logdir(); - std::string target_filename = "test_logs/file_helper_test.txt"; + spdlog::filename_t target_filename = SPDLOG_FILENAME_T("test_logs/file_helper_test.txt"); size_t expected_size = 123; { file_helper helper; @@ -40,7 +40,7 @@ TEST_CASE("file_helper_size", "[file_helper::size()]]") TEST_CASE("file_helper_reopen", "[file_helper::reopen()]]") { prepare_logdir(); - std::string target_filename = "test_logs/file_helper_test.txt"; + spdlog::filename_t target_filename = SPDLOG_FILENAME_T("test_logs/file_helper_test.txt"); file_helper helper; helper.open(target_filename); write_with_helper(helper, 12); @@ -52,7 +52,7 @@ TEST_CASE("file_helper_reopen", "[file_helper::reopen()]]") TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]]") { prepare_logdir(); - std::string target_filename = "test_logs/file_helper_test.txt"; + spdlog::filename_t target_filename = SPDLOG_FILENAME_T("test_logs/file_helper_test.txt"); size_t expected_size = 14; file_helper helper; helper.open(target_filename); @@ -62,16 +62,12 @@ TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]]") REQUIRE(helper.size() == expected_size); } -static void test_split_ext(const char *fname, const char *expect_base, const char *expect_ext) +static void test_split_ext(const spdlog::filename_t::value_type *fname, const spdlog::filename_t::value_type *expect_base, const spdlog::filename_t::value_type *expect_ext) { spdlog::filename_t filename(fname); spdlog::filename_t expected_base(expect_base); spdlog::filename_t expected_ext(expect_ext); -#ifdef _WIN32 // replace folder sep - std::replace(filename.begin(), filename.end(), '/', '\\'); - std::replace(expected_base.begin(), expected_base.end(), '/', '\\'); -#endif spdlog::filename_t basename; spdlog::filename_t ext; std::tie(basename, ext) = file_helper::split_by_extension(filename); @@ -81,22 +77,22 @@ static void test_split_ext(const char *fname, const char *expect_base, const cha TEST_CASE("file_helper_split_by_extension", "[file_helper::split_by_extension()]]") { - test_split_ext("mylog.txt", "mylog", ".txt"); - test_split_ext(".mylog.txt", ".mylog", ".txt"); - test_split_ext(".mylog", ".mylog", ""); - test_split_ext("/aaa/bb.d/mylog", "/aaa/bb.d/mylog", ""); - test_split_ext("/aaa/bb.d/mylog.txt", "/aaa/bb.d/mylog", ".txt"); - test_split_ext("aaa/bbb/ccc/mylog.txt", "aaa/bbb/ccc/mylog", ".txt"); - test_split_ext("aaa/bbb/ccc/mylog.", "aaa/bbb/ccc/mylog.", ""); - test_split_ext("aaa/bbb/ccc/.mylog.txt", "aaa/bbb/ccc/.mylog", ".txt"); - test_split_ext("/aaa/bbb/ccc/mylog.txt", "/aaa/bbb/ccc/mylog", ".txt"); - test_split_ext("/aaa/bbb/ccc/.mylog", "/aaa/bbb/ccc/.mylog", ""); - test_split_ext("../mylog.txt", "../mylog", ".txt"); - test_split_ext(".././mylog.txt", ".././mylog", ".txt"); - test_split_ext(".././mylog.txt/xxx", ".././mylog.txt/xxx", ""); - test_split_ext("/mylog.txt", "/mylog", ".txt"); - test_split_ext("//mylog.txt", "//mylog", ".txt"); - test_split_ext("", "", ""); - test_split_ext(".", ".", ""); - test_split_ext("..txt", ".", ".txt"); + test_split_ext(SPDLOG_FILENAME_T("mylog.txt"), SPDLOG_FILENAME_T("mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T(".mylog.txt"), SPDLOG_FILENAME_T(".mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T(".mylog"), SPDLOG_FILENAME_T(".mylog"), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("/aaa/bb.d/mylog"), SPDLOG_FILENAME_T("/aaa/bb.d/mylog"), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("/aaa/bb.d/mylog.txt"), SPDLOG_FILENAME_T("/aaa/bb.d/mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog.txt"), SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog."), SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog."), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("aaa/bbb/ccc/.mylog.txt"), SPDLOG_FILENAME_T("aaa/bbb/ccc/.mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T("/aaa/bbb/ccc/mylog.txt"), SPDLOG_FILENAME_T("/aaa/bbb/ccc/mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T("/aaa/bbb/ccc/.mylog"), SPDLOG_FILENAME_T("/aaa/bbb/ccc/.mylog"), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("../mylog.txt"), SPDLOG_FILENAME_T("../mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T(".././mylog.txt"), SPDLOG_FILENAME_T(".././mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T(".././mylog.txt/xxx"), SPDLOG_FILENAME_T(".././mylog.txt/xxx"), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("/mylog.txt"), SPDLOG_FILENAME_T("/mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T("//mylog.txt"), SPDLOG_FILENAME_T("//mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T(""), SPDLOG_FILENAME_T(""), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("."), SPDLOG_FILENAME_T("."), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("..txt"), SPDLOG_FILENAME_T("."), SPDLOG_FILENAME_T(".txt")); } diff --git a/tests/test_file_logging.cpp b/tests/test_file_logging.cpp index 394b4bb2..eab524dc 100644 --- a/tests/test_file_logging.cpp +++ b/tests/test_file_logging.cpp @@ -3,10 +3,13 @@ */ #include "includes.h" +#define SIMPLE_LOG "test_logs/simple_log" +#define ROTATING_LOG "test_logs/rotating_log" + TEST_CASE("simple_file_logger", "[simple_logger]]") { prepare_logdir(); - std::string filename = "test_logs/simple_log"; + spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); auto logger = spdlog::create("logger", filename); logger->set_pattern("%v"); @@ -15,29 +18,29 @@ TEST_CASE("simple_file_logger", "[simple_logger]]") logger->info("Test message {}", 2); logger->flush(); - require_message_count(filename, 2); + require_message_count(SIMPLE_LOG, 2); using spdlog::details::os::default_eol; - REQUIRE(file_contents(filename) == fmt::format("Test message 1{}Test message 2{}", default_eol, default_eol)); + REQUIRE(file_contents(SIMPLE_LOG) == fmt::format("Test message 1{}Test message 2{}", default_eol, default_eol)); } TEST_CASE("flush_on", "[flush_on]]") { prepare_logdir(); - std::string filename = "test_logs/simple_log"; + spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); auto logger = spdlog::create("logger", filename); logger->set_pattern("%v"); logger->set_level(spdlog::level::trace); logger->flush_on(spdlog::level::info); logger->trace("Should not be flushed"); - REQUIRE(count_lines(filename) == 0); + REQUIRE(count_lines(SIMPLE_LOG) == 0); logger->info("Test message {}", 1); logger->info("Test message {}", 2); - require_message_count(filename, 3); + require_message_count(SIMPLE_LOG, 3); using spdlog::details::os::default_eol; - REQUIRE(file_contents(filename) == + REQUIRE(file_contents(SIMPLE_LOG) == fmt::format("Should not be flushed{}Test message 1{}Test message 2{}", default_eol, default_eol, default_eol)); } @@ -45,7 +48,7 @@ TEST_CASE("rotating_file_logger1", "[rotating_logger]]") { prepare_logdir(); size_t max_size = 1024 * 10; - std::string basename = "test_logs/rotating_log"; + spdlog::filename_t basename = SPDLOG_FILENAME_T(ROTATING_LOG); auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 0); for (int i = 0; i < 10; ++i) @@ -54,14 +57,14 @@ TEST_CASE("rotating_file_logger1", "[rotating_logger]]") } logger->flush(); - require_message_count(basename, 10); + require_message_count(ROTATING_LOG, 10); } TEST_CASE("rotating_file_logger2", "[rotating_logger]]") { prepare_logdir(); size_t max_size = 1024 * 10; - std::string basename = "test_logs/rotating_log"; + spdlog::filename_t basename = SPDLOG_FILENAME_T(ROTATING_LOG); { // make an initial logger to create the first output file @@ -83,7 +86,7 @@ TEST_CASE("rotating_file_logger2", "[rotating_logger]]") logger->flush(); - require_message_count(basename, 10); + require_message_count(ROTATING_LOG, 10); for (int i = 0; i < 1000; i++) { @@ -92,7 +95,6 @@ TEST_CASE("rotating_file_logger2", "[rotating_logger]]") } logger->flush(); - REQUIRE(get_filesize(basename) <= max_size); - auto filename1 = basename + ".1"; - REQUIRE(get_filesize(filename1) <= max_size); + REQUIRE(get_filesize(ROTATING_LOG) <= max_size); + REQUIRE(get_filesize(ROTATING_LOG ".1") <= max_size); } diff --git a/tests/test_pattern_formatter.cpp b/tests/test_pattern_formatter.cpp index 3efe1c44..6d169988 100644 --- a/tests/test_pattern_formatter.cpp +++ b/tests/test_pattern_formatter.cpp @@ -372,7 +372,7 @@ TEST_CASE("clone-custom_formatter", "[pattern_formatter]") // #ifdef _WIN32 -static const char *const test_path = "\\a\\b\\myfile.cpp"; +static const char *const test_path = "\\a\\b\\c/myfile.cpp"; #else static const char *const test_path = "/a/b//myfile.cpp"; #endif diff --git a/tests/utils.cpp b/tests/utils.cpp index 32b7c03f..4735be71 100644 --- a/tests/utils.cpp +++ b/tests/utils.cpp @@ -84,7 +84,7 @@ bool ends_with(std::string const &value, std::string const &ending) std::size_t count_files(const std::string &folder) { size_t counter = 0; - WIN32_FIND_DATA ffd; + WIN32_FIND_DATAA ffd; // Start iterating over the files in the folder directory. HANDLE hFind = ::FindFirstFileA((folder + "\\*").c_str(), &ffd); @@ -94,7 +94,7 @@ std::size_t count_files(const std::string &folder) { if (ffd.cFileName[0] != '.') counter++; - } while (::FindNextFile(hFind, &ffd) != 0); + } while (::FindNextFileA(hFind, &ffd) != 0); ::FindClose(hFind); } else From 19dc30567e933957770d3e5d852e56e86556568e Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Wed, 6 Jan 2021 18:55:57 -0500 Subject: [PATCH 2/9] Fix build errors --- example/example.cpp | 10 +++++----- tests/test_async.cpp | 12 +++++++----- tests/test_daily_logger.cpp | 4 ++-- tests/test_file_helper.cpp | 12 +++++++----- tests/test_macros.cpp | 12 +++++++----- tests/test_registry.cpp | 2 +- 6 files changed, 29 insertions(+), 23 deletions(-) diff --git a/example/example.cpp b/example/example.cpp index 2f27d4a8..1f4ba002 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -109,21 +109,21 @@ void stdout_logger_example() void basic_example() { // Create basic file logger (not rotated). - auto my_logger = spdlog::basic_logger_mt("file_logger", "logs/basic-log.txt"); + auto my_logger = spdlog::basic_logger_mt("file_logger", SPDLOG_FILENAME_T("logs/basic-log.txt")); } #include "spdlog/sinks/rotating_file_sink.h" void rotating_example() { // Create a file rotating logger with 5mb size max and 3 rotated files. - auto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3); + auto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", SPDLOG_FILENAME_T("logs/rotating.txt"), 1048576 * 5, 3); } #include "spdlog/sinks/daily_file_sink.h" void daily_example() { // Create a daily logger - a new file is created every day on 2:30am. - auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30); + auto daily_logger = spdlog::daily_logger_mt("daily_logger", SPDLOG_FILENAME_T("logs/daily.txt"), 2, 30); } #include "spdlog/cfg/env.h" @@ -143,7 +143,7 @@ void async_example() { // Default thread pool settings can be modified *before* creating the async logger: // spdlog::init_thread_pool(32768, 1); // queue with max 32k items 1 backing thread. - auto async_file = spdlog::basic_logger_mt("async_file_logger", "logs/async_log.txt"); + auto async_file = spdlog::basic_logger_mt("async_file_logger", SPDLOG_FILENAME_T("logs/async_log.txt")); // alternatively: // auto async_file = spdlog::create_async("async_file_logger", "logs/async_log.txt"); @@ -211,7 +211,7 @@ void multi_sink_example() console_sink->set_level(spdlog::level::warn); console_sink->set_pattern("[multi_sink_example] [%^%l%$] %v"); - auto file_sink = std::make_shared("logs/multisink.txt", true); + auto file_sink = std::make_shared(SPDLOG_FILENAME_T("logs/multisink.txt"), true); file_sink->set_level(spdlog::level::trace); spdlog::logger logger("multi_sink", {console_sink, file_sink}); diff --git a/tests/test_async.cpp b/tests/test_async.cpp index 49b97ef2..83fc0ec6 100644 --- a/tests/test_async.cpp +++ b/tests/test_async.cpp @@ -3,6 +3,8 @@ #include "spdlog/sinks/basic_file_sink.h" #include "test_sink.h" +#define TEST_FILENAME "test_logs/async_test.log" + TEST_CASE("basic async test ", "[async]") { auto test_sink = std::make_shared(); @@ -149,7 +151,7 @@ TEST_CASE("to_file", "[async]") prepare_logdir(); size_t messages = 1024; size_t tp_threads = 1; - std::string filename = "test_logs/async_test.log"; + spdlog::filename_t filename = SPDLOG_FILENAME_T(TEST_FILENAME); { auto file_sink = std::make_shared(filename, true); auto tp = std::make_shared(messages, tp_threads); @@ -161,8 +163,8 @@ TEST_CASE("to_file", "[async]") } } - require_message_count(filename, messages); - auto contents = file_contents(filename); + require_message_count(TEST_FILENAME, messages); + auto contents = file_contents(TEST_FILENAME); using spdlog::details::os::default_eol; REQUIRE(ends_with(contents, fmt::format("Hello message #1023{}", default_eol))); } @@ -172,7 +174,7 @@ TEST_CASE("to_file multi-workers", "[async]") prepare_logdir(); size_t messages = 1024 * 10; size_t tp_threads = 10; - std::string filename = "test_logs/async_test.log"; + spdlog::filename_t filename = SPDLOG_FILENAME_T(TEST_FILENAME); { auto file_sink = std::make_shared(filename, true); auto tp = std::make_shared(messages, tp_threads); @@ -184,5 +186,5 @@ TEST_CASE("to_file multi-workers", "[async]") } } - require_message_count(filename, messages); + require_message_count(TEST_FILENAME, messages); } diff --git a/tests/test_daily_logger.cpp b/tests/test_daily_logger.cpp index c66f283d..5d24685e 100644 --- a/tests/test_daily_logger.cpp +++ b/tests/test_daily_logger.cpp @@ -25,7 +25,7 @@ TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]") #ifdef SPDLOG_WCHAR_FILENAMES spdlog::memory_buf_t buf; - spdlog::details::os::wstr_to_utf8buf(fmt::to_string(w)); + spdlog::details::os::wstr_to_utf8buf(fmt::to_string(w), buf); auto filename = fmt::to_string(buf); #else auto filename = fmt::to_string(w); @@ -65,7 +65,7 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger]") #ifdef SPDLOG_WCHAR_FILENAMES spdlog::memory_buf_t buf; - spdlog::details::os::wstr_to_utf8buf(fmt::to_string(w)); + spdlog::details::os::wstr_to_utf8buf(fmt::to_string(w), buf); auto filename = fmt::to_string(buf); #else auto filename = fmt::to_string(w); diff --git a/tests/test_file_helper.cpp b/tests/test_file_helper.cpp index 937cf0e9..57f5d8fa 100644 --- a/tests/test_file_helper.cpp +++ b/tests/test_file_helper.cpp @@ -3,6 +3,8 @@ */ #include "includes.h" +#define TEST_FILENAME "test_logs/file_helper_test.txt" + using spdlog::details::file_helper; static void write_with_helper(file_helper &helper, size_t howmany) @@ -18,7 +20,7 @@ TEST_CASE("file_helper_filename", "[file_helper::filename()]]") prepare_logdir(); file_helper helper; - spdlog::filename_t target_filename = SPDLOG_FILENAME_T("test_logs/file_helper_test.txt"); + spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME); helper.open(target_filename); REQUIRE(helper.filename() == target_filename); } @@ -26,7 +28,7 @@ TEST_CASE("file_helper_filename", "[file_helper::filename()]]") TEST_CASE("file_helper_size", "[file_helper::size()]]") { prepare_logdir(); - spdlog::filename_t target_filename = SPDLOG_FILENAME_T("test_logs/file_helper_test.txt"); + spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME); size_t expected_size = 123; { file_helper helper; @@ -34,13 +36,13 @@ TEST_CASE("file_helper_size", "[file_helper::size()]]") write_with_helper(helper, expected_size); REQUIRE(static_cast(helper.size()) == expected_size); } - REQUIRE(get_filesize(target_filename) == expected_size); + REQUIRE(get_filesize(TEST_FILENAME) == expected_size); } TEST_CASE("file_helper_reopen", "[file_helper::reopen()]]") { prepare_logdir(); - spdlog::filename_t target_filename = SPDLOG_FILENAME_T("test_logs/file_helper_test.txt"); + spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME); file_helper helper; helper.open(target_filename); write_with_helper(helper, 12); @@ -52,7 +54,7 @@ TEST_CASE("file_helper_reopen", "[file_helper::reopen()]]") TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]]") { prepare_logdir(); - spdlog::filename_t target_filename = SPDLOG_FILENAME_T("test_logs/file_helper_test.txt"); + spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME); size_t expected_size = 14; file_helper helper; helper.open(target_filename); diff --git a/tests/test_macros.cpp b/tests/test_macros.cpp index 37f5c892..afa66ff3 100644 --- a/tests/test_macros.cpp +++ b/tests/test_macros.cpp @@ -8,11 +8,13 @@ #error "Invalid SPDLOG_ACTIVE_LEVEL in test. Should be SPDLOG_LEVEL_DEBUG" #endif +#define TEST_FILENAME "test_logs/simple_log" + TEST_CASE("debug and trace w/o format string", "[macros]]") { prepare_logdir(); - std::string filename = "test_logs/simple_log"; + spdlog::filename_t filename = SPDLOG_FILENAME_T(TEST_FILENAME); auto logger = spdlog::create("logger", filename); logger->set_pattern("%v"); @@ -23,8 +25,8 @@ TEST_CASE("debug and trace w/o format string", "[macros]]") logger->flush(); using spdlog::details::os::default_eol; - REQUIRE(ends_with(file_contents(filename), fmt::format("Test message 2{}", default_eol))); - REQUIRE(count_lines(filename) == 1); + REQUIRE(ends_with(file_contents(TEST_FILENAME), fmt::format("Test message 2{}", default_eol))); + REQUIRE(count_lines(TEST_FILENAME) == 1); spdlog::set_default_logger(logger); @@ -32,8 +34,8 @@ TEST_CASE("debug and trace w/o format string", "[macros]]") SPDLOG_DEBUG("Test message {}", 4); logger->flush(); - require_message_count(filename, 2); - REQUIRE(ends_with(file_contents(filename), fmt::format("Test message 4{}", default_eol))); + require_message_count(TEST_FILENAME, 2); + REQUIRE(ends_with(file_contents(TEST_FILENAME), fmt::format("Test message 4{}", default_eol))); } TEST_CASE("disable param evaluation", "[macros]") diff --git a/tests/test_registry.cpp b/tests/test_registry.cpp index cd8bab84..8e632cc6 100644 --- a/tests/test_registry.cpp +++ b/tests/test_registry.cpp @@ -103,7 +103,7 @@ TEST_CASE("disable automatic registration", "[registry]") spdlog::set_level(log_level); // but disable automatic registration spdlog::set_automatic_registration(false); - auto logger1 = spdlog::create(tested_logger_name, "filename", 11, 59); + auto logger1 = spdlog::create(tested_logger_name, SPDLOG_FILENAME_T("filename"), 11, 59); auto logger2 = spdlog::create_async(tested_logger_name2); // loggers should not be part of the registry REQUIRE_FALSE(spdlog::get(tested_logger_name)); From c691769e46e49aa03fdabbcec499af0f8ff9d428 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Wed, 6 Jan 2021 19:39:47 -0500 Subject: [PATCH 3/9] Fix other build errors and unit tests --- tests/test_create_dir.cpp | 26 ++++++++++---------------- tests/test_daily_logger.cpp | 4 ++-- tests/test_errors.cpp | 2 +- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/tests/test_create_dir.cpp b/tests/test_create_dir.cpp index 8d5161bd..0bd78bc1 100644 --- a/tests/test_create_dir.cpp +++ b/tests/test_create_dir.cpp @@ -55,26 +55,20 @@ TEST_CASE("dir_name", "[create_dir]") REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\file.txt)")) == SPDLOG_FILENAME_T("dir")); REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir/file)")) == SPDLOG_FILENAME_T("dir")); REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\file.txt\)")) == SPDLOG_FILENAME_T(R"(dir\file.txt)")); - REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir/file.txt/)")) == SPDLOG_FILENAME_T(R"(dir\file.txt)")); REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(\dir\file.txt)")) == SPDLOG_FILENAME_T(R"(\dir)")); - REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(/dir/file.txt)")) == SPDLOG_FILENAME_T(R"(\dir)")); REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(\\dir\file.txt)")) == SPDLOG_FILENAME_T(R"(\\dir)")); - REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(//dir/file.txt)")) == SPDLOG_FILENAME_T(R"(\\dir)")); REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(..\file.txt)")) == SPDLOG_FILENAME_T("..")); - REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(../file.txt)")) == SPDLOG_FILENAME_T("..")); REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(.\file.txt)")) == SPDLOG_FILENAME_T(".")); - REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(./file.txt)")) == SPDLOG_FILENAME_T(".")); REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(c:\\a\b\c\d\file.txt)")) == SPDLOG_FILENAME_T(R"(c:\\a\b\c\d)")); - REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(c://a/b/c/d/file.txt)")) == SPDLOG_FILENAME_T(R"(c:\\a\b\c\d)")); -#else - REQUIRE(dir_name("dir/") == "dir"); - REQUIRE(dir_name("dir///") == "dir//"); - REQUIRE(dir_name("dir/file") == "dir"); - REQUIRE(dir_name("dir/file.txt") == "dir"); - REQUIRE(dir_name("dir/file.txt/") == "dir/file.txt"); - REQUIRE(dir_name("/dir/file.txt") == "/dir"); - REQUIRE(dir_name("//dir/file.txt") == "//dir"); - REQUIRE(dir_name("../file.txt") == ".."); - REQUIRE(dir_name("./file.txt") == "."); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(c://a/b/c/d/file.txt)")) == SPDLOG_FILENAME_T(R"(c://a/b/c/d)")); #endif + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir/")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir///")) == SPDLOG_FILENAME_T("dir//")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir/file")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir/file.txt")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir/file.txt/")) == SPDLOG_FILENAME_T("dir/file.txt")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("/dir/file.txt")) == SPDLOG_FILENAME_T("/dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("//dir/file.txt")) == SPDLOG_FILENAME_T("//dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("../file.txt")) == SPDLOG_FILENAME_T("..")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("./file.txt")) == SPDLOG_FILENAME_T(".")); } diff --git a/tests/test_daily_logger.cpp b/tests/test_daily_logger.cpp index 5d24685e..10e365c5 100644 --- a/tests/test_daily_logger.cpp +++ b/tests/test_daily_logger.cpp @@ -52,8 +52,8 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger]") // calculate filename (time based) spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_dateonly"); std::tm tm = spdlog::details::os::localtime(); - spdlog::memory_buf_t w; - fmt::format_to(w, "{}{:04d}{:02d}{:02d}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); + spdlog::filename_memory_buf_t w; + fmt::format_to(w, SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); auto logger = spdlog::create("logger", basename, 0, 0); for (int i = 0; i < 10; ++i) diff --git a/tests/test_errors.cpp b/tests/test_errors.cpp index d6db535e..10ee929c 100644 --- a/tests/test_errors.cpp +++ b/tests/test_errors.cpp @@ -100,7 +100,7 @@ TEST_CASE("async_error_handler2", "[errors]]") prepare_logdir(); std::string err_msg("This is async handler error message"); { - spdlog::details::os::create_dir("test_logs"); + spdlog::details::os::create_dir(SPDLOG_FILENAME_T("test_logs")); spdlog::init_thread_pool(128, 1); auto logger = spdlog::create_async("failed_logger"); logger->set_error_handler([=](const std::string &) { From f0a4ddd78be3cba6423552eb242cdcd1c9e4e3f2 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Wed, 6 Jan 2021 20:00:59 -0500 Subject: [PATCH 4/9] Fix character issues in test_errors.cpp --- tests/test_errors.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/test_errors.cpp b/tests/test_errors.cpp index 10ee929c..b7673581 100644 --- a/tests/test_errors.cpp +++ b/tests/test_errors.cpp @@ -5,6 +5,9 @@ #include +#define SIMPLE_LOG "test_logs/simple_log.txt" +#define SIMPLE_ASYNC_LOG "test_logs/simple_async_log.txt" + class failing_sink : public spdlog::sinks::base_sink { protected: @@ -22,7 +25,7 @@ protected: TEST_CASE("default_error_handler", "[errors]]") { prepare_logdir(); - std::string filename = "test_logs/simple_log.txt"; + spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); auto logger = spdlog::create("test-error", filename, true); logger->set_pattern("%v"); @@ -31,8 +34,8 @@ TEST_CASE("default_error_handler", "[errors]]") logger->flush(); using spdlog::details::os::default_eol; - REQUIRE(file_contents(filename) == fmt::format("Test message 2{}", default_eol)); - REQUIRE(count_lines(filename) == 1); + REQUIRE(file_contents(SIMPLE_LOG) == fmt::format("Test message 2{}", default_eol)); + REQUIRE(count_lines(SIMPLE_LOG) == 1); } struct custom_ex @@ -40,7 +43,7 @@ struct custom_ex TEST_CASE("custom_error_handler", "[errors]]") { prepare_logdir(); - std::string filename = "test_logs/simple_log.txt"; + spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); auto logger = spdlog::create("logger", filename, true); logger->flush_on(spdlog::level::info); logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); @@ -48,7 +51,7 @@ TEST_CASE("custom_error_handler", "[errors]]") REQUIRE_THROWS_AS(logger->info("Bad format msg {} {}", "xxx"), custom_ex); logger->info("Good message #2"); - require_message_count(filename, 2); + require_message_count(SIMPLE_LOG, 2); } TEST_CASE("default_error_handler2", "[errors]]") @@ -72,7 +75,7 @@ TEST_CASE("async_error_handler", "[errors]]") prepare_logdir(); std::string err_msg("log failed with some msg"); - std::string filename = "test_logs/simple_async_log.txt"; + spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_ASYNC_LOG); { spdlog::init_thread_pool(128, 1); auto logger = spdlog::create_async("logger", filename, true); @@ -90,7 +93,7 @@ TEST_CASE("async_error_handler", "[errors]]") spdlog::drop("logger"); // force logger to drain the queue and shutdown } spdlog::init_thread_pool(128, 1); - require_message_count(filename, 2); + require_message_count(SIMPLE_ASYNC_LOG, 2); REQUIRE(file_contents("test_logs/custom_err.txt") == err_msg); } From f39ccccc0cf203f17ebf7212999e35dcaebc08a2 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Wed, 6 Jan 2021 21:52:59 -0500 Subject: [PATCH 5/9] Fix linker error --- include/spdlog/details/os.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index 0c03aed4..2c6fc91c 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -91,7 +91,7 @@ SPDLOG_API bool in_terminal(FILE *file) SPDLOG_NOEXCEPT; #if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) SPDLOG_API void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target); -SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, memory_buf_t &target); +SPDLOG_API void utf8_to_wstrbuf(string_view_t str, memory_buf_t &target); #endif // Return directory name from given path or empty string From fc594b551ac08251ff1dd8c5524582fba245456e Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Wed, 6 Jan 2021 22:17:09 -0500 Subject: [PATCH 6/9] Prevent win_eventlog_sink from silently discarding errors when wide support is enabled --- include/spdlog/common.h | 1 + include/spdlog/details/os-inl.h | 6 +++--- include/spdlog/details/os.h | 2 +- include/spdlog/sinks/win_eventlog_sink.h | 25 ++++++------------------ 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/include/spdlog/common.h b/include/spdlog/common.h index bb251e2f..e7983e3a 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -103,6 +103,7 @@ using err_handler = std::function; using string_view_t = fmt::basic_string_view; using wstring_view_t = fmt::basic_string_view; using memory_buf_t = fmt::basic_memory_buffer; +using wmemory_buf_t = fmt::basic_memory_buffer; using filename_memory_buf_t = fmt::basic_memory_buffer; #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT diff --git a/include/spdlog/details/os-inl.h b/include/spdlog/details/os-inl.h index 20e6ffa3..e37c0b97 100644 --- a/include/spdlog/details/os-inl.h +++ b/include/spdlog/details/os-inl.h @@ -469,7 +469,7 @@ SPDLOG_INLINE void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target) throw_spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError())); } -SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, memory_buf_t &target) +SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target) { if (str.size() > static_cast((std::numeric_limits::max)())) { @@ -484,7 +484,7 @@ SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, memory_buf_t &target) } int result_size = static_cast(target.capacity()); - if ((str_size + 1) * 2 < result_size) + if (str_size + 1 > result_size) { result_size = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size, NULL, 0); } @@ -492,7 +492,7 @@ SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, memory_buf_t &target) if (result_size > 0) { target.resize(result_size); - result_size = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size, (LPWSTR)target.data(), result_size); + result_size = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size, target.data(), result_size); if (result_size > 0) { diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index 2c6fc91c..9fda1447 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -91,7 +91,7 @@ SPDLOG_API bool in_terminal(FILE *file) SPDLOG_NOEXCEPT; #if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) SPDLOG_API void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target); -SPDLOG_API void utf8_to_wstrbuf(string_view_t str, memory_buf_t &target); +SPDLOG_API void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target); #endif // Return directory name from given path or empty string diff --git a/include/spdlog/sinks/win_eventlog_sink.h b/include/spdlog/sinks/win_eventlog_sink.h index f154c55a..68170dd9 100644 --- a/include/spdlog/sinks/win_eventlog_sink.h +++ b/include/spdlog/sinks/win_eventlog_sink.h @@ -224,35 +224,22 @@ protected: formatted.push_back('\0'); #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT - try - { - memory_buf_t buf; - details::os::utf8_to_wstrbuf(string_view_t(formatted.data(), formatted.size()), buf); + wmemory_buf_t buf; + details::os::utf8_to_wstrbuf(string_view_t(formatted.data(), formatted.size()), buf); - LPCWSTR lp_wstr = reinterpret_cast(buf.data()); - succeeded = ::ReportEventW(event_log_handle(), eventlog::get_event_type(msg), eventlog::get_event_category(msg), event_id_, + LPCWSTR lp_wstr = buf.data(); + succeeded = ::ReportEventW(event_log_handle(), eventlog::get_event_type(msg), eventlog::get_event_category(msg), event_id_, current_user_sid_.as_sid(), 1, 0, &lp_wstr, nullptr); - - if (!succeeded) - { - SPDLOG_THROW(win32_error("ReportEvent")); - } - } - catch (...) - { - // WCHAR string conversion can fail and if it does, we shouldn't call to report event function. - } #else - LPCSTR lp_str = reinterpret_cast(formatted.data()); - + LPCSTR lp_str = formatted.data(); succeeded = ::ReportEventA(event_log_handle(), eventlog::get_event_type(msg), eventlog::get_event_category(msg), event_id_, current_user_sid_.as_sid(), 1, 0, &lp_str, nullptr); +#endif if (!succeeded) { SPDLOG_THROW(win32_error("ReportEvent")); } -#endif } void flush_() override {} From 1234cda3b31b14187ad97bcac7197ff9e20f41a5 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Sun, 10 Jan 2021 18:19:00 -0500 Subject: [PATCH 7/9] Don't build the example with wide filenames --- appveyor.yml | 10 +++++++++- example/example.cpp | 10 +++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 82c8f276..c7b12bae 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,41 +7,49 @@ environment: WCHAR: 'OFF' WCHAR_FILES: 'OFF' BUILD_SHARED: 'OFF' + BUILD_EXAMPLE: 'ON' - GENERATOR: '"Visual Studio 14 2015"' BUILD_TYPE: Release WCHAR: 'ON' WCHAR_FILES: 'OFF' BUILD_SHARED: 'OFF' + BUILD_EXAMPLE: 'ON' - GENERATOR: '"Visual Studio 14 2015 Win64"' BUILD_TYPE: Debug WCHAR: 'ON' WCHAR_FILES: 'OFF' BUILD_SHARED: 'OFF' + BUILD_EXAMPLE: 'ON' - GENERATOR: '"Visual Studio 14 2015 Win64"' BUILD_TYPE: Release WCHAR: 'ON' WCHAR_FILES: 'OFF' BUILD_SHARED: 'OFF' + BUILD_EXAMPLE: 'ON' - GENERATOR: '"Visual Studio 15 2017 Win64"' BUILD_TYPE: Debug WCHAR: 'ON' WCHAR_FILES: 'OFF' BUILD_SHARED: 'OFF' + BUILD_EXAMPLE: 'ON' - GENERATOR: '"Visual Studio 15 2017 Win64"' BUILD_TYPE: Release WCHAR: 'OFF' WCHAR_FILES: 'OFF' BUILD_SHARED: 'OFF' + BUILD_EXAMPLE: 'ON' - GENERATOR: '"Visual Studio 15 2017 Win64"' BUILD_TYPE: Release WCHAR: 'OFF' WCHAR_FILES: 'OFF' BUILD_SHARED: 'ON' + BUILD_EXAMPLE: 'ON' - GENERATOR: '"Visual Studio 15 2017 Win64"' BUILD_TYPE: Release WCHAR: 'ON' WCHAR_FILES: 'ON' BUILD_SHARED: 'ON' + BUILD_EXAMPLE: 'OFF' build_script: - cmd: >- set @@ -52,7 +60,7 @@ build_script: set PATH=%PATH%;C:\Program Files\Git\usr\bin - cmake .. -G %GENERATOR% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DSPDLOG_WCHAR_SUPPORT=%WCHAR% -DSPDLOG_WCHAR_FILENAMES=%WCHAR_FILES% -DSPDLOG_BUILD_SHARED=%BUILD_SHARED% -DSPDLOG_BUILD_EXAMPLE=ON -DSPDLOG_BUILD_EXAMPLE_HO=ON -DSPDLOG_BUILD_TESTS=ON -DSPDLOG_BUILD_TESTS_HO=OFF -DSPDLOG_BUILD_WARNINGS=ON + cmake .. -G %GENERATOR% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DSPDLOG_WCHAR_SUPPORT=%WCHAR% -DSPDLOG_WCHAR_FILENAMES=%WCHAR_FILES% -DSPDLOG_BUILD_SHARED=%BUILD_SHARED% -DSPDLOG_BUILD_EXAMPLE=%BUILD_EXAMPLE% -DSPDLOG_BUILD_EXAMPLE_HO=%BUILD_EXAMPLE% -DSPDLOG_BUILD_TESTS=ON -DSPDLOG_BUILD_TESTS_HO=OFF -DSPDLOG_BUILD_WARNINGS=ON cmake --build . --config %BUILD_TYPE% diff --git a/example/example.cpp b/example/example.cpp index 1f4ba002..2f27d4a8 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -109,21 +109,21 @@ void stdout_logger_example() void basic_example() { // Create basic file logger (not rotated). - auto my_logger = spdlog::basic_logger_mt("file_logger", SPDLOG_FILENAME_T("logs/basic-log.txt")); + auto my_logger = spdlog::basic_logger_mt("file_logger", "logs/basic-log.txt"); } #include "spdlog/sinks/rotating_file_sink.h" void rotating_example() { // Create a file rotating logger with 5mb size max and 3 rotated files. - auto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", SPDLOG_FILENAME_T("logs/rotating.txt"), 1048576 * 5, 3); + auto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3); } #include "spdlog/sinks/daily_file_sink.h" void daily_example() { // Create a daily logger - a new file is created every day on 2:30am. - auto daily_logger = spdlog::daily_logger_mt("daily_logger", SPDLOG_FILENAME_T("logs/daily.txt"), 2, 30); + auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30); } #include "spdlog/cfg/env.h" @@ -143,7 +143,7 @@ void async_example() { // Default thread pool settings can be modified *before* creating the async logger: // spdlog::init_thread_pool(32768, 1); // queue with max 32k items 1 backing thread. - auto async_file = spdlog::basic_logger_mt("async_file_logger", SPDLOG_FILENAME_T("logs/async_log.txt")); + auto async_file = spdlog::basic_logger_mt("async_file_logger", "logs/async_log.txt"); // alternatively: // auto async_file = spdlog::create_async("async_file_logger", "logs/async_log.txt"); @@ -211,7 +211,7 @@ void multi_sink_example() console_sink->set_level(spdlog::level::warn); console_sink->set_pattern("[multi_sink_example] [%^%l%$] %v"); - auto file_sink = std::make_shared(SPDLOG_FILENAME_T("logs/multisink.txt"), true); + auto file_sink = std::make_shared("logs/multisink.txt", true); file_sink->set_level(spdlog::level::trace); spdlog::logger logger("multi_sink", {console_sink, file_sink}); From 9e19012cb0dec7b1b7d38bc5286903674d34dcea Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Sun, 10 Jan 2021 18:19:28 -0500 Subject: [PATCH 8/9] Remove filename_memory_buf_t from headers --- include/spdlog/common.h | 1 - tests/test_daily_logger.cpp | 8 +++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/spdlog/common.h b/include/spdlog/common.h index e7983e3a..35342317 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -104,7 +104,6 @@ using string_view_t = fmt::basic_string_view; using wstring_view_t = fmt::basic_string_view; using memory_buf_t = fmt::basic_memory_buffer; using wmemory_buf_t = fmt::basic_memory_buffer; -using filename_memory_buf_t = fmt::basic_memory_buffer; #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT #ifndef _WIN32 diff --git a/tests/test_daily_logger.cpp b/tests/test_daily_logger.cpp index 10e365c5..5ab1e206 100644 --- a/tests/test_daily_logger.cpp +++ b/tests/test_daily_logger.cpp @@ -3,6 +3,8 @@ */ #include "includes.h" +using filename_memory_buf_t = fmt::basic_memory_buffer; + TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]") { using sink_type = spdlog::sinks::daily_file_sink; @@ -12,7 +14,7 @@ TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]") // calculate filename (time based) spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_dateonly"); std::tm tm = spdlog::details::os::localtime(); - spdlog::filename_memory_buf_t w; + filename_memory_buf_t w; fmt::format_to(w, SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); auto logger = spdlog::create("logger", basename, 0, 0); @@ -37,7 +39,7 @@ struct custom_daily_file_name_calculator { static spdlog::filename_t calc_filename(const spdlog::filename_t &basename, const tm &now_tm) { - spdlog::filename_memory_buf_t w; + filename_memory_buf_t w; fmt::format_to(w, SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"), basename, now_tm.tm_year + 1900, now_tm.tm_mon + 1, now_tm.tm_mday); return fmt::to_string(w); } @@ -52,7 +54,7 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger]") // calculate filename (time based) spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_dateonly"); std::tm tm = spdlog::details::os::localtime(); - spdlog::filename_memory_buf_t w; + filename_memory_buf_t w; fmt::format_to(w, SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); auto logger = spdlog::create("logger", basename, 0, 0); From ac35dd5a6f8312005ab0d86cc4db28c20083af46 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Sun, 10 Jan 2021 18:26:24 -0500 Subject: [PATCH 9/9] Prevent integer overflows in wstr_to_utf8buf and utf8_to_wstrbuf --- include/spdlog/details/os-inl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/spdlog/details/os-inl.h b/include/spdlog/details/os-inl.h index e37c0b97..50a6b5aa 100644 --- a/include/spdlog/details/os-inl.h +++ b/include/spdlog/details/os-inl.h @@ -436,7 +436,7 @@ SPDLOG_INLINE bool in_terminal(FILE *file) SPDLOG_NOEXCEPT #if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) SPDLOG_INLINE void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target) { - if (wstr.size() > static_cast((std::numeric_limits::max)())) + if (wstr.size() > static_cast(std::numeric_limits::max()) / 2 - 1) { throw_spdlog_ex("UTF-16 string is too big to be converted to UTF-8"); } @@ -471,7 +471,7 @@ SPDLOG_INLINE void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target) SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target) { - if (str.size() > static_cast((std::numeric_limits::max)())) + if (str.size() > static_cast(std::numeric_limits::max()) - 1) { throw_spdlog_ex("UTF-8 string is too big to be converted to UTF-16"); }