From 3bcd3cef2f4a7bfd2faab88f9871560f1e73f690 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Sun, 30 Jun 2019 19:00:28 -0400 Subject: [PATCH 1/3] Fix deprecation warnings in filename_to_str --- include/spdlog/common.h | 17 ++++-------- include/spdlog/details/os-inl.h | 47 +++++++++++++++++++++------------ include/spdlog/details/os.h | 6 ++--- include/spdlog/logger.h | 6 ++--- 4 files changed, 41 insertions(+), 35 deletions(-) diff --git a/include/spdlog/common.h b/include/spdlog/common.h index ae9f0fa4..2f23e9e4 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -26,11 +26,6 @@ #include #endif //_WIN32 -#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) -#include -#include -#endif - #ifdef SPDLOG_COMPILED_LIB #undef SPDLOG_HEADER_ONLY #define SPDLOG_INLINE @@ -80,11 +75,6 @@ class sink; #if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) using filename_t = std::wstring; #define SPDLOG_FILENAME_T(s) L##s -inline std::string filename_to_str(const filename_t &filename) -{ - std::wstring_convert, wchar_t> c; - return c.to_bytes(filename); -} #else using filename_t = std::string; #define SPDLOG_FILENAME_T(s) s @@ -97,10 +87,13 @@ using err_handler = std::function; // string_view type - either std::string_view or fmt::string_view (pre c++17) #if defined(FMT_USE_STD_STRING_VIEW) -using string_view_t = std::string_view; +template +using basic_string_view_t = std::basic_string_view; #else -using string_view_t = fmt::string_view; +template +using basic_string_view_t = fmt::basic_string_view; #endif +using string_view_t = basic_string_view_t; #if defined(SPDLOG_NO_ATOMIC_LEVELS) using level_t = details::null_atomic_int; diff --git a/include/spdlog/details/os-inl.h b/include/spdlog/details/os-inl.h index e0809d9b..dd4fc8f9 100644 --- a/include/spdlog/details/os-inl.h +++ b/include/spdlog/details/os-inl.h @@ -36,6 +36,10 @@ #include #endif +#if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES) +#include +#endif + #else // unix #include @@ -342,13 +346,12 @@ SPDLOG_INLINE void sleep_for_millis(int milliseconds) SPDLOG_NOEXCEPT // wchar support for windows file names (SPDLOG_WCHAR_FILENAMES must be defined) #if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) -SPDLOG_INLINE std::string filename_to_str(const filename_t &filename) SPDLOG_NOEXCEPT +SPDLOG_INLINE std::string filename_to_str(const filename_t &filename) { - std::wstring_convert, wchar_t> c; - return c.to_bytes(filename); + return wstr_to_str(filename); } #else -SPDLOG_INLINE std::string filename_to_str(const filename_t &filename) SPDLOG_NOEXCEPT +SPDLOG_INLINE std::string filename_to_str(const filename_t &filename) { return filename; } @@ -398,28 +401,38 @@ SPDLOG_INLINE bool in_terminal(FILE *file) SPDLOG_NOEXCEPT #endif } -#if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) && defined(_WIN32) -SPDLOG_INLINE void wbuf_to_utf8buf(const fmt::wmemory_buffer &wbuf, fmt::memory_buffer &target) +#if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) +SPDLOG_INLINE std::string wstr_to_str(basic_string_view_t wstr) { - int wbuf_size = static_cast(wbuf.size()); - if (wbuf_size == 0) + if (wstr.size() > static_cast(std::numeric_limits::max())) { - return; + throw spdlog::spdlog_ex("UTF-16 string is too big to be converted to UTF-8"); } - auto result_size = ::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, NULL, 0, NULL, NULL); + int wstr_size = static_cast(wstr.size()); + if (wstr_size == 0) + { + return { }; + } + + int result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, NULL, 0, NULL, NULL); if (result_size > 0) { - target.resize(result_size); - ::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, &target.data()[0], result_size, NULL, NULL); - } - else - { - throw spdlog::spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError())); + std::string result; + result.resize(result_size); + result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, &result[0], result_size, NULL, NULL); + + if (result_size > 0) + { + result.resize(result_size); + return result; + } } + + throw spdlog::spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError())); } -#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT) && _WIN32 +#endif // (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) } // namespace os } // namespace details diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index 4afe0cb9..30c569c5 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -68,7 +68,7 @@ size_t thread_id() SPDLOG_NOEXCEPT; // See https://github.com/gabime/spdlog/issues/609 void sleep_for_millis(int milliseconds) SPDLOG_NOEXCEPT; -std::string filename_to_str(const filename_t &filename) SPDLOG_NOEXCEPT; +std::string filename_to_str(const filename_t &filename); int pid() SPDLOG_NOEXCEPT; @@ -80,8 +80,8 @@ bool is_color_terminal() SPDLOG_NOEXCEPT; // Source: https://github.com/agauniyal/rang/ bool in_terminal(FILE *file) SPDLOG_NOEXCEPT; -#if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) && defined(_WIN32) -void wbuf_to_utf8buf(const fmt::wmemory_buffer &wbuf, fmt::memory_buffer &target); +#if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) +std::string wstr_to_str(basic_string_view_t wstr); #endif } // namespace os diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index bc627c4b..59cb5db6 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -243,9 +243,9 @@ public: // format to wmemory_buffer and convert to utf8 fmt::wmemory_buffer wbuf; fmt::format_to(wbuf, fmt, args...); - fmt::memory_buffer buf; - details::os::wbuf_to_utf8buf(wbuf, buf); - details::log_msg log_msg(source, name_, lvl, string_view_t(buf.data(), buf.size())); + + const auto payload = details::os::wstr_to_str({ wbuf.data(), wbuf.size() }); + details::log_msg log_msg(source, name_, lvl, payload); sink_it_(log_msg); } catch (const std::exception &ex) From f529afa625c4a9bf4111620a788517cc9652000c Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Sun, 30 Jun 2019 21:34:19 -0400 Subject: [PATCH 2/3] Use stack allocated space when possible --- include/spdlog/details/os-inl.h | 24 +++++++++++++++--------- include/spdlog/details/os.h | 2 +- include/spdlog/logger.h | 6 ++++-- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/include/spdlog/details/os-inl.h b/include/spdlog/details/os-inl.h index dd4fc8f9..3c2fc9e9 100644 --- a/include/spdlog/details/os-inl.h +++ b/include/spdlog/details/os-inl.h @@ -348,7 +348,9 @@ SPDLOG_INLINE void sleep_for_millis(int milliseconds) SPDLOG_NOEXCEPT #if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) SPDLOG_INLINE std::string filename_to_str(const filename_t &filename) { - return wstr_to_str(filename); + fmt::memory_buffer buf; + wstr_to_utf8buf(filename, buf); + return fmt::to_string(buf); } #else SPDLOG_INLINE std::string filename_to_str(const filename_t &filename) @@ -402,7 +404,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 std::string wstr_to_str(basic_string_view_t wstr) +SPDLOG_INLINE void wstr_to_utf8buf(basic_string_view_t wstr, fmt::memory_buffer &target) { if (wstr.size() > static_cast(std::numeric_limits::max())) { @@ -412,21 +414,25 @@ SPDLOG_INLINE std::string wstr_to_str(basic_string_view_t wstr) int wstr_size = static_cast(wstr.size()); if (wstr_size == 0) { - return { }; + target.resize(0); + return; } - int result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, NULL, 0, NULL, NULL); + int result_size = target.capacity(); + if ((wstr_size + 1) * 2 > result_size) + { + result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, NULL, 0, NULL, NULL); + } if (result_size > 0) { - std::string result; - result.resize(result_size); - result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, &result[0], result_size, NULL, NULL); + target.resize(result_size); + result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, target.data(), result_size, NULL, NULL); if (result_size > 0) { - result.resize(result_size); - return result; + target.resize(result_size); + return; } } diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index 30c569c5..27694494 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -81,7 +81,7 @@ bool is_color_terminal() SPDLOG_NOEXCEPT; bool in_terminal(FILE *file) SPDLOG_NOEXCEPT; #if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) -std::string wstr_to_str(basic_string_view_t wstr); +void wstr_to_utf8buf(basic_string_view_t wstr, fmt::memory_buffer &target); #endif } // namespace os diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index 59cb5db6..1d831362 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -244,8 +244,10 @@ public: fmt::wmemory_buffer wbuf; fmt::format_to(wbuf, fmt, args...); - const auto payload = details::os::wstr_to_str({ wbuf.data(), wbuf.size() }); - details::log_msg log_msg(source, name_, lvl, payload); + fmt::memory_buffer buf; + details::os::wstr_to_utf8buf(basic_string_view_t(wbuf.data(), wbuf.size()), buf); + + details::log_msg log_msg(source, name_, lvl, string_view_t(buf.data(), buf.size())); sink_it_(log_msg); } catch (const std::exception &ex) From 9e602a491b71ddb00cd76ba6f7a2c5c66661d72e Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Sun, 30 Jun 2019 21:43:28 -0400 Subject: [PATCH 3/3] Silence narrowing warning --- include/spdlog/details/os-inl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/spdlog/details/os-inl.h b/include/spdlog/details/os-inl.h index 3c2fc9e9..0675436b 100644 --- a/include/spdlog/details/os-inl.h +++ b/include/spdlog/details/os-inl.h @@ -418,7 +418,7 @@ SPDLOG_INLINE void wstr_to_utf8buf(basic_string_view_t wstr, fmt::memor return; } - int result_size = target.capacity(); + int result_size = static_cast(target.capacity()); if ((wstr_size + 1) * 2 > result_size) { result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, NULL, 0, NULL, NULL);