From 2b59393bda0a5b660e64b1526837824579040d68 Mon Sep 17 00:00:00 2001 From: Artem Martynovich Date: Mon, 13 Jul 2015 19:43:22 +0600 Subject: [PATCH] Add wchar_t support for Windows. --- include/spdlog/common.h | 8 +++++ include/spdlog/details/format.h | 7 ++++- include/spdlog/details/os.h | 20 ++++++++++-- include/spdlog/details/spdlog_impl.h | 16 +++++----- include/spdlog/sinks/file_sinks.h | 47 ++++++++++++++-------------- include/spdlog/spdlog.h | 8 ++--- 6 files changed, 68 insertions(+), 38 deletions(-) diff --git a/include/spdlog/common.h b/include/spdlog/common.h index cde5a9eb..8e601547 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -36,6 +36,14 @@ #define SPDLOG_NOEXCEPT throw() #endif +#ifdef WIN32 +typedef std::wstring tstring; +typedef wchar_t tchar; +#else +#define L +typedef std::string tstring; +typedef char tchar; +#endif namespace spdlog { diff --git a/include/spdlog/details/format.h b/include/spdlog/details/format.h index 7ec3b390..f1cfd48b 100644 --- a/include/spdlog/details/format.h +++ b/include/spdlog/details/format.h @@ -2648,6 +2648,11 @@ Any write method will throw ``std::runtime_error`` if the output doesn't fit into the array. You can use one of the following typedefs for common character types: +#ifdef WIN32 +#define TMemoryWriter WMemoryWriter +#else +#define TMemoryWriter MemoryWriter +#endif +--------------+---------------------------+ | Type | Definition | @@ -3152,4 +3157,4 @@ FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) # include "format.cc" #endif -#endif // FMT_FORMAT_H_ \ No newline at end of file +#endif // FMT_FORMAT_H_ diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index 753b6d91..1d010937 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -147,17 +147,33 @@ constexpr inline unsigned short eol_size() #endif //fopen_s on non windows for writing -inline int fopen_s(FILE** fp, const std::string& filename, const char* mode) +inline int fopen_s(FILE** fp, const tstring& filename, tchar* mode) { #ifdef _WIN32 - *fp = _fsopen((filename.c_str()), mode, _SH_DENYWR); + *fp = _wfsopen((filename.c_str()), mode, _SH_DENYWR); return *fp == nullptr; #else *fp = fopen((filename.c_str()), mode); return *fp == nullptr; #endif +} +inline int remove(const tchar* filename) +{ +#ifdef _WIN32 + return _wremove(filename); +#else + return std::remove(filename); +#endif +} +inline int rename(const tchar* filename1, const tchar* filename2) +{ +#ifdef _WIN32 + return _wrename(filename1, filename2); +#else + return std::remove(filename1, filename2); +#endif } //Return utc offset in minutes or -1 on failure diff --git a/include/spdlog/details/spdlog_impl.h b/include/spdlog/details/spdlog_impl.h index cfd6f826..18cd5b65 100644 --- a/include/spdlog/details/spdlog_impl.h +++ b/include/spdlog/details/spdlog_impl.h @@ -48,24 +48,24 @@ inline void spdlog::drop(const std::string &name) } // Create multi/single threaded rotating file logger -inline std::shared_ptr spdlog::rotating_logger_mt(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool force_flush) +inline std::shared_ptr spdlog::rotating_logger_mt(const std::string& logger_name, const tstring& filename, size_t max_file_size, size_t max_files, bool force_flush) { - return create(logger_name, filename, "txt", max_file_size, max_files, force_flush); + return create(logger_name, filename, L"txt", max_file_size, max_files, force_flush); } -inline std::shared_ptr spdlog::rotating_logger_st(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool force_flush) +inline std::shared_ptr spdlog::rotating_logger_st(const std::string& logger_name, const tstring& filename, size_t max_file_size, size_t max_files, bool force_flush) { - return create(logger_name, filename, "txt", max_file_size, max_files, force_flush); + return create(logger_name, filename, L"txt", max_file_size, max_files, force_flush); } // Create file logger which creates new file at midnight): -inline std::shared_ptr spdlog::daily_logger_mt(const std::string& logger_name, const std::string& filename, int hour, int minute, bool force_flush) +inline std::shared_ptr spdlog::daily_logger_mt(const std::string& logger_name, const tstring& filename, int hour, int minute, bool force_flush) { - return create(logger_name, filename, "txt", hour, minute, force_flush); + return create(logger_name, filename, L"txt", hour, minute, force_flush); } -inline std::shared_ptr spdlog::daily_logger_st(const std::string& logger_name, const std::string& filename, int hour, int minute, bool force_flush) +inline std::shared_ptr spdlog::daily_logger_st(const std::string& logger_name, const tstring& filename, int hour, int minute, bool force_flush) { - return create(logger_name, filename, "txt", hour, minute, force_flush); + return create(logger_name, filename, L"txt", hour, minute, force_flush); } diff --git a/include/spdlog/sinks/file_sinks.h b/include/spdlog/sinks/file_sinks.h index 79cbb4e4..5f980ef3 100644 --- a/include/spdlog/sinks/file_sinks.h +++ b/include/spdlog/sinks/file_sinks.h @@ -29,6 +29,7 @@ #include "../details/null_mutex.h" #include "../details/file_helper.h" #include "../details/format.h" +#include "../details/os.h" namespace spdlog { @@ -71,7 +72,7 @@ template class rotating_file_sink : public base_sink < Mutex > { public: - rotating_file_sink(const std::string &base_filename, const std::string &extension, + rotating_file_sink(const tstring &base_filename, const tstring &extension, std::size_t max_size, std::size_t max_files, bool force_flush = false) : _base_filename(base_filename), @@ -102,13 +103,13 @@ protected: } private: - static std::string calc_filename(const std::string& filename, std::size_t index, const std::string& extension) + static tstring calc_filename(const tstring& filename, std::size_t index, const tstring& extension) { - fmt::MemoryWriter w; + fmt::TMemoryWriter w; if (index) - w.write("{}.{}.{}", filename, index, extension); + w.write(L"{}.{}.{}", filename, index, extension); else - w.write("{}.{}", filename, extension); + w.write(L"{}.{}", filename, extension); return w.str(); } @@ -123,28 +124,28 @@ private: _file_helper.close(); for (auto i = _max_files; i > 0; --i) { - std::string src = calc_filename(_base_filename, i - 1, _extension); - std::string target = calc_filename(_base_filename, i, _extension); + tstring src = calc_filename(_base_filename, i - 1, _extension); + tstring target = calc_filename(_base_filename, i, _extension); if (details::file_helper::file_exists(target)) { - if (std::remove(target.c_str()) != 0) + if (details::os::remove(target.c_str()) != 0) { - throw spdlog_ex("rotating_file_sink: failed removing " + target); + throw spdlog_ex("rotating_file_sink: failed removing"); } } - if (details::file_helper::file_exists(src) && std::rename(src.c_str(), target.c_str())) + if (details::file_helper::file_exists(src) && details::os::rename(src.c_str(), target.c_str())) { - throw spdlog_ex("rotating_file_sink: failed renaming " + src + " to " + target); + throw spdlog_ex("rotating_file_sink: failed renaming"); } } _file_helper.reopen(true); } - std::string _base_filename; - std::string _extension; - std::size_t _max_size; - std::size_t _max_files; - std::size_t _current_size; + tstring _base_filename, + _extension; + std::size_t _max_size, + _max_files, + _current_size; details::file_helper _file_helper; }; @@ -160,8 +161,8 @@ class daily_file_sink :public base_sink < Mutex > public: //create daily file sink which rotates on given time daily_file_sink( - const std::string& base_filename, - const std::string& extension, + const tstring& base_filename, + const tstring& extension, int rotation_hour, int rotation_minute, bool force_flush = false) : _base_filename(base_filename), @@ -210,16 +211,16 @@ private: } //Create filename for the form basename.YYYY-MM-DD.extension - static std::string calc_filename(const std::string& basename, const std::string& extension) + static tstring calc_filename(const tstring& basename, const tstring& extension) { std::tm tm = spdlog::details::os::localtime(); - fmt::MemoryWriter w; - w.write("{}_{:04d}-{:02d}-{:02d}_{:02d}-{:02d}.{}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, extension); + fmt::TMemoryWriter w; + w.write(L"{}_{:04d}-{:02d}-{:02d}_{:02d}-{:02d}.{}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, extension); return w.str(); } - std::string _base_filename; - std::string _extension; + tstring _base_filename; + tstring _extension; int _rotation_h; int _rotation_m; std::chrono::system_clock::time_point _rotation_tp; diff --git a/include/spdlog/spdlog.h b/include/spdlog/spdlog.h index 5cec5623..61e9a8b3 100644 --- a/include/spdlog/spdlog.h +++ b/include/spdlog/spdlog.h @@ -76,14 +76,14 @@ void set_sync_mode(); // // Create and register multi/single threaded rotating file logger // -std::shared_ptr rotating_logger_mt(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool force_flush = false); -std::shared_ptr rotating_logger_st(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool force_flush = false); +std::shared_ptr rotating_logger_mt(const std::string& logger_name, const tstring& filename, size_t max_file_size, size_t max_files, bool force_flush = false); +std::shared_ptr rotating_logger_st(const std::string& logger_name, const tstring& filename, size_t max_file_size, size_t max_files, bool force_flush = false); // // Create file logger which creates new file on the given time (default in midnight): // -std::shared_ptr daily_logger_mt(const std::string& logger_name, const std::string& filename, int hour=0, int minute=0, bool force_flush = false); -std::shared_ptr daily_logger_st(const std::string& logger_name, const std::string& filename, int hour=0, int minute=0, bool force_flush = false); +std::shared_ptr daily_logger_mt(const std::string& logger_name, const tstring& filename, int hour=0, int minute=0, bool force_flush = false); +std::shared_ptr daily_logger_st(const std::string& logger_name, const tstring& filename, int hour=0, int minute=0, bool force_flush = false); //