Compare commits

...

10 Commits

Author SHA1 Message Date
gabime
22a169bc31 Merge branch 'v1.x' of https://github.com/gabime/spdlog into v1.x 2020-05-27 00:02:51 +03:00
Gabi Melman
ac19803d03 Merge pull request #1571 from IIFE/filename-deadlock
fix deadlock on filename() call. Thanks @IIFE
2020-05-27 00:01:58 +03:00
IIFEgit
95485ee89b keep filename as it's public 2020-05-26 21:59:57 +01:00
gabime
bc61f69058 Bump fmt version to 6.2.1 2020-05-26 23:47:57 +03:00
IIFEgit
0b86d6a451 fix deadlock on filename() call 2020-05-26 21:35:04 +01:00
gabime
0317731dc9 Fix #1569 2020-05-26 23:34:17 +03:00
Gabi Melman
3dedb52163 Merged again pr #1563 2020-05-20 22:50:35 +03:00
Gabi Melman
ad393b83a2 Revert 01dac453db 2020-05-20 22:39:25 +03:00
Gabi Melman
01dac453db Merge pull request #1563 from vekkuli/fix_ringbuffer_sink_last
Fixed ringbuffer_sink last_raw and last_formatted
2020-05-20 22:30:46 +03:00
Jaakko Rantala
03abdf49a0 Fixed ringbuffer_sink last_raw and last_formatted giving the first lim number of elements instead of last. 2020-05-20 19:05:24 +03:00
7 changed files with 60 additions and 23 deletions

View File

@@ -84,7 +84,7 @@ SPDLOG_API bool is_color_terminal() SPDLOG_NOEXCEPT;
SPDLOG_API bool in_terminal(FILE *file) SPDLOG_NOEXCEPT; SPDLOG_API bool in_terminal(FILE *file) SPDLOG_NOEXCEPT;
#if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) #if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target); SPDLOG_API void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target);
#endif #endif
// Return directory name from given path or empty string // Return directory name from given path or empty string

View File

