From 08c727e4f8aa6955a0b14a26e83fb06fe9caeace Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Thu, 5 Dec 2024 19:14:25 +0200 Subject: [PATCH] Use std filesystem (#3284) * Use std::filesystem for path names and impl --- CMakeLists.txt | 11 ++- example/example.cpp | 14 ++-- include/spdlog/common.h | 39 +--------- include/spdlog/details/file_helper.h | 16 +---- include/spdlog/details/os.h | 76 +++++++++++++------- include/spdlog/file_event_handlers.h | 19 +++++ include/spdlog/filename_t.h | 18 +++++ include/spdlog/fmt/fmt.h | 1 + include/spdlog/sinks/daily_file_sink.h | 28 ++++---- include/spdlog/sinks/hourly_file_sink.h | 12 ++-- include/spdlog/sinks/rotating_file_sink.h | 2 +- src/details/file_helper.cpp | 34 +-------- src/details/os_filesystem.cpp | 73 +++++++++++++++++++ src/details/os_unix.cpp | 66 +++-------------- src/details/os_windows.cpp | 86 +++++------------------ src/sinks/rotating_file_sink.cpp | 14 ++-- tests/includes.h | 5 ++ tests/test_create_dir.cpp | 35 ++++----- tests/test_daily_and_rotation_loggers.cpp | 51 +++++++++----- tests/test_file_helper.cpp | 6 +- tests/test_fmt_helper.cpp | 1 - tests/test_pattern_formatter.cpp | 1 - tests/utils.cpp | 4 +- tests/utils.h | 6 +- 24 files changed, 300 insertions(+), 318 deletions(-) create mode 100644 include/spdlog/file_event_handlers.h create mode 100644 include/spdlog/filename_t.h create mode 100644 src/details/os_filesystem.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cbb53be..f0947445 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ endif() option(SPDLOG_PREVENT_CHILD_FD "Prevent from child processes to inherit log file descriptors" OFF) option(SPDLOG_NO_THREAD_ID "prevent spdlog from querying the thread id on each log call if thread id is not needed" OFF) option(SPDLOG_DISABLE_DEFAULT_LOGGER "Disable default logger creation" OFF) +option(SPDLOG_NO_TLS "Disable thread local storage" OFF) # clang-tidy option(SPDLOG_TIDY "run clang-tidy" OFF) @@ -198,6 +199,7 @@ set(SPDLOG_SRCS "src/spdlog.cpp" "src/cfg/helpers.cpp" "src/details/file_helper.cpp" + "src/details/os_filesystem.cpp" "src/details/log_msg.cpp" "src/details/log_msg_buffer.cpp" "src/details/periodic_worker.cpp" @@ -307,8 +309,13 @@ endif() # --------------------------------------------------------------------------------------- # spdlog private defines according to the options # --------------------------------------------------------------------------------------- -foreach(SPDLOG_OPTION SPDLOG_CLOCK_COARSE SPDLOG_PREVENT_CHILD_FD SPDLOG_NO_THREAD_ID SPDLOG_DISABLE_DEFAULT_LOGGER - SPDLOG_FWRITE_UNLOCKED) +foreach(SPDLOG_OPTION + SPDLOG_CLOCK_COARSE + SPDLOG_PREVENT_CHILD_FD + SPDLOG_NO_THREAD_ID + SPDLOG_DISABLE_DEFAULT_LOGGER + SPDLOG_NO_TLS + SPDLOG_FWRITE_UNLOCKED) if(${SPDLOG_OPTION}) target_compile_definitions(spdlog PRIVATE ${SPDLOG_OPTION}) endif() diff --git a/example/example.cpp b/example/example.cpp index 35e6c48a..1de2b063 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -1,4 +1,4 @@ -// +// // Copyright(c) 2015 Gabi Melman. // Distributed under the MIT License (http://opensource.org/licenses/MIT) @@ -299,16 +299,16 @@ void custom_flags_example() { void file_events_example() { // pass the spdlog::file_event_handlers to file sinks for open/close log file notifications spdlog::file_event_handlers handlers; - handlers.before_open = [](spdlog::filename_t filename) { spdlog::info("Before opening {}", filename); }; - handlers.after_open = [](spdlog::filename_t filename, std::FILE *fstream) { - spdlog::info("After opening {}", filename); + handlers.before_open = [](spdlog::filename_t) { spdlog::info("Before opening logfile"); }; + handlers.after_open = [](spdlog::filename_t, std::FILE *fstream) { + spdlog::info("After opening logfile"); fputs("After opening\n", fstream); }; - handlers.before_close = [](spdlog::filename_t filename, std::FILE *fstream) { - spdlog::info("Before closing {}", filename); + handlers.before_close = [](spdlog::filename_t, std::FILE *fstream) { + spdlog::info("Before closing logfile"); fputs("Before closing\n", fstream); }; - handlers.after_close = [](spdlog::filename_t filename) { spdlog::info("After closing {}", filename); }; + handlers.after_close = [](spdlog::filename_t) { spdlog::info("After closing logfile"); }; auto file_sink = std::make_shared("logs/events-sample.txt", true, handlers); spdlog::logger my_logger("some_logger", file_sink); my_logger.info("Some log line"); diff --git a/include/spdlog/common.h b/include/spdlog/common.h index ca039aa9..36c58c4a 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -5,14 +5,14 @@ #include #include -#include #include #include #include #include #include #include -#include +#include +#include #include "./source_loc.h" @@ -47,9 +47,6 @@ namespace sinks { class sink; } -using filename_t = std::string; -#define SPDLOG_FILENAME_T(s) s - using log_clock = std::chrono::system_clock; using sink_ptr = std::shared_ptr; using sinks_init_list = std::initializer_list; @@ -64,7 +61,6 @@ using wmemory_buf_t = fmt::basic_memory_buffer; template using format_string_t = fmt::format_string; -#define SPDLOG_BUF_TO_STRING(x) fmt::to_string(x) #define SPDLOG_LEVEL_TRACE 0 #define SPDLOG_LEVEL_DEBUG 1 #define SPDLOG_LEVEL_INFO 2 @@ -102,7 +98,7 @@ constexpr std::array short_level_names{"T", "D", return level_string_views.at(level_to_number(lvl)); } -[[nodiscard]] constexpr const std::string_view to_short_string_view(spdlog::level lvl) noexcept { +[[nodiscard]] constexpr std::string_view to_short_string_view(spdlog::level lvl) noexcept { return short_level_names.at(level_to_number(lvl)); } @@ -140,33 +136,4 @@ private: [[noreturn]] SPDLOG_API void throw_spdlog_ex(const std::string &msg, int last_errno); [[noreturn]] SPDLOG_API void throw_spdlog_ex(std::string msg); -struct file_event_handlers { - file_event_handlers() - : before_open(nullptr), - after_open(nullptr), - before_close(nullptr), - after_close(nullptr) {} - - std::function before_open; - std::function after_open; - std::function before_close; - std::function after_close; -}; - -namespace details { - -// to_string_view - -[[nodiscard]] constexpr spdlog::string_view_t to_string_view(const memory_buf_t &buf) noexcept { - return spdlog::string_view_t{buf.data(), buf.size()}; -} - -[[nodiscard]] constexpr spdlog::string_view_t to_string_view(spdlog::string_view_t str) noexcept { return str; } - -template -[[nodiscard]] constexpr fmt::basic_string_view to_string_view(fmt::basic_format_string fmt) noexcept { - return fmt; -} - -} // namespace details } // namespace spdlog diff --git a/include/spdlog/details/file_helper.h b/include/spdlog/details/file_helper.h index 128fe153..97677885 100644 --- a/include/spdlog/details/file_helper.h +++ b/include/spdlog/details/file_helper.h @@ -6,6 +6,7 @@ #include #include "../common.h" +#include "../file_event_handlers.h" namespace spdlog { namespace details { @@ -32,21 +33,6 @@ public: size_t size() const; const filename_t &filename() const; - // - // return file path and its extension: - // - // "mylog.txt" => ("mylog", ".txt") - // "mylog" => ("mylog", "") - // "mylog." => ("mylog.", "") - // "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt") - // - // the starting dot in filenames is ignored (hidden files): - // - // ".mylog" => (".mylog". "") - // "my_folder/.mylog" => ("my_folder/.mylog", "") - // "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt") - static std::tuple split_by_extension(const filename_t &fname); - private: const int open_tries_ = 5; const unsigned int open_interval_ = 10; diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index cb669458..f6c6d445 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -4,8 +4,9 @@ #pragma once #include // std::time_t - +#include #include "../common.h" +#include "../filename_t.h" namespace spdlog { namespace details { @@ -24,27 +25,13 @@ SPDLOG_API std::tm gmtime() noexcept; // eol definition and folder separator for the current os #ifdef _WIN32 constexpr static const char *default_eol = "\r\n"; -constexpr static const filename_t::value_type folder_seps_filename[] = SPDLOG_FILENAME_T("\\/"); #else constexpr static const char *default_eol = "\n"; -constexpr static const filename_t::value_type folder_seps_filename[] = SPDLOG_FILENAME_T("/"); #endif // fopen_s on non windows for writing SPDLOG_API bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode); -// Remove filename. return 0 on success -SPDLOG_API int remove(const filename_t &filename) noexcept; - -// Remove file if exists. return 0 on success -// Note: Non atomic (might return failure to delete if concurrently deleted by other process/thread) -SPDLOG_API int remove_if_exists(const filename_t &filename) noexcept; - -SPDLOG_API int rename(const filename_t &filename1, const filename_t &filename2) noexcept; - -// Return if file exists. -SPDLOG_API bool path_exists(const filename_t &filename) noexcept; - // Return file size according to open FILE* object SPDLOG_API size_t filesize(FILE *f); @@ -63,8 +50,7 @@ SPDLOG_API size_t thread_id() noexcept; // See https://github.com/gabime/spdlog/issues/609 SPDLOG_API void sleep_for_millis(unsigned int milliseconds) noexcept; -SPDLOG_API std::string filename_to_str(const filename_t &filename); - +// Return pid SPDLOG_API int pid() noexcept; // Determine if the terminal supports colors @@ -80,16 +66,6 @@ SPDLOG_API void wstr_to_utf8buf(wstring_view_t wstr, 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 -// "abc/file" => "abc" -// "abc/" => "abc" -// "abc" => "" -// "abc///" => "abc//" -SPDLOG_API filename_t dir_name(const filename_t &path); - -// Create a dir from the given path. -// Return true if succeeded or if this dir already exists. -SPDLOG_API bool create_dir(const filename_t &path); // non thread safe, cross platform getenv/getenv_s // return empty string if field not found @@ -103,6 +79,52 @@ SPDLOG_API bool fsync(FILE *fp); // Return true on success. SPDLOG_API bool fwrite_bytes(const void *ptr, const size_t n_bytes, FILE *fp); +// +// std::filesystem wrapper functions +// + +// Return directory name from given path or empty string +// "abc/file" => "abc" +// "abc/" => "abc" +// "abc" => "" +SPDLOG_API filename_t dir_name(const filename_t &path); + +// Create a dir from the given path. +// Return true if succeeded or if this dir already exists. +SPDLOG_API bool create_dir(const filename_t &path); + +// Remove filename. return true on success +SPDLOG_API bool remove(const filename_t &filename); + +// Remove file if exists. return 0 on success +// Note: Non atomic (might return failure to delete if concurrently deleted by other process/thread) +SPDLOG_API bool remove_if_exists(const filename_t &filename); + +// Rename file. return true on success +SPDLOG_API bool rename(const filename_t &filename1, const filename_t &filename2) noexcept; + +// Return if file exists. +SPDLOG_API bool path_exists(const filename_t &filename) noexcept; + + +// Return file path and its extension: +// +// "mylog.txt" => ("mylog", ".txt") +// "mylog" => ("mylog", "") +// "mylog." => ("mylog.", "") +// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt") +// +// the starting dot in filenames is ignored (hidden files): +// +// ".mylog" => (".mylog". "") +// "my_folder/.mylog" => ("my_folder/.mylog", "") +// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt") +SPDLOG_API std::tuple split_by_extension(const filename_t &fname); + +// Try tp convert filename to string. Return "??" if failed +SPDLOG_API std::string filename_to_str(const filename_t &filename); + + } // namespace os } // namespace details } // namespace spdlog diff --git a/include/spdlog/file_event_handlers.h b/include/spdlog/file_event_handlers.h new file mode 100644 index 00000000..4a53df7f --- /dev/null +++ b/include/spdlog/file_event_handlers.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include "./filename_t.h" + +namespace spdlog { +struct file_event_handlers { + file_event_handlers() + : before_open(nullptr), + after_open(nullptr), + before_close(nullptr), + after_close(nullptr) {} + + std::function before_open; + std::function after_open; + std::function before_close; + std::function after_close; +}; +} // namespace spdlog diff --git a/include/spdlog/filename_t.h b/include/spdlog/filename_t.h new file mode 100644 index 00000000..f8756ab3 --- /dev/null +++ b/include/spdlog/filename_t.h @@ -0,0 +1,18 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +#include + +#ifdef _WIN32 + // In windows, add L prefix for filename literals (e.g. L"filename.txt") + #define SPDLOG_FILENAME_T_INNER(s) L##s + #define SPDLOG_FILENAME_T(s) SPDLOG_FILENAME_T_INNER(s) +#else + #define SPDLOG_FILENAME_T(s) s +#endif + +namespace spdlog { +using filename_t = std::filesystem::path; +} // namespace spdlog diff --git a/include/spdlog/fmt/fmt.h b/include/spdlog/fmt/fmt.h index a261e14b..4db29253 100644 --- a/include/spdlog/fmt/fmt.h +++ b/include/spdlog/fmt/fmt.h @@ -6,3 +6,4 @@ #pragma once #include "fmt/format.h" +#include "fmt/xchar.h" diff --git a/include/spdlog/sinks/daily_file_sink.h b/include/spdlog/sinks/daily_file_sink.h index d4b3ebac..68477707 100644 --- a/include/spdlog/sinks/daily_file_sink.h +++ b/include/spdlog/sinks/daily_file_sink.h @@ -11,41 +11,43 @@ #include #include "../common.h" +#include "./base_sink.h" #include "../details/circular_q.h" #include "../details/file_helper.h" #include "../details/null_mutex.h" #include "../details/os.h" #include "../details/synchronous_factory.h" -#include "./base_sink.h" + namespace spdlog { namespace sinks { /* - * Generator of daily log file names in format basename.YYYY-MM-DD.ext + * Generator of daily log file names in format basename_YYYY-MM-DD.ext */ -struct daily_filename_calculator { - // Create filename for the form basename.YYYY-MM-DD +struct daily_filename_calculator { static filename_t calc_filename(const filename_t &filename, const tm &now_tm) { filename_t basename, ext; - std::tie(basename, ext) = details::file_helper::split_by_extension(filename); - return fmt_lib::format(SPDLOG_FMT_STRING(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}{}")), basename, now_tm.tm_year + 1900, - now_tm.tm_mon + 1, now_tm.tm_mday, ext); + std::tie(basename, ext) = details::os::split_by_extension(filename); + std::basic_ostringstream oss; + oss << basename.native() << '_' << std::setfill(SPDLOG_FILENAME_T('0')) << std::setw(4) << now_tm.tm_year + 1900 << '-' + << std::setw(2) << now_tm.tm_mon + 1 << '-' << std::setw(2) << now_tm.tm_mday << ext.native(); + return oss.str(); } }; /* * Generator of daily log file names with strftime format. * Usages: - * auto sink = - * std::make_shared("myapp-%Y-%m-%d:%H:%M:%S.log", hour, - * minute);" auto logger = spdlog::daily_logger_format_mt("loggername, "myapp-%Y-%m-%d:%X.log", - * hour, minute)" + * + * std::make_shared("myapp-%Y-%m-%d:%H:%M:%S.log", hour, minute); + * or + * spdlog::daily_logger_format_mt("loggername, "myapp-%Y-%m-%d:%X.log", hour, minute)" * */ struct daily_filename_format_calculator { static filename_t calc_filename(const filename_t &file_path, const tm &now_tm) { - std::stringstream stream; + std::basic_ostringstream stream; stream << std::put_time(&now_tm, file_path.c_str()); return stream.str(); } @@ -164,7 +166,7 @@ private: if (filenames_q_.full()) { auto old_filename = std::move(filenames_q_.front()); filenames_q_.pop_front(); - bool ok = remove_if_exists(old_filename) == 0; + bool ok = remove_if_exists(old_filename); if (!ok) { filenames_q_.push_back(std::move(current_file)); throw_spdlog_ex("Failed removing daily file " + filename_to_str(old_filename), errno); diff --git a/include/spdlog/sinks/hourly_file_sink.h b/include/spdlog/sinks/hourly_file_sink.h index a4c72543..d1460113 100644 --- a/include/spdlog/sinks/hourly_file_sink.h +++ b/include/spdlog/sinks/hourly_file_sink.h @@ -22,15 +22,17 @@ namespace spdlog { namespace sinks { /* - * Generator of Hourly log file names in format basename.YYYY-MM-DD-HH.ext + * Generator of Hourly log file names in format basename_YYYY-MM-DD_HH.ext */ struct hourly_filename_calculator { - // Create filename for the form basename.YYYY-MM-DD-H static filename_t calc_filename(const filename_t &filename, const tm &now_tm) { filename_t basename, ext; - std::tie(basename, ext) = details::file_helper::split_by_extension(filename); - return fmt_lib::format(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}_{:02d}{}"), basename, now_tm.tm_year + 1900, - now_tm.tm_mon + 1, now_tm.tm_mday, now_tm.tm_hour, ext); + std::tie(basename, ext) = details::os::split_by_extension(filename); + std::basic_ostringstream oss; + oss << basename.native() << '_' << std::setfill(SPDLOG_FILENAME_T('0')) << std::setw(4) << now_tm.tm_year + 1900 << '-' + << std::setw(2) << now_tm.tm_mon + 1 << '-' << std::setw(2) << now_tm.tm_mday << '_' << std::setw(2) << now_tm.tm_hour + << ext.native(); + return oss.str(); } }; diff --git a/include/spdlog/sinks/rotating_file_sink.h b/include/spdlog/sinks/rotating_file_sink.h index b3011175..ec441168 100644 --- a/include/spdlog/sinks/rotating_file_sink.h +++ b/include/spdlog/sinks/rotating_file_sink.h @@ -43,7 +43,7 @@ private: // delete the target if exists, and rename the src file to target // return true on success, false otherwise. - static bool rename_file_(const filename_t &src_filename, const filename_t &target_filename); + static bool rename_file_(const filename_t &src_filename, const filename_t &target_filename) noexcept; filename_t base_filename_; std::size_t max_size_; diff --git a/src/details/file_helper.cpp b/src/details/file_helper.cpp index 6903ef85..efc3160a 100644 --- a/src/details/file_helper.cpp +++ b/src/details/file_helper.cpp @@ -1,12 +1,13 @@ // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. // Distributed under the MIT License (http://opensource.org/licenses/MIT) -#include "spdlog/details/file_helper.h" #include #include #include +#include +#include "spdlog/details/file_helper.h" #include "spdlog/common.h" #include "spdlog/details/os.h" @@ -107,37 +108,6 @@ size_t file_helper::size() const { const filename_t &file_helper::filename() const { return filename_; } -// -// return file path and its extension: -// -// "mylog.txt" => ("mylog", ".txt") -// "mylog" => ("mylog", "") -// "mylog." => ("mylog.", "") -// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt") -// -// the starting dot in filenames is ignored (hidden files): -// -// ".mylog" => (".mylog". "") -// "my_folder/.mylog" => ("my_folder/.mylog", "") -// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt") -std::tuple file_helper::split_by_extension(const filename_t &fname) { - auto ext_index = fname.rfind('.'); - - // no valid extension found - return whole path and empty string as - // extension - if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1) { - return std::make_tuple(fname, filename_t()); - } - - // treat cases like "/etc/rc.d/somelogfile or "/abc/.hiddenfile" - 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()); - } - - // finally - return a valid base and extension tuple - return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index)); -} } // namespace details } // namespace spdlog diff --git a/src/details/os_filesystem.cpp b/src/details/os_filesystem.cpp new file mode 100644 index 00000000..f811cb54 --- /dev/null +++ b/src/details/os_filesystem.cpp @@ -0,0 +1,73 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#include +#include + +#include "spdlog/common.h" +#include "spdlog/details/os.h" + +namespace spdlog { +namespace details { +namespace os { + +bool remove(const filename_t &filename) { + return std::filesystem::remove(filename); +} + +bool remove_if_exists(const filename_t &filename) { + if (path_exists(filename)) { + return os::remove(filename); + } + return false; +} + +// Rename if regular file +bool rename(const filename_t &filename1, const filename_t &filename2) noexcept { + if (!std::filesystem::is_regular_file(filename1)) { + return false; + } + std::error_code ec; + std::filesystem::rename(filename1, filename2, ec); + return !ec; +} + +// Return true if path exists (file or directory) +bool path_exists(const filename_t &filename) noexcept { return std::filesystem::exists(filename); } + +// Return directory name from given path or empty string +// "abc/file" => "abc" +// "abc/" => "abc" +// "abc" => "" +// "abc///" => "abc//" +filename_t dir_name(const filename_t &path) { return path.parent_path(); } + + +// Create the given directory - and all directories leading to it +// return true on success or if the directory already exists +bool create_dir(const filename_t &path) { + std::error_code ec; + return std::filesystem::create_directories(path, ec) || !ec; +} + + +// Return file path and its extension: +// +// "mylog.txt" => ("mylog", ".txt") +// "mylog" => ("mylog", "") +// "mylog." => ("mylog", ".") +// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt") +// +// the starting dot in filenames is ignored (hidden files): +// +// ".mylog" => (".mylog". "") +// "my_folder/.mylog" => ("my_folder/.mylog", "") +// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt") +std::tuple split_by_extension(const filename_t &fname) { + const auto ext = fname.extension(); + auto without_ext = filename_t(fname).replace_extension(); + return std::make_tuple(without_ext, ext); +} +} // namespace os +} // namespace details +} // namespace spdlog diff --git a/src/details/os_unix.cpp b/src/details/os_unix.cpp index 8319f633..98550bc3 100644 --- a/src/details/os_unix.cpp +++ b/src/details/os_unix.cpp @@ -99,19 +99,6 @@ bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode) { return *fp == nullptr; } -int remove(const filename_t &filename) noexcept { return std::remove(filename.c_str()); } - -int remove_if_exists(const filename_t &filename) noexcept { return path_exists(filename) ? remove(filename) : 0; } - -int rename(const filename_t &filename1, const filename_t &filename2) noexcept { - return std::rename(filename1.c_str(), filename2.c_str()); -} - -// Return true if path exists (file or directory) -bool path_exists(const filename_t &filename) noexcept { - struct stat buffer {}; - return (::stat(filename.c_str(), &buffer) == 0); -} // Return file size according to open FILE* object size_t filesize(FILE *f) { @@ -232,16 +219,22 @@ size_t _thread_id() noexcept { // Return current thread id as size_t (from thread local storage) size_t thread_id() noexcept { - // cache thread id in tls +#if defined(SPDLOG_NO_TLS) + return _thread_id(); +#else // cache thread id in tls static thread_local const size_t tid = _thread_id(); return tid; +#endif } void sleep_for_millis(unsigned int milliseconds) noexcept { std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds)); } -std::string filename_to_str(const filename_t &filename) { return filename; } +std::string filename_to_str(const filename_t &filename) { + static_assert(std::is_same_v, "filename_t type must be char"); + return filename; +} int pid() noexcept { return static_cast(::getpid()); } @@ -274,49 +267,6 @@ bool is_color_terminal() noexcept { // Source: https://github.com/agauniyal/rang/ bool in_terminal(FILE *file) noexcept { return ::isatty(fileno(file)) != 0; } -// return true on success -static bool mkdir_(const filename_t &path) { return ::mkdir(path.c_str(), static_cast(0755)) == 0; } - -// create the given directory - and all directories leading to it -// return true on success or if the directory already exists -bool create_dir(const filename_t &path) { - if (path_exists(path)) { - return true; - } - - if (path.empty()) { - return false; - } - - size_t search_offset = 0; - do { - 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) { - token_pos = path.size(); - } - - auto subdir = path.substr(0, token_pos); - - if (!subdir.empty() && !path_exists(subdir) && !mkdir_(subdir)) { - return false; // return error if failed creating dir - } - search_offset = token_pos + 1; - } while (search_offset < path.size()); - - return true; -} - -// Return directory name from given path or empty string -// "abc/file" => "abc" -// "abc/" => "abc" -// "abc" => "" -// "abc///" => "abc//" -filename_t dir_name(const filename_t &path) { - auto pos = path.find_last_of(folder_seps_filename); - return pos != filename_t::npos ? path.substr(0, pos) : filename_t{}; -} - std::string getenv(const char *field) { char *buf = ::getenv(field); return buf != nullptr ? buf : std::string{}; diff --git a/src/details/os_windows.cpp b/src/details/os_windows.cpp index 074a8c09..c827a897 100644 --- a/src/details/os_windows.cpp +++ b/src/details/os_windows.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include "spdlog/common.h" #include "spdlog/details/os.h" @@ -63,7 +62,7 @@ std::tm gmtime() noexcept { } bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode) { - *fp = ::_fsopen((filename.c_str()), mode.c_str(), _SH_DENYNO); + *fp = ::_wfsopen((filename.c_str()), mode.c_str(), _SH_DENYNO); #if defined(SPDLOG_PREVENT_CHILD_FD) if (*fp != nullptr) { auto file_handle = reinterpret_cast(_get_osfhandle(::_fileno(*fp))); @@ -76,19 +75,7 @@ bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode) { return *fp == nullptr; } -int remove(const filename_t &filename) noexcept { return std::remove(filename.c_str()); } -int remove_if_exists(const filename_t &filename) noexcept { return path_exists(filename) ? remove(filename) : 0; } - -int rename(const filename_t &filename1, const filename_t &filename2) noexcept { - return std::rename(filename1.c_str(), filename2.c_str()); -} - -// Return true if path exists (file or directory) -bool path_exists(const filename_t &filename) noexcept { - struct _stat buffer; - return (::_stat(filename.c_str(), &buffer) == 0); -} #ifdef _MSC_VER // avoid warning about unreachable statement at the end of filesize() @@ -149,16 +136,31 @@ size_t _thread_id() noexcept { return static_cast(::GetCurrentThreadId() // Return current thread id as size_t (from thread local storage) size_t thread_id() noexcept { - // cache thread id in tls +#if defined(SPDLOG_NO_TLS) + return _thread_id(); +#else // cache thread id in tls static thread_local const size_t tid = _thread_id(); return tid; +#endif } // This is avoid msvc issue in sleep_for that happens if the clock changes. // See https://github.com/gabime/spdlog/issues/609 void sleep_for_millis(unsigned int milliseconds) noexcept { ::Sleep(milliseconds); } -std::string filename_to_str(const filename_t &filename) { return filename; } +// Try tp convert wstring filename to string. Return "???" if failed +std::string filename_to_str(const filename_t &filename) { + static_assert(std::is_same_v, "filename_t type must be wchar_t"); + try { + memory_buf_t buf; + wstr_to_utf8buf(filename.wstring(), buf); + return std::string(buf.data(), buf.size()); + } + catch (...) { + return "???"; + } + +} int pid() noexcept { return static_cast(::GetCurrentProcessId()); } @@ -193,7 +195,7 @@ void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target) { } } - throw_spdlog_ex(fmt_lib::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError())); + throw spdlog_ex("WideCharToMultiByte failed"); } void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target) { @@ -222,56 +224,6 @@ void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target) { throw_spdlog_ex(fmt_lib::format("MultiByteToWideChar failed. Last error: {}", ::GetLastError())); } -// return true on success -static bool mkdir_(const filename_t &path) { return ::_mkdir(path.c_str()) == 0; } - -// create the given directory - and all directories leading to it -// return true on success or if the directory already exists -bool create_dir(const filename_t &path) { - if (path_exists(path)) { - return true; - } - - if (path.empty()) { - return false; - } - - size_t search_offset = 0; - do { - 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) { - token_pos = path.size(); - } - - auto subdir = path.substr(0, token_pos); - - // if subdir is just a drive letter, add a slash e.g. "c:"=>"c:\", - // otherwise path_exists(subdir) returns false (issue #3079) - const bool is_drive = subdir.length() == 2 && subdir[1] == ':'; - if (is_drive) { - subdir += '\\'; - token_pos++; - } - - if (!subdir.empty() && !path_exists(subdir) && !mkdir_(subdir)) { - return false; // return error if failed creating dir - } - search_offset = token_pos + 1; - } while (search_offset < path.size()); - - return true; -} - -// Return directory name from given path or empty string -// "abc/file" => "abc" -// "abc/" => "abc" -// "abc" => "" -// "abc///" => "abc//" -filename_t dir_name(const filename_t &path) { - auto pos = path.find_last_of(folder_seps_filename); - return pos != filename_t::npos ? path.substr(0, pos) : filename_t{}; -} std::string getenv(const char *field) { #if defined(_MSC_VER) diff --git a/src/sinks/rotating_file_sink.cpp b/src/sinks/rotating_file_sink.cpp index 5b2fad84..e55845c6 100644 --- a/src/sinks/rotating_file_sink.cpp +++ b/src/sinks/rotating_file_sink.cpp @@ -7,11 +7,11 @@ #include #include #include +#include #include "spdlog/common.h" #include "spdlog/details/file_helper.h" #include "spdlog/details/os.h" -// #include "spdlog/fmt/fmt.h" namespace spdlog { namespace sinks { @@ -51,8 +51,10 @@ filename_t rotating_file_sink::calc_filename(const filename_t &filename, filename_t basename; filename_t ext; - std::tie(basename, ext) = details::file_helper::split_by_extension(filename); - return fmt_lib::format(SPDLOG_FMT_STRING(SPDLOG_FILENAME_T("{}.{}{}")), basename, index, ext); + std::tie(basename, ext) = details::os::split_by_extension(filename); + std::basic_ostringstream oss; + oss << basename.native() << '.' << index << ext.native(); + return oss.str(); } template @@ -130,10 +132,8 @@ void rotating_file_sink::rotate_() { // delete the target if exists, and rename the src file to target // return true on success, false otherwise. template -bool rotating_file_sink::rename_file_(const filename_t &src_filename, const filename_t &target_filename) { - // try to delete the target file in case it already exists. - (void)details::os::remove(target_filename); - return details::os::rename(src_filename, target_filename) == 0; +bool rotating_file_sink::rename_file_(const filename_t &src_filename, const filename_t &target_filename) noexcept{ + return details::os::rename(src_filename, target_filename); } } // namespace sinks diff --git a/tests/includes.h b/tests/includes.h index d08001c1..f45174b5 100644 --- a/tests/includes.h +++ b/tests/includes.h @@ -31,3 +31,8 @@ #include "spdlog/sinks/null_sink.h" #include "spdlog/sinks/stdout_color_sinks.h" #include "spdlog/spdlog.h" + +// to_string_view +[[nodiscard]] constexpr spdlog::string_view_t to_string_view(const spdlog::memory_buf_t &buf) noexcept { + return spdlog::string_view_t{buf.data(), buf.size()}; +} diff --git a/tests/test_create_dir.cpp b/tests/test_create_dir.cpp index 7d46dfc0..55b8e255 100644 --- a/tests/test_create_dir.cpp +++ b/tests/test_create_dir.cpp @@ -43,34 +43,38 @@ TEST_CASE("create_invalid_dir", "[create_dir]") { } TEST_CASE("dir_name", "[create_dir]") { - using spdlog::details::os::dir_name; - REQUIRE(dir_name(SPDLOG_FILENAME_T("")).empty()); - REQUIRE(dir_name(SPDLOG_FILENAME_T("dir")).empty()); - -#ifdef WIN32 + using spdlog::details::os::dir_name; +#ifdef WIN32 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\\\)")) == 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)")); - 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"(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)")); #endif + REQUIRE(dir_name(SPDLOG_FILENAME_T("")).empty()); + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir")).empty()); 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///")) == 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("/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(".")); + +#ifdef _WIN32 + REQUIRE(dir_name(SPDLOG_FILENAME_T("//dir/file.txt")) == SPDLOG_FILENAME_T("//dir/")); +#else + REQUIRE(dir_name(SPDLOG_FILENAME_T("//dir/file.txt")) == SPDLOG_FILENAME_T("//dir")); +#endif } #ifdef _WIN32 @@ -122,15 +126,4 @@ TEST_CASE("create_abs_path2", "[create_dir]") { REQUIRE(create_dir(abs_path) == true); } -TEST_CASE("non_existing_drive", "[create_dir]") { - prepare_logdir(); - spdlog::filename_t path; - - auto non_existing_drive = find_non_existing_drive(); - path += non_existing_drive; - path += SPDLOG_FILENAME_T(":\\"); - REQUIRE(create_dir(path) == false); - path += SPDLOG_FILENAME_T("subdir"); - REQUIRE(create_dir(path) == false); -} #endif // _WIN32 diff --git a/tests/test_daily_and_rotation_loggers.cpp b/tests/test_daily_and_rotation_loggers.cpp index 6505cc1b..757404b5 100644 --- a/tests/test_daily_and_rotation_loggers.cpp +++ b/tests/test_daily_and_rotation_loggers.cpp @@ -5,6 +5,7 @@ #include "includes.h" #include "spdlog/sinks/daily_file_sink.h" #include "spdlog/sinks/rotating_file_sink.h" +#include "spdlog/sinks/hourly_file_sink.h" using filename_memory_buf_t = spdlog::memory_buf_t; @@ -16,9 +17,8 @@ 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(); - filename_memory_buf_t w; - spdlog::fmt_lib::format_to(std::back_inserter(w), SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}"), basename, tm.tm_year + 1900, - tm.tm_mon + 1, tm.tm_mday); + auto w = spdlog::fmt_lib::format(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}"), basename.native(), 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) { @@ -26,16 +26,15 @@ TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]") { } logger->flush(); - require_message_count(SPDLOG_BUF_TO_STRING(w), 10); + require_message_count(w, 10); } struct custom_daily_file_name_calculator { static spdlog::filename_t calc_filename(const spdlog::filename_t &basename, const tm &now_tm) { - filename_memory_buf_t w; - spdlog::fmt_lib::format_to(std::back_inserter(w), SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"), basename, - now_tm.tm_year + 1900, now_tm.tm_mon + 1, now_tm.tm_mday); + auto w = spdlog::fmt_lib::format(SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"), basename.native(), now_tm.tm_year + 1900, + now_tm.tm_mon + 1, now_tm.tm_mday); - return SPDLOG_BUF_TO_STRING(w); + return w; } }; @@ -47,9 +46,10 @@ 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(); - filename_memory_buf_t w; - spdlog::fmt_lib::format_to(std::back_inserter(w), SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"), basename, tm.tm_year + 1900, - tm.tm_mon + 1, tm.tm_mday); + + auto w = spdlog::fmt_lib::format(SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"), basename.native(), 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) { @@ -57,7 +57,7 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger]") { } logger->flush(); - require_message_count(SPDLOG_BUF_TO_STRING(w), 10); + require_message_count(w, 10); } /* @@ -82,17 +82,32 @@ TEST_CASE("rotating_file_sink::calc_filename3", "[rotating_file_sink]") { // regex supported only from gcc 4.9 and above #if defined(_MSC_VER) || !(__GNUC__ <= 4 && __GNUC_MINOR__ < 9) - #include +#include 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(SPDLOG_FILENAME_T("daily.txt"), + spdlog::details::os::localtime()); + // date regex based on https://www.regular-expressions.info/dates.html + 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.native(), match, re)); +} + + +TEST_CASE("hourly_file_sink::hourly_filename_calculator", "[hrouly_file_sink]") { // daily_YYYY-MM-DD_hh-mm.txt auto filename = - spdlog::sinks::daily_filename_calculator::calc_filename(SPDLOG_FILENAME_T("daily.txt"), spdlog::details::os::localtime()); + spdlog::sinks::hourly_filename_calculator::calc_filename(SPDLOG_FILENAME_T("hourly.txt"), spdlog::details::os::localtime()); // date regex based on https://www.regular-expressions.info/dates.html 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)); + SPDLOG_FILENAME_T(R"(^hourly_(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])_\d\d\.txt$)")); + + std::match_results match; + REQUIRE(std::regex_match(filename.native(), match, re)); } #endif @@ -148,4 +163,4 @@ TEST_CASE("daily_logger rotate", "[daily_file_sink]") { test_rotate(days_to_run, 10, 10); test_rotate(days_to_run, 11, 10); test_rotate(days_to_run, 20, 10); -} +} \ No newline at end of file diff --git a/tests/test_file_helper.cpp b/tests/test_file_helper.cpp index 26a03b83..bd5c18fe 100644 --- a/tests/test_file_helper.cpp +++ b/tests/test_file_helper.cpp @@ -70,7 +70,7 @@ static void test_split_ext(const spdlog::filename_t::value_type *fname, spdlog::filename_t basename; spdlog::filename_t ext; - std::tie(basename, ext) = file_helper::split_by_extension(filename); + std::tie(basename, ext) = spdlog::details::os::split_by_extension(filename); REQUIRE(basename == expected_base); REQUIRE(ext == expected_ext); } @@ -82,7 +82,7 @@ TEST_CASE("file_helper_split_by_extension", "[file_helper::split_by_extension()] 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."), 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"), @@ -92,7 +92,7 @@ TEST_CASE("file_helper_split_by_extension", "[file_helper::split_by_extension()] 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("///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_fmt_helper.cpp b/tests/test_fmt_helper.cpp index 31b93067..6bd0245f 100644 --- a/tests/test_fmt_helper.cpp +++ b/tests/test_fmt_helper.cpp @@ -2,7 +2,6 @@ #include "includes.h" using spdlog::memory_buf_t; -using spdlog::details::to_string_view; void test_pad2(int n, const char *expected) { memory_buf_t buf; diff --git a/tests/test_pattern_formatter.cpp b/tests/test_pattern_formatter.cpp index 1da38ed3..fd75cb97 100644 --- a/tests/test_pattern_formatter.cpp +++ b/tests/test_pattern_formatter.cpp @@ -3,7 +3,6 @@ #include "test_sink.h" using spdlog::memory_buf_t; -using spdlog::details::to_string_view; // log to str and return it template diff --git a/tests/utils.cpp b/tests/utils.cpp index 6ca82df4..cd594644 100644 --- a/tests/utils.cpp +++ b/tests/utils.cpp @@ -27,7 +27,7 @@ std::string file_contents(const std::string &filename) { return std::string((std::istreambuf_iterator(ifs)), (std::istreambuf_iterator())); } -std::size_t count_lines(const std::string &filename) { +std::size_t count_lines(const spdlog::filename_t &filename) { std::ifstream ifs(filename); if (!ifs) { throw std::runtime_error("Failed open file "); @@ -39,7 +39,7 @@ std::size_t count_lines(const std::string &filename) { return counter; } -void require_message_count(const std::string &filename, const std::size_t messages) { +void require_message_count(const std::filesystem::path &filename, const std::size_t messages) { if (strlen(spdlog::details::os::default_eol) == 0) { REQUIRE(count_lines(filename) == 1); } else { diff --git a/tests/utils.h b/tests/utils.h index 53c09b46..f935fb83 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -2,6 +2,7 @@ #include #include +#include std::size_t count_files(const std::string &folder); @@ -9,9 +10,10 @@ void prepare_logdir(); std::string file_contents(const std::string &filename); -std::size_t count_lines(const std::string &filename); +//std::size_t count_lines(const std::string &filename); +std::size_t count_lines(const std::filesystem::path &filename); -void require_message_count(const std::string &filename, const std::size_t messages); +void require_message_count(const std::filesystem::path &filename, const std::size_t messages); std::size_t get_filesize(const std::string &filename);