From a453bccff056bf458c06fbdd8b0b0c54b9792be2 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Wed, 6 Jan 2021 03:55:46 -0500 Subject: [PATCH] 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