@@ -18,7 +18,7 @@
#include <vector> #include <vector>
// The fmt library version in the form major * 10000 + minor * 100 + patch. // The fmt library version in the form major * 10000 + minor * 100 + patch.
#define FMT_VERSION 60200 #define FMT_VERSION 60201
#ifdef __has_feature #ifdef __has_feature
# define FMT_HAS_FEATURE(x) __has_feature(x) # define FMT_HAS_FEATURE(x) __has_feature(x)
@@ -830,7 +830,8 @@ template <typename Char> struct string_value {
template <typename Context> struct custom_value { template <typename Context> struct custom_value {
using parse_context = basic_format_parse_context<typename Context::char_type>; using parse_context = basic_format_parse_context<typename Context::char_type>;
const void* value; const void* value;
void (*format)(const void* arg, parse_context& parse_ctx, Context& ctx); void (*format)(const void* arg,
typename Context::parse_context_type& parse_ctx, Context& ctx);
}; };
// A formatting argument value. // A formatting argument value.
@@ -890,8 +891,8 @@ template <typename Context> class value {
private: private:
// Formats an argument of a custom type, such as a user-defined class. // Formats an argument of a custom type, such as a user-defined class.
template <typename T, typename Formatter> template <typename T, typename Formatter>
static void format_custom_arg( static void format_custom_arg(const void* arg,
const void* arg, basic_format_parse_context<char_type>& parse_ctx, typename Context::parse_context_type& parse_ctx,
Context& ctx) { Context& ctx) {
Formatter f; Formatter f;
parse_ctx.advance_to(f.parse(parse_ctx)); parse_ctx.advance_to(f.parse(parse_ctx));
@@ -1061,7 +1062,7 @@ template <typename Context> class basic_format_arg {
public: public:
explicit handle(internal::custom_value<Context> custom) : custom_(custom) {} explicit handle(internal::custom_value<Context> custom) : custom_(custom) {}
void format(basic_format_parse_context<char_type>& parse_ctx, void format(typename Context::parse_context_type& parse_ctx,
Context& ctx) const { Context& ctx) const {
custom_.format(custom_.value, parse_ctx, ctx); custom_.format(custom_.value, parse_ctx, ctx);
} }
@@ -1207,13 +1208,16 @@ FMT_CONSTEXPR basic_format_arg<Context> make_arg(const T& value) {
return arg; return arg;
} }
template <bool IS_PACKED, typename Context, typename T, // The type template parameter is there to avoid an ODR violation when using
// a fallback formatter in one translation unit and an implicit conversion in
// another (not recommended).
template <bool IS_PACKED, typename Context, type, typename T,
FMT_ENABLE_IF(IS_PACKED)> FMT_ENABLE_IF(IS_PACKED)>
inline value<Context> make_arg(const T& val) { inline value<Context> make_arg(const T& val) {
return arg_mapper<Context>().map(val); return arg_mapper<Context>().map(val);
} }
template <bool IS_PACKED, typename Context, typename T, template <bool IS_PACKED, typename Context, type, typename T,
FMT_ENABLE_IF(!IS_PACKED)> FMT_ENABLE_IF(!IS_PACKED)>
inline basic_format_arg<Context> make_arg(const T& value) { inline basic_format_arg<Context> make_arg(const T& value) {
return make_arg<Context>(value); return make_arg<Context>(value);
@@ -1272,6 +1276,7 @@ template <typename OutputIt, typename Char> class basic_format_context {
public: public:
using iterator = OutputIt; using iterator = OutputIt;
using format_arg = basic_format_arg<basic_format_context>; using format_arg = basic_format_arg<basic_format_context>;
using parse_context_type = basic_format_parse_context<Char>;
template <typename T> using formatter_type = formatter<T, char_type>; template <typename T> using formatter_type = formatter<T, char_type>;
basic_format_context(const basic_format_context&) = delete; basic_format_context(const basic_format_context&) = delete;
@@ -1346,7 +1351,9 @@ class format_arg_store
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
basic_format_args<Context>(*this), basic_format_args<Context>(*this),
#endif #endif
data_{internal::make_arg<is_packed, Context>(args)...} { data_{internal::make_arg<
is_packed, Context,
internal::mapped_type_constant<Args, Context>::value>(args)...} {
} }
}; };

View File

@@ -9,9 +9,14 @@
#define FMT_OSTREAM_H_ #define FMT_OSTREAM_H_
#include <ostream> #include <ostream>
#include "format.h" #include "format.h"
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
template <typename CHar> class basic_printf_parse_context;
template <typename OutputIt, typename Char> class basic_printf_context;
namespace internal { namespace internal {
template <class Char> class formatbuf : public std::basic_streambuf<Char> { template <class Char> class formatbuf : public std::basic_streambuf<Char> {
@@ -104,14 +109,32 @@ void format_value(buffer<Char>& buf, const T& value,
// Formats an object of type T that has an overloaded ostream operator<<. // Formats an object of type T that has an overloaded ostream operator<<.
template <typename T, typename Char> template <typename T, typename Char>
struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>> struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>>
: formatter<basic_string_view<Char>, Char> { : private formatter<basic_string_view<Char>, Char> {
template <typename Context> auto parse(basic_format_parse_context<Char>& ctx) -> decltype(ctx.begin()) {
auto format(const T& value, Context& ctx) -> decltype(ctx.out()) { return formatter<basic_string_view<Char>, Char>::parse(ctx);
}
template <typename ParseCtx,
FMT_ENABLE_IF(std::is_same<
ParseCtx, basic_printf_parse_context<Char>>::value)>
auto parse(ParseCtx& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename OutputIt>
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx)
-> OutputIt {
basic_memory_buffer<Char> buffer; basic_memory_buffer<Char> buffer;
format_value(buffer, value, ctx.locale()); format_value(buffer, value, ctx.locale());
basic_string_view<Char> str(buffer.data(), buffer.size()); basic_string_view<Char> str(buffer.data(), buffer.size());
return formatter<basic_string_view<Char>, Char>::format(str, ctx); return formatter<basic_string_view<Char>, Char>::format(str, ctx);
} }
template <typename OutputIt>
auto format(const T& value, basic_printf_context<OutputIt, Char>& ctx)
-> OutputIt {
basic_memory_buffer<Char> buffer;
format_value(buffer, value, ctx.locale());
return std::copy(buffer.begin(), buffer.end(), ctx.out());
}
}; };
} // namespace internal } // namespace internal

View File

@@ -189,6 +189,10 @@ using internal::printf; // For printing into memory_buffer.
template <typename Range> class printf_arg_formatter; template <typename Range> class printf_arg_formatter;
template <typename Char>
class basic_printf_parse_context : public basic_format_parse_context<Char> {
using basic_format_parse_context<Char>::basic_format_parse_context;
};
template <typename OutputIt, typename Char> class basic_printf_context; template <typename OutputIt, typename Char> class basic_printf_context;
/** /**
@@ -324,6 +328,7 @@ template <typename OutputIt, typename Char> class basic_printf_context {
using char_type = Char; using char_type = Char;
using iterator = OutputIt; using iterator = OutputIt;
using format_arg = basic_format_arg<basic_printf_context>; using format_arg = basic_format_arg<basic_printf_context>;
using parse_context_type = basic_printf_parse_context<Char>;
template <typename T> using formatter_type = printf_formatter<T>; template <typename T> using formatter_type = printf_formatter<T>;
private: private:
@@ -331,7 +336,7 @@ template <typename OutputIt, typename Char> class basic_printf_context {
OutputIt out_; OutputIt out_;
basic_format_args<basic_printf_context> args_; basic_format_args<basic_printf_context> args_;
basic_format_parse_context<Char> parse_ctx_; parse_context_type parse_ctx_;
static void parse_flags(format_specs& specs, const Char*& it, static void parse_flags(format_specs& specs, const Char*& it,
const Char* end); const Char* end);
@@ -362,7 +367,7 @@ template <typename OutputIt, typename Char> class basic_printf_context {
format_arg arg(int id) const { return args_.get(id); } format_arg arg(int id) const { return args_.get(id); }
basic_format_parse_context<Char>& parse_context() { return parse_ctx_; } parse_context_type& parse_context() { return parse_ctx_; }
FMT_CONSTEXPR void on_error(const char* message) { FMT_CONSTEXPR void on_error(const char* message) {
parse_ctx_.on_error(message); parse_ctx_.on_error(message);

View File

@@ -155,7 +155,7 @@ private:
using details::os::filename_to_str; using details::os::filename_to_str;
using details::os::remove_if_exists; using details::os::remove_if_exists;
filename_t current_file = filename(); filename_t current_file = file_helper_.filename();
if (filenames_q_.full()) if (filenames_q_.full())
{ {
auto old_filename = std::move(filenames_q_.front()); auto old_filename = std::move(filenames_q_.front());

View File

@@ -28,10 +28,11 @@ public:
std::vector<details::log_msg_buffer> last_raw(size_t lim = 0) std::vector<details::log_msg_buffer> last_raw(size_t lim = 0)
{ {
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_); std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
auto n_items = lim > 0 ? (std::min)(lim, q_.size()) : q_.size(); auto items_available = q_.size();
auto n_items = lim > 0 ? (std::min)(lim, items_available) : items_available;
std::vector<details::log_msg_buffer> ret; std::vector<details::log_msg_buffer> ret;
ret.reserve(n_items); ret.reserve(n_items);
for (size_t i = 0; i < n_items; i++) for (size_t i = (items_available - n_items); i < items_available; i++)
{ {
ret.push_back(q_.at(i)); ret.push_back(q_.at(i));
} }
@@ -41,10 +42,11 @@ public:
std::vector<std::string> last_formatted(size_t lim = 0) std::vector<std::string> last_formatted(size_t lim = 0)
{ {
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_); std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
auto n_items = lim > 0 ? (std::min)(lim, q_.size()) : q_.size(); auto items_available = q_.size();
auto n_items = lim > 0 ? (std::min)(lim, items_available) : items_available;
std::vector<std::string> ret; std::vector<std::string> ret;
ret.reserve(n_items); ret.reserve(n_items);
for (size_t i = 0; i < n_items; i++) for (size_t i = (items_available - n_items); i < items_available; i++)
{ {
memory_buf_t formatted; memory_buf_t formatted;
base_sink<Mutex>::formatter_->format(q_.at(i), formatted); base_sink<Mutex>::formatter_->format(q_.at(i), formatted);

View File

@@ -5,6 +5,6 @@
#define SPDLOG_VER_MAJOR 1 #define SPDLOG_VER_MAJOR 1
#define SPDLOG_VER_MINOR 6 #define SPDLOG_VER_MINOR 6
#define SPDLOG_VER_PATCH 0 #define SPDLOG_VER_PATCH 1
#define SPDLOG_VERSION (SPDLOG_VER_MAJOR * 10000 + SPDLOG_VER_MINOR * 100 + SPDLOG_VER_PATCH) #define SPDLOG_VERSION (SPDLOG_VER_MAJOR * 10000 + SPDLOG_VER_MINOR * 100 + SPDLOG_VER_PATCH)