Better support for / separators on Windows, improve wchar filename coverage

This commit is contained in:
Charles Milette
2021-01-06 03:55:46 -05:00
parent aa2053a575
commit a453bccff0
14 changed files with 163 additions and 112 deletions

View File

@@ -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<void(const std::string &err_msg)>;
using string_view_t = fmt::basic_string_view<char>;
using wstring_view_t = fmt::basic_string_view<wchar_t>;
using memory_buf_t = fmt::basic_memory_buffer<char, 250>;
using filename_memory_buf_t = fmt::basic_memory_buffer<filename_t::value_type, 250>;
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
#ifndef _WIN32

View File

@@ -118,7 +118,7 @@ SPDLOG_INLINE std::tuple<filename_t, filename_t> 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());

View File

@@ -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{};
}

View File

@@ -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);

View File

@@ -13,11 +13,13 @@
#include <spdlog/fmt/fmt.h>
#include <spdlog/formatter.h>
#include <algorithm>
#include <array>
#include <chrono>
#include <ctime>
#include <cctype>
#include <cstring>
#include <iterator>
#include <memory>
#include <mutex>
#include <string>
@@ -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<const char*> begin(filename + std::strlen(filename));
const std::reverse_iterator<const char*> 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
{

View File

@@ -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 <fmt/format.h> so set your -I flag